From 35613821b7cfcc432c167e8b90d2a586080c1798 Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Sun, 15 Nov 2020 20:16:15 +0100 Subject: [PATCH 1/7] Allow for different types of inventories Added anvil, barrel, beacon, blast furnace, brewing stand, cartography table, crafting table, dispenser, dropper, enchanting table, ender chest, furnace, grindstone, hopper, shulker box, smithing table, smoker and stonecutter inventories. --- IF/pom.xml | 191 +++ .../inventoryframework/HumanEntityCache.java | 352 ++-- .../UnsupportedVersionException.java | 21 + .../exception/XMLLoadException.java | 84 +- .../exception/XMLReflectionException.java | 70 +- .../inventoryframework/font/CSVFont.java | 130 +- .../inventoryframework/font/util/Font.java | 550 +++---- .../inventoryframework/gui}/GuiItem.java | 430 ++--- .../inventoryframework/gui}/GuiListener.java | 561 ++++--- .../gui/InventoryComponent.java | 499 ++++++ .../inventoryframework/gui/type/AnvilGui.java | 348 ++++ .../gui/type/BarrelGui.java | 224 +++ .../gui/type/BeaconGui.java | 242 +++ .../gui/type/BlastFurnaceGui.java | 268 +++ .../gui/type/BrewingStandGui.java | 318 ++++ .../gui/type/CartographyTableGui.java | 325 ++++ .../inventoryframework/gui/type/ChestGui.java | 281 ++++ .../gui/type/CraftingTableGui.java | 243 +++ .../gui/type/DispenserGui.java | 218 +++ .../gui/type/DropperGui.java | 218 +++ .../gui/type/EnchantingTableGui.java | 268 +++ .../gui/type/EnderChestGui.java | 223 +++ .../gui/type/FurnaceGui.java | 268 +++ .../gui/type/GrindstoneGui.java | 296 ++++ .../gui/type/HopperGui.java | 218 +++ .../gui/type/ShulkerBoxGui.java | 223 +++ .../gui/type/SmithingTableGui.java | 336 ++++ .../gui/type/SmokerGui.java | 268 +++ .../gui/type/StonecutterGui.java | 296 ++++ .../gui/type/util}/Gui.java | 1346 +++++++-------- .../gui/type/util/NamedGui.java | 82 + .../inventoryframework/pane/Flippable.java | 126 +- .../inventoryframework/pane/MasonryPane.java | 570 ++++--- .../inventoryframework/pane/Orientable.java | 140 +- .../inventoryframework/pane/OutlinePane.java | 960 ++++++----- .../pane/PaginatedPane.java | 718 ++++---- .../inventoryframework/pane/Pane.java | 1442 +++++++++-------- .../inventoryframework/pane/Rotatable.java | 102 +- .../inventoryframework/pane/StaticPane.java | 655 ++++---- .../pane/component/CycleButton.java | 412 +++-- .../pane/component/Label.java | 436 ++--- .../pane/component/PercentageBar.java | 317 ++-- .../pane/component/Slider.java | 337 ++-- .../pane/component/ToggleButton.java | 431 +++-- .../pane/component/util/VariableBar.java | 506 +++--- .../inventoryframework/pane/util/Mask.java | 288 ++-- .../inventoryframework/util/CSVUtil.java | 198 +-- .../inventoryframework/util/GeometryUtil.java | 120 +- .../inventoryframework/util/SkullUtil.java | 134 +- .../inventoryframework/util/UUIDTagType.java | 116 +- .../inventoryframework/util/XMLUtil.java | 164 +- .../util/version/Version.java | 77 + .../util/version/VersionMatcher.java | 291 ++++ .../main/resources/fonts/birch-planks.csv | 234 +-- .../src}/main/resources/fonts/black.csv | 234 +-- {src => IF/src}/main/resources/fonts/blue.csv | 234 +-- .../src}/main/resources/fonts/brown.csv | 234 +-- .../src}/main/resources/fonts/cobblestone.csv | 234 +-- {src => IF/src}/main/resources/fonts/cyan.csv | 234 +-- .../src}/main/resources/fonts/diamond.csv | 234 +-- {src => IF/src}/main/resources/fonts/dirt.csv | 234 +-- {src => IF/src}/main/resources/fonts/gold.csv | 234 +-- {src => IF/src}/main/resources/fonts/gray.csv | 234 +-- .../src}/main/resources/fonts/green.csv | 234 +-- .../main/resources/fonts/jungle-planks.csv | 234 +-- .../src}/main/resources/fonts/letter-cube.csv | 188 +-- .../src}/main/resources/fonts/light-blue.csv | 234 +-- .../src}/main/resources/fonts/light-gray.csv | 234 +-- {src => IF/src}/main/resources/fonts/lime.csv | 234 +-- .../src}/main/resources/fonts/magenta.csv | 234 +-- .../src}/main/resources/fonts/monitor.csv | 292 ++-- .../src}/main/resources/fonts/oak-log.csv | 234 +-- .../src}/main/resources/fonts/oak-planks.csv | 236 +-- .../src}/main/resources/fonts/orange.csv | 234 +-- {src => IF/src}/main/resources/fonts/pink.csv | 234 +-- .../src}/main/resources/fonts/plush.csv | 234 +-- .../src}/main/resources/fonts/pumpkin.csv | 232 +-- .../src}/main/resources/fonts/purple.csv | 234 +-- .../src}/main/resources/fonts/quartz.csv | 234 +-- .../src}/main/resources/fonts/rainbow.csv | 234 +-- {src => IF/src}/main/resources/fonts/red.csv | 234 +-- .../main/resources/fonts/spruce-planks.csv | 234 +-- .../src}/main/resources/fonts/stone.csv | 234 +-- .../src}/main/resources/fonts/watermelon.csv | 234 +-- .../src}/main/resources/fonts/white.csv | 234 +-- .../src}/main/resources/fonts/yellow.csv | 234 +-- .../gui/InventoryComponentTest.java | 99 ++ .../pane/MasonryPaneTest.java | 73 +- .../pane/OutlinePaneTest.java | 94 +- .../pane/PaginatedPaneTest.java | 80 +- .../inventoryframework/pane/PaneTest.java | 20 + .../pane/StaticPaneTest.java | 64 +- .../pane/component/CycleButtonTest.java | 60 +- .../pane/util/MaskTest.java | 148 +- .../inventoryframework/util/CSVUtilTest.java | 60 +- .../util/GeometryUtilTest.java | 64 +- .../util/PaginatedPaneTest.java | 108 +- .../src}/test/resources/test-csv-file.csv | 10 +- nms/1_14_R1/pom.xml | 29 + .../nms/v1_14_R1/AnvilInventoryImpl.java | 304 ++++ .../nms/v1_14_R1/BeaconInventoryImpl.java | 181 +++ .../CartographyTableInventoryImpl.java | 199 +++ .../EnchantingTableInventoryImpl.java | 194 +++ .../nms/v1_14_R1/GrindstoneInventoryImpl.java | 227 +++ .../v1_14_R1/StonecutterInventoryImpl.java | 199 +++ nms/1_15_R1/pom.xml | 29 + .../nms/v1_15_R1/AnvilInventoryImpl.java | 304 ++++ .../nms/v1_15_R1/BeaconInventoryImpl.java | 181 +++ .../CartographyTableInventoryImpl.java | 199 +++ .../EnchantingTableInventoryImpl.java | 194 +++ .../nms/v1_15_R1/GrindstoneInventoryImpl.java | 227 +++ .../v1_15_R1/StonecutterInventoryImpl.java | 199 +++ nms/1_16_R1/pom.xml | 29 + .../nms/v1_16_R1/AnvilInventoryImpl.java | 241 +++ .../nms/v1_16_R1/BeaconInventoryImpl.java | 181 +++ .../CartographyTableInventoryImpl.java | 199 +++ .../EnchantingTableInventoryImpl.java | 194 +++ .../nms/v1_16_R1/GrindstoneInventoryImpl.java | 227 +++ .../v1_16_R1/SmithingTableInventoryImpl.java | 226 +++ .../v1_16_R1/StonecutterInventoryImpl.java | 199 +++ nms/1_16_R2/pom.xml | 29 + .../nms/v1_16_R2/AnvilInventoryImpl.java | 241 +++ .../nms/v1_16_R2/BeaconInventoryImpl.java | 178 ++ .../CartographyTableInventoryImpl.java | 196 +++ .../EnchantingTableInventoryImpl.java | 191 +++ .../nms/v1_16_R2/GrindstoneInventoryImpl.java | 224 +++ .../v1_16_R2/SmithingTableInventoryImpl.java | 224 +++ .../v1_16_R2/StonecutterInventoryImpl.java | 196 +++ nms/1_16_R3/pom.xml | 30 + .../nms/v1_16_R3/AnvilInventoryImpl.java | 241 +++ .../nms/v1_16_R3/BeaconInventoryImpl.java | 181 +++ .../CartographyTableInventoryImpl.java | 199 +++ .../EnchantingTableInventoryImpl.java | 194 +++ .../nms/v1_16_R3/GrindstoneInventoryImpl.java | 227 +++ .../v1_16_R3/SmithingTableInventoryImpl.java | 227 +++ .../v1_16_R3/StonecutterInventoryImpl.java | 199 +++ nms/abstraction/pom.xml | 24 + .../abstraction/AnvilInventory.java | 121 ++ .../abstraction/BeaconInventory.java | 57 + .../CartographyTableInventory.java | 58 + .../abstraction/EnchantingTableInventory.java | 58 + .../abstraction/GrindstoneInventory.java | 58 + .../abstraction/SmithingTableInventory.java | 102 ++ .../abstraction/StonecutterInventory.java | 58 + pom.xml | 47 +- 145 files changed, 24087 insertions(+), 10186 deletions(-) create mode 100644 IF/pom.xml rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java (95%) create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/UnsupportedVersionException.java rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java (90%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java (96%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java (97%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java (96%) rename {src/main/java/com/github/stefvanschie/inventoryframework => IF/src/main/java/com/github/stefvanschie/inventoryframework/gui}/GuiItem.java (95%) rename {src/main/java/com/github/stefvanschie/inventoryframework => IF/src/main/java/com/github/stefvanschie/inventoryframework/gui}/GuiListener.java (56%) create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponent.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/AnvilGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BarrelGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BeaconGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BlastFurnaceGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BrewingStandGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CartographyTableGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ChestGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CraftingTableGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DispenserGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DropperGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnchantingTableGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnderChestGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/FurnaceGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/GrindstoneGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/HopperGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ShulkerBoxGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmithingTableGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmokerGui.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/StonecutterGui.java rename {src/main/java/com/github/stefvanschie/inventoryframework => IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util}/Gui.java (63%) create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/NamedGui.java rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java (96%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java (84%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java (96%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java (83%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java (86%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java (87%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java (97%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java (80%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java (76%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java (90%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java (80%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java (81%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java (77%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java (89%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java (95%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java (97%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java (97%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java (97%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java (96%) rename {src => IF/src}/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java (97%) create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java create mode 100644 IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java rename {src => IF/src}/main/resources/fonts/birch-planks.csv (98%) rename {src => IF/src}/main/resources/fonts/black.csv (98%) rename {src => IF/src}/main/resources/fonts/blue.csv (98%) rename {src => IF/src}/main/resources/fonts/brown.csv (98%) rename {src => IF/src}/main/resources/fonts/cobblestone.csv (98%) rename {src => IF/src}/main/resources/fonts/cyan.csv (98%) rename {src => IF/src}/main/resources/fonts/diamond.csv (98%) rename {src => IF/src}/main/resources/fonts/dirt.csv (98%) rename {src => IF/src}/main/resources/fonts/gold.csv (98%) rename {src => IF/src}/main/resources/fonts/gray.csv (98%) rename {src => IF/src}/main/resources/fonts/green.csv (98%) rename {src => IF/src}/main/resources/fonts/jungle-planks.csv (98%) rename {src => IF/src}/main/resources/fonts/letter-cube.csv (98%) rename {src => IF/src}/main/resources/fonts/light-blue.csv (98%) rename {src => IF/src}/main/resources/fonts/light-gray.csv (98%) rename {src => IF/src}/main/resources/fonts/lime.csv (98%) rename {src => IF/src}/main/resources/fonts/magenta.csv (98%) rename {src => IF/src}/main/resources/fonts/monitor.csv (98%) rename {src => IF/src}/main/resources/fonts/oak-log.csv (98%) rename {src => IF/src}/main/resources/fonts/oak-planks.csv (98%) rename {src => IF/src}/main/resources/fonts/orange.csv (98%) rename {src => IF/src}/main/resources/fonts/pink.csv (98%) rename {src => IF/src}/main/resources/fonts/plush.csv (98%) rename {src => IF/src}/main/resources/fonts/pumpkin.csv (98%) rename {src => IF/src}/main/resources/fonts/purple.csv (98%) rename {src => IF/src}/main/resources/fonts/quartz.csv (98%) rename {src => IF/src}/main/resources/fonts/rainbow.csv (98%) rename {src => IF/src}/main/resources/fonts/red.csv (98%) rename {src => IF/src}/main/resources/fonts/spruce-planks.csv (98%) rename {src => IF/src}/main/resources/fonts/stone.csv (98%) rename {src => IF/src}/main/resources/fonts/watermelon.csv (98%) rename {src => IF/src}/main/resources/fonts/white.csv (98%) rename {src => IF/src}/main/resources/fonts/yellow.csv (98%) create mode 100644 IF/src/test/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponentTest.java rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java (94%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java (97%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java (97%) create mode 100644 IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaneTest.java rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java (97%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java (97%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java (85%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java (97%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java (97%) rename {src => IF/src}/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java (96%) rename {src => IF/src}/test/resources/test-csv-file.csv (89%) create mode 100644 nms/1_14_R1/pom.xml create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/AnvilInventoryImpl.java create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/BeaconInventoryImpl.java create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/CartographyTableInventoryImpl.java create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/EnchantingTableInventoryImpl.java create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/GrindstoneInventoryImpl.java create mode 100644 nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/StonecutterInventoryImpl.java create mode 100644 nms/1_15_R1/pom.xml create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/AnvilInventoryImpl.java create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/BeaconInventoryImpl.java create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/CartographyTableInventoryImpl.java create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/EnchantingTableInventoryImpl.java create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/GrindstoneInventoryImpl.java create mode 100644 nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/StonecutterInventoryImpl.java create mode 100644 nms/1_16_R1/pom.xml create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/AnvilInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/BeaconInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/CartographyTableInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/EnchantingTableInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/GrindstoneInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/SmithingTableInventoryImpl.java create mode 100644 nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/StonecutterInventoryImpl.java create mode 100644 nms/1_16_R2/pom.xml create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/AnvilInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/BeaconInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/CartographyTableInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/EnchantingTableInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/GrindstoneInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/SmithingTableInventoryImpl.java create mode 100644 nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/StonecutterInventoryImpl.java create mode 100644 nms/1_16_R3/pom.xml create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/AnvilInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/BeaconInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/CartographyTableInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/EnchantingTableInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/GrindstoneInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/SmithingTableInventoryImpl.java create mode 100644 nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/StonecutterInventoryImpl.java create mode 100644 nms/abstraction/pom.xml create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/AnvilInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/BeaconInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/CartographyTableInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/EnchantingTableInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/GrindstoneInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/SmithingTableInventory.java create mode 100644 nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/StonecutterInventory.java diff --git a/IF/pom.xml b/IF/pom.xml new file mode 100644 index 00000000..64481c4d --- /dev/null +++ b/IF/pom.xml @@ -0,0 +1,191 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + + 4.0.0 + + IF + jar + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + mojang-repo + https://libraries.minecraft.net/ + + + + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + com.github.stefvanschie.inventoryframework + 1_14_R1 + 0.7.2 + compile + + + com.github.stefvanschie.inventoryframework + 1_15_R1 + 0.7.2 + compile + + + com.github.stefvanschie.inventoryframework + 1_16_R1 + 0.7.2 + compile + + + com.github.stefvanschie.inventoryframework + 1_16_R2 + 0.7.2 + compile + + + com.github.stefvanschie.inventoryframework + 1_16_R3 + 0.7.2 + compile + + + org.spigotmc + spigot-api + 1.16.4-R0.1-SNAPSHOT + provided + + + com.mojang + authlib + 1.5.21 + provided + + + org.junit.jupiter + junit-jupiter-api + 5.3.1 + test + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + deploy + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + + + ${project.parent.name}-${project.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + + org.junit.platform + junit-platform-surefire-provider + 1.2.0-M1 + + + org.junit.jupiter + junit-jupiter-engine + 5.2.0 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + package + + shade + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.1 + + + attach-javadocs + + jar + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java similarity index 95% rename from src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java index d6737dc4..bb909b5a 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/HumanEntityCache.java @@ -1,176 +1,176 @@ -package com.github.stefvanschie.inventoryframework; - -import org.bukkit.entity.HumanEntity; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Map; - -/** - * A class for containing players and their inventory state for later use - * - * @since 0.4.0 - */ -public class HumanEntityCache { - - /** - * A map containing the player's and their inventory contents. The ItemStack[] contains only the hotbar and - * inventory contents. 0-8 is the hotbar, with 9-35 being the inventory both starting in the top-left corner and - * continuing in reading order. - */ - private final Map inventories = new HashMap<>(); - - /** - * Stores this player's inventory in the cache. If the player was already stored, their cache will be overwritten. - * Clears the player's inventory afterwards. - * - * @param humanEntity the human entity to keep in the cache - */ - public void storeAndClear(@NotNull HumanEntity humanEntity) { - store(humanEntity); - - Inventory inventory = humanEntity.getInventory(); - for (int i = 0; i < 36; i++) { - inventory.clear(i); - } - } - - /** - * Restores the contents of the specified human entity, clearing the cache afterwards. - * This method will fail silently if no cache is available. - * - * @param humanEntity the human entity to restore its cache for - * @since 0.5.19 - */ - public void restoreAndForget(@NotNull HumanEntity humanEntity) { - restore(humanEntity); - clearCache(humanEntity); - } - - /** - * Restores all players' contents into their inventory, clearing the cache afterwards. - * - * @since 0.5.19 - */ - public void restoreAndForgetAll() { - restoreAll(); - clearCache(); - } - - /** - * Adds the given item stack to the human entity's cached inventory. The returned amount is the amount of items of - * the provided item stack that could not be put into the cached inventory. This number will always be equal or - * less than the amount of items in the provided item stack, but no less than zero. The item stack provided will not - * be updated with this leftover amount. If the human entity provided is not in the human entity cache, this method - * will return an {@link IllegalStateException}. The items will be added to the inventory in the same way as the - * items are stored. The items may be added to an already existing item stack, but the item stack's amount will - * never go over the maximum stack size. - * - * @param humanEntity the human entity to add the item to - * @param item the item to add to the cached inventory - * @return the amount of leftover items that couldn't be fit in the cached inventory - * @throws IllegalStateException if the human entity's inventory is not cached - * @since 0.6.1 - */ - protected int add(@NotNull HumanEntity humanEntity, @NotNull ItemStack item) { - ItemStack[] items = inventories.get(humanEntity); - - if (items == null) { - throw new IllegalStateException("The human entity '" + humanEntity.getUniqueId().toString() + - "' does not have a cached inventory"); - } - - int amountPutIn = 0; - - for (int i = 0; i < items.length; i++) { - ItemStack itemStack = items[i]; - - if (itemStack == null) { - items[i] = item.clone(); - items[i].setAmount(item.getAmount() - amountPutIn); - amountPutIn = item.getAmount(); - break; - } - - if (!itemStack.isSimilar(item)) { - continue; - } - - int additionalAmount = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), item.getAmount()); - - itemStack.setAmount(itemStack.getAmount() + additionalAmount); - amountPutIn += additionalAmount; - - if (amountPutIn == item.getAmount()) { - break; - } - } - - return item.getAmount() - amountPutIn; - } - - /** - * Stores this player's inventory in the cache. If the player was already stored, their cache will be overwritten. - * - * @param humanEntity the human entity to keep in the cache - * @since 0.4.0 - */ - private void store(@NotNull HumanEntity humanEntity) { - ItemStack[] items = new ItemStack[36]; - - for (int i = 0 ; i < 36; i++) { - items[i] = humanEntity.getInventory().getItem(i); - } - - inventories.put(humanEntity, items); - } - - /** - * Restores the contents of the specified human entity. This method will fail silently if no cache is available. The - * cache will not be cleared. - * - * @param humanEntity the human entity to restore its cache for - * @since 0.4.0 - */ - private void restore(@NotNull HumanEntity humanEntity) { - ItemStack[] items = inventories.get(humanEntity); - - if (items == null) { - return; - } - - for (int i = 0; i < items.length; i++) { - humanEntity.getInventory().setItem(i, items[i]); - } - } - - /** - * Restores all players' contents into their inventory. The cache will not be cleared. - * - * @since 0.4.0 - */ - private void restoreAll() { - inventories.keySet().forEach(this::restore); - } - - /** - * Clear the cache for the specified human entity - * - * @param humanEntity the human entity to clear the cache for - * @since 0.4.0 - */ - private void clearCache(@NotNull HumanEntity humanEntity) { - inventories.remove(humanEntity); - } - - /** - * This clears the cache. - * - * @since 0.4.0 - */ - private void clearCache() { - inventories.clear(); - } -} +package com.github.stefvanschie.inventoryframework; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * A class for containing players and their inventory state for later use + * + * @since 0.4.0 + */ +public class HumanEntityCache { + + /** + * A map containing the player's and their inventory contents. The ItemStack[] contains only the hotbar and + * inventory contents. 0-8 is the hotbar, with 9-35 being the inventory both starting in the top-left corner and + * continuing in reading order. + */ + private final Map inventories = new HashMap<>(); + + /** + * Stores this player's inventory in the cache. If the player was already stored, their cache will be overwritten. + * Clears the player's inventory afterwards. + * + * @param humanEntity the human entity to keep in the cache + */ + public void storeAndClear(@NotNull HumanEntity humanEntity) { + store(humanEntity); + + Inventory inventory = humanEntity.getInventory(); + for (int i = 0; i < 36; i++) { + inventory.clear(i); + } + } + + /** + * Restores the contents of the specified human entity, clearing the cache afterwards. + * This method will fail silently if no cache is available. + * + * @param humanEntity the human entity to restore its cache for + * @since 0.5.19 + */ + public void restoreAndForget(@NotNull HumanEntity humanEntity) { + restore(humanEntity); + clearCache(humanEntity); + } + + /** + * Restores all players' contents into their inventory, clearing the cache afterwards. + * + * @since 0.5.19 + */ + public void restoreAndForgetAll() { + restoreAll(); + clearCache(); + } + + /** + * Adds the given item stack to the human entity's cached inventory. The returned amount is the amount of items of + * the provided item stack that could not be put into the cached inventory. This number will always be equal or + * less than the amount of items in the provided item stack, but no less than zero. The item stack provided will not + * be updated with this leftover amount. If the human entity provided is not in the human entity cache, this method + * will return an {@link IllegalStateException}. The items will be added to the inventory in the same way as the + * items are stored. The items may be added to an already existing item stack, but the item stack's amount will + * never go over the maximum stack size. + * + * @param humanEntity the human entity to add the item to + * @param item the item to add to the cached inventory + * @return the amount of leftover items that couldn't be fit in the cached inventory + * @throws IllegalStateException if the human entity's inventory is not cached + * @since 0.6.1 + */ + public int add(@NotNull HumanEntity humanEntity, @NotNull ItemStack item) { + ItemStack[] items = inventories.get(humanEntity); + + if (items == null) { + throw new IllegalStateException("The human entity '" + humanEntity.getUniqueId().toString() + + "' does not have a cached inventory"); + } + + int amountPutIn = 0; + + for (int i = 0; i < items.length; i++) { + ItemStack itemStack = items[i]; + + if (itemStack == null) { + items[i] = item.clone(); + items[i].setAmount(item.getAmount() - amountPutIn); + amountPutIn = item.getAmount(); + break; + } + + if (!itemStack.isSimilar(item)) { + continue; + } + + int additionalAmount = Math.min(itemStack.getMaxStackSize() - itemStack.getAmount(), item.getAmount()); + + itemStack.setAmount(itemStack.getAmount() + additionalAmount); + amountPutIn += additionalAmount; + + if (amountPutIn == item.getAmount()) { + break; + } + } + + return item.getAmount() - amountPutIn; + } + + /** + * Stores this player's inventory in the cache. If the player was already stored, their cache will be overwritten. + * + * @param humanEntity the human entity to keep in the cache + * @since 0.4.0 + */ + private void store(@NotNull HumanEntity humanEntity) { + ItemStack[] items = new ItemStack[36]; + + for (int i = 0 ; i < 36; i++) { + items[i] = humanEntity.getInventory().getItem(i); + } + + inventories.put(humanEntity, items); + } + + /** + * Restores the contents of the specified human entity. This method will fail silently if no cache is available. The + * cache will not be cleared. + * + * @param humanEntity the human entity to restore its cache for + * @since 0.4.0 + */ + private void restore(@NotNull HumanEntity humanEntity) { + ItemStack[] items = inventories.get(humanEntity); + + if (items == null) { + return; + } + + for (int i = 0; i < items.length; i++) { + humanEntity.getInventory().setItem(i, items[i]); + } + } + + /** + * Restores all players' contents into their inventory. The cache will not be cleared. + * + * @since 0.4.0 + */ + private void restoreAll() { + inventories.keySet().forEach(this::restore); + } + + /** + * Clear the cache for the specified human entity + * + * @param humanEntity the human entity to clear the cache for + * @since 0.4.0 + */ + private void clearCache(@NotNull HumanEntity humanEntity) { + inventories.remove(humanEntity); + } + + /** + * This clears the cache. + * + * @since 0.4.0 + */ + private void clearCache() { + inventories.clear(); + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/UnsupportedVersionException.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/UnsupportedVersionException.java new file mode 100644 index 00000000..f80468c4 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/UnsupportedVersionException.java @@ -0,0 +1,21 @@ +package com.github.stefvanschie.inventoryframework.exception; + +import org.jetbrains.annotations.NotNull; + +/** + * An exception indicating that the provided version is not supported. + * + * @since 0.8.0 + */ +public class UnsupportedVersionException extends RuntimeException { + + /** + * Constructs the exception with a given message + * + * @param message the message to show + * @since 0.8.0 + */ + public UnsupportedVersionException(@NotNull String message) { + super(message); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java similarity index 90% rename from src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java index 83b0732e..881ebe4e 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLLoadException.java @@ -1,42 +1,42 @@ -package com.github.stefvanschie.inventoryframework.exception; - -import com.github.stefvanschie.inventoryframework.Gui; -import org.jetbrains.annotations.NotNull; - -/** - * An exception indicating that something went wrong while trying to load a {@link Gui} from an XML file. - * - * @since 0.3.0 - */ -public class XMLLoadException extends RuntimeException { - - /** - * Constructs the exception with a given message - * - * @param message the message to show - * @since 0.3.0 - */ - public XMLLoadException(@NotNull String message) { - super(message); - } - - /** - * Constructs the exception with a given cause - * - * @param cause the cause of this exception - * @since 0.3.1 - */ - public XMLLoadException(@NotNull Throwable cause) { - super(cause); - } - - /** - * Constructs the exception with a given message and cause - * - * @param message the message to show - * @param cause the cause of this exception - */ - public XMLLoadException(@NotNull String message, @NotNull Throwable cause) { - super(message, cause); - } -} +package com.github.stefvanschie.inventoryframework.exception; + +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import org.jetbrains.annotations.NotNull; + +/** + * An exception indicating that something went wrong while trying to load a {@link Gui} from an XML file. + * + * @since 0.3.0 + */ +public class XMLLoadException extends RuntimeException { + + /** + * Constructs the exception with a given message + * + * @param message the message to show + * @since 0.3.0 + */ + public XMLLoadException(@NotNull String message) { + super(message); + } + + /** + * Constructs the exception with a given cause + * + * @param cause the cause of this exception + * @since 0.3.1 + */ + public XMLLoadException(@NotNull Throwable cause) { + super(cause); + } + + /** + * Constructs the exception with a given message and cause + * + * @param message the message to show + * @param cause the cause of this exception + */ + public XMLLoadException(@NotNull String message, @NotNull Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java similarity index 96% rename from src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java index 3ffc1019..71a43503 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/exception/XMLReflectionException.java @@ -1,35 +1,35 @@ -package com.github.stefvanschie.inventoryframework.exception; - -import org.jetbrains.annotations.NotNull; - -/** - * An exception indicating that something went wrong while executing reflection that was loaded prior from an XML file. - * - * Keep in mind that, while this exception is thrown because of reflection, reflection that is executed while loading - * from the XML file will throw an {@link XMLLoadException} if something goes wrong. This exception will only occur when - * the reflection error happens after loading has finished. - * - * @since 0.3.1 - */ -public class XMLReflectionException extends RuntimeException { - - /** - * Constructs the exception with a given message - * - * @param message the message to show - * @since 0.3.1 - */ - public XMLReflectionException(@NotNull String message) { - super(message); - } - - /** - * Constructs the exception with a given cause - * - * @param cause the cause of this exception - * @since 0.3.1 - */ - public XMLReflectionException(@NotNull Throwable cause) { - super(cause); - } -} +package com.github.stefvanschie.inventoryframework.exception; + +import org.jetbrains.annotations.NotNull; + +/** + * An exception indicating that something went wrong while executing reflection that was loaded prior from an XML file. + * + * Keep in mind that, while this exception is thrown because of reflection, reflection that is executed while loading + * from the XML file will throw an {@link XMLLoadException} if something goes wrong. This exception will only occur when + * the reflection error happens after loading has finished. + * + * @since 0.3.1 + */ +public class XMLReflectionException extends RuntimeException { + + /** + * Constructs the exception with a given message + * + * @param message the message to show + * @since 0.3.1 + */ + public XMLReflectionException(@NotNull String message) { + super(message); + } + + /** + * Constructs the exception with a given cause + * + * @param cause the cause of this exception + * @since 0.3.1 + */ + public XMLReflectionException(@NotNull Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java index f78f298f..b165a79f 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/font/CSVFont.java @@ -1,65 +1,65 @@ -package com.github.stefvanschie.inventoryframework.font; - -import com.github.stefvanschie.inventoryframework.font.util.Font; -import com.github.stefvanschie.inventoryframework.util.CSVUtil; -import com.github.stefvanschie.inventoryframework.util.SkullUtil; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * A font for characters with a space as default character. Only one instance of this class should ever exist and should - * be used everywhere. - * - * @since 0.5.0 - */ -public class CSVFont extends Font { - - /** - * A map with all the items and their dedicated characters - */ - private final Map characterMappings; - - /** - * The default character to use when a requested character cannot be found - */ - private final char defaultCharacter; - - /** - * Creates a new default font - * - * @param defaultCharacter the default character to use when a requested character cannot be found - * @param filePath the relative file path to the csv file containing the character mappings - * @since 0.5.0 - */ - public CSVFont(char defaultCharacter, String filePath) { - this.defaultCharacter = defaultCharacter; - - try (InputStream inputStream = getClass().getResourceAsStream(filePath)) { - characterMappings = CSVUtil.readAll(inputStream).stream() - .collect(Collectors.toMap(v -> v[0].charAt(0), v -> SkullUtil.getSkull(v[1]))); - } catch (IOException e) { - throw new RuntimeException("Error loading CSV-based font: " + filePath, e); - } - } - - @NotNull - @Contract(pure = true) - @Override - public ItemStack getDefaultItem() { - return characterMappings.get(defaultCharacter); - } - - @Nullable - @Contract(pure = true) - @Override - public ItemStack toItem(char character) { - return characterMappings.get(character); - } -} +package com.github.stefvanschie.inventoryframework.font; + +import com.github.stefvanschie.inventoryframework.font.util.Font; +import com.github.stefvanschie.inventoryframework.util.CSVUtil; +import com.github.stefvanschie.inventoryframework.util.SkullUtil; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * A font for characters with a space as default character. Only one instance of this class should ever exist and should + * be used everywhere. + * + * @since 0.5.0 + */ +public class CSVFont extends Font { + + /** + * A map with all the items and their dedicated characters + */ + private final Map characterMappings; + + /** + * The default character to use when a requested character cannot be found + */ + private final char defaultCharacter; + + /** + * Creates a new default font + * + * @param defaultCharacter the default character to use when a requested character cannot be found + * @param filePath the relative file path to the csv file containing the character mappings + * @since 0.5.0 + */ + public CSVFont(char defaultCharacter, String filePath) { + this.defaultCharacter = defaultCharacter; + + try (InputStream inputStream = getClass().getResourceAsStream(filePath)) { + characterMappings = CSVUtil.readAll(inputStream).stream() + .collect(Collectors.toMap(v -> v[0].charAt(0), v -> SkullUtil.getSkull(v[1]))); + } catch (IOException e) { + throw new RuntimeException("Error loading CSV-based font: " + filePath, e); + } + } + + @NotNull + @Contract(pure = true) + @Override + public ItemStack getDefaultItem() { + return characterMappings.get(defaultCharacter); + } + + @Nullable + @Contract(pure = true) + @Override + public ItemStack toItem(char character) { + return characterMappings.get(character); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java similarity index 96% rename from src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java index 66b16f38..c37333ac 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/font/util/Font.java @@ -1,275 +1,275 @@ -package com.github.stefvanschie.inventoryframework.font.util; - -import com.github.stefvanschie.inventoryframework.font.*; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -/** - * An interface for fonts - * - * @since 0.5.0 - */ -public abstract class Font { - - /** - * A map containing font names and mapping them to the fonts - */ - @NotNull - private static final Map FONT_BY_NAME = new HashMap<>(); - - /** - * The birch planks font - */ - public static final Font BIRCH_PLANKS = new CSVFont(' ', "/fonts/birch-planks.csv"); - - /** - * The black font - */ - public static final Font BLACK = new CSVFont(' ', "/fonts/black.csv"); - - /** - * The blue font - */ - public static final Font BLUE = new CSVFont(' ', "/fonts/blue.csv"); - - /** - * The brown font - */ - public static final Font BROWN = new CSVFont(' ', "/fonts/brown.csv"); - - /** - * The cobblestone font - */ - public static final Font COBBLESTONE = new CSVFont(' ', "/fonts/cobblestone.csv"); - - /** - * The cyan font - */ - public static final Font CYAN = new CSVFont(' ', "/fonts/cyan.csv"); - - /** - * The diamond font - */ - public static final Font DIAMOND = new CSVFont(' ', "/fonts/diamond.csv"); - - /** - * The dirt font - */ - public static final Font DIRT = new CSVFont(' ', "/fonts/dirt.csv"); - - /** - * The gold font - */ - public static final Font GOLD = new CSVFont(' ', "/fonts/gold.csv"); - - /** - * The gray font - */ - public static final Font GRAY = new CSVFont(' ', "/fonts/gray.csv"); - - /** - * The green font - */ - public static final Font GREEN = new CSVFont(' ', "/fonts/green.csv"); - - /** - * The jungle planks font - */ - public static final Font JUNGLE_PLANKS = new CSVFont(' ', "/fonts/jungle-planks.csv"); - - /** - * The letter cube font - */ - public static final Font LETTER_CUBE = new CSVFont(' ', "/fonts/letter-cube.csv"); - - /** - * The light blue font - */ - public static final Font LIGHT_BLUE = new CSVFont(' ', "/fonts/light-blue.csv"); - - /** - * The light gray font - */ - public static final Font LIGHT_GRAY = new CSVFont(' ', "/fonts/light-gray.csv"); - - /** - * The lime font - */ - public static final Font LIME = new CSVFont(' ', "/fonts/lime.csv"); - - /** - * The magenta font - */ - public static final Font MAGENTA = new CSVFont(' ', "/fonts/magenta.csv"); - - /** - * The monitor font - */ - public static final Font MONITOR = new CSVFont(' ', "/fonts/monitor.csv"); - - /** - * The oak log font - */ - public static final Font OAK_LOG = new CSVFont(' ', "/fonts/oak-log.csv"); - - /** - * The oak planks font - */ - public static final Font OAK_PLANKS = new CSVFont(' ', "/fonts/oak-planks.csv"); - - /** - * The orange font - */ - public static final Font ORANGE = new CSVFont(' ', "/fonts/orange.csv"); - - /** - * The pink font - */ - public static final Font PINK = new CSVFont(' ', "/fonts/pink.csv"); - - /** - * The plush font - */ - public static final Font PLUSH = new CSVFont(' ', "/fonts/plush.csv"); - - /** - * The pumpkin font - */ - public static final Font PUMPKIN = new CSVFont('_', "/fonts/pumpkin.csv"); - - /** - * The purple font - */ - public static final Font PURPLE = new CSVFont(' ', "/fonts/purple.csv"); - - /** - * The quartz font - */ - public static final Font QUARTZ = new CSVFont(' ', "/fonts/quartz.csv"); - - /** - * The rainbow font - */ - public static final Font RAINBOW = new CSVFont(' ', "/fonts/rainbow.csv"); - - /** - * The red font - */ - public static final Font RED = new CSVFont(' ', "/fonts/red.csv"); - - /** - * The spruce planks font - */ - public static final Font SPRUCE_PLANKS = new CSVFont(' ', "/fonts/spruce-planks.csv"); - - /** - * The stone font - */ - public static final Font STONE = new CSVFont(' ', "/fonts/stone.csv"); - - /** - * The watermelon font - */ - public static final Font WATERMELON = new CSVFont(' ', "/fonts/watermelon.csv"); - - /** - * The white font - */ - public static final Font WHITE = new CSVFont(' ', "/fonts/white.csv"); - - /** - * The yellow font - */ - public static final Font YELLOW = new CSVFont(' ', "/fonts/yellow.csv"); - - /** - * Gets a default item for characters that do not have a dedicated item - * - * @return the default item - * @since 0.5.0 - */ - @NotNull - @Contract(pure = true) - public abstract ItemStack getDefaultItem(); - - /** - * Turns the specified character into an {@link ItemStack} representing the specified character. If there is no item - * for the specified character this will return null. - * - * @param character the character to get an item from - * @return the item - * @since 0.5.0 - */ - @Nullable - @Contract(pure = true) - public abstract ItemStack toItem(char character); - - /** - * Gets a font by its name. The name will be made uppercase and spaces will be replaced with underscore before - * trying to access it. - * - * @param name the name of the font - * @return the font - * @since 0.5.0 - */ - @Nullable - @Contract(pure = true) - public static Font fromName(@NotNull String name) { - return FONT_BY_NAME.get(name.replace(' ', '_').toUpperCase(Locale.getDefault())); - } - - /** - * Registers a custom font so it can be used in lookups and XML files. The name will be made upper case and spaces - * will be turned into underscores to ensure a standardized format for all font names. - * - * @param name the font name - * @param font the font - * @since 0.5.0 - */ - @Contract(pure = true) - public static void registerFont(@NotNull String name, @NotNull Font font) { - FONT_BY_NAME.put(name.replace(' ', '_').toUpperCase(Locale.getDefault()), font); - } - - static { - FONT_BY_NAME.put("BIRCH_PLANKS", BIRCH_PLANKS); - FONT_BY_NAME.put("BLACK", BLACK); - FONT_BY_NAME.put("BLUE", BLUE); - FONT_BY_NAME.put("BROWN", BROWN); - FONT_BY_NAME.put("COBBLESTONE", COBBLESTONE); - FONT_BY_NAME.put("CYAN", CYAN); - FONT_BY_NAME.put("DIAMOND", DIAMOND); - FONT_BY_NAME.put("DIRT", DIRT); - FONT_BY_NAME.put("GOLD", GOLD); - FONT_BY_NAME.put("GRAY", GRAY); - FONT_BY_NAME.put("GREEN", GREEN); - FONT_BY_NAME.put("JUNGLE_PLANKS", JUNGLE_PLANKS); - FONT_BY_NAME.put("LETTER_CUBE", LETTER_CUBE); - FONT_BY_NAME.put("LIGHT_BLUE", LIGHT_BLUE); - FONT_BY_NAME.put("LIGHT_GRAY", LIGHT_GRAY); - FONT_BY_NAME.put("LIME", LIME); - FONT_BY_NAME.put("MAGENTA", MAGENTA); - FONT_BY_NAME.put("MONITOR", MONITOR); - FONT_BY_NAME.put("OAK_LOG", OAK_LOG); - FONT_BY_NAME.put("OAK_PLANKS", OAK_PLANKS); - FONT_BY_NAME.put("ORANGE", ORANGE); - FONT_BY_NAME.put("PINK", PINK); - FONT_BY_NAME.put("PLUSH", PLUSH); - FONT_BY_NAME.put("PUMPKIN", PUMPKIN); - FONT_BY_NAME.put("PURPLE", PURPLE); - FONT_BY_NAME.put("QUARTZ", QUARTZ); - FONT_BY_NAME.put("RAINBOW", RAINBOW); - FONT_BY_NAME.put("RED", RED); - FONT_BY_NAME.put("SPRUCE_PLANKS", SPRUCE_PLANKS); - FONT_BY_NAME.put("STONE", STONE); - FONT_BY_NAME.put("WATERMELON", WATERMELON); - FONT_BY_NAME.put("WHITE", WHITE); - FONT_BY_NAME.put("YELLOW", YELLOW); - } -} +package com.github.stefvanschie.inventoryframework.font.util; + +import com.github.stefvanschie.inventoryframework.font.*; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * An interface for fonts + * + * @since 0.5.0 + */ +public abstract class Font { + + /** + * A map containing font names and mapping them to the fonts + */ + @NotNull + private static final Map FONT_BY_NAME = new HashMap<>(); + + /** + * The birch planks font + */ + public static final Font BIRCH_PLANKS = new CSVFont(' ', "/fonts/birch-planks.csv"); + + /** + * The black font + */ + public static final Font BLACK = new CSVFont(' ', "/fonts/black.csv"); + + /** + * The blue font + */ + public static final Font BLUE = new CSVFont(' ', "/fonts/blue.csv"); + + /** + * The brown font + */ + public static final Font BROWN = new CSVFont(' ', "/fonts/brown.csv"); + + /** + * The cobblestone font + */ + public static final Font COBBLESTONE = new CSVFont(' ', "/fonts/cobblestone.csv"); + + /** + * The cyan font + */ + public static final Font CYAN = new CSVFont(' ', "/fonts/cyan.csv"); + + /** + * The diamond font + */ + public static final Font DIAMOND = new CSVFont(' ', "/fonts/diamond.csv"); + + /** + * The dirt font + */ + public static final Font DIRT = new CSVFont(' ', "/fonts/dirt.csv"); + + /** + * The gold font + */ + public static final Font GOLD = new CSVFont(' ', "/fonts/gold.csv"); + + /** + * The gray font + */ + public static final Font GRAY = new CSVFont(' ', "/fonts/gray.csv"); + + /** + * The green font + */ + public static final Font GREEN = new CSVFont(' ', "/fonts/green.csv"); + + /** + * The jungle planks font + */ + public static final Font JUNGLE_PLANKS = new CSVFont(' ', "/fonts/jungle-planks.csv"); + + /** + * The letter cube font + */ + public static final Font LETTER_CUBE = new CSVFont(' ', "/fonts/letter-cube.csv"); + + /** + * The light blue font + */ + public static final Font LIGHT_BLUE = new CSVFont(' ', "/fonts/light-blue.csv"); + + /** + * The light gray font + */ + public static final Font LIGHT_GRAY = new CSVFont(' ', "/fonts/light-gray.csv"); + + /** + * The lime font + */ + public static final Font LIME = new CSVFont(' ', "/fonts/lime.csv"); + + /** + * The magenta font + */ + public static final Font MAGENTA = new CSVFont(' ', "/fonts/magenta.csv"); + + /** + * The monitor font + */ + public static final Font MONITOR = new CSVFont(' ', "/fonts/monitor.csv"); + + /** + * The oak log font + */ + public static final Font OAK_LOG = new CSVFont(' ', "/fonts/oak-log.csv"); + + /** + * The oak planks font + */ + public static final Font OAK_PLANKS = new CSVFont(' ', "/fonts/oak-planks.csv"); + + /** + * The orange font + */ + public static final Font ORANGE = new CSVFont(' ', "/fonts/orange.csv"); + + /** + * The pink font + */ + public static final Font PINK = new CSVFont(' ', "/fonts/pink.csv"); + + /** + * The plush font + */ + public static final Font PLUSH = new CSVFont(' ', "/fonts/plush.csv"); + + /** + * The pumpkin font + */ + public static final Font PUMPKIN = new CSVFont('_', "/fonts/pumpkin.csv"); + + /** + * The purple font + */ + public static final Font PURPLE = new CSVFont(' ', "/fonts/purple.csv"); + + /** + * The quartz font + */ + public static final Font QUARTZ = new CSVFont(' ', "/fonts/quartz.csv"); + + /** + * The rainbow font + */ + public static final Font RAINBOW = new CSVFont(' ', "/fonts/rainbow.csv"); + + /** + * The red font + */ + public static final Font RED = new CSVFont(' ', "/fonts/red.csv"); + + /** + * The spruce planks font + */ + public static final Font SPRUCE_PLANKS = new CSVFont(' ', "/fonts/spruce-planks.csv"); + + /** + * The stone font + */ + public static final Font STONE = new CSVFont(' ', "/fonts/stone.csv"); + + /** + * The watermelon font + */ + public static final Font WATERMELON = new CSVFont(' ', "/fonts/watermelon.csv"); + + /** + * The white font + */ + public static final Font WHITE = new CSVFont(' ', "/fonts/white.csv"); + + /** + * The yellow font + */ + public static final Font YELLOW = new CSVFont(' ', "/fonts/yellow.csv"); + + /** + * Gets a default item for characters that do not have a dedicated item + * + * @return the default item + * @since 0.5.0 + */ + @NotNull + @Contract(pure = true) + public abstract ItemStack getDefaultItem(); + + /** + * Turns the specified character into an {@link ItemStack} representing the specified character. If there is no item + * for the specified character this will return null. + * + * @param character the character to get an item from + * @return the item + * @since 0.5.0 + */ + @Nullable + @Contract(pure = true) + public abstract ItemStack toItem(char character); + + /** + * Gets a font by its name. The name will be made uppercase and spaces will be replaced with underscore before + * trying to access it. + * + * @param name the name of the font + * @return the font + * @since 0.5.0 + */ + @Nullable + @Contract(pure = true) + public static Font fromName(@NotNull String name) { + return FONT_BY_NAME.get(name.replace(' ', '_').toUpperCase(Locale.getDefault())); + } + + /** + * Registers a custom font so it can be used in lookups and XML files. The name will be made upper case and spaces + * will be turned into underscores to ensure a standardized format for all font names. + * + * @param name the font name + * @param font the font + * @since 0.5.0 + */ + @Contract(pure = true) + public static void registerFont(@NotNull String name, @NotNull Font font) { + FONT_BY_NAME.put(name.replace(' ', '_').toUpperCase(Locale.getDefault()), font); + } + + static { + FONT_BY_NAME.put("BIRCH_PLANKS", BIRCH_PLANKS); + FONT_BY_NAME.put("BLACK", BLACK); + FONT_BY_NAME.put("BLUE", BLUE); + FONT_BY_NAME.put("BROWN", BROWN); + FONT_BY_NAME.put("COBBLESTONE", COBBLESTONE); + FONT_BY_NAME.put("CYAN", CYAN); + FONT_BY_NAME.put("DIAMOND", DIAMOND); + FONT_BY_NAME.put("DIRT", DIRT); + FONT_BY_NAME.put("GOLD", GOLD); + FONT_BY_NAME.put("GRAY", GRAY); + FONT_BY_NAME.put("GREEN", GREEN); + FONT_BY_NAME.put("JUNGLE_PLANKS", JUNGLE_PLANKS); + FONT_BY_NAME.put("LETTER_CUBE", LETTER_CUBE); + FONT_BY_NAME.put("LIGHT_BLUE", LIGHT_BLUE); + FONT_BY_NAME.put("LIGHT_GRAY", LIGHT_GRAY); + FONT_BY_NAME.put("LIME", LIME); + FONT_BY_NAME.put("MAGENTA", MAGENTA); + FONT_BY_NAME.put("MONITOR", MONITOR); + FONT_BY_NAME.put("OAK_LOG", OAK_LOG); + FONT_BY_NAME.put("OAK_PLANKS", OAK_PLANKS); + FONT_BY_NAME.put("ORANGE", ORANGE); + FONT_BY_NAME.put("PINK", PINK); + FONT_BY_NAME.put("PLUSH", PLUSH); + FONT_BY_NAME.put("PUMPKIN", PUMPKIN); + FONT_BY_NAME.put("PURPLE", PURPLE); + FONT_BY_NAME.put("QUARTZ", QUARTZ); + FONT_BY_NAME.put("RAINBOW", RAINBOW); + FONT_BY_NAME.put("RED", RED); + FONT_BY_NAME.put("SPRUCE_PLANKS", SPRUCE_PLANKS); + FONT_BY_NAME.put("STONE", STONE); + FONT_BY_NAME.put("WATERMELON", WATERMELON); + FONT_BY_NAME.put("WHITE", WHITE); + FONT_BY_NAME.put("YELLOW", YELLOW); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/GuiItem.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiItem.java similarity index 95% rename from src/main/java/com/github/stefvanschie/inventoryframework/GuiItem.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiItem.java index ccff8cd3..028d3390 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/GuiItem.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiItem.java @@ -1,215 +1,215 @@ -package com.github.stefvanschie.inventoryframework; - -import com.github.stefvanschie.inventoryframework.util.UUIDTagType; -import org.bukkit.NamespacedKey; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.UUID; -import java.util.function.Consumer; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.List; -import java.util.ArrayList; - -/** - * An item for in an inventory - */ -public class GuiItem { - - /** - * The {@link NamespacedKey} that specifies the location of the (internal) {@link UUID} in {@link PersistentDataContainer}s. - * The {@link PersistentDataType} that should be used is {@link UUIDTagType}. - */ - public static final NamespacedKey KEY_UUID = new NamespacedKey(JavaPlugin.getProvidingPlugin(GuiItem.class), "IF-uuid"); - - /** - * An action for the inventory - */ - @Nullable - private Consumer action; - - /** - * List of item's properties - */ - @NotNull - private List properties; - - /** - * The items shown - */ - @NotNull - private final ItemStack item; - - /** - * Whether this item is visible or not - */ - private boolean visible; - - /** - * Internal UUID for keeping track of this item - */ - @NotNull - private UUID uuid = UUID.randomUUID(); - - /** - * Creates a new gui item based on the item stack and action - * - * @param item the item stack - * @param action the action called whenever an interaction with this item happens - */ - public GuiItem(@NotNull ItemStack item, @Nullable Consumer action) { - this.action = action; - this.visible = true; - this.properties = new ArrayList<>(); - - ItemMeta meta = item.getItemMeta(); - if (meta == null) { - throw new IllegalArgumentException("item must be able to have ItemMeta (it mustn't be AIR)"); - } - - meta.getPersistentDataContainer().set(KEY_UUID, UUIDTagType.INSTANCE, uuid); - item.setItemMeta(meta); - this.item = item; - } - - /** - * Creates a new gui item based on the item stack and action - * - * @param item the item stack - */ - public GuiItem(@NotNull ItemStack item) { - this(item, null); - } - - /** - * Makes a copy of this gui item and returns it. This makes a deep copy of the gui item. This entails that the - * underlying item will be copied as per their {@link ItemStack#clone()} and miscellaneous data will be copied in - * such a way that they are identical. The returned gui item will never be reference equal to the current gui item. - * - * @return a copy of the gui item - * @since 0.6.2 - */ - @NotNull - @Contract(pure = true) - public GuiItem copy() { - GuiItem guiItem = new GuiItem(item.clone(), action); - - guiItem.visible = visible; - guiItem.uuid = uuid; - guiItem.properties = new ArrayList<>(properties); - ItemMeta meta = guiItem.item.getItemMeta(); - - if (meta == null) { - throw new IllegalArgumentException("item must be able to have ItemMeta (it mustn't be AIR)"); - } - - meta.getPersistentDataContainer().set(KEY_UUID, UUIDTagType.INSTANCE, guiItem.uuid); - guiItem.item.setItemMeta(meta); - - return guiItem; - } - - /** - * Calls the handler of the {@link InventoryClickEvent} - * if such a handler was specified in the constructor. - * Catches and logs all exceptions the handler might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callAction(@NotNull InventoryClickEvent event) { - if (action == null) { - return; - } - - try { - action.accept(event); - } catch (Throwable t) { - Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); - logger.log(Level.SEVERE, "Exception while handling click event in inventory '" - + event.getView().getTitle() + "', slot=" + event.getSlot() + ", item=" + item.getType(), t); - } - } - - /** - * Sets the action to be executed when a human entity clicks on this item. - * - * @param action the action of this item - * @since 0.7.1 - */ - public void setAction(@NotNull Consumer action) { - this.action = action; - } - - /** - * Returns the list of properties - * - * @return the list of properties that belong to this gui item - * @since 0.7.2 - */ - @NotNull - @Contract(pure = true) - public List getProperties(){ - return properties; - } - - /** - * Sets the list of properties for this gui item - * - * @param properties list of new properties - * @since 0.7.2 - */ - public void setProperties(@NotNull List properties){ - this.properties = properties; - } - - /** - * Returns the item - * - * @return the item that belongs to this gui item - */ - @NotNull - @Contract(pure = true) - public ItemStack getItem() { - return item; - } - - /** - * Gets the {@link UUID} associated with this {@link GuiItem}. This is for internal use only, and should not be - * used. - * - * @return the {@link UUID} of this item - * @since 0.5.9 - */ - @NotNull - @Contract(pure = true) - public UUID getUUID() { - return uuid; - } - - /** - * Returns whether or not this item is visible - * - * @return true if this item is visible, false otherwise - */ - public boolean isVisible() { - return visible; - } - - /** - * Sets the visibility of this item to the new visibility - * - * @param visible the new visibility - */ - public void setVisible(boolean visible) { - this.visible = visible; - } -} +package com.github.stefvanschie.inventoryframework.gui; + +import com.github.stefvanschie.inventoryframework.util.UUIDTagType; +import org.bukkit.NamespacedKey; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; +import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.List; +import java.util.ArrayList; + +/** + * An item for in an inventory + */ +public class GuiItem { + + /** + * The {@link NamespacedKey} that specifies the location of the (internal) {@link UUID} in {@link PersistentDataContainer}s. + * The {@link PersistentDataType} that should be used is {@link UUIDTagType}. + */ + public static final NamespacedKey KEY_UUID = new NamespacedKey(JavaPlugin.getProvidingPlugin(GuiItem.class), "IF-uuid"); + + /** + * An action for the inventory + */ + @Nullable + private Consumer action; + + /** + * List of item's properties + */ + @NotNull + private List properties; + + /** + * The items shown + */ + @NotNull + private final ItemStack item; + + /** + * Whether this item is visible or not + */ + private boolean visible; + + /** + * Internal UUID for keeping track of this item + */ + @NotNull + private UUID uuid = UUID.randomUUID(); + + /** + * Creates a new gui item based on the item stack and action + * + * @param item the item stack + * @param action the action called whenever an interaction with this item happens + */ + public GuiItem(@NotNull ItemStack item, @Nullable Consumer action) { + this.action = action; + this.visible = true; + this.properties = new ArrayList<>(); + + ItemMeta meta = item.getItemMeta(); + if (meta == null) { + throw new IllegalArgumentException("item must be able to have ItemMeta (it mustn't be AIR)"); + } + + meta.getPersistentDataContainer().set(KEY_UUID, UUIDTagType.INSTANCE, uuid); + item.setItemMeta(meta); + this.item = item; + } + + /** + * Creates a new gui item based on the item stack and action + * + * @param item the item stack + */ + public GuiItem(@NotNull ItemStack item) { + this(item, null); + } + + /** + * Makes a copy of this gui item and returns it. This makes a deep copy of the gui item. This entails that the + * underlying item will be copied as per their {@link ItemStack#clone()} and miscellaneous data will be copied in + * such a way that they are identical. The returned gui item will never be reference equal to the current gui item. + * + * @return a copy of the gui item + * @since 0.6.2 + */ + @NotNull + @Contract(pure = true) + public GuiItem copy() { + GuiItem guiItem = new GuiItem(item.clone(), action); + + guiItem.visible = visible; + guiItem.uuid = uuid; + guiItem.properties = new ArrayList<>(properties); + ItemMeta meta = guiItem.item.getItemMeta(); + + if (meta == null) { + throw new IllegalArgumentException("item must be able to have ItemMeta (it mustn't be AIR)"); + } + + meta.getPersistentDataContainer().set(KEY_UUID, UUIDTagType.INSTANCE, guiItem.uuid); + guiItem.item.setItemMeta(meta); + + return guiItem; + } + + /** + * Calls the handler of the {@link InventoryClickEvent} + * if such a handler was specified in the constructor. + * Catches and logs all exceptions the handler might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callAction(@NotNull InventoryClickEvent event) { + if (action == null) { + return; + } + + try { + action.accept(event); + } catch (Throwable t) { + Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); + logger.log(Level.SEVERE, "Exception while handling click event in inventory '" + + event.getView().getTitle() + "', slot=" + event.getSlot() + ", item=" + item.getType(), t); + } + } + + /** + * Sets the action to be executed when a human entity clicks on this item. + * + * @param action the action of this item + * @since 0.7.1 + */ + public void setAction(@NotNull Consumer action) { + this.action = action; + } + + /** + * Returns the list of properties + * + * @return the list of properties that belong to this gui item + * @since 0.7.2 + */ + @NotNull + @Contract(pure = true) + public List getProperties(){ + return properties; + } + + /** + * Sets the list of properties for this gui item + * + * @param properties list of new properties + * @since 0.7.2 + */ + public void setProperties(@NotNull List properties){ + this.properties = properties; + } + + /** + * Returns the item + * + * @return the item that belongs to this gui item + */ + @NotNull + @Contract(pure = true) + public ItemStack getItem() { + return item; + } + + /** + * Gets the {@link UUID} associated with this {@link GuiItem}. This is for internal use only, and should not be + * used. + * + * @return the {@link UUID} of this item + * @since 0.5.9 + */ + @NotNull + @Contract(pure = true) + public UUID getUUID() { + return uuid; + } + + /** + * Returns whether or not this item is visible + * + * @return true if this item is visible, false otherwise + */ + public boolean isVisible() { + return visible; + } + + /** + * Sets the visibility of this item to the new visibility + * + * @param visible the new visibility + */ + public void setVisible(boolean visible) { + this.visible = visible; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/GuiListener.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiListener.java similarity index 56% rename from src/main/java/com/github/stefvanschie/inventoryframework/GuiListener.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiListener.java index 2f921f4f..1ab24528 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/GuiListener.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/GuiListener.java @@ -1,222 +1,339 @@ -package com.github.stefvanschie.inventoryframework; - -import com.github.stefvanschie.inventoryframework.pane.Pane; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityPickupItemEvent; -import org.bukkit.event.inventory.*; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -/** - * Listens to events for {@link Gui}s. Only one instance of this class gets constructed. - * (One instance per plugin, but plugins are supposed to shade and relocate IF.) - * - * @since 0.5.4 - */ -public class GuiListener implements Listener { - - /** - * A collection of all {@link Gui} instances that have at least one viewer. - */ - @NotNull - private final Set activeGuiInstances = new HashSet<>(); - - /** - * Handles clicks in inventories - * - * @param event the event fired - * @since 0.5.4 - */ - @EventHandler(ignoreCancelled = true) - public void onInventoryClick(@NotNull InventoryClickEvent event) { - if (!(event.getInventory().getHolder() instanceof Gui)) { - return; - } - - Gui gui = (Gui) event.getInventory().getHolder(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - if (inventory == null) { - gui.callOnOutsideClick(event); - return; - } - - gui.callOnGlobalClick(event); - if (inventory.equals(view.getTopInventory())) { - gui.callOnTopClick(event); - } else { - gui.callOnBottomClick(event); - } - - if ((inventory.equals(view.getBottomInventory()) && gui.getState() == Gui.State.TOP) || - event.getCurrentItem() == null) { - return; - } - - List panes = gui.getPanes(); - - //loop through the panes reverse, because the pane with the highest priority (last in list) is most likely to have the correct item - for (int i = panes.size() - 1; i >= 0; i--) { - if (panes.get(i).click(gui, event, 0, 0, 9, gui.getRows() + 4)) - break; - } - } - - /** - * Handles users picking up items while their bottom inventory is in use. - * - * @param event the event fired when an entity picks up an item - * @since 0.6.1 - */ - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onEntityPickupItem(@NotNull EntityPickupItemEvent event) { - if (!(event.getEntity() instanceof HumanEntity)) { - return; - } - - InventoryHolder holder = ((HumanEntity) event.getEntity()).getOpenInventory().getTopInventory().getHolder(); - - if (!(holder instanceof Gui)) { - return; - } - - Gui gui = (Gui) holder; - - if (gui.getState() != Gui.State.BOTTOM) { - return; - } - - int leftOver = gui.getHumanEntityCache().add((HumanEntity) event.getEntity(), event.getItem().getItemStack()); - - if (leftOver == 0) { - event.getItem().remove(); - } else { - ItemStack itemStack = event.getItem().getItemStack(); - - itemStack.setAmount(leftOver); - - event.getItem().setItemStack(itemStack); - } - - event.setCancelled(true); - } - - /** - * Handles small drag events which are likely clicks instead. These small drags will be interpreted as clicks and - * will fire a click event. - * - * @param event the event fired - * @since 0.6.1 - */ - @EventHandler - public void onInventoryDrag(@NotNull InventoryDragEvent event) { - if (!(event.getInventory().getHolder() instanceof Gui)) { - return; - } - - Set inventorySlots = event.getInventorySlots(); - - if (inventorySlots.size() > 1) { - return; - } - - InventoryView view = event.getView(); - int index = inventorySlots.toArray(new Integer[0])[0]; - InventoryType.SlotType slotType = view.getSlotType(index); - - boolean even = event.getType() == DragType.EVEN; - - ClickType clickType = even ? ClickType.LEFT : ClickType.RIGHT; - InventoryAction inventoryAction = even ? InventoryAction.PLACE_SOME : InventoryAction.PLACE_ONE; - - //this is a fake click event, firing this may cause other plugins to function incorrectly, so keep it local - InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(view, slotType, index, clickType, - inventoryAction); - - onInventoryClick(inventoryClickEvent); - - event.setCancelled(inventoryClickEvent.isCancelled()); - } - - /** - * Handles closing in inventories - * - * @param event the event fired - * @since 0.5.4 - */ - @EventHandler(ignoreCancelled = true) - public void onInventoryClose(@NotNull InventoryCloseEvent event) { - if (!(event.getInventory().getHolder() instanceof Gui)) { - return; - } - - Gui gui = (Gui) event.getInventory().getHolder(); - - if (!gui.isUpdating()) { - gui.callOnClose(event); - } - - gui.getHumanEntityCache().restoreAndForget(event.getPlayer()); - - if (gui.getViewerCount() == 1) { - activeGuiInstances.remove(gui); - } - } - - /** - * Registers newly opened inventories - * - * @param event the event fired - * @since 0.5.19 - */ - @EventHandler(ignoreCancelled = true) - public void onInventoryOpen(@NotNull InventoryOpenEvent event) { - if (!(event.getInventory().getHolder() instanceof Gui)) { - return; - } - - Gui gui = (Gui) event.getInventory().getHolder(); - activeGuiInstances.add(gui); - } - - /** - * Handles the disabling of the plugin - * - * @param event the event fired - * @since 0.5.19 - */ - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onPluginDisable(@NotNull PluginDisableEvent event) { - Plugin thisPlugin = JavaPlugin.getProvidingPlugin(getClass()); - if (event.getPlugin() != thisPlugin) { - return; - } - - int counter = 0; //callbacks might open GUIs, eg. in nested menus - int maxCount = 10; - while (!activeGuiInstances.isEmpty() && counter++ < maxCount) { - for (Gui gui : new ArrayList<>(activeGuiInstances)) { - for (HumanEntity viewer : gui.getViewers()) { - viewer.closeInventory(); - } - } - } - - if (counter == maxCount) { - thisPlugin.getLogger().warning("Unable to close GUIs on plugin disable: they keep getting opened " - + "(tried: " + maxCount + " times)"); - } - } -} +package com.github.stefvanschie.inventoryframework.gui; + +import com.github.stefvanschie.inventoryframework.gui.type.*; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.inventory.*; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Listens to events for {@link Gui}s. Only one instance of this class gets constructed. + * (One instance per plugin, but plugins are supposed to shade and relocate IF.) + * + * @since 0.5.4 + */ +public class GuiListener implements Listener { + + /** + * A collection of all {@link Gui} instances that have at least one viewer. + */ + @NotNull + private final Set activeGuiInstances = new HashSet<>(); + + /** + * Handles clicks in inventories + * + * @param event the event fired + * @since 0.5.4 + */ + @EventHandler(ignoreCancelled = true) + public void onInventoryClick(@NotNull InventoryClickEvent event) { + if (!(event.getInventory().getHolder() instanceof Gui)) { + return; + } + + Gui gui = (Gui) event.getInventory().getHolder(); + InventoryView view = event.getView(); + Inventory inventory = view.getInventory(event.getRawSlot()); + + if (inventory == null) { + gui.callOnOutsideClick(event); + return; + } + + gui.callOnGlobalClick(event); + if (inventory.equals(view.getTopInventory())) { + gui.callOnTopClick(event); + } else { + gui.callOnBottomClick(event); + } + + gui.click(event); + } + + /** + * Resets the items into the correct positions for anvil guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsAnvil(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof AnvilGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((AnvilGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for beacon guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsBeacon(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof BeaconGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((BeaconGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for cartography table guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsCartographyTable(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof CartographyTableGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((CartographyTableGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for enchanting table guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsEnchantingTable(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof EnchantingTableGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((EnchantingTableGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for grindstone guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsGrindstone(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof GrindstoneGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((GrindstoneGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for stonecutter guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsStonecutter(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof StonecutterGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((StonecutterGui) holder).handleClickEvent(event); + } + + /** + * Resets the items into the correct positions for smithing table guis + * + * @param event the event fired + * @since 0.8.0 + */ + @EventHandler(priority = EventPriority.HIGHEST) + public void resetItemsSmithingTable(@NotNull InventoryClickEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + + if (!(holder instanceof SmithingTableGui) || !(event.getWhoClicked() instanceof Player)) { + return; + } + + ((SmithingTableGui) holder).handleClickEvent(event); + } + + /** + * Handles users picking up items while their bottom inventory is in use. + * + * @param event the event fired when an entity picks up an item + * @since 0.6.1 + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onEntityPickupItem(@NotNull EntityPickupItemEvent event) { + if (!(event.getEntity() instanceof HumanEntity)) { + return; + } + + InventoryHolder holder = ((HumanEntity) event.getEntity()).getOpenInventory().getTopInventory().getHolder(); + + if (!(holder instanceof Gui)) { + return; + } + + Gui gui = (Gui) holder; + + if (!gui.isPlayerInventoryUsed()) { + return; + } + + int leftOver = gui.getHumanEntityCache().add((HumanEntity) event.getEntity(), event.getItem().getItemStack()); + + if (leftOver == 0) { + event.getItem().remove(); + } else { + ItemStack itemStack = event.getItem().getItemStack(); + + itemStack.setAmount(leftOver); + + event.getItem().setItemStack(itemStack); + } + + event.setCancelled(true); + } + + /** + * Handles small drag events which are likely clicks instead. These small drags will be interpreted as clicks and + * will fire a click event. + * + * @param event the event fired + * @since 0.6.1 + */ + @EventHandler + public void onInventoryDrag(@NotNull InventoryDragEvent event) { + if (!(event.getInventory().getHolder() instanceof Gui)) { + return; + } + + Set inventorySlots = event.getInventorySlots(); + + if (inventorySlots.size() > 1) { + return; + } + + InventoryView view = event.getView(); + int index = inventorySlots.toArray(new Integer[0])[0]; + InventoryType.SlotType slotType = view.getSlotType(index); + + boolean even = event.getType() == DragType.EVEN; + + ClickType clickType = even ? ClickType.LEFT : ClickType.RIGHT; + InventoryAction inventoryAction = even ? InventoryAction.PLACE_SOME : InventoryAction.PLACE_ONE; + + //this is a fake click event, firing this may cause other plugins to function incorrectly, so keep it local + InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(view, slotType, index, clickType, + inventoryAction); + + onInventoryClick(inventoryClickEvent); + + event.setCancelled(inventoryClickEvent.isCancelled()); + } + + /** + * Handles closing in inventories + * + * @param event the event fired + * @since 0.5.4 + */ + @EventHandler(ignoreCancelled = true) + public void onInventoryClose(@NotNull InventoryCloseEvent event) { + if (!(event.getInventory().getHolder() instanceof Gui)) { + return; + } + + Gui gui = (Gui) event.getInventory().getHolder(); + + if (!gui.isUpdating()) { + gui.callOnClose(event); + } + + //this is a hack to remove items correctly when players press the x button in a beacon + Bukkit.getScheduler().runTask(JavaPlugin.getProvidingPlugin(getClass()), () -> { + HumanEntity humanEntity = event.getPlayer(); + + humanEntity.closeInventory(); + gui.getHumanEntityCache().restoreAndForget(humanEntity); + }); + + if (gui.getViewerCount() == 1) { + activeGuiInstances.remove(gui); + } + } + + /** + * Registers newly opened inventories + * + * @param event the event fired + * @since 0.5.19 + */ + @EventHandler(ignoreCancelled = true) + public void onInventoryOpen(@NotNull InventoryOpenEvent event) { + if (!(event.getInventory().getHolder() instanceof Gui)) { + return; + } + + Gui gui = (Gui) event.getInventory().getHolder(); + activeGuiInstances.add(gui); + } + + /** + * Handles the disabling of the plugin + * + * @param event the event fired + * @since 0.5.19 + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPluginDisable(@NotNull PluginDisableEvent event) { + Plugin thisPlugin = JavaPlugin.getProvidingPlugin(getClass()); + if (event.getPlugin() != thisPlugin) { + return; + } + + int counter = 0; //callbacks might open GUIs, eg. in nested menus + int maxCount = 10; + while (!activeGuiInstances.isEmpty() && counter++ < maxCount) { + for (Gui gui : new ArrayList<>(activeGuiInstances)) { + for (HumanEntity viewer : gui.getViewers()) { + viewer.closeInventory(); + } + } + } + + if (counter == maxCount) { + thisPlugin.getLogger().warning("Unable to close GUIs on plugin disable: they keep getting opened " + + "(tried: " + maxCount + " times)"); + } + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponent.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponent.java new file mode 100644 index 00000000..39908ad3 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponent.java @@ -0,0 +1,499 @@ +package com.github.stefvanschie.inventoryframework.gui; + +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; + +/** + * Represents a component within an inventory that can hold items. This is always in the shape of a rectangular grid. + * + * @since 0.8.0 + */ +public class InventoryComponent { + + /** + * A set of all panes in this inventory. This is guaranteed to be sorted in order of the pane's priorities, from the + * lowest priority to the highest priority. The order of panes with the same priority is unspecified. + */ + @NotNull + protected final List panes = new ArrayList<>(); + + /** + * The items this inventory component has, stored in row-major order. Slots that are empty are represented as null. + */ + @Nullable + private final ItemStack[][] items; + + /** + * The length and height of this inventory component + */ + private final int length, height; + + /** + * Creates a new inventory component with the specified length and width. If either the length or the width is less + * than zero, an {@link IllegalArgumentException} will be thrown. + * + * @param length the length of the component + * @param height the height of the component + * @since 0.8.0 + */ + public InventoryComponent(int length, int height) { + if (length < 0 || height < 0) { + throw new IllegalArgumentException("Sizes must be greater or equal to zero"); + } + + this.length = length; + this.height = height; + + this.items = new ItemStack[length][height]; + } + + /** + * Adds a pane to the current collection of panes. + * + * @param pane the pane to add + * @since 0.8.0 + */ + public void addPane(@NotNull Pane pane) { + int size = getPanes().size(); + + if (size == 0) { + getPanes().add(pane); + + return; + } + + Pane.Priority priority = pane.getPriority(); + + int left = 0; + int right = size - 1; + + while (left <= right) { + int middle = (left + right) / 2; + + Pane.Priority middlePriority = getPane(middle).getPriority(); + + if (middlePriority == priority) { + getPanes().add(middle, pane); + + return; + } + + if (middlePriority.isLessThan(priority)) { + left = middle + 1; + } else if (middlePriority.isGreaterThan(priority)) { + right = middle - 1; + } + } + + getPanes().add(right + 1, pane); + } + + /** + * This will make each pane in this component render their items in this inventory component. The panes are + * displayed according to their priority, with the lowest priority rendering first and the highest priority (note: + * highest priority, not {@link Pane.Priority#HIGHEST} priority) rendering last. The items displayed in this + * inventory component will be put into the specified inventory. The slots will start at the given offset up to this + * component's size + the offset specified. + * + * @param inventory the inventory to place the items in + * @param offset the offset from which to start counting the slots + * @since 0.8.0 + * @see #display(PlayerInventory, int) + */ + public void display(@NotNull Inventory inventory, int offset) { + display(); + + placeItems(inventory, offset); + } + + /** + * This will make each pane in this component render their items in this inventory component. The panes are + * displayed according to their priority, with the lowest priority rendering first and the highest priority (note: + * highest priority, not {@link Pane.Priority#HIGHEST} priority) rendering last. The items displayed in this + * inventory component will be put into the inventory found in {@link Gui#getInventory()}. The slots will be placed + * from the top-right to the bottom-left, continuing from left-to-right, top-to-bottom plus the specified offset. + * This ordering is different from the normal ordering of the indices of a {@link PlayerInventory}. See for the + * normal ordering of a {@link PlayerInventory}'s slots its documentation. + * + * @param inventory the inventory to place the items in + * @param offset the offset from which to start counting the slots + * @since 0.8.0 + * @see #display(Inventory, int) + */ + public void display(@NotNull PlayerInventory inventory, int offset) { + display(); + + placeItems(inventory, offset); + } + + /** + * This places the items currently existing in this inventory component into the specified player inventory. The + * slots will be placed from the top-right to the bottom-left, continuing from left-to-right, top-to-bottom plus the + * specified offset. This ordering is different from the normal ordering of the indices of a + * {@link PlayerInventory}. See for the normal ordering of a {@link PlayerInventory}'s slots its documentation. In + * contrast to {@link #display(PlayerInventory, int)} this does not render the panes of this component. + * + * @param inventory the inventory to place the items in + * @param offset the offset from which to start counting the slots + * @since 0.8.0 + * @see #placeItems(Inventory, int) + */ + public void placeItems(@NotNull PlayerInventory inventory, int offset) { + for (int x = 0; x < getLength(); x++) { + for (int y = 0; y < getHeight(); y++) { + int slot; + + if (y == getHeight() - 1) { + slot = x + offset; + } else { + slot = (y + 1) * getLength() + x + offset; + } + + inventory.setItem(slot, getItem(x, y)); + } + } + } + + /** + * This places the items currently existing in this inventory component into the specified inventory. The slots will + * start at the given offset up to this component's size + the offset specified. In contrast to + * {@link #display(Inventory, int)} this does not render the panes of this component. + * + * @param inventory the inventory to place the items in + * @param offset the offset from which to start counting the slots + * @since 0.8.0 + * @see #placeItems(PlayerInventory, int) + */ + public void placeItems(@NotNull Inventory inventory, int offset) { + for (int x = 0; x < getLength(); x++) { + for (int y = 0; y < getHeight(); y++) { + inventory.setItem(y * getLength() + x + offset, getItem(x, y)); + } + } + } + + /** + * Delegates the handling of the specified click event to the panes of this component. This will call + * {@link Pane#click(Gui, InventoryClickEvent, int, int, int, int, int)} on each pane until the right item has been + * found. + * + * @param gui the gui this inventory component belongs to + * @param event the event to delegate + * @param slot the slot that was clicked + * @since 0.8.0 + */ + public void click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot) { + List panes = getPanes(); + + //loop panes in reverse, because the highest priority pane (last in list) is most likely to have the right item + for (int i = panes.size() - 1; i >= 0; i--) { + if (panes.get(i).click(gui, event, slot, 0, 0, getLength(), getHeight())) { + break; + } + } + } + + /** + * Creates a deep copy of this inventory component. This means that all internal items will be cloned and all panes + * will be copied as per their own {@link ItemStack#clone()} and {@link Pane#copy()} methods. The returned inventory + * component is guaranteed to not reference equals this inventory component. + * + * @return the new inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent copy() { + InventoryComponent inventoryComponent = new InventoryComponent(getLength(), getHeight()); + + for (int x = 0; x < getLength(); x++) { + for (int y = 0; y < getHeight(); y++) { + ItemStack item = getItem(x, y); + + if (item == null) { + continue; + } + + inventoryComponent.setItem(item.clone(), x, y); + } + } + + for (Pane pane : getPanes()) { + inventoryComponent.addPane(pane.copy()); + } + + return inventoryComponent; + } + + /** + * Returns a new inventory component, excluding the range of specified rows. The new inventory component will have + * its size shrunk so only the included rows are present and any items in the excluded rows are discarded. All panes + * will stay present. Note that while this does make a new inventory component, it does not make a copy. For + * example, the panes in the new inventory component will be the exact same panes as in this one and will not be + * copied. This is also true for any retained items. The specified range is 0-indexed: the first row starts at index + * 0 and the last row ends at height - 1. The range is inclusive on both ends, the row specified at either parameter + * will also be excluded. When the range specified is invalid - that is, part of the range contains rows that are + * not included in this inventory component, and {@link IllegalArgumentException} will be thrown. + * + * @param from the starting index of the range + * @param end the ending index of the range + * @return the new, shrunk inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent excludeRows(int from, int end) { + if (from < 0 || end >= getHeight()) { + throw new IllegalArgumentException("Specified range includes non-existent rows"); + } + + int newHeight = getHeight() - (end - from + 1); + + InventoryComponent newInventoryComponent = new InventoryComponent(getLength(), newHeight); + + for (Pane pane : getPanes()) { + newInventoryComponent.addPane(pane); + } + + for (int x = 0; x < getLength(); x++) { + int newY = 0; + + for (int y = 0; y < getHeight(); y++) { + ItemStack item = getItem(x, y); + + if (y >= from && y <= end) { + continue; + } + + if (item != null) { + newInventoryComponent.setItem(item, x, newY); + } + + newY++; + } + } + + return newInventoryComponent; + } + + /** + * Loads the provided element's child panes onto this component. If the element contains any child panes, this will + * mutate this component. + * + * @param instance the instance to apply field and method references on + * @param element the element to load + * @since 0.8.0 + */ + public void load(@NotNull Object instance, @NotNull Element element) { + NodeList childNodes = element.getChildNodes(); + + for (int innerIndex = 0; innerIndex < childNodes.getLength(); innerIndex++) { + Node innerItem = childNodes.item(innerIndex); + + if (innerItem.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + addPane(Gui.loadPane(instance, innerItem)); + } + } + + /** + * Checks whether this component has at least one item. If it does, true is returned; false otherwise. + * + * @return true if this has an item, false otherwise + * @since 0.8.0 + */ + @Contract(pure = true) + public boolean hasItem() { + for (int x = 0; x < getLength(); x++) { + for (int y = 0; y < getHeight(); y++) { + if (getItem(x, y) != null) { + return true; + } + } + } + + return false; + } + + /** + * This will make each pane in this component render their items in this inventory component. The panes are + * displayed according to their priority, with the lowest priority rendering first and the highest priority (note: + * highest priority, not {@link Pane.Priority#HIGHEST} priority) rendering last. + * + * @since 0.8.0 + * @see #display(Inventory, int) + */ + public void display() { + for (Pane pane : getPanes()) { + if (!pane.isVisible()) { + continue; + } + + pane.display(this, 0, 0, getLength(), getHeight()); + } + } + + /** + * Checks whether the item at the specified coordinates exists. If the specified coordinates are not within this + * inventory component, an {@link IllegalArgumentException} will be thrown. + * + * @param x the x coordinate + * @param y the y coordinate + * @return true if an item exists at the given coordinates, false otherwise + * @since 0.8.0 + * @throws IllegalArgumentException when the coordinates are out of bounds + */ + @Contract(pure = true) + public boolean hasItem(int x, int y) { + return getItem(x, y) != null; + } + + /** + * Gets the item at the specified coordinates, or null if this cell is empty. If the specified coordinates are not + * within this inventory component, an {@link IllegalArgumentException} will be thrown. + * + * @param x the x coordinate + * @param y the y coordinate + * @return the item or null + * @since 0.8.0 + * @throws IllegalArgumentException when the coordinates are out of bounds + */ + @Nullable + @Contract(pure = true) + public ItemStack getItem(int x, int y) { + if (!isInBounds(x, y)) { + throw new IllegalArgumentException("Coordinates must be in-bounds: x = " + x + ", y = " + y + + "; should be below " + getLength() + " and " + getHeight()); + } + + return this.items[x][y]; + } + + /** + * Gets a list of panes this inventory component contains. The returned list is modifiable. If this inventory + * component currently does not have any panes, an empty list is returned. This list is guaranteed to be sorted + * according to the panes' priorities. + * + * @return the panes this component has + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public List getPanes() { + return this.panes; + } + + /** + * Adds the specified item in the slot at the specified positions. This will override an already set item if it + * resides in the same position as specified. If the position specified is outside of the boundaries set by this + * component, an {@link IllegalArgumentException} will be thrown. + * + * @param item the item to place in this inventory component + * @param x the x coordinate of the item + * @param y the y coordinate of the item + * @since 0.8.0 + */ + public void setItem(@NotNull ItemStack item, int x, int y) { + if (!isInBounds(x, y)) { + throw new IllegalArgumentException("Coordinates must be in-bounds: x = " + x + ", y = " + y + + "; should be below " + getLength() + " and " + getHeight()); + } + + this.items[x][y] = item; + } + + /** + * Gets the total size of this inventory component. + * + * @return the size + * @since 0.8.0 + */ + @Contract(pure = true) + public int getSize() { + return getLength() * getHeight(); + } + + /** + * Gets the height of this inventory component. + * + * @return the height + * @since 0.8.0 + */ + @Contract(pure = true) + public int getHeight() { + return this.height; + } + + /** + * Gets the length of this inventory component. + * + * @return the length + * @since 0.8.0 + */ + @Contract(pure = true) + public int getLength() { + return this.length; + } + + /** + * Returns whether the specified coordinates are inside the boundary of this inventory component or outside of this + * inventory component; true is returned for the former case and false for the latter case. + * + * @param x the x coordinate + * @param y the y coordinate + * @return true if the coordinates are in bounds, false otherwise + * @since 0.8.0 + */ + @Contract(pure = true) + private boolean isInBounds(int x, int y) { + boolean xBounds = isInBounds(0, getLength() - 1, x); + boolean yBounds = isInBounds(0, getHeight() - 1, y); + + return xBounds && yBounds; + } + + /** + * Gets the pane at the specified index. + * + * @param index the index of the pane + * @return the pane + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private Pane getPane(int index) { + if (!isInBounds(0, this.panes.size() - 1, index)) { + throw new IllegalArgumentException("Index not in pane list"); + } + + return this.panes.get(index); + } + + /** + * Checks whether a number is within the specified number bound (inclusive on both ends). + * + * @param lowerBound the lower bound of the range + * @param upperBound the upper bound of the range + * @param value the value to check + * @return true if the value is within the bounds, false otherwise + * @since 0.8.0 + */ + @Contract(pure = true) + private boolean isInBounds(int lowerBound, int upperBound, int value) { + return lowerBound <= value && value <= upperBound; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/AnvilGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/AnvilGui.java new file mode 100644 index 00000000..f009c7d7 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/AnvilGui.java @@ -0,0 +1,348 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of an anvil + * + * @since 0.8.0 + */ +public class AnvilGui extends NamedGui { + + /** + * Represents the inventory component for the first item + */ + @NotNull + private InventoryComponent firstItemComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the second item + */ + @NotNull + private InventoryComponent secondItemComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the result + */ + @NotNull + private InventoryComponent resultComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal anvil inventory + */ + @NotNull + private final AnvilInventory anvilInventory = VersionMatcher.newAnvilInventory(Version.getVersion(), + this); + + /** + * Constructs a new anvil gui + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public AnvilGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Anvils can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getFirstItemComponent().display(getInventory(), 0); + getSecondItemComponent().display(getInventory(), 1); + getResultComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + anvilInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public AnvilGui copy() { + AnvilGui gui = new AnvilGui(getTitle()); + + gui.firstItemComponent = firstItemComponent.copy(); + gui.secondItemComponent = secondItemComponent.copy(); + gui.resultComponent = resultComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getFirstItemComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getSecondItemComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getResultComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.ANVIL, title); + } + + /** + * Gets the rename text currently specified in the anvil. + * + * @return the rename text + * @since 0.8.0 + * @see org.bukkit.inventory.AnvilInventory#getRenameText() + */ + @NotNull + @Contract(pure = true) + public String getRenameText() { + return anvilInventory.getRenameText(); + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 3 && slot <= 38) { + anvilInventory.sendItems(player, getTopItems()); + } else if (slot == 0 || slot == 1) { + if (event.isCancelled()) { + if (slot == 0) { + anvilInventory.sendFirstItem(player, getFirstItemComponent().getItem(0, 0)); + } else { + anvilInventory.sendSecondItem(player, getSecondItemComponent().getItem(0, 0)); + } + + anvilInventory.clearCursor(player); + } + + anvilInventory.sendResultItem(player, getResultComponent().getItem(0, 0)); + } else if (slot == 2 && !event.isCancelled()) { + anvilInventory.clearResultItem(player); + + ItemStack resultItem = getResultComponent().getItem(0, 0); + + if (resultItem != null) { + anvilInventory.setCursor(player, resultItem); + } + } + } + + /** + * Gets the inventory component representing the first item + * + * @return the first item component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFirstItemComponent() { + return firstItemComponent; + } + + /** + * Gets the inventory component representing the second item + * + * @return the second item component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getSecondItemComponent() { + return secondItemComponent; + } + + /** + * Gets the inventory component representing the result + * + * @return the result component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getResultComponent() { + return resultComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Gets the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getFirstItemComponent().getItem(0, 0), + getSecondItemComponent().getItem(0, 0), + getResultComponent().getItem(0, 0) + }; + } + + /** + * Loads an anvil gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded anvil gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static AnvilGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads an anvil gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded anvil gui + * @since 0.8.0 + */ + @NotNull + public static AnvilGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + AnvilGui anvilGui = new AnvilGui(element.getAttribute("title")); + anvilGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return anvilGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "first-item": + component = anvilGui.getFirstItemComponent(); + break; + case "second-item": + component = anvilGui.getSecondItemComponent(); + break; + case "result": + component = anvilGui.getResultComponent(); + break; + case "player-inventory": + component = anvilGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return anvilGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BarrelGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BarrelGui.java new file mode 100644 index 00000000..d440a04f --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BarrelGui.java @@ -0,0 +1,224 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a gui in the form of a barrel. + * + * @since 0.8.0 + */ +public class BarrelGui extends NamedGui { + + /** + * Represents the inventory component for the entire gui + */ + @NotNull + private InventoryComponent inventoryComponent = new InventoryComponent(9, 7); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public BarrelGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + int height = getInventoryComponent().getHeight(); + + getInventoryComponent().display(); + + InventoryComponent topComponent = getInventoryComponent().excludeRows(height - 4, height - 1); + InventoryComponent bottomComponent = getInventoryComponent().excludeRows(0, height - 5); + + topComponent.placeItems(getInventory(), 0); + bottomComponent.placeItems(humanEntity.getInventory(), 0); + + if (!bottomComponent.hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public BarrelGui copy() { + BarrelGui gui = new BarrelGui(getTitle()); + + gui.inventoryComponent = inventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + getInventoryComponent().click(this, event, event.getRawSlot()); + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getInventoryComponent().excludeRows(0, getInventoryComponent().getHeight() - 5).hasItem(); + } + + /** + * Adds a pane to this gui + * + * @param pane the pane to add + * @since 0.8.0 + */ + public void addPane(@NotNull Pane pane) { + this.inventoryComponent.addPane(pane); + } + + /** + * Gets all the panes in this gui, this includes child panes from other panes + * + * @return all panes + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public List getPanes() { + return this.inventoryComponent.getPanes(); + } + + /** + * Gets all the items in all underlying panes + * + * @return all items + */ + @NotNull + @Contract(pure = true) + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.BARREL, title); + } + + /** + * Gets the inventory component for this gui + * + * @return the inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInventoryComponent() { + return inventoryComponent; + } + + /** + * Loads a barrel gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded barrel gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static BarrelGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a barrel gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded barrel gui + * @since 0.8.0 + */ + @NotNull + public static BarrelGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + BarrelGui barrelGui = new BarrelGui(element.getAttribute("title")); + barrelGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return barrelGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + InventoryComponent inventoryComponent = barrelGui.getInventoryComponent(); + + if (componentElement.getTagName().equalsIgnoreCase("component")) { + inventoryComponent.load(instance, componentElement); + } else { + inventoryComponent.load(instance, element); + } + + break; + } + + return barrelGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BeaconGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BeaconGui.java new file mode 100644 index 00000000..84a7f77e --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BeaconGui.java @@ -0,0 +1,242 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a beacon + * + * @since 0.8.0 + */ +public class BeaconGui extends Gui { + + /** + * Represents the payment item inventory component + */ + @NotNull + private InventoryComponent paymentItemComponent = new InventoryComponent(1, 1); + + /** + * Represents the player inventory component + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal beacon inventory + */ + @NotNull + private final BeaconInventory beaconInventory = VersionMatcher.newBeaconInventory(Version.getVersion(), + this); + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Beacons can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getPaymentItemComponent().display(getInventory(), 0); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + beaconInventory.openInventory((Player) humanEntity, getPaymentItemComponent().getItem(0, 0)); + } + + @NotNull + @Contract(pure = true) + @Override + public BeaconGui copy() { + BeaconGui gui = new BeaconGui(); + + gui.paymentItemComponent = paymentItemComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getPaymentItemComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 1); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory() { + return Bukkit.createInventory(this, InventoryType.BEACON); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 1 && slot <= 36) { + beaconInventory.sendItem(player, getPaymentItemComponent().getItem(0, 0)); + } else if (slot == 0 && event.isCancelled()) { + beaconInventory.sendItem(player, getPaymentItemComponent().getItem(0, 0)); + + beaconInventory.clearCursor(player); + } + } + + /** + * Gets the inventory component representing the payment item + * + * @return the payment item component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPaymentItemComponent() { + return paymentItemComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a beacon gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded beacon gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static BeaconGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a beacon gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded beacon gui + * @since 0.8.0 + */ + @NotNull + public static BeaconGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + BeaconGui beaconGui = new BeaconGui(); + beaconGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return beaconGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "payment-item": + component = beaconGui.getPaymentItemComponent(); + break; + case "player-inventory": + component = beaconGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return beaconGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BlastFurnaceGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BlastFurnaceGui.java new file mode 100644 index 00000000..43de1327 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BlastFurnaceGui.java @@ -0,0 +1,268 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a blast furnace + * + * @since 0.8.0 + */ +public class BlastFurnaceGui extends NamedGui { + + /** + * Represents the inventory component for the ingredient + */ + @NotNull + private InventoryComponent ingredientComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the fuel + */ + @NotNull + private InventoryComponent fuelComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the output + */ + @NotNull + private InventoryComponent outputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public BlastFurnaceGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getIngredientComponent().display(getInventory(), 0); + getFuelComponent().display(getInventory(), 1); + getOutputComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public BlastFurnaceGui copy() { + BlastFurnaceGui gui = new BlastFurnaceGui(getTitle()); + + gui.ingredientComponent = ingredientComponent.copy(); + gui.fuelComponent = fuelComponent.copy(); + gui.outputComponent = outputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getIngredientComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getFuelComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getOutputComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.BLAST_FURNACE, title); + } + + /** + * Gets the inventory component representing the ingredient + * + * @return the ingredient component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getIngredientComponent() { + return ingredientComponent; + } + + /** + * Gets the inventory component representing the fuel + * + * @return the fuel component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFuelComponent() { + return fuelComponent; + } + + /** + * Gets the inventory component representing the output + * + * @return the output component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getOutputComponent() { + return outputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a blast furnace gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded blast furnace gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static BlastFurnaceGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a blast furnace gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded blast furnace gui + * @since 0.8.0 + */ + @NotNull + public static BlastFurnaceGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + BlastFurnaceGui blastFurnaceGui = new BlastFurnaceGui(element.getAttribute("title")); + blastFurnaceGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return blastFurnaceGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "ingredient": + component = blastFurnaceGui.getIngredientComponent(); + break; + case "fuel": + component = blastFurnaceGui.getFuelComponent(); + break; + case "output": + component = blastFurnaceGui.getOutputComponent(); + break; + case "player-inventory": + component = blastFurnaceGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return blastFurnaceGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BrewingStandGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BrewingStandGui.java new file mode 100644 index 00000000..9187d410 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/BrewingStandGui.java @@ -0,0 +1,318 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a brewing stand + * + * @since 0.8.0 + */ +public class BrewingStandGui extends NamedGui { + + /** + * Represents the inventory component for the first bottle + */ + @NotNull + private InventoryComponent firstBottleComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the second bottle + */ + @NotNull + private InventoryComponent secondBottleComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the third bottle + */ + @NotNull + private InventoryComponent thirdBottleComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the potion ingredient + */ + @NotNull + private InventoryComponent potionIngredientComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the blaze powder + */ + @NotNull + private InventoryComponent blazePowderComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public BrewingStandGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getFirstBottleComponent().display(getInventory(), 0); + getSecondBottleComponent().display(getInventory(), 1); + getThirdBottleComponent().display(getInventory(), 2); + getPotionIngredientComponent().display(getInventory(), 3); + getBlazePowderComponent().display(getInventory(), 4); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public BrewingStandGui copy() { + BrewingStandGui gui = new BrewingStandGui(getTitle()); + + gui.firstBottleComponent = firstBottleComponent.copy(); + gui.secondBottleComponent = secondBottleComponent.copy(); + gui.thirdBottleComponent = thirdBottleComponent.copy(); + gui.potionIngredientComponent = potionIngredientComponent.copy(); + gui.blazePowderComponent = blazePowderComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getFirstBottleComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getSecondBottleComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getThirdBottleComponent().click(this, event, 0); + } else if (rawSlot == 3) { + getPotionIngredientComponent().click(this, event, 0); + } else if (rawSlot == 4) { + getBlazePowderComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 5); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.BREWING, title); + } + + /** + * Gets the inventory component representing the first bottle + * + * @return the first bottle component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFirstBottleComponent() { + return firstBottleComponent; + } + + /** + * Gets the inventory component representing the second bottle + * + * @return the second bottle component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getSecondBottleComponent() { + return secondBottleComponent; + } + + /** + * Gets the inventory component representing the third bottle + * + * @return the third bottle component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getThirdBottleComponent() { + return thirdBottleComponent; + } + + /** + * Gets the inventory component representing the potion ingredient + * + * @return the potion ingredient component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPotionIngredientComponent() { + return potionIngredientComponent; + } + + /** + * Gets the inventory component representing the blaze powder + * + * @return the blaze powder component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getBlazePowderComponent() { + return blazePowderComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a brewing stand gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded brewing stand gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static BrewingStandGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a brewing stand gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded brewing stand gui + * @since 0.8.0 + */ + @NotNull + public static BrewingStandGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + BrewingStandGui brewingStandGui = new BrewingStandGui(element.getAttribute("title")); + brewingStandGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return brewingStandGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "first-bottle": + component = brewingStandGui.getFirstBottleComponent(); + break; + case "second-bottle": + component = brewingStandGui.getSecondBottleComponent(); + break; + case "third-bottle": + component = brewingStandGui.getThirdBottleComponent(); + break; + case "potion-ingredient": + component = brewingStandGui.getPotionIngredientComponent(); + break; + case "blaze-powder": + component = brewingStandGui.getBlazePowderComponent(); + break; + case "player-inventory": + component = brewingStandGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return brewingStandGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CartographyTableGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CartographyTableGui.java new file mode 100644 index 00000000..d106f193 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CartographyTableGui.java @@ -0,0 +1,325 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a cartography table + * + * @since 0.8.0 + */ +public class CartographyTableGui extends NamedGui { + + /** + * Represents the inventory component for the map + */ + @NotNull + private InventoryComponent mapComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the paper + */ + @NotNull + private InventoryComponent paperComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the output + */ + @NotNull + private InventoryComponent outputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal cartography table inventory + */ + @NotNull + private final CartographyTableInventory cartographyTableInventory = VersionMatcher.newCartographyTableInventory( + Version.getVersion(), this + ); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public CartographyTableGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Cartography tables can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getMapComponent().display(getInventory(), 0); + getPaperComponent().display(getInventory(), 1); + getOutputComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + cartographyTableInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public CartographyTableGui copy() { + CartographyTableGui gui = new CartographyTableGui(getTitle()); + + gui.mapComponent = mapComponent.copy(); + gui.paperComponent = paperComponent.copy(); + gui.outputComponent = outputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getMapComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getPaperComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getOutputComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.CARTOGRAPHY, title); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 3 && slot <= 38) { + cartographyTableInventory.sendItems(player, getTopItems()); + } else if (slot >= 0 && slot <= 2) { + //the client rejects the output item if send immediately + Bukkit.getScheduler().runTask(JavaPlugin.getProvidingPlugin(getClass()), () -> + cartographyTableInventory.sendItems(player, getTopItems())); + + if (event.isCancelled()) { + cartographyTableInventory.clearCursor(player); + } + } + } + + /** + * Gets the inventory component representing the map + * + * @return the map component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getMapComponent() { + return mapComponent; + } + + /** + * Gets the inventory component representing the paper + * + * @return the paper component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPaperComponent() { + return paperComponent; + } + + /** + * Gets the inventory component representing the output + * + * @return the output component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getOutputComponent() { + return outputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Gets the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getMapComponent().getItem(0, 0), + getPaperComponent().getItem(0, 0), + getOutputComponent().getItem(0, 0) + }; + } + + /** + * Loads a cartography table gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded cartography table gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static CartographyTableGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a cartography table gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded cartography table gui + * @since 0.8.0 + */ + @NotNull + public static CartographyTableGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + CartographyTableGui cartographyTableGui = new CartographyTableGui(element.getAttribute("title")); + cartographyTableGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return cartographyTableGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "map": + component = cartographyTableGui.getMapComponent(); + break; + case "paper": + component = cartographyTableGui.getPaperComponent(); + break; + case "output": + component = cartographyTableGui.getOutputComponent(); + break; + case "player-inventory": + component = cartographyTableGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return cartographyTableGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ChestGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ChestGui.java new file mode 100644 index 00000000..95e62b71 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ChestGui.java @@ -0,0 +1,281 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a gui in the form of a chest. Unlike traditional chests, this may take on any amount of rows between 1 and + * 6. + * + * @since 0.8.0 + */ +public class ChestGui extends NamedGui { + + /** + * Represents the inventory component for the entire gui + */ + @NotNull + private InventoryComponent inventoryComponent; + + /** + * The amount of rows this gui has + */ + private int rows; + + /** + * Constructs a new chest GUI + * + * @param rows the amount of rows this gui should contain, in range 1..6. + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public ChestGui(int rows, @NotNull String title) { + super(title); + + if (!(rows >= 1 && rows <= 6)) { + throw new IllegalArgumentException("Rows should be between 1 and 6"); + } + + this.inventoryComponent = new InventoryComponent(9, rows + 4); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + int height = getInventoryComponent().getHeight(); + + getInventoryComponent().display(); + + InventoryComponent topComponent = getInventoryComponent().excludeRows(height - 4, height - 1); + InventoryComponent bottomComponent = getInventoryComponent().excludeRows(0, height - 5); + + topComponent.placeItems(getInventory(), 0); + bottomComponent.placeItems(humanEntity.getInventory(), 0); + + if (!bottomComponent.hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public ChestGui copy() { + ChestGui gui = new ChestGui(getRows(), getTitle()); + + gui.inventoryComponent = inventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + getInventoryComponent().click(this, event, event.getRawSlot()); + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getInventoryComponent().excludeRows(0, getInventoryComponent().getHeight() - 5).hasItem(); + } + + /** + * Sets the amount of rows for this inventory. + * This will (unlike most other methods) directly update itself in order to ensure all viewers will still be viewing + * the new inventory as well. + * + * @param rows the amount of rows in range 1..6. + * @since 0.8.0 + */ + public void setRows(int rows) { + if (!(rows >= 1 && rows <= 6)) { + throw new IllegalArgumentException("Rows should be between 1 and 6"); + } + + this.inventoryComponent = new InventoryComponent(9, rows + 4); + + //copy the viewers + List viewers = getViewers(); + + this.inventory = Bukkit.createInventory(this, rows * 9, getTitle()); + + viewers.forEach(humanEntity -> humanEntity.openInventory(inventory)); + } + + /** + * Adds a pane to this gui + * + * @param pane the pane to add + * @since 0.8.0 + */ + public void addPane(@NotNull Pane pane) { + this.inventoryComponent.addPane(pane); + } + + /** + * Gets all the panes in this gui, this includes child panes from other panes + * + * @return all panes + */ + @NotNull + @Contract(pure = true) + public List getPanes() { + return this.inventoryComponent.getPanes(); + } + + /** + * Gets all the items in all underlying panes + * + * @return all items + */ + @NotNull + @Contract(pure = true) + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, getRows() * 9, title); + } + + /** + * Returns the amount of rows this gui currently has + * + * @return the amount of rows + * @since 0.8.0 + */ + @Contract(pure = true) + public int getRows() { + return getInventoryComponent().getHeight() - 4; + } + + /** + * Gets the inventory component for this gui + * + * @return the inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInventoryComponent() { + return inventoryComponent; + } + + /** + * Loads a chest gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded chest gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static ChestGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a chest gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded chest gui + * @since 0.8.0 + */ + @NotNull + public static ChestGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + if (!element.hasAttribute("rows")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory rows attribute set"); + } + + int rows; + + try { + rows = Integer.parseInt(element.getAttribute("rows")); + } catch (NumberFormatException exception) { + throw new XMLLoadException("Rows attribute is not an integer", exception); + } + + ChestGui chestGui = new ChestGui(rows, element.getAttribute("title")); + chestGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return chestGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + InventoryComponent inventoryComponent = chestGui.getInventoryComponent(); + + if (componentElement.getTagName().equalsIgnoreCase("component")) { + inventoryComponent.load(instance, componentElement); + } else { + inventoryComponent.load(instance, element); + } + + break; + } + + return chestGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CraftingTableGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CraftingTableGui.java new file mode 100644 index 00000000..3c811b9b --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/CraftingTableGui.java @@ -0,0 +1,243 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a crafting table + * + * @since 0.8.0 + */ +public class CraftingTableGui extends NamedGui { + + /** + * Represents the inventory component for the input + */ + @NotNull + private InventoryComponent inputComponent = new InventoryComponent(3, 3); + + /** + * Represents the inventory component for the output + */ + @NotNull + private InventoryComponent outputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public CraftingTableGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getOutputComponent().display(getInventory(), 0); + getInputComponent().display(getInventory(), 1); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public CraftingTableGui copy() { + CraftingTableGui gui = new CraftingTableGui(getTitle()); + + gui.inputComponent = inputComponent.copy(); + gui.outputComponent = outputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getOutputComponent().click(this, event, 0); + } else if (rawSlot >= 1 && rawSlot <= 9) { + getInputComponent().click(this, event, rawSlot - 1); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 10); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.WORKBENCH, title); + } + + /** + * Gets the inventory component representing the input + * + * @return the input component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInputComponent() { + return inputComponent; + } + + /** + * Gets the inventory component representing the output + * + * @return the output component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getOutputComponent() { + return outputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a crafting table gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded crafting table gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static CraftingTableGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a crafting table gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded crafting table gui + * @since 0.8.0 + */ + @NotNull + public static CraftingTableGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + CraftingTableGui craftingTableGui = new CraftingTableGui(element.getAttribute("title")); + craftingTableGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return craftingTableGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "input": + component = craftingTableGui.getInputComponent(); + break; + case "output": + component = craftingTableGui.getOutputComponent(); + break; + case "player-inventory": + component = craftingTableGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return craftingTableGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DispenserGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DispenserGui.java new file mode 100644 index 00000000..c833bad7 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DispenserGui.java @@ -0,0 +1,218 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a dispenser + * + * @since 0.8.0 + */ +public class DispenserGui extends NamedGui { + + /** + * Represents the inventory component for the contents + */ + @NotNull + private InventoryComponent contentsComponent = new InventoryComponent(3, 3); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public DispenserGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getContentsComponent().display(getInventory(), 0); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public DispenserGui copy() { + DispenserGui gui = new DispenserGui(getTitle()); + + gui.contentsComponent = contentsComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot >= 0 && rawSlot <= 8) { + getContentsComponent().click(this, event, rawSlot); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 9); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.DISPENSER, title); + } + + /** + * Gets the inventory component representing the contents + * + * @return the contents component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getContentsComponent() { + return contentsComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a dispenser gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded dispenser gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static DispenserGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a dispenser gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded dispenser gui + * @since 0.8.0 + */ + @NotNull + public static DispenserGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + DispenserGui dispenserGui = new DispenserGui(element.getAttribute("title")); + dispenserGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return dispenserGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "contents": + component = dispenserGui.getContentsComponent(); + break; + case "player-inventory": + component = dispenserGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return dispenserGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DropperGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DropperGui.java new file mode 100644 index 00000000..17edb12a --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/DropperGui.java @@ -0,0 +1,218 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a dropper + * + * @since 0.8.0 + */ +public class DropperGui extends NamedGui { + + /** + * Represents the inventory component for the contents + */ + @NotNull + private InventoryComponent contentsComponent = new InventoryComponent(3, 3); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public DropperGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getContentsComponent().display(getInventory(), 0); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public DropperGui copy() { + DropperGui gui = new DropperGui(getTitle()); + + gui.contentsComponent = contentsComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot >= 0 && rawSlot <= 8) { + getContentsComponent().click(this, event, rawSlot); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 9); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.DROPPER, title); + } + + /** + * Gets the inventory component representing the contents + * + * @return the contents component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getContentsComponent() { + return contentsComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a dropper gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded dropper gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static DropperGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a dropper gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded dropper gui + * @since 0.8.0 + */ + @NotNull + public static DropperGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + DropperGui dropperGui = new DropperGui(element.getAttribute("title")); + dropperGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return dropperGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "contents": + component = dropperGui.getContentsComponent(); + break; + case "player-inventory": + component = dropperGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return dropperGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnchantingTableGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnchantingTableGui.java new file mode 100644 index 00000000..96aa39d4 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnchantingTableGui.java @@ -0,0 +1,268 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of an enchanting table + * + * @since 0.8.0 + */ +public class EnchantingTableGui extends NamedGui { + + /** + * Represents the inventory component for the input + */ + @NotNull + private InventoryComponent inputComponent = new InventoryComponent(2, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal enchanting table inventory + */ + @NotNull + private final EnchantingTableInventory enchantingTableInventory = VersionMatcher.newEnchantingTableInventory( + Version.getVersion(), this); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public EnchantingTableGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Enchanting tables can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getInputComponent().display(getInventory(), 0); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + enchantingTableInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public EnchantingTableGui copy() { + EnchantingTableGui gui = new EnchantingTableGui(getTitle()); + + gui.inputComponent = inputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot >= 0 && rawSlot <= 1) { + getInputComponent().click(this, event, rawSlot); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 2); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.ENCHANTING, title); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 2 && slot <= 37) { + enchantingTableInventory.sendItems(player, getTopItems()); + } else if ((slot == 0 || slot == 1) && event.isCancelled()) { + enchantingTableInventory.sendItems(player, getTopItems()); + + enchantingTableInventory.clearCursor(player); + } + } + + /** + * Gets the inventory component representing the input + * + * @return the input component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInputComponent() { + return inputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Gets the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getInputComponent().getItem(0, 0), + getInputComponent().getItem(1, 0) + }; + } + + /** + * Loads an enchanting table gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded enchanting table gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static EnchantingTableGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads an enchanting table gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded enchanting table gui + * @since 0.8.0 + */ + @NotNull + public static EnchantingTableGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + EnchantingTableGui enchantingTableGui = new EnchantingTableGui(element.getAttribute("title")); + enchantingTableGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return enchantingTableGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "input": + component = enchantingTableGui.getInputComponent(); + break; + case "player-inventory": + component = enchantingTableGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return enchantingTableGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnderChestGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnderChestGui.java new file mode 100644 index 00000000..71519ee3 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/EnderChestGui.java @@ -0,0 +1,223 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a gui in the form of an ender chest + * + * @since 0.8.0 + */ +public class EnderChestGui extends NamedGui { + + /** + * Represents the inventory component for the entire gui + */ + @NotNull + private InventoryComponent inventoryComponent = new InventoryComponent(9, 7); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public EnderChestGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + int height = getInventoryComponent().getHeight(); + + getInventoryComponent().display(); + + InventoryComponent topComponent = getInventoryComponent().excludeRows(height - 4, height - 1); + InventoryComponent bottomComponent = getInventoryComponent().excludeRows(0, height - 5); + + topComponent.placeItems(getInventory(), 0); + bottomComponent.placeItems(humanEntity.getInventory(), 0); + + if (!bottomComponent.hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public EnderChestGui copy() { + EnderChestGui gui = new EnderChestGui(getTitle()); + + gui.inventoryComponent = inventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getInventoryComponent().excludeRows(0, getInventoryComponent().getHeight() - 5).hasItem(); + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + getInventoryComponent().click(this, event, event.getRawSlot()); + } + + /** + * Adds a pane to this gui + * + * @param pane the pane to add + * @since 0.8.0 + */ + public void addPane(@NotNull Pane pane) { + this.inventoryComponent.addPane(pane); + } + + /** + * Gets all the panes in this gui, this includes child panes from other panes + * + * @return all panes + */ + @NotNull + @Contract(pure = true) + public List getPanes() { + return this.inventoryComponent.getPanes(); + } + + /** + * Gets all the items in all underlying panes + * + * @return all items + */ + @NotNull + @Contract(pure = true) + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.ENDER_CHEST, title); + } + + /** + * Gets the inventory component for this gui + * + * @return the inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInventoryComponent() { + return inventoryComponent; + } + + /** + * Loads an ender chest gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded ender chest gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static EnderChestGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads an ender chest gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded ender chest gui + * @since 0.8.0 + */ + @NotNull + public static EnderChestGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + EnderChestGui enderChestGui = new EnderChestGui(element.getAttribute("title")); + enderChestGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return enderChestGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + InventoryComponent inventoryComponent = enderChestGui.getInventoryComponent(); + + if (componentElement.getTagName().equalsIgnoreCase("component")) { + inventoryComponent.load(instance, componentElement); + } else { + inventoryComponent.load(instance, element); + } + + break; + } + + return enderChestGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/FurnaceGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/FurnaceGui.java new file mode 100644 index 00000000..e4eeb34e --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/FurnaceGui.java @@ -0,0 +1,268 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a furnace + * + * @since 0.8.0 + */ +public class FurnaceGui extends NamedGui { + + /** + * Represents the inventory component for the ingredient + */ + @NotNull + private InventoryComponent ingredientComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the fuel + */ + @NotNull + private InventoryComponent fuelComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the output + */ + @NotNull + private InventoryComponent outputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public FurnaceGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getIngredientComponent().display(getInventory(), 0); + getFuelComponent().display(getInventory(), 1); + getOutputComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public FurnaceGui copy() { + FurnaceGui gui = new FurnaceGui(getTitle()); + + gui.ingredientComponent = ingredientComponent.copy(); + gui.fuelComponent = fuelComponent.copy(); + gui.outputComponent = outputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getIngredientComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getFuelComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getOutputComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.FURNACE, title); + } + + /** + * Gets the inventory component representing the ingredient + * + * @return the ingredient component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getIngredientComponent() { + return ingredientComponent; + } + + /** + * Gets the inventory component representing the fuel + * + * @return the fuel component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFuelComponent() { + return fuelComponent; + } + + /** + * Gets the inventory component representing the output + * + * @return the output component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getOutputComponent() { + return outputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a furnace gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded furnace gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static FurnaceGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a furnace gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded furnace gui + * @since 0.8.0 + */ + @NotNull + public static FurnaceGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + FurnaceGui furnaceGui = new FurnaceGui(element.getAttribute("title")); + furnaceGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return furnaceGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "ingredient": + component = furnaceGui.getIngredientComponent(); + break; + case "fuel": + component = furnaceGui.getFuelComponent(); + break; + case "output": + component = furnaceGui.getOutputComponent(); + break; + case "player-inventory": + component = furnaceGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return furnaceGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/GrindstoneGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/GrindstoneGui.java new file mode 100644 index 00000000..b8aee5f9 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/GrindstoneGui.java @@ -0,0 +1,296 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a grindstone + * + * @since 0.8.0 + */ +public class GrindstoneGui extends NamedGui { + + /** + * Represents the inventory component for the items + */ + @NotNull + private InventoryComponent itemsComponent = new InventoryComponent(1, 2); + + /** + * Represents the inventory component for the result + */ + @NotNull + private InventoryComponent resultComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal grindstone inventory + */ + @NotNull + private final GrindstoneInventory grindstoneInventory = VersionMatcher.newGrindstoneInventory(Version.getVersion(), + this); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public GrindstoneGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Grindstones can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getItemsComponent().display(getInventory(), 0); + getResultComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + grindstoneInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public GrindstoneGui copy() { + GrindstoneGui gui = new GrindstoneGui(getTitle()); + + gui.itemsComponent = itemsComponent.copy(); + gui.resultComponent = resultComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot >= 0 && rawSlot <= 1) { + getItemsComponent().click(this, event, rawSlot); + } else if (rawSlot == 2) { + getResultComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.GRINDSTONE, title); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 3 && slot <= 38) { + grindstoneInventory.sendItems(player, getTopItems()); + } else if (slot >= 0 && slot <= 2) { + grindstoneInventory.sendItems(player, getTopItems()); + + if (event.isCancelled()) { + grindstoneInventory.clearCursor(player); + } + } + } + + /** + * Gets the inventory component representing the items + * + * @return the items component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getItemsComponent() { + return itemsComponent; + } + + /** + * Gets the inventory component representing the result + * + * @return the result component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getResultComponent() { + return resultComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Gets the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getItemsComponent().getItem(0, 0), + getItemsComponent().getItem(0, 1), + getResultComponent().getItem(0, 0) + }; + } + + /** + * Loads a grindstone gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded furnace gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static GrindstoneGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a grindstone gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded grindstone gui + * @since 0.8.0 + */ + @NotNull + public static GrindstoneGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + GrindstoneGui grindstoneGui = new GrindstoneGui(element.getAttribute("title")); + grindstoneGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return grindstoneGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "items": + component = grindstoneGui.getItemsComponent(); + break; + case "result": + component = grindstoneGui.getResultComponent(); + break; + case "player-inventory": + component = grindstoneGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return grindstoneGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/HopperGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/HopperGui.java new file mode 100644 index 00000000..26c455e0 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/HopperGui.java @@ -0,0 +1,218 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a hopper + * + * @since 0.8.0 + */ +public class HopperGui extends NamedGui { + + /** + * Represents the inventory component for the slots + */ + @NotNull + private InventoryComponent slotsComponent = new InventoryComponent(5, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public HopperGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getSlotsComponent().display(getInventory(), 0); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public HopperGui copy() { + HopperGui gui = new HopperGui(getTitle()); + + gui.slotsComponent = slotsComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot >= 0 && rawSlot <= 4) { + getSlotsComponent().click(this, event, rawSlot); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 5); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.HOPPER, title); + } + + /** + * Gets the inventory component for the slots + * + * @return the slots component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getSlotsComponent() { + return slotsComponent; + } + + /** + * Gets the inventory component for the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a hopper gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded hopper gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static HopperGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a hopper gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded hopper gui + * @since 0.8.0 + */ + @NotNull + public static HopperGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + HopperGui hopperGui = new HopperGui(element.getAttribute("title")); + hopperGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return hopperGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "slots": + component = hopperGui.getSlotsComponent(); + break; + case "player-inventory": + component = hopperGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return hopperGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ShulkerBoxGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ShulkerBoxGui.java new file mode 100644 index 00000000..c9e0c5d4 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/ShulkerBoxGui.java @@ -0,0 +1,223 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Represents a gui in the form a shulker box + * + * @since 0.8.0 + */ +public class ShulkerBoxGui extends NamedGui { + + /** + * Represents the inventory component for the entire gui + */ + @NotNull + private InventoryComponent inventoryComponent = new InventoryComponent(9, 7); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public ShulkerBoxGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + int height = getInventoryComponent().getHeight(); + + getInventoryComponent().display(); + + InventoryComponent topComponent = getInventoryComponent().excludeRows(height - 4, height - 1); + InventoryComponent bottomComponent = getInventoryComponent().excludeRows(0, height - 5); + + topComponent.placeItems(getInventory(), 0); + bottomComponent.placeItems(humanEntity.getInventory(), 0); + + if (!bottomComponent.hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public ShulkerBoxGui copy() { + ShulkerBoxGui gui = new ShulkerBoxGui(getTitle()); + + gui.inventoryComponent = inventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getInventoryComponent().excludeRows(0, getInventoryComponent().getHeight() - 5).hasItem(); + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + getInventoryComponent().click(this, event, event.getRawSlot()); + } + + /** + * Adds a pane to this gui + * + * @param pane the pane to add + * @since 0.8.0 + */ + public void addPane(@NotNull Pane pane) { + this.inventoryComponent.addPane(pane); + } + + /** + * Gets all the panes in this gui, this includes child panes from other panes + * + * @return all panes + */ + @NotNull + @Contract(pure = true) + public List getPanes() { + return this.inventoryComponent.getPanes(); + } + + /** + * Gets all the items in all underlying panes + * + * @return all items + */ + @NotNull + @Contract(pure = true) + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.SHULKER_BOX, title); + } + + /** + * Gets the inventory component for this gui + * + * @return the inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInventoryComponent() { + return inventoryComponent; + } + + /** + * Loads a shulker box gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded shulker box gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static ShulkerBoxGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a shulker box gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded shulker box gui + * @since 0.8.0 + */ + @NotNull + public static ShulkerBoxGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + ShulkerBoxGui shulkerBoxGui = new ShulkerBoxGui(element.getAttribute("title")); + shulkerBoxGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return shulkerBoxGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + InventoryComponent inventoryComponent = shulkerBoxGui.getInventoryComponent(); + + if (componentElement.getTagName().equalsIgnoreCase("component")) { + inventoryComponent.load(instance, componentElement); + } else { + inventoryComponent.load(instance, element); + } + + break; + } + + return shulkerBoxGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmithingTableGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmithingTableGui.java new file mode 100644 index 00000000..d6198db1 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmithingTableGui.java @@ -0,0 +1,336 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.SmithingTableInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a smithing table + * + * @since 0.8.0 + */ +public class SmithingTableGui extends NamedGui { + + /** + * Represents the inventory component for the first item + */ + @NotNull + private InventoryComponent firstItemComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the second item + */ + @NotNull + private InventoryComponent secondItemComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the result + */ + @NotNull + private InventoryComponent resultComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal smithing inventory + */ + @NotNull + private final SmithingTableInventory smithingTableInventory = VersionMatcher.newSmithingTableInventory( + Version.getVersion(), this + ); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public SmithingTableGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Smithing tables can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getFirstItemComponent().display(getInventory(), 0); + getSecondItemComponent().display(getInventory(), 1); + getResultComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + smithingTableInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public SmithingTableGui copy() { + SmithingTableGui gui = new SmithingTableGui(getTitle()); + + gui.firstItemComponent = firstItemComponent.copy(); + gui.secondItemComponent = secondItemComponent.copy(); + gui.resultComponent = resultComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getFirstItemComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getSecondItemComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getResultComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.SMITHING, title); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 3 && slot <= 38) { + smithingTableInventory.sendItems(player, getTopItems()); + } else if (slot == 0 || slot == 1) { + if (event.isCancelled()) { + if (slot == 0) { + smithingTableInventory.sendFirstItem(player, getFirstItemComponent().getItem(0, 0)); + } else { + smithingTableInventory.sendSecondItem(player, getSecondItemComponent().getItem(0, 0)); + } + + smithingTableInventory.clearCursor(player); + } + + smithingTableInventory.sendResultItem(player, getResultComponent().getItem(0, 0)); + } else if (slot == 2 && !event.isCancelled()) { + smithingTableInventory.clearResultItem(player); + + ItemStack resultItem = getResultComponent().getItem(0, 0); + + if (resultItem != null) { + smithingTableInventory.setCursor(player, resultItem); + } + } + } + + /** + * Gets the inventory component representing the first item + * + * @return the first item component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFirstItemComponent() { + return firstItemComponent; + } + + /** + * Gets the inventory component representing the second item + * + * @return the second item component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getSecondItemComponent() { + return secondItemComponent; + } + + /** + * Gets the inventory component representing the result + * + * @return the result component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getResultComponent() { + return resultComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Gets the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getFirstItemComponent().getItem(0, 0), + getSecondItemComponent().getItem(0, 0), + getResultComponent().getItem(0, 0) + }; + } + + /** + * Loads a smithing table gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded smithing table gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static SmithingTableGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a smithing table gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded smithing table gui + * @since 0.8.0 + */ + @NotNull + public static SmithingTableGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + SmithingTableGui smithingTableGui = new SmithingTableGui(element.getAttribute("title")); + smithingTableGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return smithingTableGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "first-item": + component = smithingTableGui.getFirstItemComponent(); + break; + case "second-item": + component = smithingTableGui.getSecondItemComponent(); + break; + case "result": + component = smithingTableGui.getResultComponent(); + break; + case "player-inventory": + component = smithingTableGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return smithingTableGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmokerGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmokerGui.java new file mode 100644 index 00000000..f2ed3183 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/SmokerGui.java @@ -0,0 +1,268 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a smoker + * + * @since 0.8.0 + */ +public class SmokerGui extends NamedGui { + + /** + * Represents the inventory component for the ingredient + */ + @NotNull + private InventoryComponent ingredientComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the fuel + */ + @NotNull + private InventoryComponent fuelComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the output + */ + @NotNull + private InventoryComponent outputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public SmokerGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getIngredientComponent().display(getInventory(), 0); + getFuelComponent().display(getInventory(), 1); + getOutputComponent().display(getInventory(), 2); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + humanEntity.openInventory(getInventory()); + } + + @NotNull + @Contract(pure = true) + @Override + public SmokerGui copy() { + SmokerGui gui = new SmokerGui(getTitle()); + + gui.ingredientComponent = ingredientComponent.copy(); + gui.fuelComponent = fuelComponent.copy(); + gui.outputComponent = outputComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getIngredientComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getFuelComponent().click(this, event, 0); + } else if (rawSlot == 2) { + getOutputComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 3); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.SMOKER, title); + } + + /** + * Gets the inventory component representing the ingredient + * + * @return the ingredient component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getIngredientComponent() { + return ingredientComponent; + } + + /** + * Gets the inventory component representing the fuel + * + * @return the fuel component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getFuelComponent() { + return fuelComponent; + } + + /** + * Gets the inventory component representing the output + * + * @return the output component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getOutputComponent() { + return outputComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Loads a smoker gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded smoker gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static SmokerGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a smoker gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded smoker gui + * @since 0.8.0 + */ + @NotNull + public static SmokerGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + SmokerGui smokerGui = new SmokerGui(element.getAttribute("title")); + smokerGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return smokerGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "ingredient": + component = smokerGui.getIngredientComponent(); + break; + case "fuel": + component = smokerGui.getFuelComponent(); + break; + case "output": + component = smokerGui.getOutputComponent(); + break; + case "player-inventory": + component = smokerGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return smokerGui; + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/StonecutterGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/StonecutterGui.java new file mode 100644 index 00000000..292f10fe --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/StonecutterGui.java @@ -0,0 +1,296 @@ +package com.github.stefvanschie.inventoryframework.gui.type; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.NamedGui; +import com.github.stefvanschie.inventoryframework.util.version.Version; +import com.github.stefvanschie.inventoryframework.util.version.VersionMatcher; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Represents a gui in the form of a stonecutter + * + * @since 0.8.0 + */ +public class StonecutterGui extends NamedGui { + + /** + * Represents the inventory component for the input + */ + @NotNull + private InventoryComponent inputComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the result + */ + @NotNull + private InventoryComponent resultComponent = new InventoryComponent(1, 1); + + /** + * Represents the inventory component for the player inventory + */ + @NotNull + private InventoryComponent playerInventoryComponent = new InventoryComponent(9, 4); + + /** + * An internal stonecutter inventory + */ + @NotNull + private final StonecutterInventory stonecutterInventory = VersionMatcher.newStonecutterInventory( + Version.getVersion(), this + ); + + /** + * Constructs a new GUI + * + * @param title the title/name of this gui. + * @since 0.8.0 + */ + public StonecutterGui(@NotNull String title) { + super(title); + } + + @Override + public void show(@NotNull HumanEntity humanEntity) { + if (!(humanEntity instanceof Player)) { + throw new IllegalArgumentException("Enchanting tables can only be opened by players"); + } + + getInventory().clear(); + + getHumanEntityCache().storeAndClear(humanEntity); + + getInputComponent().display(getInventory(), 0); + getResultComponent().display(getInventory(), 1); + getPlayerInventoryComponent().display(humanEntity.getInventory(), 0); + + if (!getPlayerInventoryComponent().hasItem()) { + getHumanEntityCache().restoreAndForget(humanEntity); + } + + stonecutterInventory.openInventory((Player) humanEntity, getTitle(), getTopItems()); + } + + @NotNull + @Contract(pure = true) + @Override + public StonecutterGui copy() { + StonecutterGui gui = new StonecutterGui(getTitle()); + + gui.inputComponent = inputComponent.copy(); + gui.resultComponent = resultComponent.copy(); + gui.playerInventoryComponent = playerInventoryComponent.copy(); + + gui.setOnTopClick(this.onTopClick); + gui.setOnBottomClick(this.onBottomClick); + gui.setOnGlobalClick(this.onGlobalClick); + gui.setOnOutsideClick(this.onOutsideClick); + gui.setOnClose(this.onClose); + + return gui; + } + + @Override + public void click(@NotNull InventoryClickEvent event) { + int rawSlot = event.getRawSlot(); + + if (rawSlot == 0) { + getInputComponent().click(this, event, 0); + } else if (rawSlot == 1) { + getResultComponent().click(this, event, 0); + } else { + getPlayerInventoryComponent().click(this, event, rawSlot - 2); + } + } + + @Contract(pure = true) + @Override + public boolean isPlayerInventoryUsed() { + return getPlayerInventoryComponent().hasItem(); + } + + @NotNull + @Contract(pure = true) + @Override + public Inventory createInventory(@NotNull String title) { + return Bukkit.createInventory(this, InventoryType.STONECUTTER, title); + } + + /** + * Handles an incoming inventory click event + * + * @param event the event to handle + * @since 0.8.0 + */ + public void handleClickEvent(@NotNull InventoryClickEvent event) { + int slot = event.getRawSlot(); + Player player = (Player) event.getWhoClicked(); + + if (slot >= 2 && slot <= 37) { + stonecutterInventory.sendItems(player, getTopItems()); + } else if (slot == 0 || slot == 1) { + stonecutterInventory.sendItems(player, getTopItems()); + + if (event.isCancelled()) { + stonecutterInventory.clearCursor(player); + } + } + } + + /** + * Gets the inventory component representing the input + * + * @return the input component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getInputComponent() { + return inputComponent; + } + + /** + * Gets the inventory component representing the result + * + * @return the result component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getResultComponent() { + return resultComponent; + } + + /** + * Gets the inventory component representing the player inventory + * + * @return the player inventory component + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public InventoryComponent getPlayerInventoryComponent() { + return playerInventoryComponent; + } + + /** + * Get the top items + * + * @return the top items + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + private ItemStack[] getTopItems() { + return new ItemStack[] { + getInputComponent().getItem(0, 0), + getResultComponent().getItem(0, 0) + }; + } + + /** + * Loads a stone cutter gui from an XML file. + * + * @param instance the instance on which to reference fields and methods + * @param inputStream the input stream containing the XML data + * @return the loaded stone cutter gui + * @since 0.8.0 + */ + @Nullable + @Contract(pure = true) + public static StonecutterGui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + return load(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Loads a stonecutter gui from the specified element, applying code references to the provided instance. + * + * @param instance the instance on which to reference fields and methods + * @param element the element to load the gui from + * @return the loaded stonecutter gui + * @since 0.8.0 + */ + @NotNull + public static StonecutterGui load(@NotNull Object instance, @NotNull Element element) { + if (!element.hasAttribute("title")) { + throw new XMLLoadException("Provided XML element's gui tag doesn't have the mandatory title attribute set"); + } + + StonecutterGui stonecutterGui = new StonecutterGui(element.getAttribute("title")); + stonecutterGui.initializeOrThrow(instance, element); + + if (element.hasAttribute("populate")) { + return stonecutterGui; + } + + NodeList childNodes = element.getChildNodes(); + + for (int index = 0; index < childNodes.getLength(); index++) { + Node item = childNodes.item(index); + + if (item.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element componentElement = (Element) item; + + if (!componentElement.getTagName().equalsIgnoreCase("component")) { + throw new XMLLoadException("Gui element contains non-component tags"); + } + + if (!componentElement.hasAttribute("name")) { + throw new XMLLoadException("Component tag does not have a name specified"); + } + + InventoryComponent component; + + switch (componentElement.getAttribute("name")) { + case "input": + component = stonecutterGui.getInputComponent(); + break; + case "result": + component = stonecutterGui.getResultComponent(); + break; + case "player-inventory": + component = stonecutterGui.getPlayerInventoryComponent(); + break; + default: + throw new XMLLoadException("Unknown component name"); + } + + component.load(instance, componentElement); + } + + return stonecutterGui; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/Gui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/Gui.java similarity index 63% rename from src/main/java/com/github/stefvanschie/inventoryframework/Gui.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/Gui.java index 7230233e..2d46d831 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/Gui.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/Gui.java @@ -1,732 +1,614 @@ -package com.github.stefvanschie.inventoryframework; - -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.*; -import com.github.stefvanschie.inventoryframework.pane.component.*; -import com.github.stefvanschie.inventoryframework.util.XMLUtil; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.InputStream; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * The base class of all GUIs - */ -public class Gui implements InventoryHolder { - - /** - * A set of all panes in this inventory - */ - @NotNull - private final List panes; - - /** - * The inventory of this gui - */ - @NotNull - private Inventory inventory; - - /** - * The title of this gui - */ - @NotNull - private String title; - - /** - * The state of this gui - */ - @NotNull - private State state = State.TOP; - - /** - * A player cache for storing player's inventories - */ - @NotNull - private final HumanEntityCache humanEntityCache = new HumanEntityCache(); - - /** - * The consumer that will be called once a players clicks in the top-half of the gui - */ - @Nullable - private Consumer onTopClick; - - /** - * The consumer that will be called once a players clicks in the bottom-half of the gui - */ - @Nullable - private Consumer onBottomClick; - - /** - * The consumer that will be called once a players clicks in the gui or in their inventory - */ - @Nullable - private Consumer onGlobalClick; - - /** - * The consumer that will be called once a player clicks outside of the gui screen - */ - @Nullable - private Consumer onOutsideClick; - - /** - * The consumer that will be called once a player closes the gui - */ - @Nullable - private Consumer onClose; - - /** - * Whether this gui is updating (as invoked by {@link #update()}), true if this is the case, false otherwise. This - * is used to indicate that inventory close events due to updating should be ignored. - */ - private boolean updating = false; - - /** - * The pane mapping which will allow users to register their own panes to be used in XML files - */ - @NotNull - private static final Map> PANE_MAPPINGS = new HashMap<>(); - - /** - * Whether listeners have ben registered by some gui - */ - private static boolean hasRegisteredListeners; - - /** - * Constructs a new GUI - * - * @param plugin the main plugin. - * @param rows the amount of rows this gui should contain, in range 1..6. - * @param title the title/name of this gui. - * @deprecated use {@link #Gui(int, String)} instead - */ - @Deprecated - public Gui(@NotNull Plugin plugin, int rows, @NotNull String title) { - this(rows, title); - } - - /** - * Constructs a new GUI - * - * @param rows the amount of rows this gui should contain, in range 1..6. - * @param title the title/name of this gui. - * @since 0.6.0 - */ - public Gui(int rows, @NotNull String title) { - if (!(rows >= 1 && rows <= 6)) { - throw new IllegalArgumentException("Rows should be between 1 and 6"); - } - - this.panes = new ArrayList<>(); - this.inventory = Bukkit.createInventory(this, rows * 9, title); - this.title = title; - - if (!hasRegisteredListeners) { - Bukkit.getPluginManager().registerEvents(new GuiListener(), - JavaPlugin.getProvidingPlugin(getClass())); - - hasRegisteredListeners = true; - } - } - - /** - * Adds a pane to this gui - * - * @param pane the pane to add - */ - public void addPane(@NotNull Pane pane) { - this.panes.add(pane); - - this.panes.sort(Comparator.comparing(Pane::getPriority)); - } - - /** - * Shows a gui to a player - * - * @param humanEntity the human entity to show the gui to - */ - public void show(@NotNull HumanEntity humanEntity) { - inventory.clear(); - - //set the state to the top, so in case there are no longer any bottom part panes, their inventory will be shown again - setState(State.TOP); - - humanEntityCache.storeAndClear(humanEntity); - - //initialize the inventory first - panes.stream().filter(Pane::isVisible).forEach(pane -> pane.display(this, inventory, - humanEntity.getInventory(), 0, 0, 9, getRows() + 4)); - - //ensure that the inventory is cached before being overwritten and restore it if we end up not needing the bottom part after all - if (state == State.TOP) { - humanEntityCache.restoreAndForget(humanEntity); - } - - humanEntity.openInventory(inventory); - } - - /** - * Makes a copy of this gui and returns it. This makes a deep copy of the gui. This entails that the underlying - * panes will be copied as per their {@link Pane#copy} and miscellaneous data will be copied. The copy of this gui, - * will however have no viewers even if this gui currently has viewers. With this, cache data for viewers will also - * be non-existent for the copied gui. The returned gui will never be reference equal to the current gui. - * - * @return a copy of the gui - * @since 0.6.2 - */ - @NotNull - @Contract(pure = true) - public Gui copy() { - Gui gui = new Gui(getRows(), getTitle()); - - for (Pane pane : panes) { - gui.addPane(pane.copy()); - } - - gui.onTopClick = onTopClick; - gui.onBottomClick = onBottomClick; - gui.onGlobalClick = onGlobalClick; - gui.onOutsideClick = onOutsideClick; - gui.onClose = onClose; - - return gui; - } - - /** - * Sets the amount of rows for this inventory. - * This will (unlike most other methods) directly update itself in order to ensure all viewers will still be viewing the new inventory as well. - * - * @param rows the amount of rows in range 1..6. - */ - public void setRows(int rows) { - if (!(rows >= 1 && rows <= 6)) { - throw new IllegalArgumentException("Rows should be between 1 and 6"); - } - - //copy the viewers - List viewers = getViewers(); - - this.inventory = Bukkit.createInventory(this, rows * 9, getTitle()); - - viewers.forEach(humanEntity -> humanEntity.openInventory(inventory)); - } - - /** - * Gets the count of {@link HumanEntity} instances that are currently viewing this GUI. - * - * @return the count of viewers - * @since 0.5.19 - */ - @Contract(pure = true) - public int getViewerCount() { - return inventory.getViewers().size(); - } - - /** - * Gets a mutable snapshot of the current {@link HumanEntity} viewers of this GUI. - * This is a snapshot (copy) and not a view, therefore modifications aren't visible. - * - * @return a snapshot of the current viewers - * @see #getViewerCount() - * @since 0.5.19 - */ - @NotNull - @Contract(pure = true) - public List getViewers() { - return new ArrayList<>(inventory.getViewers()); - } - - /** - * Gets all the panes in this gui, this includes child panes from other panes - * - * @return all panes - */ - @NotNull - @Contract(pure = true) - public List getPanes() { - List panes = new ArrayList<>(); - - this.panes.forEach(pane -> panes.addAll(pane.getPanes())); - panes.addAll(this.panes); - - return panes; - } - - /** - * Sets the title for this inventory. This will (unlike most other methods) directly update itself in order - * to ensure all viewers will still be viewing the new inventory as well. - * - * @param title the title - */ - public void setTitle(@NotNull String title) { - //copy the viewers - List viewers = getViewers(); - - this.inventory = Bukkit.createInventory(this, this.inventory.getSize(), title); - this.title = title; - - viewers.forEach(humanEntity -> humanEntity.openInventory(inventory)); - } - - /** - * Gets all the items in all underlying panes - * - * @return all items - */ - @NotNull - @Contract(pure = true) - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); - } - - /** - * Update the gui for everyone - */ - public void update() { - updating = true; - - getViewers().forEach(this::show); - - if (!updating) - throw new AssertionError("Gui#isUpdating became false before Gui#update finished"); - - updating = false; - } - - /** - * Calling this method will set the state of this gui. If this state is set to top state, it will restore all the - * stored inventories of the players and will assume no pane extends into the bottom inventory part. If the state is - * set to bottom state it will assume one or more panes overflow into the bottom half of the inventory and will - * store all players' inventories and clear those. - * - * Do not call this method if you just want the player's inventory to be cleared. - * - * @param state the new gui state - * @since 0.4.0 - */ - public void setState(@NotNull State state) { - this.state = state; - - if (state == State.TOP) { - humanEntityCache.restoreAndForgetAll(); - } else if (state == State.BOTTOM) { - inventory.getViewers().forEach(humanEntityCache::storeAndClear); - } - } - - /** - * Gets the state of this gui - * - * @return the state - * @since 0.5.4 - */ - @NotNull - @Contract(pure = true) - public State getState() { - return state; - } - - /** - * Gets the human entity cache used for this gui - * - * @return the human entity cache - * @see HumanEntityCache - * @since 0.5.4 - */ - @NotNull - @Contract(pure = true) - protected HumanEntityCache getHumanEntityCache() { - return humanEntityCache; - } - - /** - * Loads a Gui from a given input stream. - * Returns null instead of throwing an exception in case of a failure. - * - * @param plugin the main plugin - * @param instance the class instance for all reflection lookups - * @param inputStream the file - * @return the gui or null if the loading failed - * @see #loadOrThrow(Object, InputStream) - * @deprecated use {@link #load(Object, InputStream)} instead - */ - @Nullable - @Deprecated - public static Gui load(@NotNull Plugin plugin, @NotNull Object instance, @NotNull InputStream inputStream) { - return load(instance, inputStream); - } - - /** - * Loads a Gui from a given input stream. - * Returns null instead of throwing an exception in case of a failure. - * - * @param instance the class instance for all reflection lookups - * @param inputStream the file - * @return the gui or null if the loading failed - * @see #loadOrThrow(Object, InputStream) - */ - @Nullable - public static Gui load(@NotNull Object instance, @NotNull InputStream inputStream) { - try { - return loadOrThrow(instance, inputStream); - } catch (RuntimeException e) { - e.printStackTrace(); - return null; - } - } - - /** - * Loads a Gui from a given input stream. - * Throws a {@link RuntimeException} instead of returning null in case of a failure. - * - * @param plugin the main plugin - * @param instance the class instance for all reflection lookups - * @param inputStream the file - * @return the gui - * @see #load(Object, InputStream) - * @deprecated use {@link #loadOrThrow(Object, InputStream)} instead - */ - @NotNull - @Deprecated - public static Gui loadOrThrow(@NotNull Plugin plugin, @NotNull Object instance, @NotNull InputStream inputStream) { - return loadOrThrow(instance, inputStream); - } - - /** - * Loads a Gui from a given input stream. - * Throws a {@link RuntimeException} instead of returning null in case of a failure. - * - * @param instance the class instance for all reflection lookups - * @param inputStream the file - * @return the gui - * @see #load(Object, InputStream) - */ - @NotNull - public static Gui loadOrThrow(@NotNull Object instance, @NotNull InputStream inputStream) { - Plugin plugin = JavaPlugin.getProvidingPlugin(Gui.class); - try { - Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); - Element documentElement = document.getDocumentElement(); - - documentElement.normalize(); - - Gui gui = new Gui(plugin, Integer.parseInt(documentElement.getAttribute("rows")), ChatColor - .translateAlternateColorCodes('&', documentElement.getAttribute("title"))); - - if (documentElement.hasAttribute("field")) - XMLUtil.loadFieldAttribute(instance, documentElement, gui); - - if (documentElement.hasAttribute("onTopClick")) { - gui.setOnTopClick(XMLUtil.loadOnEventAttribute(instance, - documentElement, InventoryClickEvent.class, "onTopClick")); - } - - if (documentElement.hasAttribute("onBottomClick")) { - gui.setOnBottomClick(XMLUtil.loadOnEventAttribute(instance, - documentElement, InventoryClickEvent.class, "onBottomClick")); - } - - if (documentElement.hasAttribute("onGlobalClick")) { - gui.setOnGlobalClick(XMLUtil.loadOnEventAttribute(instance, - documentElement, InventoryClickEvent.class, "onGlobalClick")); - } - - if (documentElement.hasAttribute("onOutsideClick")) { - gui.setOnOutsideClick(XMLUtil.loadOnEventAttribute(instance, - documentElement, InventoryClickEvent.class, "onOutsideClick")); - } - - if (documentElement.hasAttribute("onClose")) { - gui.setOnClose(XMLUtil.loadOnEventAttribute(instance, - documentElement, InventoryCloseEvent.class, "onClose")); - } - - if (documentElement.hasAttribute("populate")) { - MethodUtils.invokeExactMethod(instance, "populate", gui, Gui.class); - } else { - NodeList childNodes = documentElement.getChildNodes(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - - if (item.getNodeType() == Node.ELEMENT_NODE) - gui.addPane(loadPane(instance, item)); - } - } - - return gui; - } catch (Exception e) { - throw new XMLLoadException("Error loading " + plugin.getName() + "'s gui with associated class: " - + instance.getClass().getSimpleName(), e); - } - } - - /** - * Set the consumer that should be called whenever this gui is clicked in. - * - * @param onTopClick the consumer that gets called - */ - public void setOnTopClick(@Nullable Consumer onTopClick) { - this.onTopClick = onTopClick; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnTopClick(Consumer)}, - * so the consumer that should be called whenever this gui is clicked in. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callOnTopClick(@NotNull InventoryClickEvent event) { - callCallback(onTopClick, event, "onTopClick"); - } - - /** - * Set the consumer that should be called whenever the inventory is clicked in. - * - * @param onBottomClick the consumer that gets called - */ - public void setOnBottomClick(@Nullable Consumer onBottomClick) { - this.onBottomClick = onBottomClick; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnBottomClick(Consumer)}, - * so the consumer that should be called whenever the inventory is clicked in. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callOnBottomClick(@NotNull InventoryClickEvent event) { - callCallback(onBottomClick, event, "onBottomClick"); - } - - /** - * Set the consumer that should be called whenever this gui or inventory is clicked in. - * - * @param onGlobalClick the consumer that gets called - */ - public void setOnGlobalClick(@Nullable Consumer onGlobalClick) { - this.onGlobalClick = onGlobalClick; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnGlobalClick(Consumer)}, - * so the consumer that should be called whenever this gui or inventory is clicked in. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callOnGlobalClick(@NotNull InventoryClickEvent event) { - callCallback(onGlobalClick, event, "onGlobalClick"); - } - - /** - * Set the consumer that should be called whenever a player clicks outside the gui. - * - * @param onOutsideClick the consumer that gets called - * @since 0.5.7 - */ - public void setOnOutsideClick(@Nullable Consumer onOutsideClick) { - this.onOutsideClick = onOutsideClick; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnOutsideClick(Consumer)}, - * so the consumer that should be called whenever a player clicks outside the gui. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callOnOutsideClick(@NotNull InventoryClickEvent event) { - callCallback(onOutsideClick, event, "onOutsideClick"); - } - - /** - * Set the consumer that should be called whenever this gui is closed. - * - * @param onClose the consumer that gets called - */ - public void setOnClose(@Nullable Consumer onClose) { - this.onClose = onClose; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnClose(Consumer)}, - * so the consumer that should be called whenever this gui is closed. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - public void callOnClose(@NotNull InventoryCloseEvent event) { - callCallback(onClose, event, "onClose"); - } - - /** - * Calls the specified consumer (if it's not null) with the specified parameter, - * catching and logging all exceptions it might throw. - * - * @param callback the consumer to call if it isn't null - * @param event the value the consumer should accept - * @param callbackName the name of the action, used for logging - * @param the type of the value the consumer is accepting - */ - private void callCallback(@Nullable Consumer callback, - @NotNull T event, @NotNull String callbackName) { - if (callback == null) { - return; - } - - try { - callback.accept(event); - } catch (Throwable t) { - Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); - String message = "Exception while handling " + callbackName + " in inventory '" + title + "', state=" + state; - if (event instanceof InventoryClickEvent) { - InventoryClickEvent clickEvent = (InventoryClickEvent) event; - message += ", slot=" + clickEvent.getSlot(); - } - logger.log(Level.SEVERE, message, t); - } - } - - /** - * Returns the amount of rows this gui currently has - * - * @return the amount of rows - */ - public int getRows() { - return inventory.getSize() / 9; - } - - /** - * Returns the title of this gui - * - * @return the title - */ - @NotNull - @Contract(pure = true) - public String getTitle() { - return title; - } - - @NotNull - @Override - public Inventory getInventory() { - return inventory; - } - - /** - * Gets whether this gui is being updated, as invoked by {@link #update()}. This returns true if this is the case - * and false otherwise. - * - * @return whether this gui is being updated - * @since 0.5.15 - */ - @Contract(pure = true) - protected boolean isUpdating() { - return updating; - } - - /** - * Registers a property that can be used inside an XML file to add additional new properties. - * - * @param attributeName the name of the property. This is the same name you'll be using to specify the property - * type in the XML file. - * @param function how the property should be processed. This converts the raw text input from the XML node value - * into the correct object type. - * @throws IllegalArgumentException when a property with this name is already registered. - */ - public static void registerProperty(@NotNull String attributeName, @NotNull Function function) { - Pane.registerProperty(attributeName, function); - } - - /** - * Registers a name that can be used inside an XML file to add custom panes - * - * @param name the name of the pane to be used in the XML file - * @param biFunction how the pane loading should be processed - * @throws IllegalArgumentException when a pane with this name is already registered - */ - public static void registerPane(@NotNull String name, @NotNull BiFunction biFunction) { - if (PANE_MAPPINGS.containsKey(name)) { - throw new IllegalArgumentException("pane name '" + name + "' is already registered"); - } - - PANE_MAPPINGS.put(name, biFunction); - } - - /** - * Loads a pane by the given instance and node - * - * @param instance the instance - * @param node the node - * @return the pane - */ - @NotNull - public static Pane loadPane(@NotNull Object instance, @NotNull Node node) { - return PANE_MAPPINGS.get(node.getNodeName()).apply(instance, (Element) node); - } - - /** - * The gui state - * - * @since 0.4.0 - */ - public enum State { - - /** - * This signals that only the top-half of the Gui is in use and the player's inventory will stay like it is - * - * @since 0.4.0 - */ - TOP, - - /** - * This signals that the bottom-hal of the Gui is in use and the player's inventory will be cleared and stored - * - * @since 0.4.0 - */ - BOTTOM - } - - static { - registerPane("masonrypane", MasonryPane::load); - registerPane("outlinepane", OutlinePane::load); - registerPane("paginatedpane", PaginatedPane::load); - registerPane("staticpane", StaticPane::load); - - registerPane("cyclebutton", CycleButton::load); - registerPane("label", Label::load); - registerPane("percentagebar", PercentageBar::load); - registerPane("slider", Slider::load); - registerPane("togglebutton", ToggleButton::load); - } -} +package com.github.stefvanschie.inventoryframework.gui.type.util; + +import com.github.stefvanschie.inventoryframework.HumanEntityCache; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.gui.GuiListener; +import com.github.stefvanschie.inventoryframework.gui.type.*; +import com.github.stefvanschie.inventoryframework.pane.*; +import com.github.stefvanschie.inventoryframework.pane.component.*; +import com.github.stefvanschie.inventoryframework.util.XMLUtil; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The base class of all GUIs + */ +public abstract class Gui implements InventoryHolder { + + /** + * The inventory of this gui + */ + protected Inventory inventory; + + /** + * The state of this gui + */ + @NotNull + private State state = State.TOP; + + /** + * A player cache for storing player's inventories + */ + @NotNull + protected final HumanEntityCache humanEntityCache = new HumanEntityCache(); + + /** + * The consumer that will be called once a players clicks in the top-half of the gui + */ + @Nullable + protected Consumer onTopClick; + + /** + * The consumer that will be called once a players clicks in the bottom-half of the gui + */ + @Nullable + protected Consumer onBottomClick; + + /** + * The consumer that will be called once a players clicks in the gui or in their inventory + */ + @Nullable + protected Consumer onGlobalClick; + + /** + * The consumer that will be called once a player clicks outside of the gui screen + */ + @Nullable + protected Consumer onOutsideClick; + + /** + * The consumer that will be called once a player closes the gui + */ + @Nullable + protected Consumer onClose; + + /** + * Whether this gui is updating (as invoked by {@link #update()}), true if this is the case, false otherwise. This + * is used to indicate that inventory close events due to updating should be ignored. + */ + private boolean updating = false; + + /** + * The pane mapping which will allow users to register their own panes to be used in XML files + */ + @NotNull + private static final Map> PANE_MAPPINGS = new HashMap<>(); + + /** + * The gui mappings which determine which gui type belongs to which identifier + */ + @NotNull + private static final Map> GUI_MAPPINGS + = new HashMap<>(); + + /** + * Whether listeners have ben registered by some gui + */ + private static boolean hasRegisteredListeners; + + /** + * Constructs a new GUI + * + * @since 0.8.0 + */ + public Gui() { + if (!hasRegisteredListeners) { + Bukkit.getPluginManager().registerEvents(new GuiListener(), + JavaPlugin.getProvidingPlugin(getClass())); + + hasRegisteredListeners = true; + } + } + + /** + * Creates a new inventory of the type of the implementing class with the provided title. + * + * @return the new inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public abstract Inventory createInventory(); + + /** + * Shows a gui to a player + * + * @param humanEntity the human entity to show the gui to + */ + public abstract void show(@NotNull HumanEntity humanEntity); + + /** + * Makes a copy of this gui and returns it. This makes a deep copy of the gui. This entails that the underlying + * panes will be copied as per their {@link Pane#copy} and miscellaneous data will be copied. The copy of this gui, + * will however have no viewers even if this gui currently has viewers. With this, cache data for viewers will also + * be non-existent for the copied gui. The returned gui will never be reference equal to the current gui. + * + * @return a copy of the gui + * @since 0.6.2 + */ + @NotNull + @Contract(pure = true) + public abstract Gui copy(); + + /** + * This should delegate the provided inventory click event to the right pane, which can then handle this click event + * further. This should not call any internal click handlers, since those will already have been activated. + * + * @param event the event to delegate + * @since 0.8.0 + */ + public abstract void click(@NotNull InventoryClickEvent event); + + /** + * Gets whether the player inventory is currently in use. This means whether the player inventory currently has an + * item in it. + * + * @return true if the player inventory is occupied, false otherwise + * @since 0.8.0 + */ + public abstract boolean isPlayerInventoryUsed(); + + /** + * Gets the count of {@link HumanEntity} instances that are currently viewing this GUI. + * + * @return the count of viewers + * @since 0.5.19 + */ + @Contract(pure = true) + public int getViewerCount() { + return getInventory().getViewers().size(); + } + + /** + * Gets a mutable snapshot of the current {@link HumanEntity} viewers of this GUI. + * This is a snapshot (copy) and not a view, therefore modifications aren't visible. + * + * @return a snapshot of the current viewers + * @see #getViewerCount() + * @since 0.5.19 + */ + @NotNull + @Contract(pure = true) + public List getViewers() { + return new ArrayList<>(getInventory().getViewers()); + } + + /** + * Update the gui for everyone + */ + public void update() { + updating = true; + + getViewers().forEach(this::show); + + if (!updating) + throw new AssertionError("Gui#isUpdating became false before Gui#update finished"); + + updating = false; + } + + /** + * Calling this method will set the state of this gui. If this state is set to top state, it will restore all the + * stored inventories of the players and will assume no pane extends into the bottom inventory part. If the state is + * set to bottom state it will assume one or more panes overflow into the bottom half of the inventory and will + * store all players' inventories and clear those. + * + * Do not call this method if you just want the player's inventory to be cleared. + * + * @deprecated state will be removed entirely in a future version + * @param state the new gui state + * @since 0.4.0 + */ + @Deprecated + public void setState(@NotNull State state) { + this.state = state; + + if (state == State.TOP) { + humanEntityCache.restoreAndForgetAll(); + } else if (state == State.BOTTOM) { + inventory.getViewers().forEach(humanEntityCache::storeAndClear); + } + } + + /** + * Gets the state of this gui + * + * @deprecated state will be removed entirely in a future version + * @return the state + * @since 0.5.4 + */ + @NotNull + @Contract(pure = true) + @Deprecated + public State getState() { + return state; + } + + /** + * Gets the human entity cache used for this gui + * + * @return the human entity cache + * @see HumanEntityCache + * @since 0.5.4 + */ + @NotNull + @Contract(pure = true) + public HumanEntityCache getHumanEntityCache() { + return humanEntityCache; + } + + /** + * Loads a Gui from a given input stream. + * Returns null instead of throwing an exception in case of a failure. + * + * @param instance the class instance for all reflection lookups + * @param inputStream the file + * @return the gui or null if the loading failed + */ + @Nullable + public static Gui load(@NotNull Object instance, @NotNull InputStream inputStream) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); + Element documentElement = document.getDocumentElement(); + + documentElement.normalize(); + + if (!documentElement.hasAttribute("type")) { + throw new XMLLoadException("Type attribute must be specified when loading via Gui.load"); + } + + return GUI_MAPPINGS.get(documentElement.getAttribute("type")).apply(instance, documentElement); + } catch (SAXException | ParserConfigurationException | IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Initializes standard fields from a Gui from a given input stream. + * Throws a {@link RuntimeException} instead of returning null in case of a failure. + * + * @param instance the class instance for all reflection lookups + * @param element the gui element + * @see #load(Object, InputStream) + */ + protected void initializeOrThrow(@NotNull Object instance, @NotNull Element element) { + if (element.hasAttribute("field")) + XMLUtil.loadFieldAttribute(instance, element, this); + + if (element.hasAttribute("onTopClick")) { + setOnTopClick(XMLUtil.loadOnEventAttribute(instance, + element, InventoryClickEvent.class, "onTopClick")); + } + + if (element.hasAttribute("onBottomClick")) { + setOnBottomClick(XMLUtil.loadOnEventAttribute(instance, + element, InventoryClickEvent.class, "onBottomClick")); + } + + if (element.hasAttribute("onGlobalClick")) { + setOnGlobalClick(XMLUtil.loadOnEventAttribute(instance, + element, InventoryClickEvent.class, "onGlobalClick")); + } + + if (element.hasAttribute("onOutsideClick")) { + setOnOutsideClick(XMLUtil.loadOnEventAttribute(instance, + element, InventoryClickEvent.class, "onOutsideClick")); + } + + if (element.hasAttribute("onClose")) { + setOnClose(XMLUtil.loadOnEventAttribute(instance, + element, InventoryCloseEvent.class, "onClose")); + } + + if (element.hasAttribute("populate")) { + try { + MethodUtils.invokeExactMethod(instance, "populate", this, Gui.class); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Plugin plugin = JavaPlugin.getProvidingPlugin(Gui.class); + + throw new XMLLoadException("Error loading " + plugin.getName() + "'s gui with associated class: " + + instance.getClass().getSimpleName(), e); + } + } + } + + /** + * Set the consumer that should be called whenever this gui is clicked in. + * + * @param onTopClick the consumer that gets called + */ + public void setOnTopClick(@Nullable Consumer onTopClick) { + this.onTopClick = onTopClick; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnTopClick(Consumer)}, + * so the consumer that should be called whenever this gui is clicked in. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callOnTopClick(@NotNull InventoryClickEvent event) { + callCallback(onTopClick, event, "onTopClick"); + } + + /** + * Set the consumer that should be called whenever the inventory is clicked in. + * + * @param onBottomClick the consumer that gets called + */ + public void setOnBottomClick(@Nullable Consumer onBottomClick) { + this.onBottomClick = onBottomClick; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnBottomClick(Consumer)}, + * so the consumer that should be called whenever the inventory is clicked in. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callOnBottomClick(@NotNull InventoryClickEvent event) { + callCallback(onBottomClick, event, "onBottomClick"); + } + + /** + * Set the consumer that should be called whenever this gui or inventory is clicked in. + * + * @param onGlobalClick the consumer that gets called + */ + public void setOnGlobalClick(@Nullable Consumer onGlobalClick) { + this.onGlobalClick = onGlobalClick; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnGlobalClick(Consumer)}, + * so the consumer that should be called whenever this gui or inventory is clicked in. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callOnGlobalClick(@NotNull InventoryClickEvent event) { + callCallback(onGlobalClick, event, "onGlobalClick"); + } + + /** + * Set the consumer that should be called whenever a player clicks outside the gui. + * + * @param onOutsideClick the consumer that gets called + * @since 0.5.7 + */ + public void setOnOutsideClick(@Nullable Consumer onOutsideClick) { + this.onOutsideClick = onOutsideClick; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnOutsideClick(Consumer)}, + * so the consumer that should be called whenever a player clicks outside the gui. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callOnOutsideClick(@NotNull InventoryClickEvent event) { + callCallback(onOutsideClick, event, "onOutsideClick"); + } + + /** + * Set the consumer that should be called whenever this gui is closed. + * + * @param onClose the consumer that gets called + */ + public void setOnClose(@Nullable Consumer onClose) { + this.onClose = onClose; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnClose(Consumer)}, + * so the consumer that should be called whenever this gui is closed. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + public void callOnClose(@NotNull InventoryCloseEvent event) { + callCallback(onClose, event, "onClose"); + } + + /** + * Calls the specified consumer (if it's not null) with the specified parameter, + * catching and logging all exceptions it might throw. + * + * @param callback the consumer to call if it isn't null + * @param event the value the consumer should accept + * @param callbackName the name of the action, used for logging + * @param the type of the value the consumer is accepting + */ + private void callCallback(@Nullable Consumer callback, + @NotNull T event, @NotNull String callbackName) { + if (callback == null) { + return; + } + + try { + callback.accept(event); + } catch (Throwable t) { + Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); + String message = "Exception while handling " + callbackName + ", state=" + state; + if (event instanceof InventoryClickEvent) { + InventoryClickEvent clickEvent = (InventoryClickEvent) event; + message += ", slot=" + clickEvent.getSlot(); + } + logger.log(Level.SEVERE, message, t); + } + } + + @NotNull + @Override + public Inventory getInventory() { + if (this.inventory == null) { + this.inventory = createInventory(); + } + + return inventory; + } + + /** + * Gets whether this gui is being updated, as invoked by {@link #update()}. This returns true if this is the case + * and false otherwise. + * + * @return whether this gui is being updated + * @since 0.5.15 + */ + @Contract(pure = true) + public boolean isUpdating() { + return updating; + } + + /** + * Registers a property that can be used inside an XML file to add additional new properties. + * + * @param attributeName the name of the property. This is the same name you'll be using to specify the property + * type in the XML file. + * @param function how the property should be processed. This converts the raw text input from the XML node value + * into the correct object type. + * @throws IllegalArgumentException when a property with this name is already registered. + */ + public static void registerProperty(@NotNull String attributeName, @NotNull Function function) { + Pane.registerProperty(attributeName, function); + } + + /** + * Registers a name that can be used inside an XML file to add custom panes + * + * @param name the name of the pane to be used in the XML file + * @param biFunction how the pane loading should be processed + * @throws IllegalArgumentException when a pane with this name is already registered + */ + public static void registerPane(@NotNull String name, @NotNull BiFunction biFunction) { + if (PANE_MAPPINGS.containsKey(name)) { + throw new IllegalArgumentException("pane name '" + name + "' is already registered"); + } + + PANE_MAPPINGS.put(name, biFunction); + } + + /** + * Registers a type that can be used inside an XML file to specify the gui type + * + * @param name the name of the type of gui to be used in an XML file + * @param biFunction how the gui creation should be processed + * @throws IllegalArgumentException when a gui type with this name is already registered + */ + public static void registerGui(@NotNull String name, @NotNull BiFunction biFunction) { + if (GUI_MAPPINGS.containsKey(name)) { + throw new IllegalArgumentException("Gui name '" + name + "' is already registered"); + } + + GUI_MAPPINGS.put(name, biFunction); + } + + /** + * Loads a pane by the given instance and node + * + * @param instance the instance + * @param node the node + * @return the pane + */ + @NotNull + public static Pane loadPane(@NotNull Object instance, @NotNull Node node) { + return PANE_MAPPINGS.get(node.getNodeName()).apply(instance, (Element) node); + } + + /** + * The gui state + * + * @deprecated state will be removed entirely in a future version + * @since 0.4.0 + */ + @Deprecated + public enum State { + + /** + * This signals that only the top-half of the Gui is in use and the player's inventory will stay like it is + * + * @deprecated state will be removed entirely in a future version + * @since 0.4.0 + */ + @Deprecated + TOP, + + /** + * This signals that the bottom-hal of the Gui is in use and the player's inventory will be cleared and stored + * + * @deprecated state will be removed entirely in a future version + * @since 0.4.0 + */ + @Deprecated + BOTTOM + } + + static { + registerPane("masonrypane", MasonryPane::load); + registerPane("outlinepane", OutlinePane::load); + registerPane("paginatedpane", PaginatedPane::load); + registerPane("staticpane", StaticPane::load); + + registerPane("cyclebutton", CycleButton::load); + registerPane("label", Label::load); + registerPane("percentagebar", PercentageBar::load); + registerPane("slider", Slider::load); + registerPane("togglebutton", ToggleButton::load); + + registerGui("anvil", AnvilGui::load); + registerGui("barrel", BarrelGui::load); + registerGui("beacon", BeaconGui::load); + registerGui("blast-furnace", BlastFurnaceGui::load); + registerGui("brewing-stand", BrewingStandGui::load); + registerGui("cartography-table", CartographyTableGui::load); + registerGui("chest", ChestGui::load); + registerGui("crafting-table", CraftingTableGui::load); + registerGui("dispenser", DispenserGui::load); + registerGui("dropper", DropperGui::load); + registerGui("enchanting-table", EnchantingTableGui::load); + registerGui("ender-chest", EnderChestGui::load); + registerGui("furnace", FurnaceGui::load); + registerGui("grindstone", GrindstoneGui::load); + registerGui("hopper", HopperGui::load); + registerGui("shulker-box", ShulkerBoxGui::load); + registerGui("smithing-table", SmithingTableGui::load); + registerGui("smoker", SmokerGui::load); + registerGui("stonecutter", StonecutterGui::load); + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/NamedGui.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/NamedGui.java new file mode 100644 index 00000000..9edfeeb4 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/gui/type/util/NamedGui.java @@ -0,0 +1,82 @@ +package com.github.stefvanschie.inventoryframework.gui.type.util; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class NamedGui extends Gui { + + /** + * The title of this gui + */ + @NotNull + private String title; + + /** + * Constructs a new gui with a title + * + * @param title the title/name of this gui + * @since 0.8.0 + */ + public NamedGui(@NotNull String title) { + this.title = title; + } + + /** + * Creates a new inventory of the type of the implementing class with the provided title. + * + * @param title the title for the new inventory + * @return the new inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public abstract Inventory createInventory(@NotNull String title); + + @NotNull + @Override + public Inventory getInventory() { + if (this.inventory == null) { + this.inventory = createInventory(getTitle()); + } + + return inventory; + } + + @NotNull + @Override + public Inventory createInventory() { + return createInventory(title); + } + + /** + * Sets the title for this inventory. This will (unlike most other methods) directly update itself in order + * to ensure all viewers will still be viewing the new inventory as well. + * + * @param title the title + */ + public void setTitle(@NotNull String title) { + //copy the viewers + List viewers = getViewers(); + + this.inventory = createInventory(title); + this.title = title; + + viewers.forEach(humanEntity -> humanEntity.openInventory(getInventory())); + } + + /** + * Returns the title of this gui + * + * @return the title + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public String getTitle() { + return title; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java similarity index 96% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java index a46262e4..d74a80f6 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Flippable.java @@ -1,63 +1,63 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -/** - * An interface for panes that can be flipped - * - * @since 0.3.0 - */ -public interface Flippable { - - /** - * Sets whether this pane should flip its items horizontally - * - * @param flipHorizontally whether the pane should flip items horizontally - * @since 0.3.0 - */ - void flipHorizontally(boolean flipHorizontally); - - /** - * Sets whether this pane should flip its items vertically - * - * @param flipVertically whether the pane should flip items vertically - * @since 0.3.0 - */ - void flipVertically(boolean flipVertically); - - /** - * Gets whether this pane's items are flipped horizontally - * - * @return true if the items are flipped horizontally, false otherwise - * @since 0.3.0 - */ - @Contract(pure = true) - boolean isFlippedHorizontally(); - - /** - * Gets whether this pane's items are flipped vertically - * - * @return true if the items are flipped vertically, false otherwise - * @since 0.3.0 - */ - @Contract(pure = true) - boolean isFlippedVertically(); - - /** - * Loads all elements regarding a {@link Flippable} {@link Pane} for the specified pane. The mutable pane contains - * the changes made. - * - * @param flippable the flippable pane's elements to be applied - * @param element the XML element for this pane - * @since 0.3.0 - */ - static void load(@NotNull Flippable flippable, @NotNull Element element) { - if (element.hasAttribute("flipHorizontally")) - flippable.flipHorizontally(Boolean.parseBoolean(element.getAttribute("flipHorizontally"))); - - if (element.hasAttribute("flipVertically")) - flippable.flipVertically(Boolean.parseBoolean(element.getAttribute("flipVertically"))); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * An interface for panes that can be flipped + * + * @since 0.3.0 + */ +public interface Flippable { + + /** + * Sets whether this pane should flip its items horizontally + * + * @param flipHorizontally whether the pane should flip items horizontally + * @since 0.3.0 + */ + void flipHorizontally(boolean flipHorizontally); + + /** + * Sets whether this pane should flip its items vertically + * + * @param flipVertically whether the pane should flip items vertically + * @since 0.3.0 + */ + void flipVertically(boolean flipVertically); + + /** + * Gets whether this pane's items are flipped horizontally + * + * @return true if the items are flipped horizontally, false otherwise + * @since 0.3.0 + */ + @Contract(pure = true) + boolean isFlippedHorizontally(); + + /** + * Gets whether this pane's items are flipped vertically + * + * @return true if the items are flipped vertically, false otherwise + * @since 0.3.0 + */ + @Contract(pure = true) + boolean isFlippedVertically(); + + /** + * Loads all elements regarding a {@link Flippable} {@link Pane} for the specified pane. The mutable pane contains + * the changes made. + * + * @param flippable the flippable pane's elements to be applied + * @param element the XML element for this pane + * @since 0.3.0 + */ + static void load(@NotNull Flippable flippable, @NotNull Element element) { + if (element.hasAttribute("flipHorizontally")) + flippable.flipHorizontally(Boolean.parseBoolean(element.getAttribute("flipHorizontally"))); + + if (element.hasAttribute("flipVertically")) + flippable.flipVertically(Boolean.parseBoolean(element.getAttribute("flipVertically"))); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java similarity index 84% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java index 929d5285..6077e7a2 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/MasonryPane.java @@ -1,295 +1,275 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * This pane holds panes and decides itself where every pane should go. It tries to put every pane in the top left - * corner and will move rightwards and downwards respectively if the top left corner is already in use. Depending on the - * order and size of the panes, this may leave empty spaces in certain spots. Do note however that the order of panes - * isn't always preserved. If there is a gap left in which a pane with a higher index can fit, it will be put there, - * even if there are panes with a lower index after it. Panes that do not fit will not be displayed. - * - * @since 0.3.0 - */ -public class MasonryPane extends Pane implements Orientable { - - /** - * A list of panes that should be displayed - */ - @NotNull - private final List panes = new ArrayList<>(); - - /** - * The orientation of the items in this pane - */ - @NotNull - private Orientation orientation = Orientation.HORIZONTAL; - - public MasonryPane(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - } - - public MasonryPane(int x, int y, int length, int height) { - super(x, y, length, height); - } - - public MasonryPane(int length, int height) { - super(length, height); - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength) - paneOffsetX; - int height = Math.min(this.height, maxHeight) - paneOffsetY; - - int[][] positions = new int[length][height]; - - for (int[] array : positions) { - Arrays.fill(array, -1); - } - - for (int paneIndex = 0; paneIndex < panes.size(); paneIndex++) { - Pane pane = panes.get(paneIndex); - - if (orientation == Orientation.HORIZONTAL) { - outerLoop: - for (int y = 0; y < height; y++) { - for (int x = 0; x < length; x++) { - //check whether the pane fits - boolean fits = true; - - paneFits: - for (int i = 0; i < pane.getLength(); i++) { - for (int j = 0; j < pane.getHeight(); j++) { - if (x + i >= positions.length || y + j >= positions[x + i].length || positions[x + i][y + j] != -1) { - fits = false; - break paneFits; - } - } - } - - if (fits) { - for (int i = 0; i < pane.getLength(); i++) { - for (int j = 0; j < pane.getHeight(); j++) { - positions[x + i][y + j] = paneIndex; - } - } - - pane.setX(x); - pane.setY(y); - - pane.display( - gui, - inventory, - playerInventory, - paneOffsetX + getX(), - paneOffsetY + getY(), - Math.min(this.length, maxLength), - Math.min(this.height, maxHeight) - ); - break outerLoop; - } - } - } - } else if (orientation == Orientation.VERTICAL) { - outerLoop: - for (int x = 0; x < length; x++) { - for (int y = 0; y < height; y++) { - //check whether the pane fits - boolean fits = true; - - paneFits: - for (int i = 0; i < pane.getHeight(); i++) { - for (int j = 0; j < pane.getLength(); j++) { - if (x + j >= positions.length || y + i >= positions[x + j].length || positions[x + j][y + i] != -1) { - fits = false; - break paneFits; - } - } - } - - if (fits) { - for (int i = 0; i < pane.getLength(); i++) { - for (int j = 0; j < pane.getHeight(); j++) { - positions[x + i][y + j] = paneIndex; - } - } - - pane.setX(x); - pane.setY(y); - - pane.display( - gui, - inventory, - playerInventory, - paneOffsetX + getX(), - paneOffsetY + getY(), - Math.min(this.length, maxLength), - Math.min(this.height, maxHeight) - ); - break outerLoop; - } - } - } - } - } - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - if (x < 0 || x >= length || y < 0 || y >= height) - return false; - - callOnClick(event); - - boolean success = false; - - for (Pane pane : panes) { - success = success || pane.click(gui, event, paneOffsetX + getX(), - paneOffsetY + getY(), length, height); - } - - return success; - } - - @NotNull - @Contract(pure = true) - @Override - public MasonryPane copy() { - MasonryPane masonryPane = new MasonryPane(x, y, length, height, getPriority()); - - for (Pane pane : panes) { - masonryPane.addPane(pane.copy()); - } - - masonryPane.setVisible(isVisible()); - masonryPane.onClick = onClick; - masonryPane.orientation = orientation; - - masonryPane.uuid = uuid; - - return masonryPane; - } - - /** - * Adds a pane to this masonry pane - * - * @param pane the pane to add - * @since 0.3.0 - */ - public void addPane(@NotNull Pane pane) { - panes.add(pane); - } - - @NotNull - @Override - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); - } - - @NotNull - @Override - public Collection getPanes() { - Collection panes = new HashSet<>(); - - this.panes.forEach(p -> { - panes.addAll(p.getPanes()); - panes.add(p); - }); - - return panes; - } - - @Override - public void clear() { - panes.clear(); - } - - @NotNull - @Override - public Orientation getOrientation() { - return orientation; - } - - @Override - public void setOrientation(@NotNull Orientation orientation) { - this.orientation = orientation; - } - - /** - * Loads a masonry pane from a given element - * - * @param instance the instance class - * @param element the element - * @return the masonry pane - */ - @NotNull - public static MasonryPane load(@NotNull Object instance, @NotNull Element element) { - try { - MasonryPane masonryPane = new MasonryPane( - Integer.parseInt(element.getAttribute("length")), - Integer.parseInt(element.getAttribute("height")) - ); - - Pane.load(masonryPane, instance, element); - Orientable.load(masonryPane, element); - - if (element.hasAttribute("populate")) { - return masonryPane; - } - - NodeList childNodes = element.getChildNodes(); - - for (int j = 0; j < childNodes.getLength(); j++) { - Node pane = childNodes.item(j); - - if (pane.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - - masonryPane.addPane(Gui.loadPane(instance, pane)); - } - - return masonryPane; - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * This pane holds panes and decides itself where every pane should go. It tries to put every pane in the top left + * corner and will move rightwards and downwards respectively if the top left corner is already in use. Depending on the + * order and size of the panes, this may leave empty spaces in certain spots. Do note however that the order of panes + * isn't always preserved. If there is a gap left in which a pane with a higher index can fit, it will be put there, + * even if there are panes with a lower index after it. Panes that do not fit will not be displayed. + * + * @since 0.3.0 + */ +public class MasonryPane extends Pane implements Orientable { + + /** + * A list of panes that should be displayed + */ + @NotNull + private final List panes = new ArrayList<>(); + + /** + * The orientation of the items in this pane + */ + @NotNull + private Orientation orientation = Orientation.HORIZONTAL; + + public MasonryPane(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + } + + public MasonryPane(int x, int y, int length, int height) { + super(x, y, length, height); + } + + public MasonryPane(int length, int height) { + super(length, height); + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int length = Math.min(this.length, maxLength) - paneOffsetX; + int height = Math.min(this.height, maxHeight) - paneOffsetY; + + int[][] positions = new int[length][height]; + + for (int[] array : positions) { + Arrays.fill(array, -1); + } + + for (int paneIndex = 0; paneIndex < panes.size(); paneIndex++) { + Pane pane = panes.get(paneIndex); + + if (orientation == Orientation.HORIZONTAL) { + outerLoop: + for (int y = 0; y < height; y++) { + for (int x = 0; x < length; x++) { + //check whether the pane fits + boolean fits = true; + + paneFits: + for (int i = 0; i < pane.getLength(); i++) { + for (int j = 0; j < pane.getHeight(); j++) { + if (x + i >= positions.length || y + j >= positions[x + i].length || positions[x + i][y + j] != -1) { + fits = false; + break paneFits; + } + } + } + + if (fits) { + for (int i = 0; i < pane.getLength(); i++) { + for (int j = 0; j < pane.getHeight(); j++) { + positions[x + i][y + j] = paneIndex; + } + } + + pane.setX(x); + pane.setY(y); + + pane.display( + inventoryComponent, + paneOffsetX + getX(), + paneOffsetY + getY(), + Math.min(this.length, maxLength), + Math.min(this.height, maxHeight) + ); + break outerLoop; + } + } + } + } else if (orientation == Orientation.VERTICAL) { + outerLoop: + for (int x = 0; x < length; x++) { + for (int y = 0; y < height; y++) { + //check whether the pane fits + boolean fits = true; + + paneFits: + for (int i = 0; i < pane.getHeight(); i++) { + for (int j = 0; j < pane.getLength(); j++) { + if (x + j >= positions.length || y + i >= positions[x + j].length || positions[x + j][y + i] != -1) { + fits = false; + break paneFits; + } + } + } + + if (fits) { + for (int i = 0; i < pane.getLength(); i++) { + for (int j = 0; j < pane.getHeight(); j++) { + positions[x + i][y + j] = paneIndex; + } + } + + pane.setX(x); + pane.setY(y); + + pane.display( + inventoryComponent, + paneOffsetX + getX(), + paneOffsetY + getY(), + Math.min(this.length, maxLength), + Math.min(this.height, maxHeight) + ); + break outerLoop; + } + } + } + } + } + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % length) - getX() - paneOffsetX; + int y = (slot / length) - getY() - paneOffsetY; + + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + boolean success = false; + + for (Pane pane : panes) { + success = success || pane.click(gui, event, slot, paneOffsetX + getX(), + paneOffsetY + getY(), length, height); + } + + return success; + } + + @NotNull + @Contract(pure = true) + @Override + public MasonryPane copy() { + MasonryPane masonryPane = new MasonryPane(x, y, length, height, getPriority()); + + for (Pane pane : panes) { + masonryPane.addPane(pane.copy()); + } + + masonryPane.setVisible(isVisible()); + masonryPane.onClick = onClick; + masonryPane.orientation = orientation; + + masonryPane.uuid = uuid; + + return masonryPane; + } + + /** + * Adds a pane to this masonry pane + * + * @param pane the pane to add + * @since 0.3.0 + */ + public void addPane(@NotNull Pane pane) { + panes.add(pane); + } + + @NotNull + @Override + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); + } + + @NotNull + @Override + public Collection getPanes() { + Collection panes = new HashSet<>(); + + this.panes.forEach(p -> { + panes.addAll(p.getPanes()); + panes.add(p); + }); + + return panes; + } + + @Override + public void clear() { + panes.clear(); + } + + @NotNull + @Override + public Orientation getOrientation() { + return orientation; + } + + @Override + public void setOrientation(@NotNull Orientation orientation) { + this.orientation = orientation; + } + + /** + * Loads a masonry pane from a given element + * + * @param instance the instance class + * @param element the element + * @return the masonry pane + */ + @NotNull + public static MasonryPane load(@NotNull Object instance, @NotNull Element element) { + try { + MasonryPane masonryPane = new MasonryPane( + Integer.parseInt(element.getAttribute("length")), + Integer.parseInt(element.getAttribute("height")) + ); + + Pane.load(masonryPane, instance, element); + Orientable.load(masonryPane, element); + + if (element.hasAttribute("populate")) { + return masonryPane; + } + + NodeList childNodes = element.getChildNodes(); + + for (int j = 0; j < childNodes.getLength(); j++) { + Node pane = childNodes.item(j); + + if (pane.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + masonryPane.addPane(Gui.loadPane(instance, pane)); + } + + return masonryPane; + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java similarity index 96% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java index c841098a..bc5ccc4e 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Orientable.java @@ -1,70 +1,70 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -import java.util.Locale; - -/** - * An interface for panes that can have different orientations - * - * @since 0.3.0 - */ -public interface Orientable { - - /** - * Gets the orientation of this outline pane - * - * @return the orientation - * @since 0.3.0 - */ - @NotNull - @Contract(pure = true) - Orientation getOrientation(); - - /** - * Sets the orientation of this outline pane - * - * @param orientation the new orientation - * @since 0.3.0 - */ - void setOrientation(@NotNull Orientation orientation); - - /** - * Loads all elements regarding a {@link Orientable} {@link Pane} for the specified pane. The mutable pane contains - * the changes made. - * - * @param orientable the orientable pane's elements to be applied - * @param element the XML element for this pane - * @since 0.3.0 - */ - static void load(@NotNull Orientable orientable, @NotNull Element element) { - if (element.hasAttribute("orientation")) { - orientable.setOrientation(Orientation.valueOf(element.getAttribute("orientation") - .toUpperCase(Locale.getDefault()))); - } - } - - /** - * An orientation for outline panes - * - * @since 0.3.0 - */ - enum Orientation { - - /** - * A horizontal orientation, will outline every item from the top-left corner going to the right and down - * - * @since 0.3.0 - */ - HORIZONTAL, - - /** - * A vertical orientation, will outline every item from the top-left corner going down and to the right - * - * @since 0.3.0 - */ - VERTICAL - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +import java.util.Locale; + +/** + * An interface for panes that can have different orientations + * + * @since 0.3.0 + */ +public interface Orientable { + + /** + * Gets the orientation of this outline pane + * + * @return the orientation + * @since 0.3.0 + */ + @NotNull + @Contract(pure = true) + Orientation getOrientation(); + + /** + * Sets the orientation of this outline pane + * + * @param orientation the new orientation + * @since 0.3.0 + */ + void setOrientation(@NotNull Orientation orientation); + + /** + * Loads all elements regarding a {@link Orientable} {@link Pane} for the specified pane. The mutable pane contains + * the changes made. + * + * @param orientable the orientable pane's elements to be applied + * @param element the XML element for this pane + * @since 0.3.0 + */ + static void load(@NotNull Orientable orientable, @NotNull Element element) { + if (element.hasAttribute("orientation")) { + orientable.setOrientation(Orientation.valueOf(element.getAttribute("orientation") + .toUpperCase(Locale.getDefault()))); + } + } + + /** + * An orientation for outline panes + * + * @since 0.3.0 + */ + enum Orientation { + + /** + * A horizontal orientation, will outline every item from the top-left corner going to the right and down + * + * @since 0.3.0 + */ + HORIZONTAL, + + /** + * A vertical orientation, will outline every item from the top-left corner going down and to the right + * + * @since 0.3.0 + */ + VERTICAL + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java similarity index 83% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java index 564e6b15..7f6f5ac9 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/OutlinePane.java @@ -1,494 +1,468 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.util.Mask; -import com.github.stefvanschie.inventoryframework.util.GeometryUtil; -import org.bukkit.Material; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.*; - -/** - * A pane for items that should be outlined - */ -public class OutlinePane extends Pane implements Flippable, Orientable, Rotatable { - - /** - * A set of items inside this pane - */ - @NotNull - private final List items; - - /** - * The orientation of the items in this pane - */ - @NotNull - private Orientation orientation; - - /** - * The clockwise rotation of this pane in degrees - */ - private int rotation; - - /** - * The amount of empty spots in between each item - */ - private int gap; - - /** - * Whether the items should be repeated to fill the entire pane - */ - private boolean repeat; - - /** - * Whether the items should be flipped horizontally and/or vertically - */ - private boolean flipHorizontally, flipVertically; - - /** - * The mask for this pane - */ - @NotNull - private Mask mask; - - public OutlinePane(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - - this.items = new ArrayList<>(length * height); - this.orientation = Orientation.HORIZONTAL; - - String[] mask = new String[height]; - StringBuilder maskString = new StringBuilder(); - - for (int i = 0; i < length; i++) { - maskString.append('1'); - } - - Arrays.fill(mask, maskString.toString()); - - this.mask = new Mask(mask); - } - - public OutlinePane(int x, int y, int length, int height) { - this(x, y, length, height, Priority.NORMAL); - } - - public OutlinePane(int length, int height) { - this(0, 0, length, height); - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int x = 0, y = 0; - - if (orientation == Orientation.HORIZONTAL) { - outerloop: - for (int rowIndex = 0; rowIndex < mask.getHeight(); rowIndex++) { - boolean[] row = mask.getRow(rowIndex); - - for (int columnIndex = 0; columnIndex < row.length; columnIndex++) { - if (!row[columnIndex]) { - continue; - } - - x = columnIndex; - y = rowIndex; - break outerloop; - } - } - } else if (orientation == Orientation.VERTICAL) { - outerloop: - for (int columnIndex = 0; columnIndex < mask.getLength(); columnIndex++) { - boolean[] column = mask.getColumn(columnIndex); - - for (int rowIndex = 0; rowIndex < column.length; rowIndex++) { - if (!column[rowIndex]) { - continue; - } - - x = columnIndex; - y = rowIndex; - break outerloop; - } - } - } - - int itemAmount = items.size(); - - outerloop: - for (int i = 0; i < (doesRepeat() ? mask.amountOfEnabledSlots() : itemAmount); i++) { - GuiItem item = items.get(i % itemAmount); - - if (!item.isVisible()) - continue; - - int newX = x, newY = y; - - if (flipHorizontally) - newX = length - x - 1; - - if (flipVertically) - newY = height - y - 1; - - Map.Entry coordinates = GeometryUtil.processClockwiseRotation(newX, newY, length, height, - rotation); - - newX = coordinates.getKey(); - newY = coordinates.getValue(); - - if (newX >= 0 || newX < length || newY >= 0 || newY < height) { - int finalRow = getY() + newY + paneOffsetY; - int finalColumn = getX() + newX + paneOffsetX; - - if (finalRow >= gui.getRows()) { - gui.setState(Gui.State.BOTTOM); - - if (finalRow == gui.getRows() + 3) { - playerInventory.setItem(finalColumn, item.getItem()); - } else { - playerInventory.setItem(((finalRow - gui.getRows()) + 1) * 9 + finalColumn, item.getItem()); - } - } else { - inventory.setItem(finalRow * 9 + finalColumn, item.getItem()); - } - } - - int gapCount = gap; - - do { - if (orientation == Orientation.HORIZONTAL) { - x++; - - if (x >= length) { - y++; - x = 0; - } - } else if (orientation == Orientation.VERTICAL) { - y++; - - if (y >= height) { - x++; - y = 0; - } - } - - //stop the loop when there is no more space in the pane - if (x >= length || y >= height) { - break outerloop; - } - - if (mask.isEnabled(x, y)) { - gapCount--; - } - } while (gapCount >= 0); - } - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView inventoryView = event.getView(); - Inventory inventory = inventoryView.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(inventoryView.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - //this isn't our item - if (x < 0 || x >= length || y < 0 || y >= height) - return false; - - callOnClick(event); - - ItemStack itemStack = event.getCurrentItem(); - - if (itemStack == null) { - return false; - } - - GuiItem item = findMatchingItem(items, itemStack); - - if (item == null) { - return false; - } - - item.callAction(event); - - return true; - } - - @NotNull - @Contract(pure = true) - @Override - public OutlinePane copy() { - OutlinePane outlinePane = new OutlinePane(x, y, length, height, getPriority()); - - for (GuiItem item : items) { - outlinePane.addItem(item.copy()); - } - - outlinePane.setVisible(isVisible()); - outlinePane.onClick = onClick; - - outlinePane.uuid = uuid; - - outlinePane.orientation = orientation; - outlinePane.rotation = rotation; - outlinePane.gap = gap; - outlinePane.repeat = repeat; - outlinePane.flipHorizontally = flipHorizontally; - outlinePane.flipVertically = flipVertically; - outlinePane.mask = mask; - - return outlinePane; - } - - @Override - public void setRotation(int rotation) { - if (length != height) { - throw new UnsupportedOperationException("length and height are different"); - } - - if (rotation % 90 != 0) { - throw new IllegalArgumentException("rotation isn't divisible by 90"); - } - - this.rotation = rotation % 360; - } - - /** - * Adds a gui item in the specified index - * - * @param item the item to add - * @param index the item's index - */ - public void insertItem(@NotNull GuiItem item, int index) { - items.add(index, item); - } - - /** - * Adds a gui item at the specific spot in the pane - * - * @param item the item to set - */ - public void addItem(@NotNull GuiItem item) { - items.add(item); - } - - /** - * Removes the specified item from the pane - * - * @param item the item to remove - * @since 0.5.8 - */ - public void removeItem(@NotNull GuiItem item) { - items.remove(item); - } - - @Override - public void clear() { - items.clear(); - } - - /** - * Applies a custom mask to this pane. This will throw an {@link IllegalArgumentException} when the mask's dimension - * differs from this pane's dimension. - * - * @param mask the mask to apply to this pane - * @throws IllegalArgumentException when the mask's dimension is incorrect - * @since 0.5.16 - */ - public void applyMask(@NotNull Mask mask) { - if (length != mask.getLength() || height != mask.getHeight()) { - throw new IllegalArgumentException("Mask's dimension must be the same as the pane's dimension"); - } - - this.mask = mask; - } - - @Override - public void flipHorizontally(boolean flipHorizontally) { - this.flipHorizontally = flipHorizontally; - } - - @Override - public void flipVertically(boolean flipVertically) { - this.flipVertically = flipVertically; - } - - /** - * Sets the gap of the pane - * - * @param gap the new gap - */ - public void setGap(int gap) { - this.gap = gap; - } - - @Override - public void setOrientation(@NotNull Orientation orientation) { - this.orientation = orientation; - } - - /** - * Sets whether this pane should repeat itself - * - * @param repeat whether the pane should repeat - */ - public void setRepeat(boolean repeat) { - this.repeat = repeat; - } - - @NotNull - @Contract(pure = true) - @Override - public Collection getPanes() { - return new HashSet<>(); - } - - /** - * Gets whether this outline pane repeats itself - * - * @return true if this pane repeats, false otherwise - */ - @Contract(pure = true) - public boolean doesRepeat() { - return repeat; - } - - /** - * Gets the gap of the pane - * - * @return the gap - */ - @Contract(pure = true) - public int getGap() { - return gap; - } - - @NotNull - @Override - public List getItems() { - return items; - } - - /** - * Gets the mask applied to this pane. - * - * @return the mask - * @since 0.6.2 - */ - @NotNull - @Contract(pure = true) - public Mask getMask() { - return mask; - } - - /** - * Gets the orientation of this outline pane - * - * @return the orientation - */ - @NotNull - @Contract(pure = true) - @Override - public Orientation getOrientation() { - return orientation; - } - - @Contract(pure = true) - @Override - public int getRotation() { - return rotation; - } - - @Contract(pure = true) - @Override - public boolean isFlippedHorizontally() { - return flipHorizontally; - } - - @Contract(pure = true) - @Override - public boolean isFlippedVertically() { - return flipVertically; - } - - /** - * Loads an outline pane from a given element - * - * @param instance the instance class - * @param element the element - * @return the outline pane - */ - @NotNull - public static OutlinePane load(@NotNull Object instance, @NotNull Element element) { - try { - OutlinePane outlinePane = new OutlinePane( - Integer.parseInt(element.getAttribute("length")), - Integer.parseInt(element.getAttribute("height")) - ); - - if (element.hasAttribute("gap")) - outlinePane.setGap(Integer.parseInt(element.getAttribute("gap"))); - - if (element.hasAttribute("repeat")) - outlinePane.setRepeat(Boolean.parseBoolean(element.getAttribute("repeat"))); - - Pane.load(outlinePane, instance, element); - Flippable.load(outlinePane, element); - Orientable.load(outlinePane, element); - Rotatable.load(outlinePane, element); - - if (element.hasAttribute("populate")) - return outlinePane; - - NodeList childNodes = element.getChildNodes(); - - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - - if (item.getNodeType() != Node.ELEMENT_NODE) - continue; - - if (item.getNodeName().equals("empty")) - outlinePane.addItem(new GuiItem(new ItemStack(Material.AIR))); - else - outlinePane.addItem(Pane.loadItem(instance, (Element) item)); - } - - return outlinePane; - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - } +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.pane.util.Mask; +import com.github.stefvanschie.inventoryframework.util.GeometryUtil; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; + +/** + * A pane for items that should be outlined + */ +public class OutlinePane extends Pane implements Flippable, Orientable, Rotatable { + + /** + * A set of items inside this pane + */ + @NotNull + private final List items; + + /** + * The orientation of the items in this pane + */ + @NotNull + private Orientation orientation; + + /** + * The clockwise rotation of this pane in degrees + */ + private int rotation; + + /** + * The amount of empty spots in between each item + */ + private int gap; + + /** + * Whether the items should be repeated to fill the entire pane + */ + private boolean repeat; + + /** + * Whether the items should be flipped horizontally and/or vertically + */ + private boolean flipHorizontally, flipVertically; + + /** + * The mask for this pane + */ + @NotNull + private Mask mask; + + public OutlinePane(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + + this.items = new ArrayList<>(length * height); + this.orientation = Orientation.HORIZONTAL; + + String[] mask = new String[height]; + StringBuilder maskString = new StringBuilder(); + + for (int i = 0; i < length; i++) { + maskString.append('1'); + } + + Arrays.fill(mask, maskString.toString()); + + this.mask = new Mask(mask); + } + + public OutlinePane(int x, int y, int length, int height) { + this(x, y, length, height, Priority.NORMAL); + } + + public OutlinePane(int length, int height) { + this(0, 0, length, height); + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = 0, y = 0; + + if (orientation == Orientation.HORIZONTAL) { + outerloop: + for (int rowIndex = 0; rowIndex < inventoryComponent.getHeight(); rowIndex++) { + boolean[] row = mask.getRow(rowIndex); + + for (int columnIndex = 0; columnIndex < inventoryComponent.getLength(); columnIndex++) { + if (!row[columnIndex]) { + continue; + } + + x = columnIndex; + y = rowIndex; + break outerloop; + } + } + } else if (orientation == Orientation.VERTICAL) { + outerloop: + for (int columnIndex = 0; columnIndex < inventoryComponent.getLength(); columnIndex++) { + boolean[] column = mask.getColumn(columnIndex); + + for (int rowIndex = 0; rowIndex < inventoryComponent.getHeight(); rowIndex++) { + if (!column[rowIndex]) { + continue; + } + + x = columnIndex; + y = rowIndex; + break outerloop; + } + } + } + + int itemAmount = items.size(); + + outerloop: + for (int i = 0; i < (doesRepeat() ? Math.max(mask.amountOfEnabledSlots(), inventoryComponent.getSize()) : itemAmount); i++) { + GuiItem item = items.get(i % itemAmount); + + if (!item.isVisible()) + continue; + + int newX = x, newY = y; + + if (flipHorizontally) + newX = length - x - 1; + + if (flipVertically) + newY = height - y - 1; + + Map.Entry coordinates = GeometryUtil.processClockwiseRotation(newX, newY, length, height, + rotation); + + newX = coordinates.getKey(); + newY = coordinates.getValue(); + + if (newX >= 0 && newX < length && newY >= 0 && newY < height) { + int finalRow = getY() + newY + paneOffsetY; + int finalColumn = getX() + newX + paneOffsetX; + + inventoryComponent.setItem(item.getItem(), finalColumn, finalRow); + } + + int gapCount = gap; + + do { + if (orientation == Orientation.HORIZONTAL) { + x++; + + if (x >= length) { + y++; + x = 0; + } + } else if (orientation == Orientation.VERTICAL) { + y++; + + if (y >= height) { + x++; + y = 0; + } + } + + //stop the loop when there is no more space in the pane + if (x >= length || y >= height) { + break outerloop; + } + + if (mask.isEnabled(x, y)) { + gapCount--; + } + } while (gapCount >= 0); + } + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % length) - getX() - paneOffsetX; + int y = (slot / length) - getY() - paneOffsetY; + + //this isn't our item + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + ItemStack itemStack = event.getCurrentItem(); + + if (itemStack == null) { + return false; + } + + GuiItem item = findMatchingItem(items, itemStack); + + if (item == null) { + return false; + } + + item.callAction(event); + + return true; + } + + @NotNull + @Contract(pure = true) + @Override + public OutlinePane copy() { + OutlinePane outlinePane = new OutlinePane(x, y, length, height, getPriority()); + + for (GuiItem item : items) { + outlinePane.addItem(item.copy()); + } + + outlinePane.setVisible(isVisible()); + outlinePane.onClick = onClick; + + outlinePane.uuid = uuid; + + outlinePane.orientation = orientation; + outlinePane.rotation = rotation; + outlinePane.gap = gap; + outlinePane.repeat = repeat; + outlinePane.flipHorizontally = flipHorizontally; + outlinePane.flipVertically = flipVertically; + outlinePane.mask = mask; + + return outlinePane; + } + + @Override + public void setRotation(int rotation) { + if (length != height) { + throw new UnsupportedOperationException("length and height are different"); + } + + if (rotation % 90 != 0) { + throw new IllegalArgumentException("rotation isn't divisible by 90"); + } + + this.rotation = rotation % 360; + } + + /** + * Adds a gui item in the specified index + * + * @param item the item to add + * @param index the item's index + */ + public void insertItem(@NotNull GuiItem item, int index) { + items.add(index, item); + } + + /** + * Adds a gui item at the specific spot in the pane + * + * @param item the item to set + */ + public void addItem(@NotNull GuiItem item) { + items.add(item); + } + + /** + * Removes the specified item from the pane + * + * @param item the item to remove + * @since 0.5.8 + */ + public void removeItem(@NotNull GuiItem item) { + items.remove(item); + } + + @Override + public void clear() { + items.clear(); + } + + /** + * Applies a custom mask to this pane. This will throw an {@link IllegalArgumentException} when the mask's dimension + * differs from this pane's dimension. + * + * @param mask the mask to apply to this pane + * @throws IllegalArgumentException when the mask's dimension is incorrect + * @since 0.5.16 + */ + public void applyMask(@NotNull Mask mask) { + if (length != mask.getLength() || height != mask.getHeight()) { + throw new IllegalArgumentException("Mask's dimension must be the same as the pane's dimension"); + } + + this.mask = mask; + } + + @Override + public void flipHorizontally(boolean flipHorizontally) { + this.flipHorizontally = flipHorizontally; + } + + @Override + public void flipVertically(boolean flipVertically) { + this.flipVertically = flipVertically; + } + + /** + * Sets the gap of the pane + * + * @param gap the new gap + */ + public void setGap(int gap) { + this.gap = gap; + } + + @Override + public void setOrientation(@NotNull Orientation orientation) { + this.orientation = orientation; + } + + /** + * Sets whether this pane should repeat itself + * + * @param repeat whether the pane should repeat + */ + public void setRepeat(boolean repeat) { + this.repeat = repeat; + } + + @NotNull + @Contract(pure = true) + @Override + public Collection getPanes() { + return new HashSet<>(); + } + + /** + * Gets whether this outline pane repeats itself + * + * @return true if this pane repeats, false otherwise + */ + @Contract(pure = true) + public boolean doesRepeat() { + return repeat; + } + + /** + * Gets the gap of the pane + * + * @return the gap + */ + @Contract(pure = true) + public int getGap() { + return gap; + } + + @NotNull + @Override + public List getItems() { + return items; + } + + /** + * Gets the mask applied to this pane. + * + * @return the mask + * @since 0.6.2 + */ + @NotNull + @Contract(pure = true) + public Mask getMask() { + return mask; + } + + /** + * Gets the orientation of this outline pane + * + * @return the orientation + */ + @NotNull + @Contract(pure = true) + @Override + public Orientation getOrientation() { + return orientation; + } + + @Contract(pure = true) + @Override + public int getRotation() { + return rotation; + } + + @Contract(pure = true) + @Override + public boolean isFlippedHorizontally() { + return flipHorizontally; + } + + @Contract(pure = true) + @Override + public boolean isFlippedVertically() { + return flipVertically; + } + + /** + * Loads an outline pane from a given element + * + * @param instance the instance class + * @param element the element + * @return the outline pane + */ + @NotNull + public static OutlinePane load(@NotNull Object instance, @NotNull Element element) { + try { + OutlinePane outlinePane = new OutlinePane( + Integer.parseInt(element.getAttribute("length")), + Integer.parseInt(element.getAttribute("height")) + ); + + if (element.hasAttribute("gap")) + outlinePane.setGap(Integer.parseInt(element.getAttribute("gap"))); + + if (element.hasAttribute("repeat")) + outlinePane.setRepeat(Boolean.parseBoolean(element.getAttribute("repeat"))); + + Pane.load(outlinePane, instance, element); + Flippable.load(outlinePane, element); + Orientable.load(outlinePane, element); + Rotatable.load(outlinePane, element); + + if (element.hasAttribute("populate")) + return outlinePane; + + NodeList childNodes = element.getChildNodes(); + + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + + if (item.getNodeType() != Node.ELEMENT_NODE) + continue; + + if (item.getNodeName().equals("empty")) + outlinePane.addItem(new GuiItem(new ItemStack(Material.AIR))); + else + outlinePane.addItem(Pane.loadItem(instance, (Element) item)); + } + + return outlinePane; + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + } } \ No newline at end of file diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java similarity index 86% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java index aa9f1ec0..63e66914 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPane.java @@ -1,368 +1,350 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * A pane for panes that should be spread out over multiple pages - */ -public class PaginatedPane extends Pane { - - /** - * A set of panes for the different pages - */ - @NotNull - private final Map> panes = new HashMap<>(); - - /** - * The current page - */ - private int page; - - public PaginatedPane(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - } - - public PaginatedPane(int x, int y, int length, int height) { - super(x, y, length, height); - } - - public PaginatedPane(int length, int height) { - super(length, height); - } - - /** - * Returns the current page - * - * @return the current page - */ - public int getPage() { - return page; - } - - /** - * Returns the amount of pages - * - * @return the amount of pages - */ - public int getPages() { - return panes.size(); - } - /** - * Assigns a pane to a selected page - * - * @param page the page to assign the pane to - * @param pane the new pane - */ - public void addPane(int page, @NotNull Pane pane) { - if (!this.panes.containsKey(page)) - this.panes.put(page, new ArrayList<>()); - - this.panes.get(page).add(pane); - - this.panes.get(page).sort(Comparator.comparing(Pane::getPriority)); - } - - /** - * Sets the current displayed page - * - * @param page the page - */ - public void setPage(int page) { - if (!panes.containsKey(page)) - throw new ArrayIndexOutOfBoundsException("page outside range"); - this.page = page; - } - - /** - * Populates the PaginatedPane based on the provided list by adding new pages until all items can fit. - * This can be helpful when dealing with lists of unknown size. - * - * @param items The list to populate the pane with - */ - @Contract("null -> fail") - public void populateWithItemStacks(@NotNull List items) { - //Don't do anything if the list is empty - if (items.isEmpty()) { - return; - } - - int itemsPerPage = this.height * this.length; - int pagesNeeded = (int) Math.max(Math.ceil(items.size() / (double) itemsPerPage), 1); - - for (int i = 0; i < pagesNeeded; i++) { - OutlinePane page = new OutlinePane(0, 0, this.length, this.height); - - for (int j = 0; j < itemsPerPage; j++) { - //Check if the loop reached the end of the list - int index = i * itemsPerPage + j; - - if (index >= items.size()) { - break; - } - - page.addItem(new GuiItem(items.get(index))); - } - - this.addPane(i, page); - } - } - - - /** - * Populates the PaginatedPane based on the provided list by adding new pages until all items can fit. - * This can be helpful when dealing with lists of unknown size. - * - * @param items The list to populate the pane with - */ - @Contract("null -> fail") - public void populateWithGuiItems(@NotNull List items) { - //Don't do anything if the list is empty - if (items.isEmpty()) { - return; - } - - int itemsPerPage = this.height * this.length; - int pagesNeeded = (int) Math.max(Math.ceil(items.size() / (double) itemsPerPage), 1); - - for (int i = 0; i < pagesNeeded; i++) { - OutlinePane page = new OutlinePane(0, 0, this.length, this.height); - - for (int j = 0; j < itemsPerPage; j++) { - int index = i * itemsPerPage + j; - - //Check if the loop reached the end of the list - if (index >= items.size()) { - break; - } - - page.addItem(items.get(index)); - } - - this.addPane(i, page); - } - } - - /** - * This method creates a list of ItemStacks all with the given {@code material} and the display names. - * After that it calls {@link #populateWithItemStacks(List)} - * This method also translates the color char {@code &} for all names. - * - * @param displayNames The display names for all the items - * @param material The material to use for the {@link org.bukkit.inventory.ItemStack}s - */ - @Contract("null, _ -> fail") - public void populateWithNames(@NotNull List displayNames, @Nullable Material material) { - if(material == null || material == Material.AIR) return; - - populateWithItemStacks(displayNames.stream().map(name -> { - ItemStack itemStack = new ItemStack(material); - ItemMeta itemMeta = itemStack.getItemMeta(); - itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); - itemStack.setItemMeta(itemMeta); - return itemStack; - }).collect(Collectors.toList())); - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - List panes = this.panes.get(page); - - if (panes == null) { - return; - } - - panes.forEach(pane -> pane.display(gui, inventory, playerInventory, - paneOffsetX + getX(), paneOffsetY + getY(), - Math.min(length, maxLength), Math.min(height, maxHeight))); - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, int maxLength, - int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - //this isn't our item - if (x < 0 || x >= length || y < 0 || y >= height) { - return false; - } - - callOnClick(event); - - List panes = this.panes.get(page); - - if (panes == null) { - return false; - } - - boolean success = false; - - for (Pane pane : panes) { - success = success || pane.click(gui, event, paneOffsetX + getX(), - paneOffsetY + getY(), length, height); - } - - return success; - } - - @NotNull - @Contract(pure = true) - @Override - public PaginatedPane copy() { - PaginatedPane paginatedPane = new PaginatedPane(x, y, length, height, getPriority()); - - for (Map.Entry> entry : panes.entrySet()) { - for (Pane pane : entry.getValue()) { - paginatedPane.addPane(entry.getKey(), pane.copy()); - } - } - - paginatedPane.setVisible(isVisible()); - paginatedPane.onClick = onClick; - - paginatedPane.uuid = uuid; - - paginatedPane.page = page; - - return paginatedPane; - } - - @NotNull - @Contract(pure = true) - @Override - public Collection getPanes() { - Collection panes = new HashSet<>(); - - this.panes.forEach((integer, p) -> { - p.forEach(pane -> panes.addAll(pane.getPanes())); - panes.addAll(p); - }); - - return panes; - } - - /** - * Gets all the panes from inside the specified page of this pane. If the specified page is not existent, this - * method will throw an {@link IllegalArgumentException}. If the specified page is existent, but doesn't - * have any panes, the returned collection will be empty. The returned collection is unmodifiable. The returned - * collection is not synchronized and no guarantees should be made as to the safety of concurrently accessing the - * returned collection. If synchronized behaviour should be allowed, the returned collection must be synchronized - * externally. - * - * @param page the panes of this page will be returned - * @return a collection of panes belonging to the specified page - * @since 0.5.13 - * @throws IllegalArgumentException if the page does not exist - */ - @NotNull - @Contract(pure = true) - public Collection getPanes(int page) { - Collection panes = this.panes.get(page); - - if (panes == null) { - throw new IllegalArgumentException("Invalid page"); - } - - return Collections.unmodifiableCollection(panes); - } - - @NotNull - @Contract(pure = true) - @Override - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); - } - - @Override - public void clear() { - panes.clear(); - } - - /** - * Loads a paginated pane from a given element - * - * @param instance the instance class - * @param element the element - * @return the paginated pane - */ - @NotNull - public static PaginatedPane load(@NotNull Object instance, @NotNull Element element) { - try { - PaginatedPane paginatedPane = new PaginatedPane( - Integer.parseInt(element.getAttribute("length")), - Integer.parseInt(element.getAttribute("height")) - ); - - Pane.load(paginatedPane, instance, element); - - if (element.hasAttribute("populate")) - return paginatedPane; - - int pageCount = 0; - - NodeList childNodes = element.getChildNodes(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - - if (item.getNodeType() != Node.ELEMENT_NODE) - continue; - - NodeList innerNodes = item.getChildNodes(); - - for (int j = 0; j < innerNodes.getLength(); j++) { - Node pane = innerNodes.item(j); - - if (pane.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - - paginatedPane.addPane(pageCount, Gui.loadPane(instance, pane)); - } - - pageCount++; - } - - return paginatedPane; - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * A pane for panes that should be spread out over multiple pages + */ +public class PaginatedPane extends Pane { + + /** + * A set of panes for the different pages + */ + @NotNull + private final Map> panes = new HashMap<>(); + + /** + * The current page + */ + private int page; + + public PaginatedPane(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + } + + public PaginatedPane(int x, int y, int length, int height) { + super(x, y, length, height); + } + + public PaginatedPane(int length, int height) { + super(length, height); + } + + /** + * Returns the current page + * + * @return the current page + */ + public int getPage() { + return page; + } + + /** + * Returns the amount of pages + * + * @return the amount of pages + */ + public int getPages() { + return panes.size(); + } + /** + * Assigns a pane to a selected page + * + * @param page the page to assign the pane to + * @param pane the new pane + */ + public void addPane(int page, @NotNull Pane pane) { + if (!this.panes.containsKey(page)) + this.panes.put(page, new ArrayList<>()); + + this.panes.get(page).add(pane); + + this.panes.get(page).sort(Comparator.comparing(Pane::getPriority)); + } + + /** + * Sets the current displayed page + * + * @param page the page + */ + public void setPage(int page) { + if (!panes.containsKey(page)) + throw new ArrayIndexOutOfBoundsException("page outside range"); + this.page = page; + } + + /** + * Populates the PaginatedPane based on the provided list by adding new pages until all items can fit. + * This can be helpful when dealing with lists of unknown size. + * + * @param items The list to populate the pane with + */ + @Contract("null -> fail") + public void populateWithItemStacks(@NotNull List items) { + //Don't do anything if the list is empty + if (items.isEmpty()) { + return; + } + + int itemsPerPage = this.height * this.length; + int pagesNeeded = (int) Math.max(Math.ceil(items.size() / (double) itemsPerPage), 1); + + for (int i = 0; i < pagesNeeded; i++) { + OutlinePane page = new OutlinePane(0, 0, this.length, this.height); + + for (int j = 0; j < itemsPerPage; j++) { + //Check if the loop reached the end of the list + int index = i * itemsPerPage + j; + + if (index >= items.size()) { + break; + } + + page.addItem(new GuiItem(items.get(index))); + } + + this.addPane(i, page); + } + } + + + /** + * Populates the PaginatedPane based on the provided list by adding new pages until all items can fit. + * This can be helpful when dealing with lists of unknown size. + * + * @param items The list to populate the pane with + */ + @Contract("null -> fail") + public void populateWithGuiItems(@NotNull List items) { + //Don't do anything if the list is empty + if (items.isEmpty()) { + return; + } + + int itemsPerPage = this.height * this.length; + int pagesNeeded = (int) Math.max(Math.ceil(items.size() / (double) itemsPerPage), 1); + + for (int i = 0; i < pagesNeeded; i++) { + OutlinePane page = new OutlinePane(0, 0, this.length, this.height); + + for (int j = 0; j < itemsPerPage; j++) { + int index = i * itemsPerPage + j; + + //Check if the loop reached the end of the list + if (index >= items.size()) { + break; + } + + page.addItem(items.get(index)); + } + + this.addPane(i, page); + } + } + + /** + * This method creates a list of ItemStacks all with the given {@code material} and the display names. + * After that it calls {@link #populateWithItemStacks(List)} + * This method also translates the color char {@code &} for all names. + * + * @param displayNames The display names for all the items + * @param material The material to use for the {@link org.bukkit.inventory.ItemStack}s + */ + @Contract("null, _ -> fail") + public void populateWithNames(@NotNull List displayNames, @Nullable Material material) { + if(material == null || material == Material.AIR) return; + + populateWithItemStacks(displayNames.stream().map(name -> { + ItemStack itemStack = new ItemStack(material); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + itemStack.setItemMeta(itemMeta); + return itemStack; + }).collect(Collectors.toList())); + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + List panes = this.panes.get(page); + + if (panes == null) { + return; + } + + for (Pane pane : panes) { + int newPaneOffsetX = paneOffsetX + getX(); + int newPaneOffsetY = paneOffsetY + getY(); + int newMaxLength = Math.min(length, maxLength); + int newMaxHeight = Math.min(height, maxHeight); + + pane.display(inventoryComponent, newPaneOffsetX, newPaneOffsetY, newMaxLength, newMaxHeight); + } + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % length) - getX() - paneOffsetX; + int y = (slot / length) - getY() - paneOffsetY; + + //this isn't our item + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + boolean success = false; + + for (Pane pane : this.panes.get(page)) { + success = success || pane.click(gui, event, slot,paneOffsetX + getX(), + paneOffsetY + getY(), length, height); + } + + return success; + } + + @NotNull + @Contract(pure = true) + @Override + public PaginatedPane copy() { + PaginatedPane paginatedPane = new PaginatedPane(x, y, length, height, getPriority()); + + for (Map.Entry> entry : panes.entrySet()) { + for (Pane pane : entry.getValue()) { + paginatedPane.addPane(entry.getKey(), pane.copy()); + } + } + + paginatedPane.setVisible(isVisible()); + paginatedPane.onClick = onClick; + + paginatedPane.uuid = uuid; + + paginatedPane.page = page; + + return paginatedPane; + } + + @NotNull + @Contract(pure = true) + @Override + public Collection getPanes() { + Collection panes = new HashSet<>(); + + this.panes.forEach((integer, p) -> { + p.forEach(pane -> panes.addAll(pane.getPanes())); + panes.addAll(p); + }); + + return panes; + } + + /** + * Gets all the panes from inside the specified page of this pane. If the specified page is not existent, this + * method will throw an {@link IllegalArgumentException}. If the specified page is existent, but doesn't + * have any panes, the returned collection will be empty. The returned collection is unmodifiable. The returned + * collection is not synchronized and no guarantees should be made as to the safety of concurrently accessing the + * returned collection. If synchronized behaviour should be allowed, the returned collection must be synchronized + * externally. + * + * @param page the panes of this page will be returned + * @return a collection of panes belonging to the specified page + * @since 0.5.13 + * @throws IllegalArgumentException if the page does not exist + */ + @NotNull + @Contract(pure = true) + public Collection getPanes(int page) { + Collection panes = this.panes.get(page); + + if (panes == null) { + throw new IllegalArgumentException("Invalid page"); + } + + return Collections.unmodifiableCollection(panes); + } + + @NotNull + @Contract(pure = true) + @Override + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); + } + + @Override + public void clear() { + panes.clear(); + } + + /** + * Loads a paginated pane from a given element + * + * @param instance the instance class + * @param element the element + * @return the paginated pane + */ + @NotNull + public static PaginatedPane load(@NotNull Object instance, @NotNull Element element) { + try { + PaginatedPane paginatedPane = new PaginatedPane( + Integer.parseInt(element.getAttribute("length")), + Integer.parseInt(element.getAttribute("height")) + ); + + Pane.load(paginatedPane, instance, element); + + if (element.hasAttribute("populate")) + return paginatedPane; + + int pageCount = 0; + + NodeList childNodes = element.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + + if (item.getNodeType() != Node.ELEMENT_NODE) + continue; + + NodeList innerNodes = item.getChildNodes(); + + for (int j = 0; j < innerNodes.getLength(); j++) { + Node pane = innerNodes.item(j); + + if (pane.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + paginatedPane.addPane(pageCount, Gui.loadPane(instance, pane)); + } + + pageCount++; + } + + return paginatedPane; + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java similarity index 87% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java index c06afd87..ae59f56c 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Pane.java @@ -1,696 +1,746 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.exception.XMLReflectionException; -import com.github.stefvanschie.inventoryframework.util.SkullUtil; -import com.github.stefvanschie.inventoryframework.util.UUIDTagType; -import com.github.stefvanschie.inventoryframework.util.XMLUtil; -import com.google.common.primitives.Primitives; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.lang.UnsupportedOperationException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * The base class for all panes. - */ -public abstract class Pane { - - /** - * The starting position of this pane, which is 0 by default - */ - protected int x = 0, y = 0; - - /** - * Length is horizontal, height is vertical - */ - protected int length, height; - - /** - * The visibility state of the pane - */ - private boolean visible; - - /** - * The priority of the pane, determines when it will be rendered - */ - @NotNull - private Priority priority; - - /** - * The consumer that will be called once a players clicks in this pane - */ - @Nullable - protected Consumer onClick; - - /** - * A unique identifier for panes to locate them by - */ - protected UUID uuid; - - /** - * A map containing the mappings for properties for items - */ - @NotNull - private static final Map> PROPERTY_MAPPINGS = new HashMap<>(); - - /** - * Constructs a new default pane - * - * @param x the upper left x coordinate of the pane - * @param y the upper left y coordinate of the pane - * @param length the length of the pane - * @param height the height of the pane - * @param priority the priority of the pane - */ - protected Pane(int x, int y, int length, int height, @NotNull Priority priority) { - this.x = x; - this.y = y; - - this.length = length; - this.height = height; - - this.priority = priority; - this.visible = true; - - this.uuid = UUID.randomUUID(); - } - - /** - * Constructs a new default pane, with no position - * - * @param length the length of the pane - * @param height the height of the pane - */ - protected Pane(int length, int height) { - this.length = length; - this.height = height; - - this.priority = Priority.NORMAL; - this.visible = true; - - this.uuid = UUID.randomUUID(); - } - - /** - * Constructs a new default pane - * - * @param x the upper left x coordinate of the pane - * @param y the upper left y coordinate of the pane - * @param length the length of the pane - * @param height the height of the pane - */ - protected Pane(int x, int y, int length, int height) { - this(x, y, length, height, Priority.NORMAL); - } - - /** - * Makes a copy of this pane and returns it. This makes a deep copy of the pane. This entails that the underlying - * panes and/or items will be copied as well. The returned pane will never be reference equal to the current pane. - * - * @return a copy of this pane - * @since 0.6.2 - */ - @NotNull - @Contract(pure = true) - public Pane copy() { - throw new UnsupportedOperationException("The implementing pane hasn't overridden the copy method"); - } - - /** - * Set the length of this pane - * - * @param length the new length - */ - public void setLength(int length) { - this.length = length; - } - - /** - * Set the height of this pane - * - * @param height the new height - */ - public void setHeight(int height) { - this.height = height; - } - - /** - * Set the x coordinate of this pane - * - * @param x the new x coordinate - */ - public void setX(int x) { - this.x = x; - } - - /** - * Set the y coordinate of this pane - * - * @param y the new y coordinate - */ - public void setY(int y) { - this.y = y; - } - - /** - * Returns the length of this pane - * - * @return the length - */ - @Contract(pure = true) - public int getLength() { - return length; - } - - /** - * Returns the height of this pane - * - * @return the height - */ - @Contract(pure = true) - public int getHeight() { - return height; - } - - /** - * Gets the {@link UUID} associated with this pane. - * - * @return the uuid - * @since 0.7.1 - */ - @NotNull - @Contract(pure = true) - public UUID getUUID() { - return uuid; - } - - /** - * Gets the x coordinate of this pane - * - * @return the x coordinate - */ - @Contract(pure = true) - public int getX() { - return x; - } - - /** - * Gets the y coordinate of this pane - * - * @return the y coordinate - */ - @Contract(pure = true) - public int getY() { - return y; - } - - /** - * Has to set all the items in the right spot inside the inventory - * - * @param gui the gui for which we're rendering - * @param inventory the inventory that the items should be displayed in - * @param playerInventory the player's inventory - * @param paneOffsetX the pane's offset on the x axis - * @param paneOffsetY the pane's offset on the y axis - * @param maxLength the maximum length of the pane - * @param maxHeight the maximum height of the pane - */ - public abstract void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight); - - /** - * Returns the pane's visibility state - * - * @return the pane's visibility - */ - @Contract(pure = true) - public boolean isVisible() { - return visible; - } - - /** - * Sets whether this pane is visible or not - * - * @param visible the pane's visibility - */ - public void setVisible(boolean visible) { - this.visible = visible; - } - - /** - * Called whenever there is being clicked on this pane - * - * @param gui the gui this event stems from - * @param event the event that occurred while clicking on this item - * @param paneOffsetX the pane's offset on the x axis - * @param paneOffsetY the pane's offset on the y axis - * @param maxLength the maximum length of the pane - * @param maxHeight the maximum height of the pane - * @return whether the item was found or not - */ - public abstract boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, - int paneOffsetY, int maxLength, int maxHeight); - - /** - * Sets the priority of this pane - * - * @param priority the priority - */ - public void setPriority(@NotNull Priority priority) { - this.priority = priority; - } - - /** - * Loads an item from an instance and an element - * - * @param instance the instance - * @param element the element - * @return the gui item - */ - @NotNull - @Contract(pure = true) - public static GuiItem loadItem(@NotNull Object instance, @NotNull Element element) { - String id = element.getAttribute("id"); - Material material = Objects.requireNonNull(Material.matchMaterial(id.toUpperCase(Locale.getDefault()))); - boolean hasAmount = element.hasAttribute("amount"); - boolean hasDamage = element.hasAttribute("damage"); - int amount = hasAmount ? Integer.parseInt(element.getAttribute("amount")) : 1; - short damage = hasDamage ? Short.parseShort(element.getAttribute("damage")) : 0; - - //noinspection deprecation - ItemStack itemStack = new ItemStack(material, amount, damage); - - List properties = new ArrayList<>(); - - if (element.hasChildNodes()) { - NodeList childNodes = element.getChildNodes(); - - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - - if (item.getNodeType() != Node.ELEMENT_NODE) - continue; - - Element elementItem = (Element) item; - - String nodeName = item.getNodeName(); - - if (nodeName.equals("properties") || nodeName.equals("lore") || nodeName.equals("enchantments")) { - Element innerElement = (Element) item; - NodeList innerChildNodes = innerElement.getChildNodes(); - - for (int j = 0; j < innerChildNodes.getLength(); j++) { - Node innerNode = innerChildNodes.item(j); - - if (innerNode.getNodeType() != Node.ELEMENT_NODE) - continue; - - Element innerElementChild = (Element) innerNode; - ItemMeta itemMeta = Objects.requireNonNull(itemStack.getItemMeta()); - - switch (nodeName) { - case "properties": - if (!innerNode.getNodeName().equals("property")) - continue; - - String propertyType = innerElementChild.hasAttribute("type") - ? innerElementChild.getAttribute("type") - : "string"; - - properties.add(PROPERTY_MAPPINGS.get(propertyType).apply(innerElementChild - .getTextContent())); - break; - case "lore": - if (!innerNode.getNodeName().equals("line")) - continue; - - boolean hasLore = itemMeta.hasLore(); - List lore = hasLore ? Objects.requireNonNull(itemMeta.getLore()) : new ArrayList<>(); - - lore.add(ChatColor.translateAlternateColorCodes('&', innerNode - .getTextContent())); - itemMeta.setLore(lore); - itemStack.setItemMeta(itemMeta); - break; - case "enchantments": - if (!innerNode.getNodeName().equals("enchantment")) - continue; - - Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft( - innerElementChild.getAttribute("id").toUpperCase(Locale.getDefault()) - )); - - if (enchantment == null) { - throw new XMLLoadException("Enchantment cannot be found"); - } - - int level = Integer.parseInt(innerElementChild.getAttribute("level")); - - itemMeta.addEnchant(enchantment, level, true); - itemStack.setItemMeta(itemMeta); - break; - } - } - } else if (nodeName.equals("displayname")) { - ItemMeta itemMeta = Objects.requireNonNull(itemStack.getItemMeta()); - - itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', item - .getTextContent())); - - itemStack.setItemMeta(itemMeta); - } else if (nodeName.equals("skull") && itemStack.getItemMeta() instanceof SkullMeta) { - SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); - - if (elementItem.hasAttribute("owner")) - //noinspection deprecation - skullMeta.setOwner(elementItem.getAttribute("owner")); - else if (elementItem.hasAttribute("id")) { - SkullUtil.setSkull(skullMeta, elementItem.getAttribute("id")); - } - - itemStack.setItemMeta(skullMeta); - } - } - } - - Consumer action = null; - - if (element.hasAttribute("onClick")) { - String methodName = element.getAttribute("onClick"); - for (Method method : instance.getClass().getMethods()) { - if (!method.getName().equals(methodName)) - continue; - - int parameterCount = method.getParameterCount(); - Class[] parameterTypes = method.getParameterTypes(); - - if (parameterCount == 0) - action = event -> { - try { - //because reflection with lambdas is stupid - method.setAccessible(true); - method.invoke(instance); - } catch (IllegalAccessException | InvocationTargetException exception) { - throw new XMLReflectionException(exception); - } - }; - else if (InventoryClickEvent.class.isAssignableFrom(parameterTypes[0])) { - if (parameterCount == 1) - action = event -> { - try { - //because reflection with lambdas is stupid - method.setAccessible(true); - method.invoke(instance, event); - } catch (IllegalAccessException | InvocationTargetException exception) { - throw new XMLReflectionException(exception); - } - }; - else if (parameterCount == properties.size() + 1) { - boolean correct = true; - - for (int i = 0; i < properties.size(); i++) { - Object attribute = properties.get(i); - - if (!(parameterTypes[1 + i].isPrimitive() && - Primitives.unwrap(attribute.getClass()).isAssignableFrom(parameterTypes[1 + i])) && - !attribute.getClass().isAssignableFrom(parameterTypes[1 + i])) - correct = false; - } - - if (correct) { - action = event -> { - try { - //don't ask me why we need to do this, just roll with it (actually I do know why, but it's stupid) - properties.add(0, event); - - //because reflection with lambdas is stupid - method.setAccessible(true); - method.invoke(instance, properties.toArray(new Object[0])); - - //since we'll append the event to the list next time again, we need to remove it here again - properties.remove(0); - } catch (IllegalAccessException | InvocationTargetException exception) { - throw new XMLReflectionException(exception); - } - }; - } - } - } - - break; - } - } - - GuiItem item = new GuiItem(itemStack, action); - - if (element.hasAttribute("field")) - XMLUtil.loadFieldAttribute(instance, element, item); - - if (element.hasAttribute("populate")) { - try { - MethodUtils.invokeExactMethod(instance, "populate", item, GuiItem.class); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException exception) { - throw new XMLLoadException(exception); - } - } - - item.setProperties(properties); - - return item; - } - - public static void load(@NotNull Pane pane, @NotNull Object instance, @NotNull Element element) { - if (element.hasAttribute("x")) { - pane.setX(Integer.parseInt(element.getAttribute("x"))); - } - - if (element.hasAttribute("y")) { - pane.setY(Integer.parseInt(element.getAttribute("y"))); - } - - if (element.hasAttribute("priority")) - pane.setPriority(Priority.valueOf(element.getAttribute("priority"))); - - if (element.hasAttribute("visible")) - pane.setVisible(Boolean.parseBoolean(element.getAttribute("visible"))); - - if (element.hasAttribute("field")) - XMLUtil.loadFieldAttribute(instance, element, pane); - - if (element.hasAttribute("onClick")) - pane.setOnClick(XMLUtil.loadOnEventAttribute(instance, element, InventoryClickEvent.class, "onClick")); - - if (element.hasAttribute("populate")) { - String attribute = element.getAttribute("populate"); - for (Method method: instance.getClass().getMethods()) { - if (!method.getName().equals(attribute)) - continue; - - try { - method.setAccessible(true); - method.invoke(instance, pane); - } catch (IllegalAccessException | InvocationTargetException exception) { - throw new XMLLoadException(exception); - } - } - } - } - - /** - * Finds a type of {@link GuiItem} from the provided collection of items based on the provided {@link ItemStack}. - * The items will be compared using internal data. When the item does not have this data, this method will return - * null. If the item does have such data, but its value cannot be found in the provided list, null is also returned. - * This method will not mutate any of the provided arguments, nor any of the contents inside of the arguments. The - * provided collection may be unmodifiable if preferred. This method will always return a type of {@link GuiItem} - * that is in the provided collection - when the returned result is not null - such that an element E inside the - * provided collection reference equals the returned type of {@link GuiItem}. - * - * @param items a collection of items in which will be searched - * @param item the item for which an {@link GuiItem} should be found - * @param a type of GuiItem, which will be used in the provided collection and as return type - * @return the found type of {@link GuiItem} or null if none was found - * @since 0.5.14 - */ - @Nullable - @Contract(pure = true) - protected static T findMatchingItem(@NotNull Collection items, @NotNull ItemStack item) { - ItemMeta meta = item.getItemMeta(); - if (meta == null) { - return null; - } - - UUID uuid = meta.getPersistentDataContainer().get(GuiItem.KEY_UUID, UUIDTagType.INSTANCE); - if (uuid == null) { - return null; - } - - return items.stream() - .filter(guiItem -> guiItem.getUUID().equals(uuid)) - .findAny().orElse(null); - } - - /** - * Returns the priority of the pane - * - * @return the priority - */ - @NotNull - public Priority getPriority() { - return priority; - } - - /** - * Gets all the items in this pane and all underlying panes. - * The returned collection is not guaranteed to be mutable or to be a view of the underlying data. - * (So changes to the gui are not guaranteed to be visible in the returned value.) - * - * @return all items - */ - @NotNull - @Contract(pure = true) - public abstract Collection getItems(); - - /** - * Gets all the panes in this panes, including any child panes from other panes. - * The returned collection is not guaranteed to be mutable or to be a view of the underlying data. - * (So changes to the gui are not guaranteed to be visible in the returned value.) - * - * @return all panes - */ - @NotNull - @Contract(pure = true) - public abstract Collection getPanes(); - - /** - * Clears the entire pane of any items/panes. Underlying panes will not be cleared. - * - * @since 0.3.2 - */ - public abstract void clear(); - - /** - * Set the consumer that should be called whenever this pane is clicked in. - * - * @param onClick the consumer that gets called - * @since 0.4.0 - */ - public void setOnClick(@Nullable Consumer onClick) { - this.onClick = onClick; - } - - /** - * Calls the consumer (if it's not null) that was specified using {@link #setOnClick(Consumer)}, - * so the consumer that should be called whenever this pane is clicked in. - * Catches and logs all exceptions the consumer might throw. - * - * @param event the event to handle - * @since 0.6.0 - */ - protected void callOnClick(@NotNull InventoryClickEvent event) { - if (onClick == null) { - return; - } - - try { - onClick.accept(event); - } catch (Throwable t) { - Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); - logger.log(Level.SEVERE, "Exception while handling click event in inventory '" - + event.getView().getTitle() + "', slot=" + event.getSlot() + ", for " - + getClass().getSimpleName() + ", x=" + x + ", y=" + y + ", length=" + length + ", height=" + height, t); - } - } - - /** - * Registers a property that can be used inside an XML file to add additional new properties. - * The use of {@link Gui#registerProperty(String, Function)} is preferred over this method. - * - * @param attributeName the name of the property. This is the same name you'll be using to specify the property - * type in the XML file. - * @param function how the property should be processed. This converts the raw text input from the XML node value - * into the correct object type. - * @throws IllegalArgumentException when a property with this name is already registered. - */ - public static void registerProperty(@NotNull String attributeName, @NotNull Function function) { - if (PROPERTY_MAPPINGS.containsKey(attributeName)) { - throw new IllegalArgumentException("property '" + attributeName + "' is already registered"); - } - - PROPERTY_MAPPINGS.put(attributeName, function); - } - - /** - * An enum representing the rendering priorities for the panes. Uses a similar system to Bukkit's - * {@link org.bukkit.event.EventPriority} system - */ - public enum Priority { - - /** - * The lowest priority, will be rendered first - */ - LOWEST, - - /** - * A low priority, lower than default - */ - LOW, - - /** - * A normal priority, the default - */ - NORMAL, - - /** - * A higher priority, higher than default - */ - HIGH, - - /** - * The highest priority for production use - */ - HIGHEST, - - /** - * The highest priority, will always be called last, should not be used for production code - */ - MONITOR - } - - static { - PROPERTY_MAPPINGS.put("boolean", Boolean::parseBoolean); - PROPERTY_MAPPINGS.put("byte", Byte::parseByte); - PROPERTY_MAPPINGS.put("character", value -> value.charAt(0)); - PROPERTY_MAPPINGS.put("double", Double::parseDouble); - PROPERTY_MAPPINGS.put("float", Float::parseFloat); - PROPERTY_MAPPINGS.put("integer", Integer::parseInt); - PROPERTY_MAPPINGS.put("long", Long::parseLong); - PROPERTY_MAPPINGS.put("short", Short::parseShort); - PROPERTY_MAPPINGS.put("string", value -> value); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.exception.XMLReflectionException; +import com.github.stefvanschie.inventoryframework.util.SkullUtil; +import com.github.stefvanschie.inventoryframework.util.UUIDTagType; +import com.github.stefvanschie.inventoryframework.util.XMLUtil; +import com.google.common.primitives.Primitives; +import org.apache.commons.lang3.reflect.MethodUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.lang.UnsupportedOperationException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The base class for all panes. + */ +public abstract class Pane { + + /** + * The starting position of this pane, which is 0 by default + */ + protected int x = 0, y = 0; + + /** + * Length is horizontal, height is vertical + */ + protected int length, height; + + /** + * The visibility state of the pane + */ + private boolean visible; + + /** + * The priority of the pane, determines when it will be rendered + */ + @NotNull + private Priority priority; + + /** + * The consumer that will be called once a players clicks in this pane + */ + @Nullable + protected Consumer onClick; + + /** + * A unique identifier for panes to locate them by + */ + protected UUID uuid; + + /** + * A map containing the mappings for properties for items + */ + @NotNull + private static final Map> PROPERTY_MAPPINGS = new HashMap<>(); + + /** + * Constructs a new default pane + * + * @param x the upper left x coordinate of the pane + * @param y the upper left y coordinate of the pane + * @param length the length of the pane + * @param height the height of the pane + * @param priority the priority of the pane + */ + protected Pane(int x, int y, int length, int height, @NotNull Priority priority) { + this.x = x; + this.y = y; + + this.length = length; + this.height = height; + + this.priority = priority; + this.visible = true; + + this.uuid = UUID.randomUUID(); + } + + /** + * Constructs a new default pane, with no position + * + * @param length the length of the pane + * @param height the height of the pane + */ + protected Pane(int length, int height) { + this.length = length; + this.height = height; + + this.priority = Priority.NORMAL; + this.visible = true; + + this.uuid = UUID.randomUUID(); + } + + /** + * Constructs a new default pane + * + * @param x the upper left x coordinate of the pane + * @param y the upper left y coordinate of the pane + * @param length the length of the pane + * @param height the height of the pane + */ + protected Pane(int x, int y, int length, int height) { + this(x, y, length, height, Priority.NORMAL); + } + + /** + * Makes a copy of this pane and returns it. This makes a deep copy of the pane. This entails that the underlying + * panes and/or items will be copied as well. The returned pane will never be reference equal to the current pane. + * + * @return a copy of this pane + * @since 0.6.2 + */ + @NotNull + @Contract(pure = true) + public Pane copy() { + throw new UnsupportedOperationException("The implementing pane hasn't overridden the copy method"); + } + + /** + * Set the length of this pane + * + * @param length the new length + */ + public void setLength(int length) { + this.length = length; + } + + /** + * Set the height of this pane + * + * @param height the new height + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * Set the x coordinate of this pane + * + * @param x the new x coordinate + */ + public void setX(int x) { + this.x = x; + } + + /** + * Set the y coordinate of this pane + * + * @param y the new y coordinate + */ + public void setY(int y) { + this.y = y; + } + + /** + * Returns the length of this pane + * + * @return the length + */ + @Contract(pure = true) + public int getLength() { + return length; + } + + /** + * Returns the height of this pane + * + * @return the height + */ + @Contract(pure = true) + public int getHeight() { + return height; + } + + /** + * Gets the {@link UUID} associated with this pane. + * + * @return the uuid + * @since 0.7.1 + */ + @NotNull + @Contract(pure = true) + public UUID getUUID() { + return uuid; + } + + /** + * Gets the x coordinate of this pane + * + * @return the x coordinate + */ + @Contract(pure = true) + public int getX() { + return x; + } + + /** + * Gets the y coordinate of this pane + * + * @return the y coordinate + */ + @Contract(pure = true) + public int getY() { + return y; + } + + /** + * Has to set all the items in the right spot inside the inventory + * + * @param inventoryComponent the inventory component in which the items should be displayed + * @param paneOffsetX the pane's offset on the x axis + * @param paneOffsetY the pane's offset on the y axis + * @param maxLength the maximum length of the pane + * @param maxHeight the maximum height of the pane + */ + public abstract void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, + int maxLength, int maxHeight); + + /** + * Returns the pane's visibility state + * + * @return the pane's visibility + */ + @Contract(pure = true) + public boolean isVisible() { + return visible; + } + + /** + * Sets whether this pane is visible or not + * + * @param visible the pane's visibility + */ + public void setVisible(boolean visible) { + this.visible = visible; + } + + /** + * Called whenever there is being clicked on this pane + * + * @param gui the gui in which was clicked + * @param event the event that occurred while clicking on this item + * @param slot the slot that was clicked in + * @param paneOffsetX the pane's offset on the x axis + * @param paneOffsetY the pane's offset on the y axis + * @param maxLength the maximum length of the pane + * @param maxHeight the maximum height of the pane + * @return whether the item was found or not + */ + public abstract boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight); + + /** + * Sets the priority of this pane + * + * @param priority the priority + */ + public void setPriority(@NotNull Priority priority) { + this.priority = priority; + } + + /** + * Loads an item from an instance and an element + * + * @param instance the instance + * @param element the element + * @return the gui item + */ + @NotNull + @Contract(pure = true) + public static GuiItem loadItem(@NotNull Object instance, @NotNull Element element) { + String id = element.getAttribute("id"); + Material material = Objects.requireNonNull(Material.matchMaterial(id.toUpperCase(Locale.getDefault()))); + boolean hasAmount = element.hasAttribute("amount"); + boolean hasDamage = element.hasAttribute("damage"); + int amount = hasAmount ? Integer.parseInt(element.getAttribute("amount")) : 1; + short damage = hasDamage ? Short.parseShort(element.getAttribute("damage")) : 0; + + //noinspection deprecation + ItemStack itemStack = new ItemStack(material, amount, damage); + + List properties = new ArrayList<>(); + + if (element.hasChildNodes()) { + NodeList childNodes = element.getChildNodes(); + + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + + if (item.getNodeType() != Node.ELEMENT_NODE) + continue; + + Element elementItem = (Element) item; + + String nodeName = item.getNodeName(); + + if (nodeName.equals("properties") || nodeName.equals("lore") || nodeName.equals("enchantments")) { + Element innerElement = (Element) item; + NodeList innerChildNodes = innerElement.getChildNodes(); + + for (int j = 0; j < innerChildNodes.getLength(); j++) { + Node innerNode = innerChildNodes.item(j); + + if (innerNode.getNodeType() != Node.ELEMENT_NODE) + continue; + + Element innerElementChild = (Element) innerNode; + ItemMeta itemMeta = Objects.requireNonNull(itemStack.getItemMeta()); + + switch (nodeName) { + case "properties": + if (!innerNode.getNodeName().equals("property")) + continue; + + String propertyType = innerElementChild.hasAttribute("type") + ? innerElementChild.getAttribute("type") + : "string"; + + properties.add(PROPERTY_MAPPINGS.get(propertyType).apply(innerElementChild + .getTextContent())); + break; + case "lore": + if (!innerNode.getNodeName().equals("line")) + continue; + + boolean hasLore = itemMeta.hasLore(); + List lore = hasLore ? Objects.requireNonNull(itemMeta.getLore()) : new ArrayList<>(); + + lore.add(ChatColor.translateAlternateColorCodes('&', innerNode + .getTextContent())); + itemMeta.setLore(lore); + itemStack.setItemMeta(itemMeta); + break; + case "enchantments": + if (!innerNode.getNodeName().equals("enchantment")) + continue; + + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft( + innerElementChild.getAttribute("id").toUpperCase(Locale.getDefault()) + )); + + if (enchantment == null) { + throw new XMLLoadException("Enchantment cannot be found"); + } + + int level = Integer.parseInt(innerElementChild.getAttribute("level")); + + itemMeta.addEnchant(enchantment, level, true); + itemStack.setItemMeta(itemMeta); + break; + } + } + } else if (nodeName.equals("displayname")) { + ItemMeta itemMeta = Objects.requireNonNull(itemStack.getItemMeta()); + + itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', item + .getTextContent())); + + itemStack.setItemMeta(itemMeta); + } else if (nodeName.equals("skull") && itemStack.getItemMeta() instanceof SkullMeta) { + SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); + + if (elementItem.hasAttribute("owner")) + //noinspection deprecation + skullMeta.setOwner(elementItem.getAttribute("owner")); + else if (elementItem.hasAttribute("id")) { + SkullUtil.setSkull(skullMeta, elementItem.getAttribute("id")); + } + + itemStack.setItemMeta(skullMeta); + } + } + } + + Consumer action = null; + + if (element.hasAttribute("onClick")) { + String methodName = element.getAttribute("onClick"); + for (Method method : instance.getClass().getMethods()) { + if (!method.getName().equals(methodName)) + continue; + + int parameterCount = method.getParameterCount(); + Class[] parameterTypes = method.getParameterTypes(); + + if (parameterCount == 0) + action = event -> { + try { + //because reflection with lambdas is stupid + method.setAccessible(true); + method.invoke(instance); + } catch (IllegalAccessException | InvocationTargetException exception) { + throw new XMLReflectionException(exception); + } + }; + else if (InventoryClickEvent.class.isAssignableFrom(parameterTypes[0])) { + if (parameterCount == 1) + action = event -> { + try { + //because reflection with lambdas is stupid + method.setAccessible(true); + method.invoke(instance, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + throw new XMLReflectionException(exception); + } + }; + else if (parameterCount == properties.size() + 1) { + boolean correct = true; + + for (int i = 0; i < properties.size(); i++) { + Object attribute = properties.get(i); + + if (!(parameterTypes[1 + i].isPrimitive() && + Primitives.unwrap(attribute.getClass()).isAssignableFrom(parameterTypes[1 + i])) && + !attribute.getClass().isAssignableFrom(parameterTypes[1 + i])) + correct = false; + } + + if (correct) { + action = event -> { + try { + //don't ask me why we need to do this, just roll with it (actually I do know why, but it's stupid) + properties.add(0, event); + + //because reflection with lambdas is stupid + method.setAccessible(true); + method.invoke(instance, properties.toArray(new Object[0])); + + //since we'll append the event to the list next time again, we need to remove it here again + properties.remove(0); + } catch (IllegalAccessException | InvocationTargetException exception) { + throw new XMLReflectionException(exception); + } + }; + } + } + } + + break; + } + } + + GuiItem item = new GuiItem(itemStack, action); + + if (element.hasAttribute("field")) + XMLUtil.loadFieldAttribute(instance, element, item); + + if (element.hasAttribute("populate")) { + try { + MethodUtils.invokeExactMethod(instance, "populate", item, GuiItem.class); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException exception) { + throw new XMLLoadException(exception); + } + } + + item.setProperties(properties); + + return item; + } + + public static void load(@NotNull Pane pane, @NotNull Object instance, @NotNull Element element) { + if (element.hasAttribute("x")) { + pane.setX(Integer.parseInt(element.getAttribute("x"))); + } + + if (element.hasAttribute("y")) { + pane.setY(Integer.parseInt(element.getAttribute("y"))); + } + + if (element.hasAttribute("priority")) + pane.setPriority(Priority.valueOf(element.getAttribute("priority"))); + + if (element.hasAttribute("visible")) + pane.setVisible(Boolean.parseBoolean(element.getAttribute("visible"))); + + if (element.hasAttribute("field")) + XMLUtil.loadFieldAttribute(instance, element, pane); + + if (element.hasAttribute("onClick")) + pane.setOnClick(XMLUtil.loadOnEventAttribute(instance, element, InventoryClickEvent.class, "onClick")); + + if (element.hasAttribute("populate")) { + String attribute = element.getAttribute("populate"); + for (Method method: instance.getClass().getMethods()) { + if (!method.getName().equals(attribute)) + continue; + + try { + method.setAccessible(true); + method.invoke(instance, pane); + } catch (IllegalAccessException | InvocationTargetException exception) { + throw new XMLLoadException(exception); + } + } + } + } + + /** + * Finds a type of {@link GuiItem} from the provided collection of items based on the provided {@link ItemStack}. + * The items will be compared using internal data. When the item does not have this data, this method will return + * null. If the item does have such data, but its value cannot be found in the provided list, null is also returned. + * This method will not mutate any of the provided arguments, nor any of the contents inside of the arguments. The + * provided collection may be unmodifiable if preferred. This method will always return a type of {@link GuiItem} + * that is in the provided collection - when the returned result is not null - such that an element E inside the + * provided collection reference equals the returned type of {@link GuiItem}. + * + * @param items a collection of items in which will be searched + * @param item the item for which an {@link GuiItem} should be found + * @param a type of GuiItem, which will be used in the provided collection and as return type + * @return the found type of {@link GuiItem} or null if none was found + * @since 0.5.14 + */ + @Nullable + @Contract(pure = true) + protected static T findMatchingItem(@NotNull Collection items, @NotNull ItemStack item) { + ItemMeta meta = item.getItemMeta(); + if (meta == null) { + return null; + } + + UUID uuid = meta.getPersistentDataContainer().get(GuiItem.KEY_UUID, UUIDTagType.INSTANCE); + if (uuid == null) { + return null; + } + + return items.stream() + .filter(guiItem -> guiItem.getUUID().equals(uuid)) + .findAny().orElse(null); + } + + /** + * Returns the priority of the pane + * + * @return the priority + */ + @NotNull + public Priority getPriority() { + return priority; + } + + /** + * Gets all the items in this pane and all underlying panes. + * The returned collection is not guaranteed to be mutable or to be a view of the underlying data. + * (So changes to the gui are not guaranteed to be visible in the returned value.) + * + * @return all items + */ + @NotNull + @Contract(pure = true) + public abstract Collection getItems(); + + /** + * Gets all the panes in this panes, including any child panes from other panes. + * The returned collection is not guaranteed to be mutable or to be a view of the underlying data. + * (So changes to the gui are not guaranteed to be visible in the returned value.) + * + * @return all panes + */ + @NotNull + @Contract(pure = true) + public abstract Collection getPanes(); + + /** + * Clears the entire pane of any items/panes. Underlying panes will not be cleared. + * + * @since 0.3.2 + */ + public abstract void clear(); + + /** + * Set the consumer that should be called whenever this pane is clicked in. + * + * @param onClick the consumer that gets called + * @since 0.4.0 + */ + public void setOnClick(@Nullable Consumer onClick) { + this.onClick = onClick; + } + + /** + * Calls the consumer (if it's not null) that was specified using {@link #setOnClick(Consumer)}, + * so the consumer that should be called whenever this pane is clicked in. + * Catches and logs all exceptions the consumer might throw. + * + * @param event the event to handle + * @since 0.6.0 + */ + protected void callOnClick(@NotNull InventoryClickEvent event) { + if (onClick == null) { + return; + } + + try { + onClick.accept(event); + } catch (Throwable t) { + Logger logger = JavaPlugin.getProvidingPlugin(getClass()).getLogger(); + logger.log(Level.SEVERE, "Exception while handling click event in inventory '" + + event.getView().getTitle() + "', slot=" + event.getSlot() + ", for " + + getClass().getSimpleName() + ", x=" + x + ", y=" + y + ", length=" + length + ", height=" + height, t); + } + } + + /** + * Registers a property that can be used inside an XML file to add additional new properties. + * The use of {@link Gui#registerProperty(String, Function)} is preferred over this method. + * + * @param attributeName the name of the property. This is the same name you'll be using to specify the property + * type in the XML file. + * @param function how the property should be processed. This converts the raw text input from the XML node value + * into the correct object type. + * @throws IllegalArgumentException when a property with this name is already registered. + */ + public static void registerProperty(@NotNull String attributeName, @NotNull Function function) { + if (PROPERTY_MAPPINGS.containsKey(attributeName)) { + throw new IllegalArgumentException("property '" + attributeName + "' is already registered"); + } + + PROPERTY_MAPPINGS.put(attributeName, function); + } + + /** + * An enum representing the rendering priorities for the panes. Uses a similar system to Bukkit's + * {@link org.bukkit.event.EventPriority} system + */ + public enum Priority { + + /** + * The lowest priority, will be rendered first + */ + LOWEST { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return priority != this; + } + }, + + /** + * A low priority, lower than default + */ + LOW { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return priority != this && priority != LOWEST; + } + }, + + /** + * A normal priority, the default + */ + NORMAL { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return priority != this && priority != LOW && priority != LOWEST; + } + }, + + /** + * A higher priority, higher than default + */ + HIGH { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return priority == HIGHEST || priority == MONITOR; + } + }, + + /** + * The highest priority for production use + */ + HIGHEST { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return priority == MONITOR; + } + }, + + /** + * The highest priority, will always be called last, should not be used for production code + */ + MONITOR { + @Override + public boolean isLessThan(@NotNull Priority priority) { + return false; + } + }; + + /** + * Whether this priority is less than the priority specified. + * + * @param priority the priority to compare against + * @return true if this priority is less than the specified priority, false otherwise + * @since 0.8.0 + */ + @Contract(pure = true) + public abstract boolean isLessThan(@NotNull Priority priority); + + /** + * Whether this priority is greater than the priority specified. + * + * @param priority the priority to compare against + * @return true if this priority is greater than the specified priority, false otherwise + * @since 0.8.0 + */ + @Contract(pure = true) + public boolean isGreaterThan(@NotNull Priority priority) { + return !isLessThan(priority) && this != priority; + } + } + + static { + PROPERTY_MAPPINGS.put("boolean", Boolean::parseBoolean); + PROPERTY_MAPPINGS.put("byte", Byte::parseByte); + PROPERTY_MAPPINGS.put("character", value -> value.charAt(0)); + PROPERTY_MAPPINGS.put("double", Double::parseDouble); + PROPERTY_MAPPINGS.put("float", Float::parseFloat); + PROPERTY_MAPPINGS.put("integer", Integer::parseInt); + PROPERTY_MAPPINGS.put("long", Long::parseLong); + PROPERTY_MAPPINGS.put("short", Short::parseShort); + PROPERTY_MAPPINGS.put("string", value -> value); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java index 1c804622..8905323c 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/Rotatable.java @@ -1,51 +1,51 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -/** - * An interface for panes that are rotatable - * - * @since 0.3.0 - */ -public interface Rotatable { - - /** - * Sets the rotation of this pane. The rotation is in degrees and can only be in increments of 90. Anything higher - * than 360, will be lowered to a value in between [0, 360) while maintaining the same rotational value. E.g. 450 - * degrees becomes 90 degrees, 1080 degrees becomes 0, etc. - * - * This method fails for any pane that has a length and height which are unequal. - * - * @param rotation the rotation of this pane, must be divisible by 90. - * @throws UnsupportedOperationException when the length and height of the pane are not the same - * @throws IllegalArgumentException when the rotation isn't a multiple of 90 - * @since 0.3.0 - */ - void setRotation(int rotation); - - /** - * Gets the rotation specified to this pane. If no rotation has been set, or if this pane is not capable of having a - * rotation, 0 is returned. - * - * @return the rotation for this pane - * @since 0.3.0 - */ - @Contract(pure = true) - int getRotation(); - - /** - * Loads all elements regarding a {@link Rotatable} {@link Pane} for the specified pane. The mutable pane contains - * the changes made. - * - * @param rotatable the rotatable pane's elements to be applied - * @param element the XML element for this pane - * @since 0.3.0 - */ - static void load(@NotNull Rotatable rotatable, @NotNull Element element) { - if (element.hasAttribute("rotation")) { - rotatable.setRotation(Integer.parseInt(element.getAttribute("rotation"))); - } - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * An interface for panes that are rotatable + * + * @since 0.3.0 + */ +public interface Rotatable { + + /** + * Sets the rotation of this pane. The rotation is in degrees and can only be in increments of 90. Anything higher + * than 360, will be lowered to a value in between [0, 360) while maintaining the same rotational value. E.g. 450 + * degrees becomes 90 degrees, 1080 degrees becomes 0, etc. + * + * This method fails for any pane that has a length and height which are unequal. + * + * @param rotation the rotation of this pane, must be divisible by 90. + * @throws UnsupportedOperationException when the length and height of the pane are not the same + * @throws IllegalArgumentException when the rotation isn't a multiple of 90 + * @since 0.3.0 + */ + void setRotation(int rotation); + + /** + * Gets the rotation specified to this pane. If no rotation has been set, or if this pane is not capable of having a + * rotation, 0 is returned. + * + * @return the rotation for this pane + * @since 0.3.0 + */ + @Contract(pure = true) + int getRotation(); + + /** + * Loads all elements regarding a {@link Rotatable} {@link Pane} for the specified pane. The mutable pane contains + * the changes made. + * + * @param rotatable the rotatable pane's elements to be applied + * @param element the XML element for this pane + * @since 0.3.0 + */ + static void load(@NotNull Rotatable rotatable, @NotNull Element element) { + if (element.hasAttribute("rotation")) { + rotatable.setRotation(Integer.parseInt(element.getAttribute("rotation"))); + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java similarity index 80% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java index 1a2aa101..e0daecd3 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/StaticPane.java @@ -1,343 +1,312 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.util.GeometryUtil; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.*; -import java.util.function.Consumer; - -/** - * A pane for static items and stuff. All items will have to be specified a slot, or will be added in the next position. - */ -public class StaticPane extends Pane implements Flippable, Rotatable { - - /** - * A map of locations inside this pane and their item. The locations are stored in a way where the x coordinate is - * the key and the y coordinate is the value. - */ - @NotNull - private final Map, GuiItem> items; - - /** - * The clockwise rotation of this pane in degrees - */ - private int rotation; - - /** - * Whether the items should be flipped horizontally and/or vertically - */ - private boolean flipHorizontally, flipVertically; - - public StaticPane(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - - this.items = new HashMap<>(length * height); - } - - public StaticPane(int x, int y, int length, int height) { - this(x, y, length, height, Priority.NORMAL); - } - - public StaticPane(int length, int height) { - this(0, 0, length, height); - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - items.entrySet().stream().filter(entry -> { - GuiItem item = entry.getValue(); - Map.Entry location = entry.getKey(); - - return item.isVisible() && location.getKey() + paneOffsetX <= 9 && location.getValue() + paneOffsetY <= 6; - }).forEach(entry -> { - Map.Entry location = entry.getKey(); - - int x = location.getKey(), y = location.getValue(); - - if (flipHorizontally) - x = length - x - 1; - - if (flipVertically) - y = height - y - 1; - - Map.Entry coordinates = GeometryUtil.processClockwiseRotation(x, y, length, height, - rotation); - - x = coordinates.getKey(); - y = coordinates.getValue(); - - if (x < 0 || x >= length || y < 0 || y >= height) { - return; - } - - ItemStack item = entry.getValue().getItem(); - - int finalRow = getY() + y + paneOffsetY; - int finalColumn = getX() + x + paneOffsetX; - - if (finalRow >= gui.getRows()) { - gui.setState(Gui.State.BOTTOM); - - if (finalRow == gui.getRows() + 3) { - playerInventory.setItem(finalColumn, item); - } else { - playerInventory.setItem(((finalRow - gui.getRows()) + 1) * 9 + finalColumn, item); - } - } else { - inventory.setItem(finalRow * 9 + finalColumn, item); - } - }); - } - - /** - * Adds a gui item at the specific spot in the pane. If the coordinates as specified by the x and y parameters is - * already occupied, that item will be replaced by the item parameter. - * - * @param item the item to set - * @param x the x coordinate of the position of the item - * @param y the y coordinate of the position of the item - */ - public void addItem(@NotNull GuiItem item, int x, int y) { - items.keySet().removeIf(entry -> entry.getKey() == x && entry.getValue() == y); - - items.put(new AbstractMap.SimpleEntry<>(x, y), item); - } - - /** - * Removes the specified item from the pane - * - * @param item the item to remove - * @since 0.5.8 - */ - public void removeItem(@NotNull GuiItem item) { - items.values().removeIf(guiItem -> guiItem.equals(item)); - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - //this isn't our item - if (x < 0 || x >= length || y < 0 || y >= height) - return false; - - callOnClick(event); - - ItemStack itemStack = event.getCurrentItem(); - - if (itemStack == null) { - return false; - } - - GuiItem clickedItem = findMatchingItem(items.values(), itemStack); - - if (clickedItem == null) { - return false; - } - - clickedItem.callAction(event); - - return true; - } - - @NotNull - @Contract(pure = true) - @Override - public StaticPane copy() { - StaticPane staticPane = new StaticPane(x, y, length, height, getPriority()); - - for (Map.Entry, GuiItem> entry : items.entrySet()) { - Map.Entry coordinates = entry.getKey(); - - staticPane.addItem(entry.getValue().copy(), coordinates.getKey(), coordinates.getValue()); - } - - staticPane.setVisible(isVisible()); - staticPane.onClick = onClick; - - staticPane.uuid = uuid; - - staticPane.rotation = rotation; - staticPane.flipHorizontally = flipHorizontally; - staticPane.flipVertically = flipVertically; - - return staticPane; - } - - @Override - public void setRotation(int rotation) { - if (length != height) { - throw new UnsupportedOperationException("length and height are different"); - } - if (rotation % 90 != 0) { - throw new IllegalArgumentException("rotation isn't divisible by 90"); - } - - this.rotation = rotation % 360; - } - - /** - * Fills all empty space in the pane with the given {@code itemStack} and adds the given action - * - * @param itemStack The {@link ItemStack} to fill the empty space with - * @param action The action called whenever an interaction with the item happens - * @since 0.5.9 - */ - public void fillWith(@NotNull ItemStack itemStack, @Nullable Consumer action) { - //The non empty spots - Set> locations = this.items.keySet(); - - for (int y = 0; y < this.getHeight(); y++) { - for (int x = 0; x < this.getLength(); x++) { - boolean found = false; - - for (Map.Entry location : locations) { - if (location.getKey() == x && location.getValue() == y) { - found = true; - break; - } - } - - if (!found) { - this.addItem(new GuiItem(itemStack, action), x, y); - } - } - } - } - - /** - * Fills all empty space in the pane with the given {@code itemStack} - * - * @param itemStack The {@link ItemStack} to fill the empty space with - * @since 0.2.4 - */ - @Contract("null -> fail") - public void fillWith(@NotNull ItemStack itemStack) { - this.fillWith(itemStack, null); - } - - @NotNull - @Override - public Collection getItems() { - return items.values(); - } - - @Override - public void clear() { - items.clear(); - } - - @NotNull - @Contract(pure = true) - @Override - public Collection getPanes() { - return new HashSet<>(); - } - - @Override - public void flipHorizontally(boolean flipHorizontally) { - this.flipHorizontally = flipHorizontally; - } - - @Override - public void flipVertically(boolean flipVertically) { - this.flipVertically = flipVertically; - } - - @Contract(pure = true) - @Override - public int getRotation() { - return rotation; - } - - @Contract(pure = true) - @Override - public boolean isFlippedHorizontally() { - return flipHorizontally; - } - - @Contract(pure = true) - @Override - public boolean isFlippedVertically() { - return flipVertically; - } - - /** - * Loads an outline pane from a given element - * - * @param instance the instance class - * @param element the element - * @return the outline pane - */ - @NotNull - public static StaticPane load(@NotNull Object instance, @NotNull Element element) { - try { - StaticPane staticPane = new StaticPane( - Integer.parseInt(element.getAttribute("length")), - Integer.parseInt(element.getAttribute("height")) - ); - - Pane.load(staticPane, instance, element); - Flippable.load(staticPane, element); - Rotatable.load(staticPane, element); - - if (element.hasAttribute("populate")) - return staticPane; - - NodeList childNodes = element.getChildNodes(); - - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.item(i); - - if (item.getNodeType() != Node.ELEMENT_NODE) - continue; - - Element child = (Element) item; - - staticPane.addItem(Pane.loadItem(instance, child), Integer.parseInt(child.getAttribute("x")), - Integer.parseInt(child.getAttribute("y"))); - } - - return staticPane; - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.util.GeometryUtil; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; +import java.util.function.Consumer; + +/** + * A pane for static items and stuff. All items will have to be specified a slot, or will be added in the next position. + */ +public class StaticPane extends Pane implements Flippable, Rotatable { + + /** + * A map of locations inside this pane and their item. The locations are stored in a way where the x coordinate is + * the key and the y coordinate is the value. + */ + @NotNull + private final Map, GuiItem> items; + + /** + * The clockwise rotation of this pane in degrees + */ + private int rotation; + + /** + * Whether the items should be flipped horizontally and/or vertically + */ + private boolean flipHorizontally, flipVertically; + + public StaticPane(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + + this.items = new HashMap<>(length * height); + } + + public StaticPane(int x, int y, int length, int height) { + this(x, y, length, height, Priority.NORMAL); + } + + public StaticPane(int length, int height) { + this(0, 0, length, height); + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + items.entrySet().stream().filter(entry -> entry.getValue().isVisible()).forEach(entry -> { + Map.Entry location = entry.getKey(); + + int x = location.getKey(), y = location.getValue(); + + if (flipHorizontally) + x = length - x - 1; + + if (flipVertically) + y = height - y - 1; + + Map.Entry coordinates = GeometryUtil.processClockwiseRotation(x, y, length, height, + rotation); + + x = coordinates.getKey(); + y = coordinates.getValue(); + + if (x < 0 || x >= length || y < 0 || y >= height) { + return; + } + + GuiItem item = entry.getValue(); + + int finalRow = getY() + y + paneOffsetY; + int finalColumn = getX() + x + paneOffsetX; + + inventoryComponent.setItem(item.getItem(), finalColumn, finalRow); + }); + } + + /** + * Adds a gui item at the specific spot in the pane. If the coordinates as specified by the x and y parameters is + * already occupied, that item will be replaced by the item parameter. + * + * @param item the item to set + * @param x the x coordinate of the position of the item + * @param y the y coordinate of the position of the item + */ + public void addItem(@NotNull GuiItem item, int x, int y) { + items.keySet().removeIf(entry -> entry.getKey() == x && entry.getValue() == y); + + items.put(new AbstractMap.SimpleEntry<>(x, y), item); + } + + /** + * Removes the specified item from the pane + * + * @param item the item to remove + * @since 0.5.8 + */ + public void removeItem(@NotNull GuiItem item) { + items.values().removeIf(guiItem -> guiItem.equals(item)); + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % length) - getX() - paneOffsetX; + int y = (slot / length) - getY() - paneOffsetY; + + //this isn't our item + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + ItemStack itemStack = event.getCurrentItem(); + + if (itemStack == null) { + return false; + } + + GuiItem clickedItem = findMatchingItem(items.values(), itemStack); + + if (clickedItem == null) { + return false; + } + + clickedItem.callAction(event); + + return true; + } + + @NotNull + @Contract(pure = true) + @Override + public StaticPane copy() { + StaticPane staticPane = new StaticPane(x, y, length, height, getPriority()); + + for (Map.Entry, GuiItem> entry : items.entrySet()) { + Map.Entry coordinates = entry.getKey(); + + staticPane.addItem(entry.getValue().copy(), coordinates.getKey(), coordinates.getValue()); + } + + staticPane.setVisible(isVisible()); + staticPane.onClick = onClick; + + staticPane.uuid = uuid; + + staticPane.rotation = rotation; + staticPane.flipHorizontally = flipHorizontally; + staticPane.flipVertically = flipVertically; + + return staticPane; + } + + @Override + public void setRotation(int rotation) { + if (length != height) { + throw new UnsupportedOperationException("length and height are different"); + } + if (rotation % 90 != 0) { + throw new IllegalArgumentException("rotation isn't divisible by 90"); + } + + this.rotation = rotation % 360; + } + + /** + * Fills all empty space in the pane with the given {@code itemStack} and adds the given action + * + * @param itemStack The {@link ItemStack} to fill the empty space with + * @param action The action called whenever an interaction with the item happens + * @since 0.5.9 + */ + public void fillWith(@NotNull ItemStack itemStack, @Nullable Consumer action) { + //The non empty spots + Set> locations = this.items.keySet(); + + for (int y = 0; y < this.getHeight(); y++) { + for (int x = 0; x < this.getLength(); x++) { + boolean found = false; + + for (Map.Entry location : locations) { + if (location.getKey() == x && location.getValue() == y) { + found = true; + break; + } + } + + if (!found) { + this.addItem(new GuiItem(itemStack, action), x, y); + } + } + } + } + + /** + * Fills all empty space in the pane with the given {@code itemStack} + * + * @param itemStack The {@link ItemStack} to fill the empty space with + * @since 0.2.4 + */ + @Contract("null -> fail") + public void fillWith(@NotNull ItemStack itemStack) { + this.fillWith(itemStack, null); + } + + @NotNull + @Override + public Collection getItems() { + return items.values(); + } + + @Override + public void clear() { + items.clear(); + } + + @NotNull + @Contract(pure = true) + @Override + public Collection getPanes() { + return new HashSet<>(); + } + + @Override + public void flipHorizontally(boolean flipHorizontally) { + this.flipHorizontally = flipHorizontally; + } + + @Override + public void flipVertically(boolean flipVertically) { + this.flipVertically = flipVertically; + } + + @Contract(pure = true) + @Override + public int getRotation() { + return rotation; + } + + @Contract(pure = true) + @Override + public boolean isFlippedHorizontally() { + return flipHorizontally; + } + + @Contract(pure = true) + @Override + public boolean isFlippedVertically() { + return flipVertically; + } + + /** + * Loads an outline pane from a given element + * + * @param instance the instance class + * @param element the element + * @return the outline pane + */ + @NotNull + public static StaticPane load(@NotNull Object instance, @NotNull Element element) { + try { + StaticPane staticPane = new StaticPane( + Integer.parseInt(element.getAttribute("length")), + Integer.parseInt(element.getAttribute("height")) + ); + + Pane.load(staticPane, instance, element); + Flippable.load(staticPane, element); + Rotatable.load(staticPane, element); + + if (element.hasAttribute("populate")) + return staticPane; + + NodeList childNodes = element.getChildNodes(); + + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + + if (item.getNodeType() != Node.ELEMENT_NODE) + continue; + + Element child = (Element) item; + + staticPane.addItem(Pane.loadItem(instance, child), Integer.parseInt(child.getAttribute("x")), + Integer.parseInt(child.getAttribute("y"))); + } + + return staticPane; + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java similarity index 76% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java index fbaf01c4..12b19ec3 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButton.java @@ -1,214 +1,198 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * A button for cycling between different options - * - * @since 0.5.0 - */ -public class CycleButton extends Pane { - - /** - * The list of pane used for display - */ - private final List panes = new ArrayList<>(); - - /** - * The current position of the cycle button - */ - private int position = 0; - - public CycleButton(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - } - - public CycleButton(int x, int y, int length, int height) { - super(x, y, length, height); - } - - public CycleButton(int length, int height) { - super(length, height); - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - //this isn't our item - if (x < 0 || x >= length || y < 0 || y >= height) { - return false; - } - - callOnClick(event); - - panes.get(position).click(gui, event, paneOffsetX + x, paneOffsetY + y, length, height); - - position++; - - if (position == panes.size()) { - position = 0; - } - - gui.update(); - - return true; - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int newX = paneOffsetX + x; - int newY = paneOffsetY + y; - - int newMaxLength = Math.min(maxLength, length); - int newMaxHeight = Math.min(maxHeight, height); - - panes.get(position).display(gui, inventory, playerInventory, newX, newY, newMaxLength, newMaxHeight); - } - - @NotNull - @Contract(pure = true) - @Override - public CycleButton copy() { - CycleButton cycleButton = new CycleButton(x, y, length, height, getPriority()); - - for (Pane pane : panes) { - cycleButton.addPane(pane); - } - - cycleButton.setVisible(isVisible()); - cycleButton.onClick = onClick; - - cycleButton.position = position; - - cycleButton.uuid = uuid; - - return cycleButton; - } - - @NotNull - @Override - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); - } - - /** - * Adds a pane to the current list of options - * - * @param index the index to insert the pane at - * @param pane the pane to add - * @since 0.5.0 - */ - public void addPane(int index, @NotNull Pane pane) { - panes.add(index, pane); - } - - /** - * Adds a pane to the current list of options - * - * @param pane the pane to add - * @since 0.5.0 - */ - public void addPane(@NotNull Pane pane) { - panes.add(pane); - } - - @Override - public void clear() { - panes.clear(); - } - - @NotNull - @Override - public Collection getPanes() { - return panes; - } - - /** - * Cycles through one option, making it go to the next one - * - * @since 0.5.0 - */ - public void cycle() { - position++; - } - - /** - * Loads a cycle button from a given element - * - * @param instance the instance class - * @param element the element - * @return the cycle button - * @since 0.5.0 - */ - @NotNull - public static CycleButton load(@NotNull Object instance, @NotNull Element element) { - int length; - int height; - - try { - length = Integer.parseInt(element.getAttribute("length")); - height = Integer.parseInt(element.getAttribute("height")); - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - - CycleButton cycleButton = new CycleButton(length, height); - - Pane.load(cycleButton, instance, element); - - if (element.hasAttribute("populate")) { - return cycleButton; - } - - NodeList childNodes = element.getChildNodes(); - - for (int j = 0; j < childNodes.getLength(); j++) { - Node pane = childNodes.item(j); - - if (pane.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - - cycleButton.addPane(Gui.loadPane(instance, pane)); - } - - return cycleButton; - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * A button for cycling between different options + * + * @since 0.5.0 + */ +public class CycleButton extends Pane { + + /** + * The list of pane used for display + */ + private final List panes = new ArrayList<>(); + + /** + * The current position of the cycle button + */ + private int position = 0; + + public CycleButton(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + } + + public CycleButton(int x, int y, int length, int height) { + super(x, y, length, height); + } + + public CycleButton(int length, int height) { + super(length, height); + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % 9) - getX() - paneOffsetX; + int y = (slot / 9) - getY() - paneOffsetY; + + //this isn't our item + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + Pane pane = panes.get(position); + pane.click(gui, event, slot, paneOffsetX + x, paneOffsetY + y, length, height); + + position++; + + if (position == panes.size()) { + position = 0; + } + + gui.update(); + + return true; + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int newX = paneOffsetX + x; + int newY = paneOffsetY + y; + + int newMaxLength = Math.min(maxLength, length); + int newMaxHeight = Math.min(maxHeight, height); + + panes.get(position).display(inventoryComponent, newX, newY, newMaxLength, newMaxHeight); + } + + @NotNull + @Contract(pure = true) + @Override + public CycleButton copy() { + CycleButton cycleButton = new CycleButton(x, y, length, height, getPriority()); + + for (Pane pane : panes) { + cycleButton.addPane(pane); + } + + cycleButton.setVisible(isVisible()); + cycleButton.onClick = onClick; + + cycleButton.position = position; + + cycleButton.uuid = uuid; + + return cycleButton; + } + + @NotNull + @Override + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toList()); + } + + /** + * Adds a pane to the current list of options + * + * @param index the index to insert the pane at + * @param pane the pane to add + * @since 0.5.0 + */ + public void addPane(int index, @NotNull Pane pane) { + panes.add(index, pane); + } + + /** + * Adds a pane to the current list of options + * + * @param pane the pane to add + * @since 0.5.0 + */ + public void addPane(@NotNull Pane pane) { + panes.add(pane); + } + + @Override + public void clear() { + panes.clear(); + } + + @NotNull + @Override + public Collection getPanes() { + return panes; + } + + /** + * Cycles through one option, making it go to the next one + * + * @since 0.5.0 + */ + public void cycle() { + position++; + } + + /** + * Loads a cycle button from a given element + * + * @param instance the instance class + * @param element the element + * @return the cycle button + * @since 0.5.0 + */ + @NotNull + public static CycleButton load(@NotNull Object instance, @NotNull Element element) { + int length; + int height; + + try { + length = Integer.parseInt(element.getAttribute("length")); + height = Integer.parseInt(element.getAttribute("height")); + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + + CycleButton cycleButton = new CycleButton(length, height); + + Pane.load(cycleButton, instance, element); + + if (element.hasAttribute("populate")) { + return cycleButton; + } + + NodeList childNodes = element.getChildNodes(); + + for (int j = 0; j < childNodes.getLength(); j++) { + Node pane = childNodes.item(j); + + if (pane.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + cycleButton.addPane(Gui.loadPane(instance, pane)); + } + + return cycleButton; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java similarity index 90% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java index b90de5b5..f210617c 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Label.java @@ -1,218 +1,218 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.font.util.Font; -import com.github.stefvanschie.inventoryframework.pane.*; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -/** - * A label for displaying text. - * - * @since 0.5.0 - */ -public class Label extends OutlinePane { - - /** - * The character set used for displaying the characters in this label - */ - @NotNull - private final Font font; - - /** - * The text to be displayed - */ - @NotNull - private String text; - - /** - * Creates a new label - * - * @param x the x coordinate - * @param y the y coordinate - * @param length the length - * @param height the height - * @param priority the priority - * @param font the character set - * @since 0.5.0 - */ - public Label(int x, int y, int length, int height, @NotNull Priority priority, @NotNull Font font) { - this(x, y, length, height, font); - - setPriority(priority); - } - - /** - * Creates a new label - * - * @param x the x coordinate - * @param y the y coordinate - * @param length the length - * @param height the height - * @param font the character set - * @since 0.5.0 - */ - public Label(int x, int y, int length, int height, @NotNull Font font) { - this(length, height, font); - - this.x = x; - this.y = y; - } - - /** - * Creates a new label - * - * @param length the length - * @param height the height - * @param font the character set - * @since 0.5.0 - */ - public Label(int length, int height, @NotNull Font font) { - super(length, height); - - this.font = font; - this.text = ""; - } - - /** - * Sets the text to be displayed in this label - * - * @param text the new text - * @since 0.5.0 - */ - public void setText(@NotNull String text) { - this.text = text; - - clear(); - - for (char character : text.toCharArray()) { - ItemStack item = font.toItem(character); - - if (item == null) { - item = font.toItem(Character.toUpperCase(character)); - } - - if (item == null) { - item = font.toItem(Character.toLowerCase(character)); - } - - if (item == null) { - item = font.getDefaultItem(); - } - - addItem(new GuiItem(item)); - } - } - - @NotNull - @Contract(pure = true) - @Override - public Label copy() { - Label label = new Label(x, y, length, height, getPriority(), font); - - for (GuiItem item : getItems()) { - label.addItem(item.copy()); - } - - label.setVisible(isVisible()); - label.onClick = onClick; - - label.setOrientation(getOrientation()); - label.setRotation(getRotation()); - label.setGap(getGap()); - label.setRepeat(doesRepeat()); - label.flipHorizontally(isFlippedHorizontally()); - label.flipVertically(isFlippedVertically()); - label.applyMask(getMask()); - label.uuid = uuid; - - label.text = text; - - return label; - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - event.setCancelled(true); - - return super.click(gui, event, paneOffsetX, paneOffsetY, maxLength, maxHeight); - } - - /** - * Gets the text currently displayed in this label - * - * @return the text in this label - * @since 0.5.0 - */ - @Contract(pure = true) - @NotNull - public String getText() { - return text; - } - - /** - * Gets the character set currently used for the text in this label - * - * @return the character set - * @since 0.5.0 - */ - @Contract(pure = true) - @NotNull - public Font getFont() { - return font; - } - - /** - * Loads a label from a given element - * - * @param instance the instance class - * @param element the element - * @return the percentage bar - */ - @NotNull - @Contract(pure = true) - public static Label load(@NotNull Object instance, @NotNull Element element) { - int length; - int height; - - try { - length = Integer.parseInt(element.getAttribute("length")); - height = Integer.parseInt(element.getAttribute("height")); - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - - Font font = null; - - if (element.hasAttribute("font")) { - font = Font.fromName(element.getAttribute("font")); - } - - if (font == null) { - throw new XMLLoadException("Incorrect font specified for label"); - } - - Label label = new Label(length, height, font); - - Pane.load(label, instance, element); - Orientable.load(label, element); - Flippable.load(label, element); - Rotatable.load(label, element); - - if (element.hasAttribute("populate")) { - return label; - } - - if (element.hasAttribute("text")) { - label.setText(element.getAttribute("text")); - } - - return label; - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.font.util.Font; +import com.github.stefvanschie.inventoryframework.pane.*; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * A label for displaying text. + * + * @since 0.5.0 + */ +public class Label extends OutlinePane { + + /** + * The character set used for displaying the characters in this label + */ + @NotNull + private final Font font; + + /** + * The text to be displayed + */ + @NotNull + private String text; + + /** + * Creates a new label + * + * @param x the x coordinate + * @param y the y coordinate + * @param length the length + * @param height the height + * @param priority the priority + * @param font the character set + * @since 0.5.0 + */ + public Label(int x, int y, int length, int height, @NotNull Priority priority, @NotNull Font font) { + this(x, y, length, height, font); + + setPriority(priority); + } + + /** + * Creates a new label + * + * @param x the x coordinate + * @param y the y coordinate + * @param length the length + * @param height the height + * @param font the character set + * @since 0.5.0 + */ + public Label(int x, int y, int length, int height, @NotNull Font font) { + this(length, height, font); + + this.x = x; + this.y = y; + } + + /** + * Creates a new label + * + * @param length the length + * @param height the height + * @param font the character set + * @since 0.5.0 + */ + public Label(int length, int height, @NotNull Font font) { + super(length, height); + + this.font = font; + this.text = ""; + } + + /** + * Sets the text to be displayed in this label + * + * @param text the new text + * @since 0.5.0 + */ + public void setText(@NotNull String text) { + this.text = text; + + clear(); + + for (char character : text.toCharArray()) { + ItemStack item = font.toItem(character); + + if (item == null) { + item = font.toItem(Character.toUpperCase(character)); + } + + if (item == null) { + item = font.toItem(Character.toLowerCase(character)); + } + + if (item == null) { + item = font.getDefaultItem(); + } + + addItem(new GuiItem(item)); + } + } + + @NotNull + @Contract(pure = true) + @Override + public Label copy() { + Label label = new Label(x, y, length, height, getPriority(), font); + + for (GuiItem item : getItems()) { + label.addItem(item.copy()); + } + + label.setVisible(isVisible()); + label.onClick = onClick; + + label.setOrientation(getOrientation()); + label.setRotation(getRotation()); + label.setGap(getGap()); + label.setRepeat(doesRepeat()); + label.flipHorizontally(isFlippedHorizontally()); + label.flipVertically(isFlippedVertically()); + label.applyMask(getMask()); + label.uuid = uuid; + + label.text = text; + + return label; + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + event.setCancelled(true); + + return super.click(gui, event, paneOffsetX, slot, paneOffsetY, maxLength, maxHeight); + } + + /** + * Gets the text currently displayed in this label + * + * @return the text in this label + * @since 0.5.0 + */ + @Contract(pure = true) + @NotNull + public String getText() { + return text; + } + + /** + * Gets the character set currently used for the text in this label + * + * @return the character set + * @since 0.5.0 + */ + @Contract(pure = true) + @NotNull + public Font getFont() { + return font; + } + + /** + * Loads a label from a given element + * + * @param instance the instance class + * @param element the element + * @return the percentage bar + */ + @NotNull + @Contract(pure = true) + public static Label load(@NotNull Object instance, @NotNull Element element) { + int length; + int height; + + try { + length = Integer.parseInt(element.getAttribute("length")); + height = Integer.parseInt(element.getAttribute("height")); + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + + Font font = null; + + if (element.hasAttribute("font")) { + font = Font.fromName(element.getAttribute("font")); + } + + if (font == null) { + throw new XMLLoadException("Incorrect font specified for label"); + } + + Label label = new Label(length, height, font); + + Pane.load(label, instance, element); + Orientable.load(label, element); + Flippable.load(label, element); + Rotatable.load(label, element); + + if (element.hasAttribute("populate")) { + return label; + } + + if (element.hasAttribute("text")) { + label.setText(element.getAttribute("text")); + } + + return label; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java similarity index 80% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java index 023f3b70..04563ca6 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/PercentageBar.java @@ -1,167 +1,150 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.Flippable; -import com.github.stefvanschie.inventoryframework.pane.Orientable; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import com.github.stefvanschie.inventoryframework.pane.component.util.VariableBar; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -/** - * A percentage bar for a graphical interface into what amount of a whole is set. - * - * @since 0.5.0 - */ -public class PercentageBar extends VariableBar { - - public PercentageBar(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - } - - public PercentageBar(int x, int y, int length, int height) { - super(x, y, length, height); - } - - public PercentageBar(int length, int height) { - super(length, height); - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - if (x < 0 || x >= length || y < 0 || y >= height) { - return false; - } - - callOnClick(event); - - event.setCancelled(true); - - int newPaneOffsetX = paneOffsetX + getX(); - int newPaneOffsetY = paneOffsetY + getY(); - - return this.fillPane.click(gui, event, newPaneOffsetX, newPaneOffsetY, length, height) || - this.backgroundPane.click(gui, event, newPaneOffsetX, newPaneOffsetY, length, height); - } - - /** - * Sets the percentage of this bar. The percentage has to be in (0,1). If not, this method will throw an - * {@link IllegalArgumentException}. - * - * @param percentage the new percentage. - * @throws IllegalArgumentException when the percentage is out of range - * @since 0.5.0 - */ - public void setPercentage(float percentage) { - if (percentage < 0 || percentage > 1) { - throw new IllegalArgumentException("Percentage is out of range (0,1)"); - } - - this.value = percentage; - - if (orientation == Orientation.HORIZONTAL) { - this.fillPane.setLength(Math.round(getLength() * percentage)); - - if (flipHorizontally) { - this.fillPane.setX(getLength() - this.fillPane.getLength()); - } - } else if (orientation == Orientation.VERTICAL) { - this.fillPane.setHeight(Math.round(getHeight() * percentage)); - - if (flipVertically) { - this.fillPane.setY(getHeight() - this.fillPane.getHeight()); - } - } else { - throw new UnsupportedOperationException("Unknown orientation"); - } - } - - @NotNull - @Contract(pure = true) - @Override - public PercentageBar copy() { - PercentageBar percentageBar = new PercentageBar(x, y, length, height, getPriority()); - - applyContents(percentageBar); - - return percentageBar; - } - - /** - * Gets the percentage as a float in between (0,1) this bar is currently set at. - * - * @return the percentage - * @since 0.5.0 - */ - public float getPercentage() { - return value; - } - - /** - * Loads a percentage bar from a given element - * - * @param instance the instance class - * @param element the element - * @return the percentage bar - */ - @NotNull - @Contract(pure = true) - public static PercentageBar load(@NotNull Object instance, @NotNull Element element) { - int length; - int height; - - try { - length = Integer.parseInt(element.getAttribute("length")); - height = Integer.parseInt(element.getAttribute("height")); - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - - PercentageBar percentageBar = new PercentageBar(length, height); - - Pane.load(percentageBar, instance, element); - Orientable.load(percentageBar, element); - Flippable.load(percentageBar, element); - - if (element.hasAttribute("populate")) { - return percentageBar; - } - - if (element.hasAttribute("percentage")) { - try { - percentageBar.setPercentage(Float.parseFloat(element.getAttribute("percentage"))); - } catch (IllegalArgumentException exception) { - throw new XMLLoadException(exception); - } - } - - return percentageBar; - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.pane.Flippable; +import com.github.stefvanschie.inventoryframework.pane.Orientable; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import com.github.stefvanschie.inventoryframework.pane.component.util.VariableBar; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * A percentage bar for a graphical interface into what amount of a whole is set. + * + * @since 0.5.0 + */ +public class PercentageBar extends VariableBar { + + public PercentageBar(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + } + + public PercentageBar(int x, int y, int length, int height) { + super(x, y, length, height); + } + + public PercentageBar(int length, int height) { + super(length, height); + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % 9) - getX() - paneOffsetX; + int y = (slot / 9) - getY() - paneOffsetY; + + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + event.setCancelled(true); + + int newPaneOffsetX = paneOffsetX + getX(); + int newPaneOffsetY = paneOffsetY + getY(); + + return this.fillPane.click(gui, event, slot, newPaneOffsetX, newPaneOffsetY, length, height) || + this.backgroundPane.click(gui, event, slot, newPaneOffsetX, newPaneOffsetY, length, height); + } + + /** + * Sets the percentage of this bar. The percentage has to be in (0,1). If not, this method will throw an + * {@link IllegalArgumentException}. + * + * @param percentage the new percentage. + * @throws IllegalArgumentException when the percentage is out of range + * @since 0.5.0 + */ + public void setPercentage(float percentage) { + if (percentage < 0 || percentage > 1) { + throw new IllegalArgumentException("Percentage is out of range (0,1)"); + } + + this.value = percentage; + + if (orientation == Orientation.HORIZONTAL) { + this.fillPane.setLength(Math.round(getLength() * percentage)); + + if (flipHorizontally) { + this.fillPane.setX(getLength() - this.fillPane.getLength()); + } + } else if (orientation == Orientation.VERTICAL) { + this.fillPane.setHeight(Math.round(getHeight() * percentage)); + + if (flipVertically) { + this.fillPane.setY(getHeight() - this.fillPane.getHeight()); + } + } else { + throw new UnsupportedOperationException("Unknown orientation"); + } + } + + @NotNull + @Contract(pure = true) + @Override + public PercentageBar copy() { + PercentageBar percentageBar = new PercentageBar(x, y, length, height, getPriority()); + + applyContents(percentageBar); + + return percentageBar; + } + + /** + * Gets the percentage as a float in between (0,1) this bar is currently set at. + * + * @return the percentage + * @since 0.5.0 + */ + public float getPercentage() { + return value; + } + + /** + * Loads a percentage bar from a given element + * + * @param instance the instance class + * @param element the element + * @return the percentage bar + */ + @NotNull + @Contract(pure = true) + public static PercentageBar load(@NotNull Object instance, @NotNull Element element) { + int length; + int height; + + try { + length = Integer.parseInt(element.getAttribute("length")); + height = Integer.parseInt(element.getAttribute("height")); + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + + PercentageBar percentageBar = new PercentageBar(length, height); + + Pane.load(percentageBar, instance, element); + Orientable.load(percentageBar, element); + Flippable.load(percentageBar, element); + + if (element.hasAttribute("populate")) { + return percentageBar; + } + + if (element.hasAttribute("percentage")) { + try { + percentageBar.setPercentage(Float.parseFloat(element.getAttribute("percentage"))); + } catch (IllegalArgumentException exception) { + throw new XMLLoadException(exception); + } + } + + return percentageBar; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java similarity index 81% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java index a503a4e7..995554d2 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/Slider.java @@ -1,177 +1,160 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.Flippable; -import com.github.stefvanschie.inventoryframework.pane.Orientable; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import com.github.stefvanschie.inventoryframework.pane.component.util.VariableBar; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -/** - * A slider for a graphical interface into what amount of a whole is set. - * - * @since 0.5.0 - */ -public class Slider extends VariableBar { - - public Slider(int x, int y, int length, int height, @NotNull Priority priority) { - super(x, y, length, height, priority); - } - - public Slider(int x, int y, int length, int height) { - super(x, y, length, height); - } - - public Slider(int length, int height) { - super(length, height); - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - if (x < 0 || x >= length || y < 0 || y >= height) { - return false; - } - - callOnClick(event); - - int newPaneOffsetX = paneOffsetX + getX(); - int newPaneOffsetY = paneOffsetY + getY(); - - boolean success = this.fillPane.click(gui, event, newPaneOffsetX, newPaneOffsetY, length, height) || - this.backgroundPane.click(gui, event, newPaneOffsetX, newPaneOffsetY, length, height); - - if (orientation == Orientation.HORIZONTAL) { - setValue((float) (x + 1) / length); - } else if (orientation == Orientation.VERTICAL) { - setValue((float) (y + 1) / height); - } else { - throw new UnsupportedOperationException("Unknown orientation"); - } - - gui.update(); - - return success; - } - - /** - * Sets the value of this bar. The value has to be in (0,1). If not, this method will throw an - * {@link IllegalArgumentException}. - * - * @param value the new value. - * @throws IllegalArgumentException when the value is out of range - * @since 0.5.0 - */ - public void setValue(float value) { - if (value < 0 || value > 1) { - throw new IllegalArgumentException("Value is out of range (0,1)"); - } - - this.value = value; - - if (orientation == Orientation.HORIZONTAL) { - this.fillPane.setLength(Math.round(getLength() * value)); - - if (flipHorizontally) { - this.fillPane.setX(getLength() - this.fillPane.getLength()); - } - } else if (orientation == Orientation.VERTICAL) { - this.fillPane.setHeight(Math.round(getHeight() * value)); - - if (flipVertically) { - this.fillPane.setY(getHeight() - this.fillPane.getHeight()); - } - } else { - throw new UnsupportedOperationException("Unknown orientation"); - } - } - - @NotNull - @Contract(pure = true) - @Override - public Slider copy() { - Slider slider = new Slider(x, y, length, height, getPriority()); - - applyContents(slider); - - return slider; - } - - /** - * Gets the value as a float in between (0,1) this bar is currently set at. - * - * @return the value - * @since 0.5.0 - */ - public float getValue() { - return value; - } - - /** - * Loads a percentage bar from a given element - * - * @param instance the instance class - * @param element the element - * @return the percentage bar - */ - @NotNull - @Contract(pure = true) - public static Slider load(@NotNull Object instance, @NotNull Element element) { - int length; - int height; - - try { - length = Integer.parseInt(element.getAttribute("length")); - height = Integer.parseInt(element.getAttribute("height")); - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - - Slider slider = new Slider(length, height); - - Pane.load(slider, instance, element); - Orientable.load(slider, element); - Flippable.load(slider, element); - - if (element.hasAttribute("populate")) { - return slider; - } - - if (element.hasAttribute("value")) { - try { - slider.setValue(Float.parseFloat(element.getAttribute("value"))); - } catch (IllegalArgumentException exception) { - throw new XMLLoadException(exception); - } - } - - return slider; - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.pane.Flippable; +import com.github.stefvanschie.inventoryframework.pane.Orientable; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import com.github.stefvanschie.inventoryframework.pane.component.util.VariableBar; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +/** + * A slider for a graphical interface into what amount of a whole is set. + * + * @since 0.5.0 + */ +public class Slider extends VariableBar { + + public Slider(int x, int y, int length, int height, @NotNull Priority priority) { + super(x, y, length, height, priority); + } + + public Slider(int x, int y, int length, int height) { + super(x, y, length, height); + } + + public Slider(int length, int height) { + super(length, height); + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % 9) - getX() - paneOffsetX; + int y = (slot / 9) - getY() - paneOffsetY; + + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + int newPaneOffsetX = paneOffsetX + getX(); + int newPaneOffsetY = paneOffsetY + getY(); + + boolean success = this.fillPane.click(gui, event, slot, newPaneOffsetX, newPaneOffsetY, length, height) || + this.backgroundPane.click(gui, event, slot, newPaneOffsetX, newPaneOffsetY, length, height); + + if (orientation == Orientation.HORIZONTAL) { + setValue((float) (x + 1) / length); + } else if (orientation == Orientation.VERTICAL) { + setValue((float) (y + 1) / height); + } else { + throw new UnsupportedOperationException("Unknown orientation"); + } + + gui.update(); + + return success; + } + + /** + * Sets the value of this bar. The value has to be in (0,1). If not, this method will throw an + * {@link IllegalArgumentException}. + * + * @param value the new value. + * @throws IllegalArgumentException when the value is out of range + * @since 0.5.0 + */ + public void setValue(float value) { + if (value < 0 || value > 1) { + throw new IllegalArgumentException("Value is out of range (0,1)"); + } + + this.value = value; + + if (orientation == Orientation.HORIZONTAL) { + this.fillPane.setLength(Math.round(getLength() * value)); + + if (flipHorizontally) { + this.fillPane.setX(getLength() - this.fillPane.getLength()); + } + } else if (orientation == Orientation.VERTICAL) { + this.fillPane.setHeight(Math.round(getHeight() * value)); + + if (flipVertically) { + this.fillPane.setY(getHeight() - this.fillPane.getHeight()); + } + } else { + throw new UnsupportedOperationException("Unknown orientation"); + } + } + + @NotNull + @Contract(pure = true) + @Override + public Slider copy() { + Slider slider = new Slider(x, y, length, height, getPriority()); + + applyContents(slider); + + return slider; + } + + /** + * Gets the value as a float in between (0,1) this bar is currently set at. + * + * @return the value + * @since 0.5.0 + */ + public float getValue() { + return value; + } + + /** + * Loads a percentage bar from a given element + * + * @param instance the instance class + * @param element the element + * @return the percentage bar + */ + @NotNull + @Contract(pure = true) + public static Slider load(@NotNull Object instance, @NotNull Element element) { + int length; + int height; + + try { + length = Integer.parseInt(element.getAttribute("length")); + height = Integer.parseInt(element.getAttribute("height")); + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + + Slider slider = new Slider(length, height); + + Pane.load(slider, instance, element); + Orientable.load(slider, element); + Flippable.load(slider, element); + + if (element.hasAttribute("populate")) { + return slider; + } + + if (element.hasAttribute("value")) { + try { + slider.setValue(Float.parseFloat(element.getAttribute("value"))); + } catch (IllegalArgumentException exception) { + throw new XMLLoadException(exception); + } + } + + return slider; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java similarity index 77% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java index 416088a2..5f0c0040 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/ToggleButton.java @@ -1,224 +1,207 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import org.bukkit.Material; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.w3c.dom.Element; - -import java.util.Collection; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * A button that toggles between an enabled and disabled state. - * - * @since 0.5.0 - */ -public class ToggleButton extends Pane { - - /** - * The panes used for showing the enabled and disabled states - */ - private final OutlinePane enabledPane, disabledPane; - - /** - * Whether the button is enabled or disabled - */ - private boolean enabled = false; - - public ToggleButton(int x, int y, int length, int height, @NotNull Priority priority) { - this(x, y, length, height); - - setPriority(priority); - } - - public ToggleButton(int length, int height) { - super(length, height); - - this.enabledPane = new OutlinePane(0, 0, length, height); - this.enabledPane.addItem(new GuiItem(new ItemStack(Material.GREEN_STAINED_GLASS_PANE))); - this.enabledPane.setRepeat(true); - - this.disabledPane = new OutlinePane(0, 0, length, height); - this.disabledPane.addItem(new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE))); - this.disabledPane.setRepeat(true); - } - - public ToggleButton(int x, int y, int length, int height) { - this(length, height); - - setX(x); - setY(y); - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int newX = paneOffsetX + x; - int newY = paneOffsetY + y; - - int newMaxLength = Math.min(maxLength, length); - int newMaxHeight = Math.min(maxHeight, height); - - if (enabled) { - enabledPane.display(gui, inventory, playerInventory, newX, newY, newMaxLength, newMaxHeight); - } else { - disabledPane.display(gui, inventory, playerInventory, newX, newY, newMaxLength, newMaxHeight); - } - } - - @Override - public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int paneOffsetX, int paneOffsetY, - int maxLength, int maxHeight) { - int length = Math.min(this.length, maxLength); - int height = Math.min(this.height, maxHeight); - - int slot = event.getSlot(); - InventoryView view = event.getView(); - Inventory inventory = view.getInventory(event.getRawSlot()); - - int x, y; - - if (inventory != null && inventory.equals(view.getBottomInventory())) { - x = (slot % 9) - getX() - paneOffsetX; - y = ((slot / 9) + gui.getRows() - 1) - getY() - paneOffsetY; - - if (slot / 9 == 0) { - y = (gui.getRows() + 3) - getY() - paneOffsetY; - } - } else { - x = (slot % 9) - getX() - paneOffsetX; - y = (slot / 9) - getY() - paneOffsetY; - } - - //this isn't our item - if (x < 0 || x >= length || y < 0 || y >= height) { - return false; - } - - callOnClick(event); - - int newX = paneOffsetX + x; - int newY = paneOffsetY + y; - - if (enabled) { - enabledPane.click(gui, event, newX, newY, length, height); - } else { - disabledPane.click(gui, event, newX, newY, length, height); - } - - toggle(); - - gui.update(); - - return true; - } - - @NotNull - @Contract(pure = true) - @Override - public ToggleButton copy() { - ToggleButton toggleButton = new ToggleButton(x, y, length, height, getPriority()); - - toggleButton.setVisible(isVisible()); - toggleButton.onClick = onClick; - - toggleButton.uuid = uuid; - - toggleButton.setEnabledItem(enabledPane.getItems().get(0).copy()); - toggleButton.setDisabledItem(disabledPane.getItems().get(0).copy()); - - toggleButton.enabled = enabled; - - return toggleButton; - } - - /** - * Sets the item to use when the button is set to disabled - * - * @param item the disabled item - * @since 0.5.0 - */ - public void setDisabledItem(@NotNull GuiItem item) { - disabledPane.clear(); - - disabledPane.addItem(item); - } - - /** - * Sets the item to use when the button is set to enabled - * - * @param item the enabled item - * @since 0.5.0 - */ - public void setEnabledItem(@NotNull GuiItem item) { - enabledPane.clear(); - - enabledPane.addItem(item); - } - - @NotNull - @Override - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); - } - - @NotNull - @Override - public Collection getPanes() { - return Stream.of(enabledPane, disabledPane).collect(Collectors.toSet()); - } - - /** - * Toggles between the enabled and disabled states - * - * @since 0.5.0 - */ - public void toggle() { - enabled = !enabled; - } - - @Override - public void clear() {} - - /** - * Loads a toggle button from an XML element - * - * @param instance the instance class - * @param element the element - * @return the toggle button - * @since 0.5.0 - */ - @NotNull - @Contract(pure = true) - public static ToggleButton load(@NotNull Object instance, @NotNull Element element) { - int length, height; - - try { - length = Integer.parseInt(element.getAttribute("length")); - height = Integer.parseInt(element.getAttribute("height")); - } catch (NumberFormatException exception) { - throw new XMLLoadException(exception); - } - - ToggleButton toggleButton = new ToggleButton(length, height); - - Pane.load(toggleButton, instance, element); - - if (element.hasAttribute("enabled") && Boolean.parseBoolean(element.getAttribute("enabled"))) { - toggleButton.toggle(); - } - - return toggleButton; - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.w3c.dom.Element; + +import java.util.Collection; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * A button that toggles between an enabled and disabled state. + * + * @since 0.5.0 + */ +public class ToggleButton extends Pane { + + /** + * The panes used for showing the enabled and disabled states + */ + private final OutlinePane enabledPane, disabledPane; + + /** + * Whether the button is enabled or disabled + */ + private boolean enabled = false; + + public ToggleButton(int x, int y, int length, int height, @NotNull Priority priority) { + this(x, y, length, height); + + setPriority(priority); + } + + public ToggleButton(int length, int height) { + super(length, height); + + this.enabledPane = new OutlinePane(0, 0, length, height); + this.enabledPane.addItem(new GuiItem(new ItemStack(Material.GREEN_STAINED_GLASS_PANE))); + this.enabledPane.setRepeat(true); + + this.disabledPane = new OutlinePane(0, 0, length, height); + this.disabledPane.addItem(new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE))); + this.disabledPane.setRepeat(true); + } + + public ToggleButton(int x, int y, int length, int height) { + this(length, height); + + setX(x); + setY(y); + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int newX = paneOffsetX + x; + int newY = paneOffsetY + y; + + int newMaxLength = Math.min(maxLength, length); + int newMaxHeight = Math.min(maxHeight, height); + + if (enabled) { + enabledPane.display(inventoryComponent, newX, newY, newMaxLength, newMaxHeight); + } else { + disabledPane.display(inventoryComponent, newX, newY, newMaxLength, newMaxHeight); + } + } + + @Override + public boolean click(@NotNull Gui gui, @NotNull InventoryClickEvent event, int slot, int paneOffsetX, + int paneOffsetY, int maxLength, int maxHeight) { + int length = Math.min(this.length, maxLength); + int height = Math.min(this.height, maxHeight); + + int x = (slot % 9) - getX() - paneOffsetX; + int y = (slot / 9) - getY() - paneOffsetY; + + //this isn't our item + if (x < 0 || x >= length || y < 0 || y >= height) { + return false; + } + + callOnClick(event); + + int newX = paneOffsetX + x; + int newY = paneOffsetY + y; + + if (enabled) { + enabledPane.click(gui, event, slot, newX, newY, length, height); + } else { + disabledPane.click(gui, event, slot, newX, newY, length, height); + } + + toggle(); + + gui.update(); + + return true; + } + + @NotNull + @Contract(pure = true) + @Override + public ToggleButton copy() { + ToggleButton toggleButton = new ToggleButton(x, y, length, height, getPriority()); + + toggleButton.setVisible(isVisible()); + toggleButton.onClick = onClick; + + toggleButton.uuid = uuid; + + toggleButton.setEnabledItem(enabledPane.getItems().get(0).copy()); + toggleButton.setDisabledItem(disabledPane.getItems().get(0).copy()); + + toggleButton.enabled = enabled; + + return toggleButton; + } + + /** + * Sets the item to use when the button is set to disabled + * + * @param item the disabled item + * @since 0.5.0 + */ + public void setDisabledItem(@NotNull GuiItem item) { + disabledPane.clear(); + + disabledPane.addItem(item); + } + + /** + * Sets the item to use when the button is set to enabled + * + * @param item the enabled item + * @since 0.5.0 + */ + public void setEnabledItem(@NotNull GuiItem item) { + enabledPane.clear(); + + enabledPane.addItem(item); + } + + @NotNull + @Override + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Override + public Collection getPanes() { + return Stream.of(enabledPane, disabledPane).collect(Collectors.toSet()); + } + + /** + * Toggles between the enabled and disabled states + * + * @since 0.5.0 + */ + public void toggle() { + enabled = !enabled; + } + + @Override + public void clear() {} + + /** + * Loads a toggle button from an XML element + * + * @param instance the instance class + * @param element the element + * @return the toggle button + * @since 0.5.0 + */ + @NotNull + @Contract(pure = true) + public static ToggleButton load(@NotNull Object instance, @NotNull Element element) { + int length, height; + + try { + length = Integer.parseInt(element.getAttribute("length")); + height = Integer.parseInt(element.getAttribute("height")); + } catch (NumberFormatException exception) { + throw new XMLLoadException(exception); + } + + ToggleButton toggleButton = new ToggleButton(length, height); + + Pane.load(toggleButton, instance, element); + + if (element.hasAttribute("enabled") && Boolean.parseBoolean(element.getAttribute("enabled"))) { + toggleButton.toggle(); + } + + return toggleButton; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java similarity index 89% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java index ad8c15ee..54433248 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/component/util/VariableBar.java @@ -1,255 +1,251 @@ -package com.github.stefvanschie.inventoryframework.pane.component.util; - -import com.github.stefvanschie.inventoryframework.Gui; -import com.github.stefvanschie.inventoryframework.GuiItem; -import com.github.stefvanschie.inventoryframework.pane.Flippable; -import com.github.stefvanschie.inventoryframework.pane.Orientable; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import org.bukkit.Material; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * A variable bar for UI elements that require some sort of bar - * - * @since 0.5.0 - */ -public abstract class VariableBar extends Pane implements Orientable, Flippable { - - /** - * The green and the red parts of the slider - */ - @NotNull - protected final OutlinePane fillPane, backgroundPane; - - /** - * The value this slider is at. This is a value between 0 and 1 (both inclusive). - */ - protected float value; - - /** - * The orientation of the slider - */ - @NotNull - protected Orientation orientation; - - /** - * Whether the pane is flipped horizontally or vertically - */ - protected boolean flipHorizontally, flipVertically; - - protected VariableBar(int length, int height) { - super(length, height); - - this.value = 0F; - this.orientation = Orientation.HORIZONTAL; - - this.fillPane = new OutlinePane(x, y, 0, height); - this.backgroundPane = new OutlinePane(x, y, length, height); - - this.fillPane.addItem(new GuiItem(new ItemStack(Material.GREEN_STAINED_GLASS_PANE), - event -> event.setCancelled(true))); - this.backgroundPane.addItem(new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE), - event -> event.setCancelled(true))); - - this.fillPane.setRepeat(true); - this.backgroundPane.setRepeat(true); - } - - protected VariableBar(int x, int y, int length, int height, @NotNull Priority priority) { - this(length, height); - - setX(x); - setY(y); - - setPriority(priority); - } - - protected VariableBar(int x, int y, int length, int height) { - this(x, y, length, height, Priority.NORMAL); - } - - @Override - public void setLength(int length) { - super.setLength(length); - - if (orientation == Orientation.HORIZONTAL) { - this.fillPane.setLength(Math.round(length * value)); - - if (flipHorizontally) { - this.fillPane.setX(getLength() - this.fillPane.getLength()); - } - } else if (orientation == Orientation.VERTICAL) { - this.fillPane.setLength(length); - } else { - throw new UnsupportedOperationException("Unknown orientation"); - } - - this.backgroundPane.setLength(length); - } - - @Override - public void setHeight(int height) { - super.setHeight(height); - - if (orientation == Orientation.HORIZONTAL) { - this.fillPane.setHeight(height); - } else if (orientation == Orientation.VERTICAL) { - this.fillPane.setHeight(Math.round(height * value)); - - if (flipVertically) { - this.fillPane.setY(getHeight() - this.fillPane.getHeight()); - } - } else { - throw new UnsupportedOperationException("Unknown orientation"); - } - - this.backgroundPane.setHeight(height); - } - - /** - * Applies the contents of this variable bar onto the provided copy of this variable bar. This variable bar will not - * be modified. - * - * @param copy the copy of the variable bar - * @since 0.6.2 - */ - protected void applyContents(@NotNull VariableBar copy) { - copy.x = x; - copy.y = y; - copy.length = length; - copy.height = height; - copy.setPriority(getPriority()); - - copy.setVisible(isVisible()); - copy.onClick = onClick; - - copy.setFillItem(fillPane.getItems().get(0).copy()); - copy.setBackgroundItem(backgroundPane.getItems().get(0).copy()); - - copy.value = value; - copy.orientation = orientation; - - copy.flipHorizontally = flipHorizontally; - copy.flipVertically = flipVertically; - - copy.uuid = uuid; - } - - @Override - public void setOrientation(@NotNull Orientation orientation) { - this.orientation = orientation; - - if (orientation == Orientation.HORIZONTAL) { - fillPane.setLength(Math.round(getLength() * value)); - fillPane.setHeight(getHeight()); - } else if (orientation == Orientation.VERTICAL) { - fillPane.setLength(getLength()); - fillPane.setHeight(Math.round(getHeight() * value)); - } else { - throw new IllegalArgumentException("Unknown orientation"); - } - } - - @Override - public void display(@NotNull Gui gui, @NotNull Inventory inventory, @NotNull PlayerInventory playerInventory, - int paneOffsetX, int paneOffsetY, int maxLength, int maxHeight) { - int newPaneOffsetX = paneOffsetX + getX(); - int newPaneOffsetY = paneOffsetY + getY(); - int newMaxLength = Math.min(maxLength, getLength()); - int newMaxHeight = Math.min(maxHeight, getHeight()); - - this.backgroundPane.display(gui, inventory, playerInventory, newPaneOffsetX, newPaneOffsetY, newMaxLength, - newMaxHeight); - this.fillPane.display(gui, inventory, playerInventory, newPaneOffsetX, newPaneOffsetY, newMaxLength, - newMaxHeight); - } - - @Override - public void setX(int x) { - super.setX(x); - - this.fillPane.setX(x); - this.backgroundPane.setX(x); - } - - @Override - public void setY(int y) { - super.setY(y); - - this.fillPane.setY(y); - this.backgroundPane.setY(y); - } - - /** - * Sets the fill item (foreground) - * - * @param item the new item - * @since 0.5.0 - */ - public void setFillItem(@NotNull GuiItem item) { - fillPane.clear(); - - fillPane.addItem(item); - } - - /** - * Sets the background item - * - * @param item the new item - * @since 0.5.0 - */ - public void setBackgroundItem(@NotNull GuiItem item) { - backgroundPane.clear(); - - backgroundPane.addItem(item); - } - - @NotNull - @Override - public Collection getItems() { - return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); - } - - @NotNull - @Override - public Collection getPanes() { - return Stream.of(this.fillPane, this.backgroundPane).collect(Collectors.toSet()); - } - - @Override - public void flipHorizontally(boolean flipHorizontally) { - this.flipHorizontally = flipHorizontally; - } - - @Override - public void flipVertically(boolean flipVertically) { - this.flipVertically = flipVertically; - } - - @NotNull - @Override - public Orientation getOrientation() { - return orientation; - } - - @Override - public boolean isFlippedHorizontally() { - return flipHorizontally; - } - - @Override - public boolean isFlippedVertically() { - return flipVertically; - } - - @Override - public void clear() {} -} +package com.github.stefvanschie.inventoryframework.pane.component.util; + +import com.github.stefvanschie.inventoryframework.gui.InventoryComponent; +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.pane.Flippable; +import com.github.stefvanschie.inventoryframework.pane.Orientable; +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * A variable bar for UI elements that require some sort of bar + * + * @since 0.5.0 + */ +public abstract class VariableBar extends Pane implements Orientable, Flippable { + + /** + * The green and the red parts of the slider + */ + @NotNull + protected final OutlinePane fillPane, backgroundPane; + + /** + * The value this slider is at. This is a value between 0 and 1 (both inclusive). + */ + protected float value; + + /** + * The orientation of the slider + */ + @NotNull + protected Orientation orientation; + + /** + * Whether the pane is flipped horizontally or vertically + */ + protected boolean flipHorizontally, flipVertically; + + protected VariableBar(int length, int height) { + super(length, height); + + this.value = 0F; + this.orientation = Orientation.HORIZONTAL; + + this.fillPane = new OutlinePane(x, y, 0, height); + this.backgroundPane = new OutlinePane(x, y, length, height); + + this.fillPane.addItem(new GuiItem(new ItemStack(Material.GREEN_STAINED_GLASS_PANE), + event -> event.setCancelled(true))); + this.backgroundPane.addItem(new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE), + event -> event.setCancelled(true))); + + this.fillPane.setRepeat(true); + this.backgroundPane.setRepeat(true); + } + + protected VariableBar(int x, int y, int length, int height, @NotNull Priority priority) { + this(length, height); + + setX(x); + setY(y); + + setPriority(priority); + } + + protected VariableBar(int x, int y, int length, int height) { + this(x, y, length, height, Priority.NORMAL); + } + + @Override + public void setLength(int length) { + super.setLength(length); + + if (orientation == Orientation.HORIZONTAL) { + this.fillPane.setLength(Math.round(length * value)); + + if (flipHorizontally) { + this.fillPane.setX(getLength() - this.fillPane.getLength()); + } + } else if (orientation == Orientation.VERTICAL) { + this.fillPane.setLength(length); + } else { + throw new UnsupportedOperationException("Unknown orientation"); + } + + this.backgroundPane.setLength(length); + } + + @Override + public void setHeight(int height) { + super.setHeight(height); + + if (orientation == Orientation.HORIZONTAL) { + this.fillPane.setHeight(height); + } else if (orientation == Orientation.VERTICAL) { + this.fillPane.setHeight(Math.round(height * value)); + + if (flipVertically) { + this.fillPane.setY(getHeight() - this.fillPane.getHeight()); + } + } else { + throw new UnsupportedOperationException("Unknown orientation"); + } + + this.backgroundPane.setHeight(height); + } + + /** + * Applies the contents of this variable bar onto the provided copy of this variable bar. This variable bar will not + * be modified. + * + * @param copy the copy of the variable bar + * @since 0.6.2 + */ + protected void applyContents(@NotNull VariableBar copy) { + copy.x = x; + copy.y = y; + copy.length = length; + copy.height = height; + copy.setPriority(getPriority()); + + copy.setVisible(isVisible()); + copy.onClick = onClick; + + copy.setFillItem(fillPane.getItems().get(0).copy()); + copy.setBackgroundItem(backgroundPane.getItems().get(0).copy()); + + copy.value = value; + copy.orientation = orientation; + + copy.flipHorizontally = flipHorizontally; + copy.flipVertically = flipVertically; + + copy.uuid = uuid; + } + + @Override + public void setOrientation(@NotNull Orientation orientation) { + this.orientation = orientation; + + if (orientation == Orientation.HORIZONTAL) { + fillPane.setLength(Math.round(getLength() * value)); + fillPane.setHeight(getHeight()); + } else if (orientation == Orientation.VERTICAL) { + fillPane.setLength(getLength()); + fillPane.setHeight(Math.round(getHeight() * value)); + } else { + throw new IllegalArgumentException("Unknown orientation"); + } + } + + @Override + public void display(@NotNull InventoryComponent inventoryComponent, int paneOffsetX, int paneOffsetY, int maxLength, + int maxHeight) { + int newPaneOffsetX = paneOffsetX + getX(); + int newPaneOffsetY = paneOffsetY + getY(); + int newMaxLength = Math.min(maxLength, getLength()); + int newMaxHeight = Math.min(maxHeight, getHeight()); + + this.backgroundPane.display(inventoryComponent, newPaneOffsetX, newPaneOffsetY, newMaxLength, newMaxHeight); + this.fillPane.display(inventoryComponent, newPaneOffsetX, newPaneOffsetY, newMaxLength, newMaxHeight); + } + + @Override + public void setX(int x) { + super.setX(x); + + this.fillPane.setX(x); + this.backgroundPane.setX(x); + } + + @Override + public void setY(int y) { + super.setY(y); + + this.fillPane.setY(y); + this.backgroundPane.setY(y); + } + + /** + * Sets the fill item (foreground) + * + * @param item the new item + * @since 0.5.0 + */ + public void setFillItem(@NotNull GuiItem item) { + fillPane.clear(); + + fillPane.addItem(item); + } + + /** + * Sets the background item + * + * @param item the new item + * @since 0.5.0 + */ + public void setBackgroundItem(@NotNull GuiItem item) { + backgroundPane.clear(); + + backgroundPane.addItem(item); + } + + @NotNull + @Override + public Collection getItems() { + return getPanes().stream().flatMap(pane -> pane.getItems().stream()).collect(Collectors.toSet()); + } + + @NotNull + @Override + public Collection getPanes() { + return Stream.of(this.fillPane, this.backgroundPane).collect(Collectors.toSet()); + } + + @Override + public void flipHorizontally(boolean flipHorizontally) { + this.flipHorizontally = flipHorizontally; + } + + @Override + public void flipVertically(boolean flipVertically) { + this.flipVertically = flipVertically; + } + + @NotNull + @Override + public Orientation getOrientation() { + return orientation; + } + + @Override + public boolean isFlippedHorizontally() { + return flipHorizontally; + } + + @Override + public boolean isFlippedVertically() { + return flipVertically; + } + + @Override + public void clear() {} +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java similarity index 95% rename from src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java index 612b5258..1e8030f5 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/pane/util/Mask.java @@ -1,144 +1,144 @@ -package com.github.stefvanschie.inventoryframework.pane.util; - -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; - -/** - * A mask for {@link OutlinePane}s that specifies in which positions the items should be placed. Objects of this class - * are immutable. - * - * @since 0.5.16 - */ -public class Mask { - - /** - * A two-dimensional array of booleans indicating which slots are 'enabled' and which ones are 'disabled'. This - * two-dimensional array is constructed in a row-major order fashion. - */ - private final boolean[][] mask; - - /** - * Creates a mask based on the strings provided. Each string is a row for the mask and each character is a cell of - * that row that indicates a slot for the mask. When the character is a 0, the slot will be considered 'disabled'; - * when the character is a 1, the slot will be considered 'enabled'. When there are any other characters in the - * string, an {@link IllegalArgumentException} will be thrown. When multiple strings have a different length an - * {@link IllegalArgumentException} will be thrown. - * - * @param mask a var-arg of strings that represent this mask - * @throws IllegalArgumentException when a string contains an illegal character or when strings have different - * lengths - * @since 0.5.16 - */ - public Mask(@NotNull String... mask) { - this.mask = new boolean[mask.length][mask[0].length()]; - - for (int row = 0; row < mask.length; row++) { - int length = mask[row].length(); - - if (length != this.mask[row].length) { - throw new IllegalArgumentException("Lengths of each string should be equal"); - } - - for (int column = 0; column < length; column++) { - char character = mask[row].charAt(column); - - if (character == '0') { - this.mask[row][column] = false; - } else if (character == '1') { - this.mask[row][column] = true; - } else { - throw new IllegalArgumentException("Strings may only contain '0' and '1'"); - } - } - } - } - - /** - * Returns the amount of slots in this mask that are 'enabled'. - * - * @return amount of enabled slots - * @since 0.5.16 - */ - public int amountOfEnabledSlots() { - int amount = 0; - - for (boolean[] row : mask) { - for (boolean cell : row) { - if (cell) { - amount++; - } - } - } - - return amount; - } - - /** - * Gets the column of this mask at the specified index. The values indicate the state of the slots for that slot: - * {@literal true} indicates that the slot is 'enabled'; {@literal false} indicates that the slot is 'disabled'. The - * returned array is a copy of the original; modifications to the returned array will not be reflected in the mask. - * - * @param index the column index - * @return the column of this mask - * @since 0.5.16 - */ - public boolean[] getColumn(int index) { - boolean[] column = new boolean[mask[0].length]; - - for (int i = 0; i < getHeight(); i++) { - column[i] = mask[i][index]; - } - - return column; - } - - /** - * Gets the row of this mask at the specified index. The values indicate the state of the slots for that slot: - * {@literal true} indicates that the slot is 'enabled'; {@literal false} indicates that the slot is 'disabled'. The - * returned array is a copy of the original; modifications to the returned array will not be reflected in the mask. - * - * @param index the row index - * @return the row of this mask - * @since 0.5.16 - */ - public boolean[] getRow(int index) { - boolean[] row = mask[index]; - - return Arrays.copyOf(row, row.length); - } - - /** - * Gets whether the slot at the specified row and column is 'enabled' or not. This returns {@literal true} if it is - * 'enabled' and {@literal false} if it is 'disabled'. - * - * @param x the x coordinate of the slot - * @param y the y coordinate of the slot - * @return whether the slot is enabled or not - * @since 0.5.16 - */ - public boolean isEnabled(int x, int y) { - return mask[y][x]; - } - - /** - * Gets the length of this mask - * - * @return the length - * @since 0.5.16 - */ - public int getLength() { - return mask[0].length; - } - - /** - * Gets the height of this mask - * - * @return the height - * @since 0.5.16 - */ - public int getHeight() { - return mask.length; - } -} +package com.github.stefvanschie.inventoryframework.pane.util; + +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +/** + * A mask for {@link OutlinePane}s that specifies in which positions the items should be placed. Objects of this class + * are immutable. + * + * @since 0.5.16 + */ +public class Mask { + + /** + * A two-dimensional array of booleans indicating which slots are 'enabled' and which ones are 'disabled'. This + * two-dimensional array is constructed in a row-major order fashion. + */ + private final boolean[][] mask; + + /** + * Creates a mask based on the strings provided. Each string is a row for the mask and each character is a cell of + * that row that indicates a slot for the mask. When the character is a 0, the slot will be considered 'disabled'; + * when the character is a 1, the slot will be considered 'enabled'. When there are any other characters in the + * string, an {@link IllegalArgumentException} will be thrown. When multiple strings have a different length an + * {@link IllegalArgumentException} will be thrown. + * + * @param mask a var-arg of strings that represent this mask + * @throws IllegalArgumentException when a string contains an illegal character or when strings have different + * lengths + * @since 0.5.16 + */ + public Mask(@NotNull String... mask) { + this.mask = new boolean[mask.length][mask.length == 0 ? 0 : mask[0].length()]; + + for (int row = 0; row < mask.length; row++) { + int length = mask[row].length(); + + if (length != this.mask[row].length) { + throw new IllegalArgumentException("Lengths of each string should be equal"); + } + + for (int column = 0; column < length; column++) { + char character = mask[row].charAt(column); + + if (character == '0') { + this.mask[row][column] = false; + } else if (character == '1') { + this.mask[row][column] = true; + } else { + throw new IllegalArgumentException("Strings may only contain '0' and '1'"); + } + } + } + } + + /** + * Returns the amount of slots in this mask that are 'enabled'. + * + * @return amount of enabled slots + * @since 0.5.16 + */ + public int amountOfEnabledSlots() { + int amount = 0; + + for (boolean[] row : mask) { + for (boolean cell : row) { + if (cell) { + amount++; + } + } + } + + return amount; + } + + /** + * Gets the column of this mask at the specified index. The values indicate the state of the slots for that slot: + * {@literal true} indicates that the slot is 'enabled'; {@literal false} indicates that the slot is 'disabled'. The + * returned array is a copy of the original; modifications to the returned array will not be reflected in the mask. + * + * @param index the column index + * @return the column of this mask + * @since 0.5.16 + */ + public boolean[] getColumn(int index) { + boolean[] column = new boolean[mask[0].length]; + + for (int i = 0; i < getHeight(); i++) { + column[i] = mask[i][index]; + } + + return column; + } + + /** + * Gets the row of this mask at the specified index. The values indicate the state of the slots for that slot: + * {@literal true} indicates that the slot is 'enabled'; {@literal false} indicates that the slot is 'disabled'. The + * returned array is a copy of the original; modifications to the returned array will not be reflected in the mask. + * + * @param index the row index + * @return the row of this mask + * @since 0.5.16 + */ + public boolean[] getRow(int index) { + boolean[] row = mask[index]; + + return Arrays.copyOf(row, row.length); + } + + /** + * Gets whether the slot at the specified row and column is 'enabled' or not. This returns {@literal true} if it is + * 'enabled' and {@literal false} if it is 'disabled'. + * + * @param x the x coordinate of the slot + * @param y the y coordinate of the slot + * @return whether the slot is enabled or not + * @since 0.5.16 + */ + public boolean isEnabled(int x, int y) { + return mask[y][x]; + } + + /** + * Gets the length of this mask + * + * @return the length + * @since 0.5.16 + */ + public int getLength() { + return mask[0].length; + } + + /** + * Gets the height of this mask + * + * @return the height + * @since 0.5.16 + */ + public int getHeight() { + return mask.length; + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java index 3701eebe..1f2b7579 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/CSVUtil.java @@ -1,99 +1,99 @@ -package com.github.stefvanschie.inventoryframework.util; - -import org.apache.commons.lang.StringUtils; -import org.jetbrains.annotations.NotNull; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A utility class for reading csv files - * - * @since 0.5.0 - */ -public final class CSVUtil { - - /** - * A private constructor to ensure this utility class is never instantiated - * - * @since 0.5.0 - */ - private CSVUtil() {} - - private static final Pattern UNICODE_CHARACTER_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})"); - - /** - * Reads the entire file and returns it as a list of strings. - * - * @param inputStream the input stream to read from - * @return a list of strings containing the values inside the file - * @throws IOException when reading fails for any reason - * @since 0.5.0 - */ - @NotNull - public static List readAll(@NotNull InputStream inputStream) throws IOException { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { - List strings = new ArrayList<>(); - String line; - - while ((line = reader.readLine()) != null) { - if (line.isEmpty()) { - continue; - } - - List splittingIndices = new ArrayList<>(); - char[] chars = line.toCharArray(); - boolean quote = false; - - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '"') { - quote = !quote; - } else if (chars[i] == ',' && !quote) { - splittingIndices.add(i); - } - } - - String[] array = new String[splittingIndices.size() + 1]; - - for (int i = 0; i < splittingIndices.size() + 1; i++) { - array[i] = line.substring(i - 1 < 0 ? 0 : splittingIndices.get(i - 1) + 1, i == splittingIndices.size() ? line.length() : splittingIndices.get(i)); - } - - for (int i = 0; i < array.length; i++) { - array[i] = array[i].trim(); - - if (array[i].startsWith("\"") && array[i].endsWith("\"")) { - array[i] = array[i].substring(1, array[i].length() - 1); - } - - array[i] = StringUtils.replace(array[i], "\"\"", "\""); - //Restore original code (array[i] = array[i].replace("\"\"", "\"")) - //once we update to Java 11, where it receives the current, faster implementation - - //replace unicode characters - Matcher matcher = UNICODE_CHARACTER_PATTERN.matcher(array[i]); - StringBuffer buf = new StringBuffer(array[i].length()); - - while (matcher.find()) { - String character = String.valueOf((char) Integer.parseInt(matcher.group(1), 16)); - matcher.appendReplacement(buf, Matcher.quoteReplacement(character)); - } - - matcher.appendTail(buf); - - array[i] = buf.toString(); - } - - strings.add(array); - } - - return strings; - } - } -} +package com.github.stefvanschie.inventoryframework.util; + +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A utility class for reading csv files + * + * @since 0.5.0 + */ +public final class CSVUtil { + + /** + * A private constructor to ensure this utility class is never instantiated + * + * @since 0.5.0 + */ + private CSVUtil() {} + + private static final Pattern UNICODE_CHARACTER_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})"); + + /** + * Reads the entire file and returns it as a list of strings. + * + * @param inputStream the input stream to read from + * @return a list of strings containing the values inside the file + * @throws IOException when reading fails for any reason + * @since 0.5.0 + */ + @NotNull + public static List readAll(@NotNull InputStream inputStream) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { + List strings = new ArrayList<>(); + String line; + + while ((line = reader.readLine()) != null) { + if (line.isEmpty()) { + continue; + } + + List splittingIndices = new ArrayList<>(); + char[] chars = line.toCharArray(); + boolean quote = false; + + for (int i = 0; i < chars.length; i++) { + if (chars[i] == '"') { + quote = !quote; + } else if (chars[i] == ',' && !quote) { + splittingIndices.add(i); + } + } + + String[] array = new String[splittingIndices.size() + 1]; + + for (int i = 0; i < splittingIndices.size() + 1; i++) { + array[i] = line.substring(i - 1 < 0 ? 0 : splittingIndices.get(i - 1) + 1, i == splittingIndices.size() ? line.length() : splittingIndices.get(i)); + } + + for (int i = 0; i < array.length; i++) { + array[i] = array[i].trim(); + + if (array[i].startsWith("\"") && array[i].endsWith("\"")) { + array[i] = array[i].substring(1, array[i].length() - 1); + } + + array[i] = StringUtils.replace(array[i], "\"\"", "\""); + //Restore original code (array[i] = array[i].replace("\"\"", "\"")) + //once we update to Java 11, where it receives the current, faster implementation + + //replace unicode characters + Matcher matcher = UNICODE_CHARACTER_PATTERN.matcher(array[i]); + StringBuffer buf = new StringBuffer(array[i].length()); + + while (matcher.find()) { + String character = String.valueOf((char) Integer.parseInt(matcher.group(1), 16)); + matcher.appendReplacement(buf, Matcher.quoteReplacement(character)); + } + + matcher.appendTail(buf); + + array[i] = buf.toString(); + } + + strings.add(array); + } + + return strings; + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java index f4c2b2d7..57141b03 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/GeometryUtil.java @@ -1,60 +1,60 @@ -package com.github.stefvanschie.inventoryframework.util; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.AbstractMap; -import java.util.Map; - -public class GeometryUtil { - - /** - * Calculates a clockwise rotation across a two dimensional grid - * - * @param x the standard x coordinate - * @param y the standard y coordinate - * @param length the length of the grid - * @param height the height of the grid - * @param rotation the rotation in degrees - * @return a pair of new coordinates, with the x coordinate being the key and the y coordinate being the value - */ - @NotNull - @Contract(pure = true) - public static Map.Entry processClockwiseRotation(int x, int y, int length, int height, - int rotation) { - int newX = x, newY = y; - - if (rotation == 90) { - newX = height - 1 - y; - //noinspection SuspiciousNameCombination - newY = x; - } else if (rotation == 180) { - newX = length - 1 - x; - newY = height - 1 - y; - } else if (rotation == 270) { - //noinspection SuspiciousNameCombination - newX = y; - newY = length - 1 - x; - } - - return new AbstractMap.SimpleEntry<>(newX, newY); - } - - /** - * Calculates a counter clockwise rotation across a two dimensional grid. This is the same as calling - * {@link #processClockwiseRotation(int, int, int, int, int)} with 360 - rotation as the rotation. - * - * @param x the standard x coordinate - * @param y the standard y coordinate - * @param length the length of the grid - * @param height the height of the grid - * @param rotation the rotation in degrees - * @return a pair of new coordinates, with the x coordinate being the key and the y coordinate being the value - */ - @NotNull - @Contract(pure = true) - public static Map.Entry processCounterClockwiseRotation(int x, int y, int length, int height, - int rotation) { - return processClockwiseRotation(x, y, length, height, 360 - rotation); - } -} +package com.github.stefvanschie.inventoryframework.util; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.AbstractMap; +import java.util.Map; + +public class GeometryUtil { + + /** + * Calculates a clockwise rotation across a two dimensional grid + * + * @param x the standard x coordinate + * @param y the standard y coordinate + * @param length the length of the grid + * @param height the height of the grid + * @param rotation the rotation in degrees + * @return a pair of new coordinates, with the x coordinate being the key and the y coordinate being the value + */ + @NotNull + @Contract(pure = true) + public static Map.Entry processClockwiseRotation(int x, int y, int length, int height, + int rotation) { + int newX = x, newY = y; + + if (rotation == 90) { + newX = height - 1 - y; + //noinspection SuspiciousNameCombination + newY = x; + } else if (rotation == 180) { + newX = length - 1 - x; + newY = height - 1 - y; + } else if (rotation == 270) { + //noinspection SuspiciousNameCombination + newX = y; + newY = length - 1 - x; + } + + return new AbstractMap.SimpleEntry<>(newX, newY); + } + + /** + * Calculates a counter clockwise rotation across a two dimensional grid. This is the same as calling + * {@link #processClockwiseRotation(int, int, int, int, int)} with 360 - rotation as the rotation. + * + * @param x the standard x coordinate + * @param y the standard y coordinate + * @param length the length of the grid + * @param height the height of the grid + * @param rotation the rotation in degrees + * @return a pair of new coordinates, with the x coordinate being the key and the y coordinate being the value + */ + @NotNull + @Contract(pure = true) + public static Map.Entry processCounterClockwiseRotation(int x, int y, int length, int height, + int rotation) { + return processClockwiseRotation(x, y, length, height, 360 - rotation); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java index 30e0e4c9..b28b82bc 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/SkullUtil.java @@ -1,67 +1,67 @@ -package com.github.stefvanschie.inventoryframework.util; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Field; -import java.util.Base64; -import java.util.Objects; -import java.util.UUID; - -/** - * A utility class for working with skulls - * - * @since 0.5.0 - */ -public final class SkullUtil { - - /** - * A private constructor to ensure this class isn't instantiated - * - * @since 0.5.0 - */ - private SkullUtil() {} - - /** - * Gets a skull from the specified id. The id is the value from the textures.minecraft.net website after the last - * '/' character. - * - * @param id the skull id - * @return the skull item - * @since 0.5.0 - */ - @NotNull - public static ItemStack getSkull(@NotNull String id) { - ItemStack item = new ItemStack(Material.PLAYER_HEAD); - ItemMeta itemMeta = Objects.requireNonNull(item.getItemMeta()); - setSkull(itemMeta, id); - item.setItemMeta(itemMeta); - return item; - } - - /** - * Sets the skull of an existing {@link ItemMeta} from the specified id. - * The id is the value from the textures.minecraft.net website after the last '/' character. - * - * @param meta the meta to change - * @param id the skull id - */ - public static void setSkull(@NotNull ItemMeta meta, @NotNull String id) { - GameProfile profile = new GameProfile(UUID.randomUUID(), null); - byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", - "http://textures.minecraft.net/texture/" + id).getBytes()); - profile.getProperties().put("textures", new Property("textures", new String(encodedData))); - - try { - Field profileField = meta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(meta, profile); - } catch (NoSuchFieldException | SecurityException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} +package com.github.stefvanschie.inventoryframework.util; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Field; +import java.util.Base64; +import java.util.Objects; +import java.util.UUID; + +/** + * A utility class for working with skulls + * + * @since 0.5.0 + */ +public final class SkullUtil { + + /** + * A private constructor to ensure this class isn't instantiated + * + * @since 0.5.0 + */ + private SkullUtil() {} + + /** + * Gets a skull from the specified id. The id is the value from the textures.minecraft.net website after the last + * '/' character. + * + * @param id the skull id + * @return the skull item + * @since 0.5.0 + */ + @NotNull + public static ItemStack getSkull(@NotNull String id) { + ItemStack item = new ItemStack(Material.PLAYER_HEAD); + ItemMeta itemMeta = Objects.requireNonNull(item.getItemMeta()); + setSkull(itemMeta, id); + item.setItemMeta(itemMeta); + return item; + } + + /** + * Sets the skull of an existing {@link ItemMeta} from the specified id. + * The id is the value from the textures.minecraft.net website after the last '/' character. + * + * @param meta the meta to change + * @param id the skull id + */ + public static void setSkull(@NotNull ItemMeta meta, @NotNull String id) { + GameProfile profile = new GameProfile(UUID.randomUUID(), null); + byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", + "http://textures.minecraft.net/texture/" + id).getBytes()); + profile.getProperties().put("textures", new Property("textures", new String(encodedData))); + + try { + Field profileField = meta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(meta, profile); + } catch (NoSuchFieldException | SecurityException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java similarity index 96% rename from src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java index 1ef53cd4..537bd34c 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/UUIDTagType.java @@ -1,58 +1,58 @@ -package com.github.stefvanschie.inventoryframework.util; - -import org.bukkit.persistence.PersistentDataAdapterContext; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; - -import java.nio.ByteBuffer; -import java.util.UUID; - -/** - * A {@link PersistentDataType} implementation that adds support for {@link UUID}s. - * - * @since 0.6.0 - */ -public final class UUIDTagType implements PersistentDataType { - - /** - * The one and only instance of this class. - * Since this class stores no state information (apart from this field), - * the usage of a single instance is safe even across multiple threads. - */ - public static final UUIDTagType INSTANCE = new UUIDTagType(); - - /** - * A private constructor so that only a single instance of this class can exist. - */ - private UUIDTagType() {} - - @NotNull - @Override - public Class getPrimitiveType() { - return byte[].class; - } - - @NotNull - @Override - public Class getComplexType() { - return UUID.class; - } - - @NotNull - @Override - public byte[] toPrimitive(@NotNull UUID complex, @NotNull PersistentDataAdapterContext context) { - ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); - buffer.putLong(complex.getMostSignificantBits()); - buffer.putLong(complex.getLeastSignificantBits()); - return buffer.array(); - } - - @NotNull - @Override - public UUID fromPrimitive(@NotNull byte[] primitive, @NotNull PersistentDataAdapterContext context) { - ByteBuffer buffer = ByteBuffer.wrap(primitive); - long most = buffer.getLong(); - long least = buffer.getLong(); - return new UUID(most, least); - } -} +package com.github.stefvanschie.inventoryframework.util; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.nio.ByteBuffer; +import java.util.UUID; + +/** + * A {@link PersistentDataType} implementation that adds support for {@link UUID}s. + * + * @since 0.6.0 + */ +public final class UUIDTagType implements PersistentDataType { + + /** + * The one and only instance of this class. + * Since this class stores no state information (apart from this field), + * the usage of a single instance is safe even across multiple threads. + */ + public static final UUIDTagType INSTANCE = new UUIDTagType(); + + /** + * A private constructor so that only a single instance of this class can exist. + */ + private UUIDTagType() {} + + @NotNull + @Override + public Class getPrimitiveType() { + return byte[].class; + } + + @NotNull + @Override + public Class getComplexType() { + return UUID.class; + } + + @NotNull + @Override + public byte[] toPrimitive(@NotNull UUID complex, @NotNull PersistentDataAdapterContext context) { + ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); + buffer.putLong(complex.getMostSignificantBits()); + buffer.putLong(complex.getLeastSignificantBits()); + return buffer.array(); + } + + @NotNull + @Override + public UUID fromPrimitive(@NotNull byte[] primitive, @NotNull PersistentDataAdapterContext context) { + ByteBuffer buffer = ByteBuffer.wrap(primitive); + long most = buffer.getLong(); + long least = buffer.getLong(); + return new UUID(most, least); + } +} diff --git a/src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java similarity index 97% rename from src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java rename to IF/src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java index f661f073..ede880db 100644 --- a/src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/XMLUtil.java @@ -1,82 +1,82 @@ -package com.github.stefvanschie.inventoryframework.util; - -import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; -import com.github.stefvanschie.inventoryframework.exception.XMLReflectionException; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Element; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.function.Consumer; - -public class XMLUtil { - - /** - * Loads an event consumer from the given instance and element - * - * @param instance the object instance - * @param element the element - * @param eventType the type of the event - * @param name the name of the attribute - * @return the consumer to be called on click - * @param the type of the event - */ - @Nullable - @Contract(pure = true) - public static Consumer loadOnEventAttribute(@NotNull Object instance, @NotNull Element element, - @NotNull Class eventType, @NotNull String name) { - String attribute = element.getAttribute(name); - for (Method method : instance.getClass().getMethods()) { - if (!method.getName().equals(attribute)) - continue; - - int parameterCount = method.getParameterCount(); - boolean eventParameter; - if (parameterCount == 0) { - eventParameter = false; - } else if (parameterCount == 1 && - eventType.isAssignableFrom(method.getParameterTypes()[0])) { - eventParameter = true; - } else { - continue; - } - - return event -> { - try { - method.setAccessible(true); - if (eventParameter) { - method.invoke(instance, event); - } else { - method.invoke(instance); - } - } catch (IllegalAccessException | InvocationTargetException e) { - throw new XMLReflectionException(e); - } - }; - } - - return null; - } - - /** - * Sets a field from the given instance and element to the specified value - * - * @param instance the class instance the field is located in - * @param element the element from which the field is specified - * @param value the field's new value - */ - public static void loadFieldAttribute(@NotNull Object instance, @NotNull Element element, @Nullable Object value) { - try { - Field field = instance.getClass().getField(element.getAttribute("field")); - - field.setAccessible(true); - field.set(instance, value); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new XMLLoadException(e); - } - } -} +package com.github.stefvanschie.inventoryframework.util; + +import com.github.stefvanschie.inventoryframework.exception.XMLLoadException; +import com.github.stefvanschie.inventoryframework.exception.XMLReflectionException; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Element; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.function.Consumer; + +public class XMLUtil { + + /** + * Loads an event consumer from the given instance and element + * + * @param instance the object instance + * @param element the element + * @param eventType the type of the event + * @param name the name of the attribute + * @return the consumer to be called on click + * @param the type of the event + */ + @Nullable + @Contract(pure = true) + public static Consumer loadOnEventAttribute(@NotNull Object instance, @NotNull Element element, + @NotNull Class eventType, @NotNull String name) { + String attribute = element.getAttribute(name); + for (Method method : instance.getClass().getMethods()) { + if (!method.getName().equals(attribute)) + continue; + + int parameterCount = method.getParameterCount(); + boolean eventParameter; + if (parameterCount == 0) { + eventParameter = false; + } else if (parameterCount == 1 && + eventType.isAssignableFrom(method.getParameterTypes()[0])) { + eventParameter = true; + } else { + continue; + } + + return event -> { + try { + method.setAccessible(true); + if (eventParameter) { + method.invoke(instance, event); + } else { + method.invoke(instance); + } + } catch (IllegalAccessException | InvocationTargetException e) { + throw new XMLReflectionException(e); + } + }; + } + + return null; + } + + /** + * Sets a field from the given instance and element to the specified value + * + * @param instance the class instance the field is located in + * @param element the element from which the field is specified + * @param value the field's new value + */ + public static void loadFieldAttribute(@NotNull Object instance, @NotNull Element element, @Nullable Object value) { + try { + Field field = instance.getClass().getField(element.getAttribute("field")); + + field.setAccessible(true); + field.set(instance, value); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new XMLLoadException(e); + } + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java new file mode 100644 index 00000000..aa2a2edc --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/Version.java @@ -0,0 +1,77 @@ +package com.github.stefvanschie.inventoryframework.util.version; + +import com.github.stefvanschie.inventoryframework.exception.UnsupportedVersionException; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +/** + * The different supported NMS versions + * + * @since 0.8.0 + */ +public enum Version { + + /** + * Version 1.14 R1 + * + * @since 0.8.0 + */ + V1_14_R1, + + /** + * Version 1.15 R1 + * + * @since 0.8.0 + */ + V1_15_R1, + + /** + * Version 1.16 R1 + * + * @since 0.8.0 + */ + V1_16_R1, + + /** + * Version 1.16 R2 + * + * @since 0.8.0 + */ + V1_16_R2, + + /** + * Version 1.16 R3 + * + * @since 0.8.0 + */ + V1_16_R3; + + /** + * Gets the version currently being used. If the used version is not supported, an + * {@link UnsupportedVersionException} will be thrown. + * + * @return the version of the current instance + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static Version getVersion() { + String version = Bukkit.getServer().getClass().getPackage().getName(); + + switch (version.substring(version.lastIndexOf('.') + 1)) { + case "v1_14_R1": + return V1_14_R1; + case "v1_15_R1": + return V1_15_R1; + case "v1_16_R1": + return V1_16_R1; + case "v1_16_R2": + return V1_16_R2; + case "v1_16_R3": + return V1_16_R3; + default: + throw new UnsupportedVersionException("The server version provided is not supported"); + } + } +} diff --git a/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java new file mode 100644 index 00000000..c4f108e1 --- /dev/null +++ b/IF/src/main/java/com/github/stefvanschie/inventoryframework/util/version/VersionMatcher.java @@ -0,0 +1,291 @@ +package com.github.stefvanschie.inventoryframework.util.version; + +import com.github.stefvanschie.inventoryframework.abstraction.*; +import com.github.stefvanschie.inventoryframework.exception.UnsupportedVersionException; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationTargetException; +import java.util.EnumMap; + +/** + * Utility class containing versioning related methods. + * + * @since 0.8.0 + */ +public class VersionMatcher { + + /** + * The different anvil inventories for different versions + */ + private static final EnumMap> ANVIL_INVENTORIES; + + /** + * The different beacon inventories for different versions + */ + private static final EnumMap> BEACON_INVENTORIES; + + /** + * The different cartography table inventories for different versions + */ + private static final EnumMap> CARTOGRAPHY_TABLE_INVENTORIES; + + /** + * The different enchanting table inventories for different versions + */ + private static final EnumMap> ENCHANTING_TABLE_INVENTORIES; + + /** + * The different grindstone inventories for different versions + */ + private static final EnumMap> GRINDSTONE_INVENTORIES; + + /** + * The different smithing table inventories for different versions + */ + private static final EnumMap> SMITHING_TABLE_INVENTORIES; + + /** + * The different stonecutter inventories for different versions + */ + private static final EnumMap> STONECUTTER_INVENTORIES; + + /** + * Gets a new anvil inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the anvil inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static AnvilInventory newAnvilInventory(@NotNull Version version, @NotNull InventoryHolder inventoryHolder) { + try { + return ANVIL_INVENTORIES.get(version).getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new beacon inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the beacon inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static BeaconInventory newBeaconInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + try { + return BEACON_INVENTORIES.get(version).getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new cartography table inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the cartography table inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static CartographyTableInventory newCartographyTableInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + try { + Class clazz = CARTOGRAPHY_TABLE_INVENTORIES.get(version); + + return clazz.getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new enchanting table inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the enchanting table inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static EnchantingTableInventory newEnchantingTableInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + try { + Class clazz = ENCHANTING_TABLE_INVENTORIES.get(version); + + return clazz.getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new grindstone inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the grindstone inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static GrindstoneInventory newGrindstoneInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + try { + Class clazz = GRINDSTONE_INVENTORIES.get(version); + + return clazz.getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new smithing table inventory for the specified version of the specified inventory holder. If a smithing + * table is requested for a version that does not have smithing tables, an {@link UnsupportedVersionException} is + * thrown. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the smithing table inventory + * @since 0.8.0 + * @throws UnsupportedVersionException when a smithing table is requested on a version without smithing tables + */ + @NotNull + @Contract(pure = true) + public static SmithingTableInventory newSmithingTableInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + if (version == Version.V1_14_R1 || version == Version.V1_15_R1) { + throw new UnsupportedVersionException("Smithing tables didn't exist in version " + version); + } + + try { + Class clazz = SMITHING_TABLE_INVENTORIES.get(version); + + return clazz.getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + /** + * Gets a new stonecutter inventory for the specified version of the specified inventory holder. + * + * @param version the version to get the inventory of + * @param inventoryHolder the inventory holder + * @return the stonecutter inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public static StonecutterInventory newStonecutterInventory(@NotNull Version version, + @NotNull InventoryHolder inventoryHolder) { + try { + Class clazz = STONECUTTER_INVENTORIES.get(version); + + return clazz.getConstructor(InventoryHolder.class).newInstance(inventoryHolder); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException exception) { + throw new IllegalStateException(exception); + } + } + + static { + ANVIL_INVENTORIES = new EnumMap<>(Version.class); + ANVIL_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.AnvilInventoryImpl.class); + ANVIL_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.AnvilInventoryImpl.class); + ANVIL_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.AnvilInventoryImpl.class); + ANVIL_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.AnvilInventoryImpl.class); + ANVIL_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.AnvilInventoryImpl.class); + + BEACON_INVENTORIES = new EnumMap<>(Version.class); + BEACON_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.BeaconInventoryImpl.class); + BEACON_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.BeaconInventoryImpl.class); + BEACON_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.BeaconInventoryImpl.class); + BEACON_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.BeaconInventoryImpl.class); + BEACON_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.BeaconInventoryImpl.class); + + CARTOGRAPHY_TABLE_INVENTORIES = new EnumMap<>(Version.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.CartographyTableInventoryImpl.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.CartographyTableInventoryImpl.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.CartographyTableInventoryImpl.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.CartographyTableInventoryImpl.class); + CARTOGRAPHY_TABLE_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.CartographyTableInventoryImpl.class); + + ENCHANTING_TABLE_INVENTORIES = new EnumMap<>(Version.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.EnchantingTableInventoryImpl.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.EnchantingTableInventoryImpl.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.EnchantingTableInventoryImpl.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.EnchantingTableInventoryImpl.class); + ENCHANTING_TABLE_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.EnchantingTableInventoryImpl.class); + + GRINDSTONE_INVENTORIES = new EnumMap<>(Version.class); + GRINDSTONE_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.GrindstoneInventoryImpl.class); + GRINDSTONE_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.GrindstoneInventoryImpl.class); + GRINDSTONE_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.GrindstoneInventoryImpl.class); + GRINDSTONE_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.GrindstoneInventoryImpl.class); + GRINDSTONE_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.GrindstoneInventoryImpl.class); + + SMITHING_TABLE_INVENTORIES = new EnumMap<>(Version.class); + SMITHING_TABLE_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.SmithingTableInventoryImpl.class); + SMITHING_TABLE_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.SmithingTableInventoryImpl.class); + SMITHING_TABLE_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.SmithingTableInventoryImpl.class); + + STONECUTTER_INVENTORIES = new EnumMap<>(Version.class); + STONECUTTER_INVENTORIES.put(Version.V1_14_R1, + com.github.stefvanschie.inventoryframework.nms.v1_14_R1.StonecutterInventoryImpl.class); + STONECUTTER_INVENTORIES.put(Version.V1_15_R1, + com.github.stefvanschie.inventoryframework.nms.v1_15_R1.StonecutterInventoryImpl.class); + STONECUTTER_INVENTORIES.put(Version.V1_16_R1, + com.github.stefvanschie.inventoryframework.nms.v1_16_R1.StonecutterInventoryImpl.class); + STONECUTTER_INVENTORIES.put(Version.V1_16_R2, + com.github.stefvanschie.inventoryframework.nms.v1_16_R2.StonecutterInventoryImpl.class); + STONECUTTER_INVENTORIES.put(Version.V1_16_R3, + com.github.stefvanschie.inventoryframework.nms.v1_16_R3.StonecutterInventoryImpl.class); + } +} diff --git a/src/main/resources/fonts/birch-planks.csv b/IF/src/main/resources/fonts/birch-planks.csv similarity index 98% rename from src/main/resources/fonts/birch-planks.csv rename to IF/src/main/resources/fonts/birch-planks.csv index eac6078c..c72a22bc 100644 --- a/src/main/resources/fonts/birch-planks.csv +++ b/IF/src/main/resources/fonts/birch-planks.csv @@ -1,118 +1,118 @@ -" ",97f9ce2afcd8978bb4bdafa2ba9b77b18baf423305e62fdb0c7bd8bd5b1bd -!,f6cb66d866f5beaa0224af1a41206099e6a3f7fc5c5f21666139859528ab5 -"""",76e65db2061cc7871a9cf6fc7f85e25ab5ef3707e8bddcc1e41f19131c412d7 -#,a21d2cce955bffcda4cc0367c88644488b595f27fce167b434ca5b8cd448d -$,f7536cad19381477b693fba4f769374b8213014fd20abcc3d68038473d45db54 -%,3216d17de42bd097669b8e09e8e62df8bf7837d395975496e636fda4fa95f3d -&,f57039df4238c55ea13719bfc754f5a4342472fc157c19418891187cec45d92f -',7b103abba1c5ea73f05c74df7e7ba8d7bdda4b341172417cf256de78e9816f5 -(,699f049288ac511f6e7ec5c9238f76527c2fbcad2857436ac381596cc02e4 -),d68ad255f92b839b5a8d1bbb9bb4d1a5f32743b6cf53665d99ed732aa8be7 -+,69b861aabb316c4ed73b4e5428305782e735565ba2a053912e1efd834fa5a6f -",",c6b0a5528b17bb69876f1dacf22c843ecf060bb7b3a238683fcca3364cd432 --,cc8e7d46d693341f91d286726f2555ef15514e3460b275e9747842bc9e53df -.,c0a1e26436f07745e4494d11b6c16c7c8d3d8bceef1a51d158dd6342b3c6e5 -/,2f412c16f6a9e7856cf824826182cbbcef2a51d4539e2431b8cda795f13655c -0,ba313aca5d83f979fb88e62043b38b6a5e43d92c9831ced469719f4c37622e1 -1,7fe6ca6bf3bfb7592edfe52bb78bca8cd09b6bd8de562dfe18e391cb41862d -2,40c4f88977dc91ae742b23c35c638e444e69387f7608aa8e6d355cb3147a -3,32f2926f9b485ff2229c53c1353c1e79ad771cc713638f8c3e51c26eb342b5 -4,bb125c6576dcfe6a887958d735845d3bae74dcfb55f0b8834e8c915bcfaf70 -5,9372da32bf777a9af1e3a773daec427fb718e277ff56ce2d2fab325fdc8f9515 -6,71ff4a941ce2b0c0dfdbbedcc2dcb8f7dbfac2c3e5c6a97644792fb2f139ad -7,c91855d8bdc9b8419a4ab2a22bf2f2f587c0bb5d3442bf13d2deffaed8140 -8,3bbebe3eec9f8f19a41c26a04126e8e0b6cc33d4dac967972916d5df12c98 -9,a9583486fa4abbf2f58776f8e4db8ee12f03af14d1bc55d54c1c92abbd251a6 -:,b4510e2f864997db269e5e8fa1e111bfeb8567aeee1a95ab87d66ac75154 -;,778f51015c5ade34ac9b1ef9aa22d72355c2a2fd1cf3ae63612eaff408e29 -=,2d621598a78b6ea6f7a9244aa286ce35ef4f547511db979bd9c7abab155ed49 -?,78b0b57e3ceebd673df9d2cf24d3979a3316e61d3b658d2a348cd1e6280b2 -[,7e82bbdc9afb5c7980369a95c7c7bd92afdc7fce3c934128a2b754a7e2eec556 -\,37e33caa9c2b2ac3ae827a5a6415fc7423c823273f9874ce2411a31afd8236 -],60a284e430f0ca4565eff52332efe018c3de89deec68bd9658d12b2d7a41db -_,a5a74032a29f794fd5664c867ecb44da8215d160bfc80d2b933e4b53c1e99ca -a,3eb2a9586289f35b2d5f2b1db296cb77528e20b7903e77cc53aac538d59673 -b,247257afd31518d94e802e9935626bf93e55aa6f77b56ba7e37f8be4e57d1 -c,ad7651bc86b6abd89ee7ea654d4690ca6474fae1f7f6d28bc7d4e4116a74 -d,a06cce2148f6881cc1e03357fd95c881569703d6ed683212063e888ec8df6f6 -e,fdf8568d1b42d7c11d90be4698670368afc8b4acb7c83825582e2c9eb1617d9 -f,22920c3815b9c4592e6408e3223f31351fc578f35591bc7f9bebd21efd8a097 -g,e5d8cb60e03157d5904522ff8960a71f3cb33fad715b51593349a62dc0157234 -h,e91d58ec26244887d2f87deb558d4e92b4145480c931d8428230954a7b31e6d1 -i,abcdc6f88c853e831495a1746eb27aa61b9dac2e86a44b9522e3e2b7dc5 -j,cb410c0ab4528166cfecc14a4e2238bfea02c337ca893301157c9354f31b55 -k,765a115e974d521f1b389bb3ba4cb5939b264617c838daa66b6b8dc5171a96 -l,60bd80da199ec96c2a4315d627c455b8b05031b6121d8d4ba297ee8ad9f73ec -m,19a950ca2f9fe6a19a6ac7e894ac52737cdc404d86801422526f9ae5ee9e8f -n,cc4913afc52526addd9e773f89094287de6a5bb77595a8b5c97ad40bb474e6 -o,181ad7b441f143f79f88e79ca5c674ffda91520fe2e1de41a701abdcdc0ec -p,d9f8949cb9d9844bbc98a08ee85bfc64858b152e6b7d21463cc25d5be728dc4 -q,f2b221cab16e9c894cb7a86ec87493657313f58a3ef44e58885e14526963d -r,5c1ea8204cab8f3327ffcef492d193da6344a8f864552442e155fe73bb6ba -s,f4eb8245e92eb68bb77ea26d559c38a3adf18f3cea5bf1ddec7d7f8c554448b -t,14a9fb3552d551553d9dd43c2bb1d268893df68d73e4611343b572ae6425ca -u,67f738eb507e5732b1772a53b0deac187c92a77fadce82528706586ee19d -v,74c393e8d33be192acae9355f79eba69302c3bf441af10a68d1146ac65e7 -w,ac4e248e41d28eb30b29fd31a4eca606e167bdf63af36efaf971ac4a5731f3 -x,9f74d4db4cc3be41a373d9ef9cac27e6358c53f64115d150243f25acf64f2f50 -y,79c10d8283926d720fd3de15c4e4cd3e159fb256f7fa8d897eb2f14ab8a18 -z,d64917c2414941eff7e01bc9bd159c699e9bee2d88e315ead2b9cec0cbe51c98 -{,74a94961c3a1ac97cd81e42ca2d09f87f3223dfbb15c469bafd141fa592d695 -},6a88f8f829c4cfa2eb30e42977504ab1fd8e335deeac4f476ebdba8d27797bd7 -\u00A1,3f604cdd796eaa934af16236b477df6cd33eb107a3e88133bc4ac6b3b7cc55d8 -\u00BF,ee64cb48df7bc9644170c217510cfec72dfbd186d0eff0efc6d93382217133ea -\u00E4,25e69c7d55513e7727d4ed844461994bacb685f98749e6e4e1662986547495d -\u00EB,fbc393b485b7d8672a0511882acd3e3b22f067de02157556126a23abbfd5 -\u00F1,9229c3170a9fdbfd9a820ba278a2669834e72253f1f236e3334c4719161783ce -\u00F6,773e26246acc488d605f5451877effe8a2a9b0cf37eb2c61146bc7281a7 -\u00FC,469fab39a9eee75d7437839a5657be9fe807efd2a8bb9f93ead25de7abb5ed -\u0431,a89908727183a342af836cf64e4542740156364b15f1de344417d9541850f1 -\u0433,60270961ab5ca6cf7aa80d5a3ef17d564dec928913a62f0906cf68389292f40 -\u0434,3228db8b2cd49a4b986a3b0ea8a161a1742b1c07fd0e2b15be88dc76498e5 -\u0436,26dfdd3e451f5616b0f4122044c6ca27fa860f851752abb5e442ec5a6f3fe -\u0437,d6e5cf9bf83553795573b272bea6d432cf9bf9d5593a34ffc010a7d66cf3ab -\u0438,90c833a6716637e06f996ae8f1aba17e444432eebaa4c11369e07117576c8aa0 -\u0439,d026d9213fec7836a8ad6bc2bb6c7db0957bb12e5f6f59db603912eea653ba -\u043B,a9ce71a8b3561f541f6569e51d46054feea2632e1edef9678cacc6f7d75a59 -\u043F,58347f36d6c7f3985c23fcbef667de7e9dab8d6ecadd198ec42d2dca382fd2 -\u0443,66164911dff0715eeedd693a1011a57c46fb323a589adff142a0d830d5c8196a -\u0444,7fe66ab1dd9b82bd66db116b32c9fe1d6f61ba8334afec9e61b2db2f53646f6 -\u0446,f1d4dcfc96e28e4f7e57c22559d06f41ed52cfc976a40512c9c34fdb94e -\u0447,eaedfd1adb9eb8c08f28c543c2fc7eeba3162a6e2b198bfc2feb40ebdd6d72 -\u0448,6de37c5ce74d87b87a9724a2eaf6a5a43b4f6a9afafab29952f4f62211867 -\u0449,4f89802e115cb4ae1ed5be5f6084a34fa7bd571dad94269dd9aa2282e716d573 -\u044A,c38daf1289ac6a4dda471872d79278763385ddd6198486b301c61ef2634ca2 -\u044B,13ee3dc086386f5a48de113feb585784fe3038bb5617643d4cc6138e3352e5 -\u044C,3a88c054abc8697bce5614ebc55a84799fbf715f3c54faf560dff3459d8110 -\u044D,6ad6cf5d23d98b788385f9da417afe319def93fa5593837c34856d4bd86e65 -\u044E,8d7d149631eb2d9ce94d7ee8afa28e44e1424b3697aa74c97336e0f45e6e3552 -\u044F,c43c565cd9deba81bf74358596c5caba9b29baebcac5cc5b1630b4c42b6 -\u2190,a2f0425d64fdc8992928d608109810c1251fe243d60d175bed427c651cbe -\u2191,55149dddaded20d244e0bb62a2d9fa0dc6c6a7862559328a94f77725f53c358 -\u2192,6d865aae2746a9b8e9a4fe629fb08d18d0a9251e5ccbe5fa7051f53eab9b94 -\u2193,9472c9d628bb3221ef36b4cbd0b9f15edd58e586818514d7e823d55c48c -\u2196,88c812f15965a7cb137316fad3c5a8ef54f86fb2146de8ed16c88f8534b -\u2197,e138452bca86cb9abcae325e889917bdc7bec95b4da8f1e706c3c4d4ef727bd -\u2198,6baeb0bc982e56348fe4ff5b3118cb5262e933c2529bdb3bbdfbff66f7cfb -\u2199,d71ddfe175ae5093cee609fa5cd89e32cffae7ecac7f813e4426f79e819e8ce -\u23E9,4f4486863f30e38432dbd22e5412964644ec25ea4f991a38c737376e9606479 -\u23EA,38a1f037c8e5178bbe4cb9a7d335f1b110c45c1c465f1d73dcbe8cad69d9eca -\u23F4,86e145e71295bcc0488e9bb7e6d6895b7f969a3b5bb7eb34a52e932bc84df5b -\u23F5,7697c24892cfc03c728ffaeabf34bdfb92d451147b26d203dcafa93e41ff9 -\u2640,9aaa879e154005059586543a1510090cb5f387bb02c0784e1386e240907d70f8 -\u2642,9f84b5381d740f90b268c208e03e06563e0ec7fc4194b4f2ab9714ad0fae2a6d -\u2648,7dec9942cf670789e076b3d3a34e0236f148f76783fc5165970e5ae1c05a6e2f -\u2649,5d010f52d449f7d41a9c101aaa32febebca31352253f51ac4990648eebc22d14 -\u264A,bd049f4218f56ac49e127ca9b21d8f2059a53c56a51e5f77328212e4bcee4857 -\u264B,3766fbc1134035fe00eef0bc4d05a1218511da16c83b54079cbd4cc8f978edfa -\u264C,f96f0bf09154fbdaa6e8783b9c7d9439a899a65893ab496c6b51f63546f67362 -\u264D,4176231cca75ee0c5fd09cb1373e604f1fb9af1166346fa92d956387e212ec68 -\u264E,5d3c126b72ca776f8481b69d78cf4d30c41ae37d9947cabe73fc9cc5dbf9c74e -\u264F,4d9e64fb4cbb46d2253b2cda895b39bb91c21137d3dc7d13bab6f5a053b65eb5 -\u2650,bb34f49a7f50a70761463c8fd45a4bc85e1d6286e0ac51711d0fb39004df9170 -\u2651,ae00e9d16aba45bf38dcda94a94e6e62009abe4e2da18f30d207f12df82acf7e -\u2652,cb54ee7d570566f4a1421e768ba7a7e25a72ce82b4f5c312865f29b75eb3794f -\u2653,4349246b81ea6f5f7936de811d2cccb3e7c84f33af6884e9fc4c3cdb1c5e1d83 -\u2665,76a75e5a9d648d8e98e5e7bab88a9ec5d79c53338d8e1a5d3bf29d2b248f913 -\u266A,3ade1dfd0379d1ed24fadde3d6be4b263bceb1d5d8b2a636ff99146646656220 +" ",97f9ce2afcd8978bb4bdafa2ba9b77b18baf423305e62fdb0c7bd8bd5b1bd +!,f6cb66d866f5beaa0224af1a41206099e6a3f7fc5c5f21666139859528ab5 +"""",76e65db2061cc7871a9cf6fc7f85e25ab5ef3707e8bddcc1e41f19131c412d7 +#,a21d2cce955bffcda4cc0367c88644488b595f27fce167b434ca5b8cd448d +$,f7536cad19381477b693fba4f769374b8213014fd20abcc3d68038473d45db54 +%,3216d17de42bd097669b8e09e8e62df8bf7837d395975496e636fda4fa95f3d +&,f57039df4238c55ea13719bfc754f5a4342472fc157c19418891187cec45d92f +',7b103abba1c5ea73f05c74df7e7ba8d7bdda4b341172417cf256de78e9816f5 +(,699f049288ac511f6e7ec5c9238f76527c2fbcad2857436ac381596cc02e4 +),d68ad255f92b839b5a8d1bbb9bb4d1a5f32743b6cf53665d99ed732aa8be7 ++,69b861aabb316c4ed73b4e5428305782e735565ba2a053912e1efd834fa5a6f +",",c6b0a5528b17bb69876f1dacf22c843ecf060bb7b3a238683fcca3364cd432 +-,cc8e7d46d693341f91d286726f2555ef15514e3460b275e9747842bc9e53df +.,c0a1e26436f07745e4494d11b6c16c7c8d3d8bceef1a51d158dd6342b3c6e5 +/,2f412c16f6a9e7856cf824826182cbbcef2a51d4539e2431b8cda795f13655c +0,ba313aca5d83f979fb88e62043b38b6a5e43d92c9831ced469719f4c37622e1 +1,7fe6ca6bf3bfb7592edfe52bb78bca8cd09b6bd8de562dfe18e391cb41862d +2,40c4f88977dc91ae742b23c35c638e444e69387f7608aa8e6d355cb3147a +3,32f2926f9b485ff2229c53c1353c1e79ad771cc713638f8c3e51c26eb342b5 +4,bb125c6576dcfe6a887958d735845d3bae74dcfb55f0b8834e8c915bcfaf70 +5,9372da32bf777a9af1e3a773daec427fb718e277ff56ce2d2fab325fdc8f9515 +6,71ff4a941ce2b0c0dfdbbedcc2dcb8f7dbfac2c3e5c6a97644792fb2f139ad +7,c91855d8bdc9b8419a4ab2a22bf2f2f587c0bb5d3442bf13d2deffaed8140 +8,3bbebe3eec9f8f19a41c26a04126e8e0b6cc33d4dac967972916d5df12c98 +9,a9583486fa4abbf2f58776f8e4db8ee12f03af14d1bc55d54c1c92abbd251a6 +:,b4510e2f864997db269e5e8fa1e111bfeb8567aeee1a95ab87d66ac75154 +;,778f51015c5ade34ac9b1ef9aa22d72355c2a2fd1cf3ae63612eaff408e29 +=,2d621598a78b6ea6f7a9244aa286ce35ef4f547511db979bd9c7abab155ed49 +?,78b0b57e3ceebd673df9d2cf24d3979a3316e61d3b658d2a348cd1e6280b2 +[,7e82bbdc9afb5c7980369a95c7c7bd92afdc7fce3c934128a2b754a7e2eec556 +\,37e33caa9c2b2ac3ae827a5a6415fc7423c823273f9874ce2411a31afd8236 +],60a284e430f0ca4565eff52332efe018c3de89deec68bd9658d12b2d7a41db +_,a5a74032a29f794fd5664c867ecb44da8215d160bfc80d2b933e4b53c1e99ca +a,3eb2a9586289f35b2d5f2b1db296cb77528e20b7903e77cc53aac538d59673 +b,247257afd31518d94e802e9935626bf93e55aa6f77b56ba7e37f8be4e57d1 +c,ad7651bc86b6abd89ee7ea654d4690ca6474fae1f7f6d28bc7d4e4116a74 +d,a06cce2148f6881cc1e03357fd95c881569703d6ed683212063e888ec8df6f6 +e,fdf8568d1b42d7c11d90be4698670368afc8b4acb7c83825582e2c9eb1617d9 +f,22920c3815b9c4592e6408e3223f31351fc578f35591bc7f9bebd21efd8a097 +g,e5d8cb60e03157d5904522ff8960a71f3cb33fad715b51593349a62dc0157234 +h,e91d58ec26244887d2f87deb558d4e92b4145480c931d8428230954a7b31e6d1 +i,abcdc6f88c853e831495a1746eb27aa61b9dac2e86a44b9522e3e2b7dc5 +j,cb410c0ab4528166cfecc14a4e2238bfea02c337ca893301157c9354f31b55 +k,765a115e974d521f1b389bb3ba4cb5939b264617c838daa66b6b8dc5171a96 +l,60bd80da199ec96c2a4315d627c455b8b05031b6121d8d4ba297ee8ad9f73ec +m,19a950ca2f9fe6a19a6ac7e894ac52737cdc404d86801422526f9ae5ee9e8f +n,cc4913afc52526addd9e773f89094287de6a5bb77595a8b5c97ad40bb474e6 +o,181ad7b441f143f79f88e79ca5c674ffda91520fe2e1de41a701abdcdc0ec +p,d9f8949cb9d9844bbc98a08ee85bfc64858b152e6b7d21463cc25d5be728dc4 +q,f2b221cab16e9c894cb7a86ec87493657313f58a3ef44e58885e14526963d +r,5c1ea8204cab8f3327ffcef492d193da6344a8f864552442e155fe73bb6ba +s,f4eb8245e92eb68bb77ea26d559c38a3adf18f3cea5bf1ddec7d7f8c554448b +t,14a9fb3552d551553d9dd43c2bb1d268893df68d73e4611343b572ae6425ca +u,67f738eb507e5732b1772a53b0deac187c92a77fadce82528706586ee19d +v,74c393e8d33be192acae9355f79eba69302c3bf441af10a68d1146ac65e7 +w,ac4e248e41d28eb30b29fd31a4eca606e167bdf63af36efaf971ac4a5731f3 +x,9f74d4db4cc3be41a373d9ef9cac27e6358c53f64115d150243f25acf64f2f50 +y,79c10d8283926d720fd3de15c4e4cd3e159fb256f7fa8d897eb2f14ab8a18 +z,d64917c2414941eff7e01bc9bd159c699e9bee2d88e315ead2b9cec0cbe51c98 +{,74a94961c3a1ac97cd81e42ca2d09f87f3223dfbb15c469bafd141fa592d695 +},6a88f8f829c4cfa2eb30e42977504ab1fd8e335deeac4f476ebdba8d27797bd7 +\u00A1,3f604cdd796eaa934af16236b477df6cd33eb107a3e88133bc4ac6b3b7cc55d8 +\u00BF,ee64cb48df7bc9644170c217510cfec72dfbd186d0eff0efc6d93382217133ea +\u00E4,25e69c7d55513e7727d4ed844461994bacb685f98749e6e4e1662986547495d +\u00EB,fbc393b485b7d8672a0511882acd3e3b22f067de02157556126a23abbfd5 +\u00F1,9229c3170a9fdbfd9a820ba278a2669834e72253f1f236e3334c4719161783ce +\u00F6,773e26246acc488d605f5451877effe8a2a9b0cf37eb2c61146bc7281a7 +\u00FC,469fab39a9eee75d7437839a5657be9fe807efd2a8bb9f93ead25de7abb5ed +\u0431,a89908727183a342af836cf64e4542740156364b15f1de344417d9541850f1 +\u0433,60270961ab5ca6cf7aa80d5a3ef17d564dec928913a62f0906cf68389292f40 +\u0434,3228db8b2cd49a4b986a3b0ea8a161a1742b1c07fd0e2b15be88dc76498e5 +\u0436,26dfdd3e451f5616b0f4122044c6ca27fa860f851752abb5e442ec5a6f3fe +\u0437,d6e5cf9bf83553795573b272bea6d432cf9bf9d5593a34ffc010a7d66cf3ab +\u0438,90c833a6716637e06f996ae8f1aba17e444432eebaa4c11369e07117576c8aa0 +\u0439,d026d9213fec7836a8ad6bc2bb6c7db0957bb12e5f6f59db603912eea653ba +\u043B,a9ce71a8b3561f541f6569e51d46054feea2632e1edef9678cacc6f7d75a59 +\u043F,58347f36d6c7f3985c23fcbef667de7e9dab8d6ecadd198ec42d2dca382fd2 +\u0443,66164911dff0715eeedd693a1011a57c46fb323a589adff142a0d830d5c8196a +\u0444,7fe66ab1dd9b82bd66db116b32c9fe1d6f61ba8334afec9e61b2db2f53646f6 +\u0446,f1d4dcfc96e28e4f7e57c22559d06f41ed52cfc976a40512c9c34fdb94e +\u0447,eaedfd1adb9eb8c08f28c543c2fc7eeba3162a6e2b198bfc2feb40ebdd6d72 +\u0448,6de37c5ce74d87b87a9724a2eaf6a5a43b4f6a9afafab29952f4f62211867 +\u0449,4f89802e115cb4ae1ed5be5f6084a34fa7bd571dad94269dd9aa2282e716d573 +\u044A,c38daf1289ac6a4dda471872d79278763385ddd6198486b301c61ef2634ca2 +\u044B,13ee3dc086386f5a48de113feb585784fe3038bb5617643d4cc6138e3352e5 +\u044C,3a88c054abc8697bce5614ebc55a84799fbf715f3c54faf560dff3459d8110 +\u044D,6ad6cf5d23d98b788385f9da417afe319def93fa5593837c34856d4bd86e65 +\u044E,8d7d149631eb2d9ce94d7ee8afa28e44e1424b3697aa74c97336e0f45e6e3552 +\u044F,c43c565cd9deba81bf74358596c5caba9b29baebcac5cc5b1630b4c42b6 +\u2190,a2f0425d64fdc8992928d608109810c1251fe243d60d175bed427c651cbe +\u2191,55149dddaded20d244e0bb62a2d9fa0dc6c6a7862559328a94f77725f53c358 +\u2192,6d865aae2746a9b8e9a4fe629fb08d18d0a9251e5ccbe5fa7051f53eab9b94 +\u2193,9472c9d628bb3221ef36b4cbd0b9f15edd58e586818514d7e823d55c48c +\u2196,88c812f15965a7cb137316fad3c5a8ef54f86fb2146de8ed16c88f8534b +\u2197,e138452bca86cb9abcae325e889917bdc7bec95b4da8f1e706c3c4d4ef727bd +\u2198,6baeb0bc982e56348fe4ff5b3118cb5262e933c2529bdb3bbdfbff66f7cfb +\u2199,d71ddfe175ae5093cee609fa5cd89e32cffae7ecac7f813e4426f79e819e8ce +\u23E9,4f4486863f30e38432dbd22e5412964644ec25ea4f991a38c737376e9606479 +\u23EA,38a1f037c8e5178bbe4cb9a7d335f1b110c45c1c465f1d73dcbe8cad69d9eca +\u23F4,86e145e71295bcc0488e9bb7e6d6895b7f969a3b5bb7eb34a52e932bc84df5b +\u23F5,7697c24892cfc03c728ffaeabf34bdfb92d451147b26d203dcafa93e41ff9 +\u2640,9aaa879e154005059586543a1510090cb5f387bb02c0784e1386e240907d70f8 +\u2642,9f84b5381d740f90b268c208e03e06563e0ec7fc4194b4f2ab9714ad0fae2a6d +\u2648,7dec9942cf670789e076b3d3a34e0236f148f76783fc5165970e5ae1c05a6e2f +\u2649,5d010f52d449f7d41a9c101aaa32febebca31352253f51ac4990648eebc22d14 +\u264A,bd049f4218f56ac49e127ca9b21d8f2059a53c56a51e5f77328212e4bcee4857 +\u264B,3766fbc1134035fe00eef0bc4d05a1218511da16c83b54079cbd4cc8f978edfa +\u264C,f96f0bf09154fbdaa6e8783b9c7d9439a899a65893ab496c6b51f63546f67362 +\u264D,4176231cca75ee0c5fd09cb1373e604f1fb9af1166346fa92d956387e212ec68 +\u264E,5d3c126b72ca776f8481b69d78cf4d30c41ae37d9947cabe73fc9cc5dbf9c74e +\u264F,4d9e64fb4cbb46d2253b2cda895b39bb91c21137d3dc7d13bab6f5a053b65eb5 +\u2650,bb34f49a7f50a70761463c8fd45a4bc85e1d6286e0ac51711d0fb39004df9170 +\u2651,ae00e9d16aba45bf38dcda94a94e6e62009abe4e2da18f30d207f12df82acf7e +\u2652,cb54ee7d570566f4a1421e768ba7a7e25a72ce82b4f5c312865f29b75eb3794f +\u2653,4349246b81ea6f5f7936de811d2cccb3e7c84f33af6884e9fc4c3cdb1c5e1d83 +\u2665,76a75e5a9d648d8e98e5e7bab88a9ec5d79c53338d8e1a5d3bf29d2b248f913 +\u266A,3ade1dfd0379d1ed24fadde3d6be4b263bceb1d5d8b2a636ff99146646656220 \u2713,9a75c8e51c3d105bab4c7de33a770937364b5a01c15b7db82cc3e1fe6eb93396 \ No newline at end of file diff --git a/src/main/resources/fonts/black.csv b/IF/src/main/resources/fonts/black.csv similarity index 98% rename from src/main/resources/fonts/black.csv rename to IF/src/main/resources/fonts/black.csv index d5bec56f..84946f80 100644 --- a/src/main/resources/fonts/black.csv +++ b/IF/src/main/resources/fonts/black.csv @@ -1,118 +1,118 @@ -" ",9d4f187f41cae641558f8787bf1e7be72a6d72911b21c97d916f0a7faaf28f7 -!,dd2acd9f2dfc2e05f69d941fe9970e8c3f05527a02a9381157891c8ddb8cf3 -"""",efc09c99b24760611d111cbfc4fc51a30a74d45c0faafb92339932a63965e -#,e94b5e3ddc7a8f33c79346860d3923c71a582fda16acdbf4ad3c0cc465fd926 -$,4e74d6472f811ee7e5e805ea93d7b4c761c66a64e593702fc8073db357f0464d -%,3d143dbdcc9f4e377e34f36e316bd19df634c59b3bf93a69ab21d95b2fd57b -&,f04ce4f22f29782b6eaa25d1e5fe79ce06bac859df22a76306adb86e4ea -',70dde38a52032339368e5751ea76d96a630c99e5097798a72893103fdc58a1 -(,d75a3962a1a2b41bc82ae9dd75752d8ebb7e2716f2d93b6f2972583bfbc05e -),3a5d29ce63cd10d539be2595ec5d5b27f7738bf17f481b6ab481d245a32067 -+,9a2d891c6ae9f6baa040d736ab84d48344bb6b70d7f1a280dd12cbac4d777 -",",a5fd02f646fe241c948cba117916c3a4ce6fbcf76afe3e9cb3e49e4cf7b65 --,935e4e26eafc11b52c11668e1d6634e7d1d0d21c411cb085f9394268eb4cdfba -.,95f6e3383d128f17d73cf39af7b579889779c4e5f38d2c1ef85dba2f462f6840 -/,fe6e82d12a5f7bbe34d9b7bf632e88a50371a2ac39c26bef05f72cdd75b185b -0,6d68343bd0b129de93cc8d3bba3b97a2faa7ade38d8a6e2b864cd868cfab -1,d2a6f0e84daefc8b21aa99415b16ed5fdaa6d8dc0c3cd591f49ca832b575 -2,96fab991d083993cb83e4bcf44a0b6cefac647d4189ee9cb823e9cc1571e38 -3,cd319b9343f17a35636bcbc26b819625a9333de3736111f2e932827c8e749 -4,d198d56216156114265973c258f57fc79d246bb65e3c77bbe8312ee35db6 -5,7fb91bb97749d6a6eed4449d23aea284dc4de6c3818eea5c7e149ddda6f7c9 -6,9c613f80a554918c7ab2cd4a278752f151412a44a73d7a286d61d45be4eaae1 -7,9e198fd831cb61f3927f21cf8a7463af5ea3c7e43bd3e8ec7d2948631cce879 -8,84ad12c2f21a1972f3d2f381ed05a6cc088489fcfdf68a713b387482fe91e2 -9,9f7aa0d97983cd67dfb67b7d9d9c641bc9aa34d96632f372d26fee19f71f8b7 -:,ac4c26963f8538c11eac6a8e437d27682dffea4bcc0f04afd5cda6d1d567 -;,65e3332e38a8c334b5d2a7225c9d3408590bd5c61bafa7c8714563552c28084 -=,49f181b413daa26424fde063ff32cd9715c95256b0f25037c2f0ede1d5e53b5 -?,46ba63344f49dd1c4f5488e926bf3d9e2b29916a6c50d610bb40a5273dc8c82 -[,432d6da968a4c358745f75cdb4de89b58e23585229348c82a917e6777ab68 -\,88425d354235c1334d7d09bbbf18dd965e1c0c238695b0b29023e7dcb5b3 -],32ea3cf74d242e71a0366b5b87c6028c69294ace1c71a1cedc54da1b2b4bbde -_,979a465183a3ba63fe6ae272bc1bf1cd15f2c209ebbfcc5c521b9514682a43 -a,17dd34924d2b6a213a5ed46ae5783f95373a9ef5ce5c88f9d736705983b97 -b,9eca98befd0d7efca9b11ebf4b2da459cc19a378114b3cdde67d4067afb896 -c,56b1486e1f576bc921b8f9f59fe6122ce6ce9dd70d75e2c92fdb8ab9897b5 -d,59aa69229ffdfa182889bf3097d32215c1b2159d987103b1d5843646faac -e,ced9f431a997fce0d8be1844f62090b1783ac569c9d2797528349d37c215fcc -f,9d714bafb0b5ab9cfa7db02efc8927aed1ef29797a595da066efc5c3efdc9 -g,58c336dedfe197b434b5ab67988cbe9c2c9f285ec1871fdd1ba434855b -h,bde4a89be2197f86d2e6166a0ac541ccc21dce28b7854b788d329a39daec32 -i,c148a8865bc4afe0747f3415138b96bbb4e8bbb7261f45e5d11d7219f368e4 -j,18c9dc3d38a56282e1d92337198fb19ea641b61a8c4e57fb4e27c1ba6a4b24c -k,12bfeb246f649b86f212feea87a9c216a655565d4b7992e80326b3918d923bd -l,cc58321d4bffbec2ddf66bf38cf2f9e9ddf3fa2f1387dc7d30c62b4d010c8 -m,90376dc5e3c981b52960578afe4bfc41c1778789bcd80ec2c2d2fd460e5a51a -n,612c7afea48e53325e5129038a45aec51afe256abca941b6bc8206fae1cef -o,1c27235de3a55466b627459f1233596ab6a22c435cfc89a4454b47d32b199431 -p,c584dc7ecf36b4f044f8262527985718bf24a9daef012de92e1e76d4586d96 -q,ff72cceb4a565478de5b0b0e727946e549834e36f6e0ec8f7dd7f6327b15a -r,3cb88225ee4ab39f7cbf581f22cbf08bdcc33884f1ff747689312841516c345 -s,af22d7cd53d5bfe61eafbc2fb1ac94443eec24f455292139ac9fbdb83d0d09 -t,fc2fcbc24e7382ac112bb2c0d5eca27e9f48ffca5a157e502617a96d636f5c3 -u,9fdc4f321c78d67484135ae464af4fd925bd57d459383a4fe9d2f60a3431a79 -v,2dd0143d8e449ad1ba97e1981712cee0f3fc297dbc17c83b05eea3338d659 -w,79cbc465525e16a89441d789b72f554e8ff4ea5b393447aef3ff193f0465058 -x,c38ab145747b4bd09ce0354354948ce69ff6f41d9e098c6848b80e187e919 -y,a71071bef733f477021b3291dc3d47f0bdf0be2da1b165a119a8ff1594567 -z,c992c753bf9c625853ce2a0b7b174b89a6ec26bb5c3ccb473b6a2012496312 -{,7f885af5a366bb3eb9915c6477a357066fe2cc17ede236c6c81d23e5057 -},b9e2353ef1a82b258f9b9d2d28db9b71966da0d224a536be9a6498198b11907 -\u00A1,dc4e441eac884de3347a8775a07a66bbc4c82a24ed2d0cfeb1acaf6ce99d53b6 -\u00BF,3743f0a3849afd50dc332e5cad284a2555161a4bf9122a8c635940b9d21ed393 -\u00E4,15b61375135fa952fd7bfcb19bef166287f02f73c3688f1f91286d43a634625 -\u00EB,ea85bdaef6e1e9f6376a16143f03df9d6291657707f8adc456e126bf04046 -\u00F1,f41daa63d5dc36f8cff6ab2e8bdeb70fc2cf56e1893c924489203cb8b45fe3ef -\u00F6,139926539b4a04023aed0e89b8fcb883af3bb363ab3ac44998ad47be8b257e7 -\u00FC,9b7a79f187a1478b7b555524fa7321f46c84457bef7ab88d8b3dbc6afbf1fa6d -\u0431,3f687c22ad7715f530d0bd65a2331472491261bda7e9bed086c37eb6b543623 -\u0433,ae7f9974da9d6dc8adf18f9ebd1449e077d4efd6dd779caa1db9d05893ba62e -\u0434,5bd369973c59b9f7917aa58394fffd05e84b71aa9a1bfdf9eca8d8a627f58 -\u0436,dcb4636cf894d88fffe93f4f48c823c815afe258e18665770616fb55289472d -\u0437,7e50b1d3abbaa471802920aa8b3eb215493821e5d446dabbcccab3c5fae803e -\u0438,a15922fe8bb7efda8824a8c5bd52a31a38152c77934449b548176fff82b8b -\u0439,22e3161af546d67a945c6de7e1598123d65afb46c64195b6147a73b1e272672 -\u043B,18f91c358db455bde0f8a6de8e289efb3fe06b371ba59572bcb4f74a136023 -\u043F,4359c75166cd755a01e59884f3fb7b3eb235753174ffde94c2fc68b13eedb6d -\u0443,30427b18a6b03b4f1231fd63177bd044d16f7045d39aece3f05a9080f2edbe6a -\u0444,65f2dc35eaefb68d99d9e24b31618dc61de39e5e65e80dfa2311bb477dbc47e -\u0446,683381a0132457320d033296fa3dc3ecf4de482470dca87d2fb7ec9f32afa -\u0447,bb35aa5e186df1cbed535db5ba18d0e15d48cc3cff4ec66cdfa18c2923f58f -\u0448,d1ccd87ebf862568997158d68c5ee55be2c31221085cb748a36a8c691f4667c -\u0449,1b748e6336d9537aef58eb9fb433c8631418bb83f23089ddf622f773c78084 -\u044A,1cfe5a802240b96aa67db5171f77e59f7bd5d231834152c7d4df62e694dd -\u044B,ea53755362281c881c50fb47d7cd83bc782d2289d8c91d4f26c42ffc816c6c -\u044C,993448106f2988d4cfb35334bfd776f71c1b3d668fbb7ec6af9c956e3845f2 -\u044D,a96ab73efa8b3848f6cac0aad6817aef9ed6f9e0d5bdc3629eca5045dd43256 -\u044E,3aaf87e9192cb15253f48bc7e7c6ba1953363e8df4bdd0b069f8d7f5fbab8494 -\u044F,a3d2975db2f1c2a385f8cd797886eeaa4b5e8519c07e6bcf16133c72c7d73 -\u2190,37aee9a75bf0df7897183015cca0b2a7d755c63388ff01752d5f4419fc645 -\u2191,6ccbf9883dd359fdf2385c90a459d737765382ec4117b04895ac4dc4b60fc -\u2192,682ad1b9cb4dd21259c0d75aa315ff389c3cef752be3949338164bac84a96e -\u2193,72431911f4178b4d2b413aa7f5c78ae4447fe9246943c31df31163c0e043e0d6 -\u2196,47456b506ee3dcab215f33cb93a9edd9749f3e2ff8a4893426e1784692de8b5 -\u2197,16227036b8afed6935d53143d16488d39cf4fb73a671f2b2955e80fc9dfe458 -\u2198,dbe6713f20a9c2de43803b90aefa4db9a6bf89915d7c1590f77a7e10df3a3e54 -\u2199,f1fab0e6aea88748ca3b5512ed502a6d18e76d8afc4770d995233ac0dc5186 -\u23E9,d99f28332bcc349f42023c29e6e641f4b10a6b1e48718cae557466d51eb922 -\u23EA,118a2dd5bef0b073b13271a7eeb9cfea7afe8593c57a93821e43175572461812 -\u23F4,864f779a8e3ffa231143fa69b96b14ee35c16d669e19c75fd1a7da4bf306c -\u23F5,d9eccc5c1c79aa7826a15a7f5f12fb40328157c5242164ba2aef47e5de9a5cfc -\u2640,cabf622e8ddaf409689aa45b7b01f1b57430e323a908e5ccc9c0da7228883283 -\u2642,162606025186a6523e2710da4c9fae8fa8d5dabecad6c49c96ab38149b591bd6 -\u2648,72361172d540d8f0ccea5b78dc7f4f93e24ff306e93b7b79b9cbb223da4da128 -\u2649,13c8d1d0274847532a76284bc0cdbf3ca3b974cb5e1bc1f52111064d72e6d4c1 -\u264A,ed6f9077fa20667e7ce78dd7fd81c6fe8f46d38a50a525e977efdc172d9d3308 -\u264B,d565bf7837ec875885bce1436138af22cabf834e97c58b48c79e4d13ca2b9ab2 -\u264C,61dd98a7c37d70d9237335592efee5b31c23520d72e829f746522cc982fb1ad0 -\u264D,3aeedd65a4f62bef5484b8d37b4d78383f2d66c4d8774a58a92b83ca47e1bd10 -\u264E,3865050656d3722daac24db5bc0d7cf5f7ebb99cf1a322c19a4d642db270d43c -\u264F,71c503d6cf5eb37eee1315958a31d3af9ece4686237ddc7bcda963da9609bc30 -\u2650,420b9fb8fcf7c05de1946cf4d25bbf9ec975d7e3648d2cd2970fe9c0253cfe23 -\u2651,c6be0cdaa937bcbb4df1130a6291ad710116ea838125f00af44ec988695bc6bf -\u2652,35b8018b0a9c07c1cdd530f9417f7d6bb1be77c0210ed77c2d6c15e36288c26e -\u2653,c5fbbd16424df096d4f900912f508b9db4b333d93d5af5bac46eaa244c48bcd -\u2665,ce3a59e4c5753295d8d69c214344ebb3e547f936b867ad9d5ebd519fad85ce3 -\u266A,afaaf3c0bf836cdbd2c8401ec04dc3019cbf390e6af4fbbe0e831c130688a98a +" ",9d4f187f41cae641558f8787bf1e7be72a6d72911b21c97d916f0a7faaf28f7 +!,dd2acd9f2dfc2e05f69d941fe9970e8c3f05527a02a9381157891c8ddb8cf3 +"""",efc09c99b24760611d111cbfc4fc51a30a74d45c0faafb92339932a63965e +#,e94b5e3ddc7a8f33c79346860d3923c71a582fda16acdbf4ad3c0cc465fd926 +$,4e74d6472f811ee7e5e805ea93d7b4c761c66a64e593702fc8073db357f0464d +%,3d143dbdcc9f4e377e34f36e316bd19df634c59b3bf93a69ab21d95b2fd57b +&,f04ce4f22f29782b6eaa25d1e5fe79ce06bac859df22a76306adb86e4ea +',70dde38a52032339368e5751ea76d96a630c99e5097798a72893103fdc58a1 +(,d75a3962a1a2b41bc82ae9dd75752d8ebb7e2716f2d93b6f2972583bfbc05e +),3a5d29ce63cd10d539be2595ec5d5b27f7738bf17f481b6ab481d245a32067 ++,9a2d891c6ae9f6baa040d736ab84d48344bb6b70d7f1a280dd12cbac4d777 +",",a5fd02f646fe241c948cba117916c3a4ce6fbcf76afe3e9cb3e49e4cf7b65 +-,935e4e26eafc11b52c11668e1d6634e7d1d0d21c411cb085f9394268eb4cdfba +.,95f6e3383d128f17d73cf39af7b579889779c4e5f38d2c1ef85dba2f462f6840 +/,fe6e82d12a5f7bbe34d9b7bf632e88a50371a2ac39c26bef05f72cdd75b185b +0,6d68343bd0b129de93cc8d3bba3b97a2faa7ade38d8a6e2b864cd868cfab +1,d2a6f0e84daefc8b21aa99415b16ed5fdaa6d8dc0c3cd591f49ca832b575 +2,96fab991d083993cb83e4bcf44a0b6cefac647d4189ee9cb823e9cc1571e38 +3,cd319b9343f17a35636bcbc26b819625a9333de3736111f2e932827c8e749 +4,d198d56216156114265973c258f57fc79d246bb65e3c77bbe8312ee35db6 +5,7fb91bb97749d6a6eed4449d23aea284dc4de6c3818eea5c7e149ddda6f7c9 +6,9c613f80a554918c7ab2cd4a278752f151412a44a73d7a286d61d45be4eaae1 +7,9e198fd831cb61f3927f21cf8a7463af5ea3c7e43bd3e8ec7d2948631cce879 +8,84ad12c2f21a1972f3d2f381ed05a6cc088489fcfdf68a713b387482fe91e2 +9,9f7aa0d97983cd67dfb67b7d9d9c641bc9aa34d96632f372d26fee19f71f8b7 +:,ac4c26963f8538c11eac6a8e437d27682dffea4bcc0f04afd5cda6d1d567 +;,65e3332e38a8c334b5d2a7225c9d3408590bd5c61bafa7c8714563552c28084 +=,49f181b413daa26424fde063ff32cd9715c95256b0f25037c2f0ede1d5e53b5 +?,46ba63344f49dd1c4f5488e926bf3d9e2b29916a6c50d610bb40a5273dc8c82 +[,432d6da968a4c358745f75cdb4de89b58e23585229348c82a917e6777ab68 +\,88425d354235c1334d7d09bbbf18dd965e1c0c238695b0b29023e7dcb5b3 +],32ea3cf74d242e71a0366b5b87c6028c69294ace1c71a1cedc54da1b2b4bbde +_,979a465183a3ba63fe6ae272bc1bf1cd15f2c209ebbfcc5c521b9514682a43 +a,17dd34924d2b6a213a5ed46ae5783f95373a9ef5ce5c88f9d736705983b97 +b,9eca98befd0d7efca9b11ebf4b2da459cc19a378114b3cdde67d4067afb896 +c,56b1486e1f576bc921b8f9f59fe6122ce6ce9dd70d75e2c92fdb8ab9897b5 +d,59aa69229ffdfa182889bf3097d32215c1b2159d987103b1d5843646faac +e,ced9f431a997fce0d8be1844f62090b1783ac569c9d2797528349d37c215fcc +f,9d714bafb0b5ab9cfa7db02efc8927aed1ef29797a595da066efc5c3efdc9 +g,58c336dedfe197b434b5ab67988cbe9c2c9f285ec1871fdd1ba434855b +h,bde4a89be2197f86d2e6166a0ac541ccc21dce28b7854b788d329a39daec32 +i,c148a8865bc4afe0747f3415138b96bbb4e8bbb7261f45e5d11d7219f368e4 +j,18c9dc3d38a56282e1d92337198fb19ea641b61a8c4e57fb4e27c1ba6a4b24c +k,12bfeb246f649b86f212feea87a9c216a655565d4b7992e80326b3918d923bd +l,cc58321d4bffbec2ddf66bf38cf2f9e9ddf3fa2f1387dc7d30c62b4d010c8 +m,90376dc5e3c981b52960578afe4bfc41c1778789bcd80ec2c2d2fd460e5a51a +n,612c7afea48e53325e5129038a45aec51afe256abca941b6bc8206fae1cef +o,1c27235de3a55466b627459f1233596ab6a22c435cfc89a4454b47d32b199431 +p,c584dc7ecf36b4f044f8262527985718bf24a9daef012de92e1e76d4586d96 +q,ff72cceb4a565478de5b0b0e727946e549834e36f6e0ec8f7dd7f6327b15a +r,3cb88225ee4ab39f7cbf581f22cbf08bdcc33884f1ff747689312841516c345 +s,af22d7cd53d5bfe61eafbc2fb1ac94443eec24f455292139ac9fbdb83d0d09 +t,fc2fcbc24e7382ac112bb2c0d5eca27e9f48ffca5a157e502617a96d636f5c3 +u,9fdc4f321c78d67484135ae464af4fd925bd57d459383a4fe9d2f60a3431a79 +v,2dd0143d8e449ad1ba97e1981712cee0f3fc297dbc17c83b05eea3338d659 +w,79cbc465525e16a89441d789b72f554e8ff4ea5b393447aef3ff193f0465058 +x,c38ab145747b4bd09ce0354354948ce69ff6f41d9e098c6848b80e187e919 +y,a71071bef733f477021b3291dc3d47f0bdf0be2da1b165a119a8ff1594567 +z,c992c753bf9c625853ce2a0b7b174b89a6ec26bb5c3ccb473b6a2012496312 +{,7f885af5a366bb3eb9915c6477a357066fe2cc17ede236c6c81d23e5057 +},b9e2353ef1a82b258f9b9d2d28db9b71966da0d224a536be9a6498198b11907 +\u00A1,dc4e441eac884de3347a8775a07a66bbc4c82a24ed2d0cfeb1acaf6ce99d53b6 +\u00BF,3743f0a3849afd50dc332e5cad284a2555161a4bf9122a8c635940b9d21ed393 +\u00E4,15b61375135fa952fd7bfcb19bef166287f02f73c3688f1f91286d43a634625 +\u00EB,ea85bdaef6e1e9f6376a16143f03df9d6291657707f8adc456e126bf04046 +\u00F1,f41daa63d5dc36f8cff6ab2e8bdeb70fc2cf56e1893c924489203cb8b45fe3ef +\u00F6,139926539b4a04023aed0e89b8fcb883af3bb363ab3ac44998ad47be8b257e7 +\u00FC,9b7a79f187a1478b7b555524fa7321f46c84457bef7ab88d8b3dbc6afbf1fa6d +\u0431,3f687c22ad7715f530d0bd65a2331472491261bda7e9bed086c37eb6b543623 +\u0433,ae7f9974da9d6dc8adf18f9ebd1449e077d4efd6dd779caa1db9d05893ba62e +\u0434,5bd369973c59b9f7917aa58394fffd05e84b71aa9a1bfdf9eca8d8a627f58 +\u0436,dcb4636cf894d88fffe93f4f48c823c815afe258e18665770616fb55289472d +\u0437,7e50b1d3abbaa471802920aa8b3eb215493821e5d446dabbcccab3c5fae803e +\u0438,a15922fe8bb7efda8824a8c5bd52a31a38152c77934449b548176fff82b8b +\u0439,22e3161af546d67a945c6de7e1598123d65afb46c64195b6147a73b1e272672 +\u043B,18f91c358db455bde0f8a6de8e289efb3fe06b371ba59572bcb4f74a136023 +\u043F,4359c75166cd755a01e59884f3fb7b3eb235753174ffde94c2fc68b13eedb6d +\u0443,30427b18a6b03b4f1231fd63177bd044d16f7045d39aece3f05a9080f2edbe6a +\u0444,65f2dc35eaefb68d99d9e24b31618dc61de39e5e65e80dfa2311bb477dbc47e +\u0446,683381a0132457320d033296fa3dc3ecf4de482470dca87d2fb7ec9f32afa +\u0447,bb35aa5e186df1cbed535db5ba18d0e15d48cc3cff4ec66cdfa18c2923f58f +\u0448,d1ccd87ebf862568997158d68c5ee55be2c31221085cb748a36a8c691f4667c +\u0449,1b748e6336d9537aef58eb9fb433c8631418bb83f23089ddf622f773c78084 +\u044A,1cfe5a802240b96aa67db5171f77e59f7bd5d231834152c7d4df62e694dd +\u044B,ea53755362281c881c50fb47d7cd83bc782d2289d8c91d4f26c42ffc816c6c +\u044C,993448106f2988d4cfb35334bfd776f71c1b3d668fbb7ec6af9c956e3845f2 +\u044D,a96ab73efa8b3848f6cac0aad6817aef9ed6f9e0d5bdc3629eca5045dd43256 +\u044E,3aaf87e9192cb15253f48bc7e7c6ba1953363e8df4bdd0b069f8d7f5fbab8494 +\u044F,a3d2975db2f1c2a385f8cd797886eeaa4b5e8519c07e6bcf16133c72c7d73 +\u2190,37aee9a75bf0df7897183015cca0b2a7d755c63388ff01752d5f4419fc645 +\u2191,6ccbf9883dd359fdf2385c90a459d737765382ec4117b04895ac4dc4b60fc +\u2192,682ad1b9cb4dd21259c0d75aa315ff389c3cef752be3949338164bac84a96e +\u2193,72431911f4178b4d2b413aa7f5c78ae4447fe9246943c31df31163c0e043e0d6 +\u2196,47456b506ee3dcab215f33cb93a9edd9749f3e2ff8a4893426e1784692de8b5 +\u2197,16227036b8afed6935d53143d16488d39cf4fb73a671f2b2955e80fc9dfe458 +\u2198,dbe6713f20a9c2de43803b90aefa4db9a6bf89915d7c1590f77a7e10df3a3e54 +\u2199,f1fab0e6aea88748ca3b5512ed502a6d18e76d8afc4770d995233ac0dc5186 +\u23E9,d99f28332bcc349f42023c29e6e641f4b10a6b1e48718cae557466d51eb922 +\u23EA,118a2dd5bef0b073b13271a7eeb9cfea7afe8593c57a93821e43175572461812 +\u23F4,864f779a8e3ffa231143fa69b96b14ee35c16d669e19c75fd1a7da4bf306c +\u23F5,d9eccc5c1c79aa7826a15a7f5f12fb40328157c5242164ba2aef47e5de9a5cfc +\u2640,cabf622e8ddaf409689aa45b7b01f1b57430e323a908e5ccc9c0da7228883283 +\u2642,162606025186a6523e2710da4c9fae8fa8d5dabecad6c49c96ab38149b591bd6 +\u2648,72361172d540d8f0ccea5b78dc7f4f93e24ff306e93b7b79b9cbb223da4da128 +\u2649,13c8d1d0274847532a76284bc0cdbf3ca3b974cb5e1bc1f52111064d72e6d4c1 +\u264A,ed6f9077fa20667e7ce78dd7fd81c6fe8f46d38a50a525e977efdc172d9d3308 +\u264B,d565bf7837ec875885bce1436138af22cabf834e97c58b48c79e4d13ca2b9ab2 +\u264C,61dd98a7c37d70d9237335592efee5b31c23520d72e829f746522cc982fb1ad0 +\u264D,3aeedd65a4f62bef5484b8d37b4d78383f2d66c4d8774a58a92b83ca47e1bd10 +\u264E,3865050656d3722daac24db5bc0d7cf5f7ebb99cf1a322c19a4d642db270d43c +\u264F,71c503d6cf5eb37eee1315958a31d3af9ece4686237ddc7bcda963da9609bc30 +\u2650,420b9fb8fcf7c05de1946cf4d25bbf9ec975d7e3648d2cd2970fe9c0253cfe23 +\u2651,c6be0cdaa937bcbb4df1130a6291ad710116ea838125f00af44ec988695bc6bf +\u2652,35b8018b0a9c07c1cdd530f9417f7d6bb1be77c0210ed77c2d6c15e36288c26e +\u2653,c5fbbd16424df096d4f900912f508b9db4b333d93d5af5bac46eaa244c48bcd +\u2665,ce3a59e4c5753295d8d69c214344ebb3e547f936b867ad9d5ebd519fad85ce3 +\u266A,afaaf3c0bf836cdbd2c8401ec04dc3019cbf390e6af4fbbe0e831c130688a98a \u2713,2b0c1647dae5d5f6bc5dca549f1652556c7f1bc08adee37ccfc4090bc20e647e \ No newline at end of file diff --git a/src/main/resources/fonts/blue.csv b/IF/src/main/resources/fonts/blue.csv similarity index 98% rename from src/main/resources/fonts/blue.csv rename to IF/src/main/resources/fonts/blue.csv index d4f5a15b..cfaa37a1 100644 --- a/src/main/resources/fonts/blue.csv +++ b/IF/src/main/resources/fonts/blue.csv @@ -1,118 +1,118 @@ -" ",87572b5afe38fa8b051e90bdbf461b4737abe4550a35c82fc2dca6d75583a -!,f23d5ff814f095d3fbe5e53aef08515e02f99c8591648835f6edd59356b6 -"""",40b051aab78fc982e42fa1db3873335b18124c699bfe31943328c213448fd80 -#,ec8236e3285fe62f6467346911a198e90d2b9a35a5db4ddbac91ac2992a6b -$,999af486ce72bbb1d4fe95bbcfcdf596681d9d6108b5632fb8993dfe9dbf3293 -%,7c1873d2dd1376bbaf78918af80a5b64c37ff8cb3c7432bb9765d65e6fc4 -&,fb5e9a3ff20592b4a215893589ced9153704922bc3d40d575a1a5514bd66bb3 -',2741703e1bdd27ce5821d960ed3e4d74f5562f4eecd3a274ed129de6e37b08f -(,93e5c524cf1257d27d60ccb3f186aa7e658c1784997261911c56d3793fda19 -),b63e1ed8e682595d54a4e142525d5427f28a6ec56e7b37d336b97e2fa4ab1dd -+,eaea5d7127214ee2cca1b82ef82f8ae55929325766ea84dde18c11de0c7d591 -",",fbf7cbb7eb48d44a2cb555d664724a43d0449e63f0ed1585f0be468357cac --,f84ccff09f83a2aed9ebe08b6817eec667fb996d12986cb98ede41af58bb1d -.,ffa532f4f8ea816a789dc7ad4cea1540f6dd74472da97ce12264e51727cea9e -/,8eaebe3053ad549ea82f984bffbfe4433216c3a8bacb1e99e3d1d28ef293a -0,e5a74393822151d3e81f8794ff84bc1b98c57ee9a8a81e29831f73eda2b36a -1,bd21b0bafb89721cac494ff2ef52a54a18339858e4dca99a413c42d9f88e0f6 -2,2b3513aa4117a3a329e1f9a43d2a8c51cd722aadd4e8af2feda67b33b64c298 -3,69e38c81436f3da120672efb162d2f4ea874ab0ce545ae323777f5e573c254a -4,f03d45521c27fdd2f2b1139a1a17d6495e8f47d9f123493d4dd8aa06aff40ce -5,9f2a14dbf9588126c43cd2111eb41f1de6d8c281b6519194364b9965fc456e -6,eae7cb37ffa6866317672924301b1b29633e6f23f2525513dbf729bd2d066 -7,e21d562c5a51b64229fc626f25c421f6ac38cf7839e1c6c47168fac3742ccdf8 -8,b6b56cb0b48d9c9edd1984afe1713b98eea96d29be5b2b58da4444a1018e95d -9,137fdef8295df3fb6dea21c6c8e451f1f7fd657a61cc6423a3ce42c2fb961b6c -:,f3ef3015deea8c9d5fbea7f450254c3927ae2b1c2cd18418519902ed53ad96 -;,da3322ac5145cca7bf86220e14e4ad48f32b572d4644df2798f98358e5bfcd0 -=,a7ab5cf2dfdc9e8ee3c79db14226cdf41b1b15f67b1613184a49e3c13e379de -?,59d859d6baf33eccde997501a76e8b83c41aa6859b8e4fe1be2ac08cc04843 -[,46b43224202616d4dd80a56c4b94df4d63a8d5d9ccd7996bef9840311fae52 -\,bb37fce5fa1e970802af5c66e0f9da8e165e3087af30a8fe3354eed087c3ca -],e7225c829a8181618382c638d5758b324afce7e354e3e32448c949a556817 -_,8bf88fdb1d34b7ed24f42613887d6bd754a141918c940a99932de10c348585f -a,3e69bd2a5cd6d7fcef212a706de0ca4cf14bba1f557d4f4b4c7447025ab187f -b,da1484f5c5458a3ada594a528b65bf9a9d577e25b2717da786461c9b6588b48 -c,e26fb169d3d7b849f0bb9a70eb7b481d6f71e97c8ecb13546ec9723814917 -d,c59dc2c1a22ae7fb1ed2188c7dea6c95b3542f10d9e26ddd958594eadd555a1f -e,50ef694d67285255247a85cb21793c793d9512d1b1654e615d48835ebae5c -f,7f9fd21a2e2f572e9e5bf0b552f09c416c4876cbea0d4ac3ec1e69deec59a -g,bc76b4e9fd87b77b8c95a8d18484168cbeb78fab5d529d6b6c132246cc3cbac -h,10b4addbc8adba6eeba49de553719aea364a2ea67cb2ca524a320c101254 -i,7164b69326bdc41bf7741dcb7034fe4a571c2c79f9b9835e791a3727d1afd -j,a45bfadf75768b2b72a598cd463c155ae218b01058c188a699f274d47a9ff -k,1468d692b3a3f746369476c2f262a9c0512ba9bf92cc18f13cd3d5fb8ac418 -l,6182d55bda99774190f0f88e18e53c65affc986b3ebbd6388734ca707c5d50cd -m,53fa332737915568e2a2861232ac6ea79cf1c28c4af11d5117bd76b3bb6b26 -n,5ef9efa7447af8f116f8f9d146e26d713b216ae207551e0faf177dedcf71027 -o,63f46ccae2bb1243c83d6676b248c2b1d4342eea379315caec021b7d1d3557 -p,d489ee15cced4b549930282fcbeb0ff4c1276f630396bba6ba7c03edd90d5 -q,2e759ecc8274841a8c9871db666e9cb7acc7531fd9f3bd35ac8a127a80f166 -r,b597ff664fc91cbd4a35691e22a048811347d6aa9d5fe4527c9fc39f55fc -s,5729d03f7b643ec6fb25e392a88f059e6639b6dc593e0ba845879fcecf339be -t,fe309df3c3c0b1be103ca877993baf02c723569ad1a7fb0f6f7113e8cf6ab95 -u,f705bce7db5abcd3ef63ef88395224587e570fe575d9d06310372cbcae5e -v,c8956c61188cac3d6f765f4d2a599b7ca7cdf6823ff17683c5520946c1a84 -w,8cc7bc53c8f9703383fca0fb5ae0ba35ceec114dca99a942610462c4b1c55c -x,d5e1be33374fd7b2bae9c8fc9146b6ed3eedcb1476b3b7b8010f5f44bfa843e -y,e9483d0d3ff21249da9e6f405bb0ea7886558df1a84c9ae364ef4e8674eba8 -z,a2d354928d9c728cc3d4461aa266ffe4bacfe44921afead2b59dc7c981a9346 -{,e6c22dc39c797316e6226a1c125fca54a76b48fdde1dec7c36d2f848e93fc -},a37ab2dee515368aaec6b748b0eb32d1c9b39412293cda4aca336169e9dfc092 -\u00A1,d072e767095c069eb64b234031dde8c5bbbae94c2d0518c990e556ebfe76e340 -\u00BF,f91910586567c3a57ff015bc7e5c5bf48778f188cd4b931e6788f05d30cd71f6 -\u00E4,d25653bb12b0eabc9428cac1d4e2369116e819aadf32e7842616c65dd78a68 -\u00EB,cd9e34e1c6b88fb6738a7da8ce89bf8b9928ba5785ab1840cf2a54c65be354 -\u00F1,751ababe95d08fa8669b3ea2c2d4708905029f6950e212052151ca4e8fee8c25 -\u00F6,40a2529125c66818361d19adc398e0b3857ee3c83ca3ced54284b1177af81 -\u00FC,d53ce042deed22ac9df98d7ae705d3ebb3d974cf253d451617fd0a1f4fa4634 -\u0431,dc63248ad0f06b5bdba3b1cd8211f31340f568bed41e036f8609bf6108344e8 -\u0433,19d4ad2db0cae4c063c856d8f838b47896c96156fd2baed08ce73a47a52a66d2 -\u0434,de37432521ff735fbb8e58f968176ce721f306dd1b169b3667d864126aeeb8a -\u0436,ab7e1da3b5f094216bdb225de947e40372c5595e76f17a4abdf326626c95f1 -\u0437,35a66cfeed405e978119789c5a36225457ad9fbe0c726685c90249758f425b -\u0438,9b252944fb61b227b52e6bdc07ae6de3b8978b44ec2cfdeb3d6b0ce178761dc -\u0439,9ff47bd775a67b15d9adaa1a497d535c8fbc4037b236458b953b5d31e92c36fb -\u043B,3e16289c8f7f95b0fc7d20c39a893b99c4e63445485b3e69be1ca4438e732c -\u043F,326232e340659da82d86f318bf742e6ab983429b20589fe6e3d5e9289fdca2 -\u0443,274866f31be7d81b2de9b588aa1e2a3eadf226fb929b62e139b4e6785ea490 -\u0444,28108b517ad1973bdf9e183f1c7d6e690d5865180153baf2d14c1402428279f -\u0446,5355f0923abd923edc5c4acb2d6a901b5ded3f966e2f61101d3594a2762156e -\u0447,16abf75e1cd665d3a33b51eed9c25f53f90c82d869cb9abf366d3276b3d1b4 -\u0448,7af2cdf325b6e702450b85c1f3a14d461fdabfe72297ff88ba6e2cd2719627d -\u0449,7b2826987260d5bf2136e13ff36254e196dfced86daf748a9c59d930bb856d -\u044A,cc482a9ecfcd3680fc31bb08d4ac5c8a869b764419446e4b6ed4bf7da315b9 -\u044B,ba082213639de136a2d561303acf39e264a776f5eba687b83e8a23735c14c -\u044C,3ab5d817e726acbcc319a2387322a4c78da252996c43b54930df815818a594 -\u044D,f2a967fd8a9df8d91eddd03da16afe3854273abfca83786982ba43d1881bbc8e -\u044E,77dfe052d412cb20628d9b93cf8605f2db41e4b12f1387d5b8c4b9111accf5 -\u044F,e41e6236feed403bbb43d51b32b2c46acabb8fcf013fbabb7664e9f341d9 -\u2190,5ae78451bf26cf49fd5f54cd8f2b37cd25c92e5ca76298b3634cb541e9ad89 -\u2191,f2fc23866523caaa8a9534566127a6f8389af3e76b8e3c33c2473cba6889c4 -\u2192,117f3666d3cedfae57778c78230d480c719fd5f65ffa2ad3255385e433b86e -\u2193,f0d1df8046f0b5d934c3e05798eacfeea6d7b595dbe26debf7db9acc8c4fa798 -\u2196,111f4d8f40399b845f377da9235706f6b447b638319d8e72383b4fdb74a944 -\u2197,3c8870749b145b6fcbe50ea77ad2bf22961ae6ecc425a9a1fd13e3bfb02d54 -\u2198,4d5e3d6cbd98a094f4c0ec78d34bde1ec8a62fbfe28b78c12f9ba84719f1ed5 -\u2199,288eb5f528cec583803757ba202c15362f84a3f6fbe8712e8ab256f25e5245 -\u23E9,fcc6fd57328f3a11e2b9bc89cc32bad71cafde18fd271c17504b27f6e51c -\u23EA,fad0807ac7952c4250ab59fba82646222a1a2cb6d643e4a566ae75d863254db -\u23F4,d7b99d7d3cba459e1a882447dacdb27943c1ef721b2aecacec669bad31cafa -\u23F5,74bfc66c5121351a526662fc5c15c35639abbbe3f9b17d55ef1fb5e68e6c8 -\u2640,de2be31e65f7670d60c91b7bc5d421a7931ad8530c3c293578087a1e5162c6ec -\u2642,c8b6d2a6d4dcfa035716750487e7062d3696b3ebe22fa19ff52dd20f0da0a83f -\u2648,1853758c83bf82eff977e0aa8c4d00897894cbb6b82990cf56db7b21281de9dc -\u2649,94d03635b7f25bfe3e2a8d814c9b0221fe92db29ff415113819bbc1fd4b5ef97 -\u264A,ab9ed6cc867c773ccbf573b754e9d83042f46144dc31f336ec2b9621ac8251c4 -\u264B,69b0205fe0fbd66bb8e4763383acfe3a4d7a0cc59886248f72cd1359507813d0 -\u264C,d6d569e5610f8b94294628db3e245129750c969170e2e168ac941e41138b1d28 -\u264D,7565840841db3775cddcf343870a0954090eb4aad3c56b4ec45a436b4bf02fd2 -\u264E,fbc0ea088b773ab95e5a6c056574a59c91f83d70096b76188a2ce2c1c79d43fc -\u264F,bb19d16c296a617638749a95421f9bff53956cf87a32ffabc26d11aeadf720af -\u2650,248b66d50ac6332ade2062b66e9013cd3949c7fac2317c4672a712c973ab109c -\u2651,a808d8664c44b59c1a89572f5f55f0d1565f298c47272ce838eaba3aa98bdd1c -\u2652,852dd0acf321d264249a79a5b7ac1482c253c06297709fd07a740c707a6bfd00 -\u2653,cd0a480effc0919b9c0469ecdf0e8545fe4e9845b7980ffc07055214ce9fe40e -\u2665,bfa9de39c793528e15de617f429f74bfb43609b524881c494e2fe7add45a67 -\u266A,14cf2dcde63e2d72dabf7f13483a8a886fe2c58dc60f6c3f1393d74b661e5a68 +" ",87572b5afe38fa8b051e90bdbf461b4737abe4550a35c82fc2dca6d75583a +!,f23d5ff814f095d3fbe5e53aef08515e02f99c8591648835f6edd59356b6 +"""",40b051aab78fc982e42fa1db3873335b18124c699bfe31943328c213448fd80 +#,ec8236e3285fe62f6467346911a198e90d2b9a35a5db4ddbac91ac2992a6b +$,999af486ce72bbb1d4fe95bbcfcdf596681d9d6108b5632fb8993dfe9dbf3293 +%,7c1873d2dd1376bbaf78918af80a5b64c37ff8cb3c7432bb9765d65e6fc4 +&,fb5e9a3ff20592b4a215893589ced9153704922bc3d40d575a1a5514bd66bb3 +',2741703e1bdd27ce5821d960ed3e4d74f5562f4eecd3a274ed129de6e37b08f +(,93e5c524cf1257d27d60ccb3f186aa7e658c1784997261911c56d3793fda19 +),b63e1ed8e682595d54a4e142525d5427f28a6ec56e7b37d336b97e2fa4ab1dd ++,eaea5d7127214ee2cca1b82ef82f8ae55929325766ea84dde18c11de0c7d591 +",",fbf7cbb7eb48d44a2cb555d664724a43d0449e63f0ed1585f0be468357cac +-,f84ccff09f83a2aed9ebe08b6817eec667fb996d12986cb98ede41af58bb1d +.,ffa532f4f8ea816a789dc7ad4cea1540f6dd74472da97ce12264e51727cea9e +/,8eaebe3053ad549ea82f984bffbfe4433216c3a8bacb1e99e3d1d28ef293a +0,e5a74393822151d3e81f8794ff84bc1b98c57ee9a8a81e29831f73eda2b36a +1,bd21b0bafb89721cac494ff2ef52a54a18339858e4dca99a413c42d9f88e0f6 +2,2b3513aa4117a3a329e1f9a43d2a8c51cd722aadd4e8af2feda67b33b64c298 +3,69e38c81436f3da120672efb162d2f4ea874ab0ce545ae323777f5e573c254a +4,f03d45521c27fdd2f2b1139a1a17d6495e8f47d9f123493d4dd8aa06aff40ce +5,9f2a14dbf9588126c43cd2111eb41f1de6d8c281b6519194364b9965fc456e +6,eae7cb37ffa6866317672924301b1b29633e6f23f2525513dbf729bd2d066 +7,e21d562c5a51b64229fc626f25c421f6ac38cf7839e1c6c47168fac3742ccdf8 +8,b6b56cb0b48d9c9edd1984afe1713b98eea96d29be5b2b58da4444a1018e95d +9,137fdef8295df3fb6dea21c6c8e451f1f7fd657a61cc6423a3ce42c2fb961b6c +:,f3ef3015deea8c9d5fbea7f450254c3927ae2b1c2cd18418519902ed53ad96 +;,da3322ac5145cca7bf86220e14e4ad48f32b572d4644df2798f98358e5bfcd0 +=,a7ab5cf2dfdc9e8ee3c79db14226cdf41b1b15f67b1613184a49e3c13e379de +?,59d859d6baf33eccde997501a76e8b83c41aa6859b8e4fe1be2ac08cc04843 +[,46b43224202616d4dd80a56c4b94df4d63a8d5d9ccd7996bef9840311fae52 +\,bb37fce5fa1e970802af5c66e0f9da8e165e3087af30a8fe3354eed087c3ca +],e7225c829a8181618382c638d5758b324afce7e354e3e32448c949a556817 +_,8bf88fdb1d34b7ed24f42613887d6bd754a141918c940a99932de10c348585f +a,3e69bd2a5cd6d7fcef212a706de0ca4cf14bba1f557d4f4b4c7447025ab187f +b,da1484f5c5458a3ada594a528b65bf9a9d577e25b2717da786461c9b6588b48 +c,e26fb169d3d7b849f0bb9a70eb7b481d6f71e97c8ecb13546ec9723814917 +d,c59dc2c1a22ae7fb1ed2188c7dea6c95b3542f10d9e26ddd958594eadd555a1f +e,50ef694d67285255247a85cb21793c793d9512d1b1654e615d48835ebae5c +f,7f9fd21a2e2f572e9e5bf0b552f09c416c4876cbea0d4ac3ec1e69deec59a +g,bc76b4e9fd87b77b8c95a8d18484168cbeb78fab5d529d6b6c132246cc3cbac +h,10b4addbc8adba6eeba49de553719aea364a2ea67cb2ca524a320c101254 +i,7164b69326bdc41bf7741dcb7034fe4a571c2c79f9b9835e791a3727d1afd +j,a45bfadf75768b2b72a598cd463c155ae218b01058c188a699f274d47a9ff +k,1468d692b3a3f746369476c2f262a9c0512ba9bf92cc18f13cd3d5fb8ac418 +l,6182d55bda99774190f0f88e18e53c65affc986b3ebbd6388734ca707c5d50cd +m,53fa332737915568e2a2861232ac6ea79cf1c28c4af11d5117bd76b3bb6b26 +n,5ef9efa7447af8f116f8f9d146e26d713b216ae207551e0faf177dedcf71027 +o,63f46ccae2bb1243c83d6676b248c2b1d4342eea379315caec021b7d1d3557 +p,d489ee15cced4b549930282fcbeb0ff4c1276f630396bba6ba7c03edd90d5 +q,2e759ecc8274841a8c9871db666e9cb7acc7531fd9f3bd35ac8a127a80f166 +r,b597ff664fc91cbd4a35691e22a048811347d6aa9d5fe4527c9fc39f55fc +s,5729d03f7b643ec6fb25e392a88f059e6639b6dc593e0ba845879fcecf339be +t,fe309df3c3c0b1be103ca877993baf02c723569ad1a7fb0f6f7113e8cf6ab95 +u,f705bce7db5abcd3ef63ef88395224587e570fe575d9d06310372cbcae5e +v,c8956c61188cac3d6f765f4d2a599b7ca7cdf6823ff17683c5520946c1a84 +w,8cc7bc53c8f9703383fca0fb5ae0ba35ceec114dca99a942610462c4b1c55c +x,d5e1be33374fd7b2bae9c8fc9146b6ed3eedcb1476b3b7b8010f5f44bfa843e +y,e9483d0d3ff21249da9e6f405bb0ea7886558df1a84c9ae364ef4e8674eba8 +z,a2d354928d9c728cc3d4461aa266ffe4bacfe44921afead2b59dc7c981a9346 +{,e6c22dc39c797316e6226a1c125fca54a76b48fdde1dec7c36d2f848e93fc +},a37ab2dee515368aaec6b748b0eb32d1c9b39412293cda4aca336169e9dfc092 +\u00A1,d072e767095c069eb64b234031dde8c5bbbae94c2d0518c990e556ebfe76e340 +\u00BF,f91910586567c3a57ff015bc7e5c5bf48778f188cd4b931e6788f05d30cd71f6 +\u00E4,d25653bb12b0eabc9428cac1d4e2369116e819aadf32e7842616c65dd78a68 +\u00EB,cd9e34e1c6b88fb6738a7da8ce89bf8b9928ba5785ab1840cf2a54c65be354 +\u00F1,751ababe95d08fa8669b3ea2c2d4708905029f6950e212052151ca4e8fee8c25 +\u00F6,40a2529125c66818361d19adc398e0b3857ee3c83ca3ced54284b1177af81 +\u00FC,d53ce042deed22ac9df98d7ae705d3ebb3d974cf253d451617fd0a1f4fa4634 +\u0431,dc63248ad0f06b5bdba3b1cd8211f31340f568bed41e036f8609bf6108344e8 +\u0433,19d4ad2db0cae4c063c856d8f838b47896c96156fd2baed08ce73a47a52a66d2 +\u0434,de37432521ff735fbb8e58f968176ce721f306dd1b169b3667d864126aeeb8a +\u0436,ab7e1da3b5f094216bdb225de947e40372c5595e76f17a4abdf326626c95f1 +\u0437,35a66cfeed405e978119789c5a36225457ad9fbe0c726685c90249758f425b +\u0438,9b252944fb61b227b52e6bdc07ae6de3b8978b44ec2cfdeb3d6b0ce178761dc +\u0439,9ff47bd775a67b15d9adaa1a497d535c8fbc4037b236458b953b5d31e92c36fb +\u043B,3e16289c8f7f95b0fc7d20c39a893b99c4e63445485b3e69be1ca4438e732c +\u043F,326232e340659da82d86f318bf742e6ab983429b20589fe6e3d5e9289fdca2 +\u0443,274866f31be7d81b2de9b588aa1e2a3eadf226fb929b62e139b4e6785ea490 +\u0444,28108b517ad1973bdf9e183f1c7d6e690d5865180153baf2d14c1402428279f +\u0446,5355f0923abd923edc5c4acb2d6a901b5ded3f966e2f61101d3594a2762156e +\u0447,16abf75e1cd665d3a33b51eed9c25f53f90c82d869cb9abf366d3276b3d1b4 +\u0448,7af2cdf325b6e702450b85c1f3a14d461fdabfe72297ff88ba6e2cd2719627d +\u0449,7b2826987260d5bf2136e13ff36254e196dfced86daf748a9c59d930bb856d +\u044A,cc482a9ecfcd3680fc31bb08d4ac5c8a869b764419446e4b6ed4bf7da315b9 +\u044B,ba082213639de136a2d561303acf39e264a776f5eba687b83e8a23735c14c +\u044C,3ab5d817e726acbcc319a2387322a4c78da252996c43b54930df815818a594 +\u044D,f2a967fd8a9df8d91eddd03da16afe3854273abfca83786982ba43d1881bbc8e +\u044E,77dfe052d412cb20628d9b93cf8605f2db41e4b12f1387d5b8c4b9111accf5 +\u044F,e41e6236feed403bbb43d51b32b2c46acabb8fcf013fbabb7664e9f341d9 +\u2190,5ae78451bf26cf49fd5f54cd8f2b37cd25c92e5ca76298b3634cb541e9ad89 +\u2191,f2fc23866523caaa8a9534566127a6f8389af3e76b8e3c33c2473cba6889c4 +\u2192,117f3666d3cedfae57778c78230d480c719fd5f65ffa2ad3255385e433b86e +\u2193,f0d1df8046f0b5d934c3e05798eacfeea6d7b595dbe26debf7db9acc8c4fa798 +\u2196,111f4d8f40399b845f377da9235706f6b447b638319d8e72383b4fdb74a944 +\u2197,3c8870749b145b6fcbe50ea77ad2bf22961ae6ecc425a9a1fd13e3bfb02d54 +\u2198,4d5e3d6cbd98a094f4c0ec78d34bde1ec8a62fbfe28b78c12f9ba84719f1ed5 +\u2199,288eb5f528cec583803757ba202c15362f84a3f6fbe8712e8ab256f25e5245 +\u23E9,fcc6fd57328f3a11e2b9bc89cc32bad71cafde18fd271c17504b27f6e51c +\u23EA,fad0807ac7952c4250ab59fba82646222a1a2cb6d643e4a566ae75d863254db +\u23F4,d7b99d7d3cba459e1a882447dacdb27943c1ef721b2aecacec669bad31cafa +\u23F5,74bfc66c5121351a526662fc5c15c35639abbbe3f9b17d55ef1fb5e68e6c8 +\u2640,de2be31e65f7670d60c91b7bc5d421a7931ad8530c3c293578087a1e5162c6ec +\u2642,c8b6d2a6d4dcfa035716750487e7062d3696b3ebe22fa19ff52dd20f0da0a83f +\u2648,1853758c83bf82eff977e0aa8c4d00897894cbb6b82990cf56db7b21281de9dc +\u2649,94d03635b7f25bfe3e2a8d814c9b0221fe92db29ff415113819bbc1fd4b5ef97 +\u264A,ab9ed6cc867c773ccbf573b754e9d83042f46144dc31f336ec2b9621ac8251c4 +\u264B,69b0205fe0fbd66bb8e4763383acfe3a4d7a0cc59886248f72cd1359507813d0 +\u264C,d6d569e5610f8b94294628db3e245129750c969170e2e168ac941e41138b1d28 +\u264D,7565840841db3775cddcf343870a0954090eb4aad3c56b4ec45a436b4bf02fd2 +\u264E,fbc0ea088b773ab95e5a6c056574a59c91f83d70096b76188a2ce2c1c79d43fc +\u264F,bb19d16c296a617638749a95421f9bff53956cf87a32ffabc26d11aeadf720af +\u2650,248b66d50ac6332ade2062b66e9013cd3949c7fac2317c4672a712c973ab109c +\u2651,a808d8664c44b59c1a89572f5f55f0d1565f298c47272ce838eaba3aa98bdd1c +\u2652,852dd0acf321d264249a79a5b7ac1482c253c06297709fd07a740c707a6bfd00 +\u2653,cd0a480effc0919b9c0469ecdf0e8545fe4e9845b7980ffc07055214ce9fe40e +\u2665,bfa9de39c793528e15de617f429f74bfb43609b524881c494e2fe7add45a67 +\u266A,14cf2dcde63e2d72dabf7f13483a8a886fe2c58dc60f6c3f1393d74b661e5a68 \u2713,a6f4431e983b3c854044bc00b7c54800243cd7dbf94de339b8c2f7b2566a5201 \ No newline at end of file diff --git a/src/main/resources/fonts/brown.csv b/IF/src/main/resources/fonts/brown.csv similarity index 98% rename from src/main/resources/fonts/brown.csv rename to IF/src/main/resources/fonts/brown.csv index fbb4e463..7b5ce92a 100644 --- a/src/main/resources/fonts/brown.csv +++ b/IF/src/main/resources/fonts/brown.csv @@ -1,118 +1,118 @@ -" ",37cec86f55422e6ccf9836aba09591cf5841e379a9a4394830f180957edc4395 -!,777e58e6d08fbba0bf4a1ef76b5372cdfb127638b17d322372e4c2e9728fa -"""",28cee9b73cb422c55c921d776a02b6478037d6c841fad3a368aed36ed0f297 -#,b56797e277ade8b56c6587ad73c0f16ab91b5df111f45173a8c377ac96ab72db -$,4aa580b9f2e7e2247245863f16911365e166c3d7324401cc587552d2900e5093 -%,243dd8693c8cd3264db39a2367703aecd97b7899521b5e46c0c9ce23983f57 -&,57d3eaa0b766e4fda2fcd769e88f7999cf2fe8c4293b0487ce0f24eea91837a -',ee7c98d831d45a3fa5fd9a1f198db8c41e2c14c60119c9d4050755e45ca86cd -(,a3c691a4ab8083595426afaa557678a6af9e8f959707cb47281e7887de54bb -),c6109eac62dfcd66dad9d1a52ca590ba53633f2dfec2490523a4f94ea95a3cc -+,ccb3b9ffc5334eb6249c9964605e14e3692bd6b175d2a963ca317c7958ddb2 -",",54badc10fff188a5b8b58f25eda9abbdd097274535487f2c4f54b4ec1d9eda12 --,b78666eaf42bfa6eec564a3dd7f986546da12c4ee0e5e72fbaa2c5aeb08f9c -.,36e82b51f26963ce64f09d9f503db9b221df2e54d621d3a9107b23d6d865d976 -/,566bd5b64735f3be6cbeb163890ec75522c94cc2d4c4c1a04ee2e7e43b9b -0,7bafba8a3d36476851e3655bbac87de2e718e85fc8466b2ba701aaad8cdb142 -1,3889921dfb3d93b10acc79dfbefed463c729e62b1f76a3dcce1b6c44012b -2,c6dde76e6f88665b681794b4b914ac513e57c272dd0b2f988f47b7482d4b177 -3,8b959649e1f9a20658c4142d181162014bf34710be91cb4d495bc74a7e127a -4,39240d3711b3f81134851b9228c5a3045788e7aba7014719b687f12857c538 -5,1926e41525d7219cfbf83b25c187251555dbf351369f95a25aadd70bc9dd7dd -6,905aaebbbc7fe93b6d51884bbded39f9a7c5467a86299f7fa0ffbd13e7b94e -7,dc4315942cb7ced179f13175951bd5ef91d42b534764b63bf840354086a5a7 -8,474ae33a4d1cf8a1bd2bc73e1361f5691cbcabb6d93c16b8c287bc757025 -9,b1d38a88cfa569f2a1545275fce4fd1869f75cb4853df510fc3dbe63be891e -:,8d89c095e48f93717888cff73ffc567f06baa2ef70296c7eadb915cdcd6ab4 -;,e46274c66453d6f3fab86197fe75fee12ab902532a5f36971712cb5e0a5 -=,98c8b7ceb1c32cb8997dd7f4bd73465e44f9f75a64057ee4fd6e55a71ce9a -?,6849ebf6d2ebde985d290787bcc4130b5b96ca3a96027a29cd545f911ebfbc6 -[,aa3dfbd967caab7bba68bc8d3e4adc7f19afa6023447ae245fafed3207a2bee -\,2a3f7ccf689343583f4b5aec3924865b827f92634c6d95a57903e6cb7d73b5 -],abf668e89301d1bffa0501f82aea8d84a379218cc2a512927a180d14dea39e3 -_,374fbb185ff6d1a5181db55818994883b263a835ed405a59d5d8b869eda8 -a,6f4b7b4494bd076832ff657ccd0da16327bb7beacd9a5ddf17d1db550cc7ee0 -b,f5c91616fd773b4a023640b8285e984d96f580e1322dd66732c3bd0a79e5 -c,8d2949f5c8fc51d18d71069ab15d22119a6222b56d783f6e6c5b36556b73dd -d,6e901368ccb5ce37c34ed78759381bd7a78db29ceda9b2c9eb72937b89ee6d7 -e,e4de2878f7414f91d48c69359c85939381a51a9d975f49135439d286c313e7 -f,324527c853e10b514cc95bb2352cd974e4aff1e341d0ee6a9d605746b9e013 -g,cfa5cc43ccb16946aad8cdd539821b3f5f0588bfc39eee29de9663a73375e40 -h,39b72c1c3a7aee2f3ee682a2ef8ccede14cbafbae1293dd5e34bf4c45c39b990 -i,bbb84e8f52e16e8883b5c4c846b4e942df7853339924f631e4e7047f647e1e9 -j,9112e2f34e56a9b90f781a5dc540ba7112b3ab47361c7cdf3a9d276135279 -k,bdcf90acba65c89cfc3260bfaccece74c02554696ffd2422cfd466149a262fa -l,3e98525d092e0eb946d3b9ae9c11d434b752b1060283dcab1acfaebfbaaa99 -m,8e5f8a61dce4b4ac909d84aa9d75ecfdad16d3bb97367078516668fabe8549 -n,aa590a15b4d23782db7889ce7f2c907bf4e18f0e57e9e0d3e52fd714b114 -o,4def6ac5f6b5664055f66fcd678bac5647633b6477822498ac14befd9ad5ba4a -p,edffeef89be11b325643c67bef559a33868c9d435de119477d56379591dd1c1 -q,31f0cc8a8db67e7d5f3180aac15b6f85cdfec9efa41a6ae3de248d445de33 -r,6f7dd78cdc1145e6b36d1e352b378f208f9b97d5fe2c1e50b919cc89adcdec -s,5aa0e68265c2a4e30e0859f51e8906133741b9a032c4b0103ced96e28c3bb -t,24d979e1ca980153fcd58155eeca87cfafaca31118c56bf4ad77284cc9e4bdf -u,2fe8aae1a85257733ca1365d245c8143d4c71460a571d9ad9c1f3a71e7e9463 -v,1e3f34be8f90d3c0efe87fea15f439a93d8be6e7e99c69b3a9d4cf4adbd5b68 -w,cbf68fdf363228d5144ef26157e7a8246786ba3b2edb3eb1cba3aa356015566a -x,41db2b5439101b95c6807053a1d69d8dffa7c4b8049c8810178fc4ba37a -y,ff2b399fc07f718a8416141ddaa49ab3ce7740c2b74c31d98cab8ff41bda90fd -z,e970194d73c85bb1dca424d0656e4bbc9467a67fc1edba1fc46834a37c1dd4f -{,fceebc9801ac5156940fbb4b76d255ddc9beb199dcdfd9e9eea92d944d0e7 -},9b3f8823cf9b48728bf47e76994c0a72c6b56de6d74c371dc7e1349a98550 -\u00A1,8d34f5e7c085d814f524302ce7490c435223f88b7dbccf852ff3afc9e987e1a9 -\u00BF,e665e065dd174f85e7bdb92854e3e561ab6eb3c5ee4a0ac7f7c4d1751713b1c -\u00E4,3222cea2906ff854c8efda071f1dd3ca062e7ee8a8a3ad965d6bfd266568 -\u00EB,68601f23a3c9a74d425da9b608cd0f5e7a9a16e273e9949351634999f3c32 -\u00F1,6a41a1e52ab6c0a49eee78ef65ff950887c439d1b3d315909baba636b9745e71 -\u00F6,7fa4ca50a45ee4e5b553f1313662c2c47da1e2b02f1b91e3e03eb9afce2033 -\u00FC,a7d1676c1570fe15dd71e9bcaf9447599ed546bac1436ec298afe0e8193af29f -\u0431,3d74b76bb413393acdda823f55773485397a86ace3ef898496168572c2c52 -\u0433,ab3ef6abc71972e3c1cb43e349a54bb7c7dd7fc5cf43562ac7a1824aadec176 -\u0434,12279af6dfe7babdbcfe060c456f4ef4725b9d673cc93595f2881c9feaa0b4 -\u0436,73a2db9ff069609840d54c992fa05683a5ae60b8f15ebdc1911d88cc9c49975 -\u0437,4b070e55ae46b3b18817acc34e86a1fcd9403e84ddd8df3703fb35b2f038 -\u0438,6e2cca17b0422671b91b4210851ec869b69bdbe5b4bbf495ccbac2de4990d1fd -\u0439,9791f4d0acd25582d28d9ca23d3facca3d1ff3930a0be423eacb7f32e83f34 -\u043B,e4163cce9fa563c7c3f4aa9e0872aa39770179f8e26a1ee08d70bd9d9dad3d -\u043F,14a5c4d333e6f68024818a14fcbbbda885fc7a331a1040ddedd6e54f687ff29 -\u0443,a9ce2dc1c72073a88421579f66c8899c75a877eaed02d7d6e59ae6523ce860 -\u0444,efc4a2c843cb8e36d802ddb71d7eacf85613791ea05e8eca7a642fd1a7ce38 -\u0446,fbe54386565c4f6875696b8d297629d63dcbfbcc1f5870fcac1e15a9d773e6 -\u0447,63cff2137b803e7189797dbffec745f6567e65c7a5ff4999104b43795b3cba99 -\u0448,317e6086827a28fff163291ccd954fb49d1e2973fed86da81cd14735e06662b -\u0449,a8f1e39a47215a5cba15eb8492eb11da829df28a3b8775c34b90c93951c9817e -\u044A,de28691a694d513bbe679a92ed9629b494bb7e8b5c612b64c6fe9e54999ce -\u044B,e6b2da3d73aab6e1250d9e23075bb37ccda4d58574b83b86052137c1a4b76d8 -\u044C,11d7414375a83dadbd4ae1de013765f094dcdc48a8eb9dc9c2ffbbc342093 -\u044D,8d1a5f3c6f6a5d1c778b51e3e248817a4b8028f4fb3299b8d02e7b56cac8e6 -\u044E,d6fcef514ad1e0ea780568b8116ef277b888abd67764a358558529ed21be1a7 -\u044F,27d5aa9a8fdfcfffbce1c5528e99f59f1a1c3d647c55e22c6126827fece68c7 -\u2190,5d4b334dc51156a8d8abc42c84b32c9ce8763c4204ca573bbd09fd037147b -\u2191,142413cb28cdcb7edd0deca654b26d584d81646d94b825e8529db2f2df30e0 -\u2192,b2825bca38e9a22edf5ec9e096a3f68f59ece8e4ec471f7cdca337096fefa83 -\u2193,53c1a4cf49514b57a78c15d484fc0eaa87f2fc6487cd54ac3b5807f64c6a72d -\u2196,8dcf932252c968e3e1b21a5cc778bbc8ccfd787f061116c7e4dbb07a60b3a -\u2197,8e4697895473ccd953699fa0e3a72fe1437814b0ea6035fd81012e42d16eb5 -\u2198,e03fd8d6b2a2bf1ba54570a1849953f8dcbf76e12a4c25695e5344af050a5 -\u2199,c123fbbff27bbf98ca6840b890dfb4667f0925d3ba91d853dfa26ba12d1d961 -\u23E9,779491c6df5ddbd4b3fa41e0aa3539162a6bd0aef748bb3e484fa677a925d9 -\u23EA,cf2b839e7689a050c41c5c76c78f5e66e743133ed96a69c735a6e8f388c9c4 -\u23F4,6a2f119ce0d3a9bf6bd02e8e8dcab217ae6c9e7484b73e5ad65e57ad6cabc0 -\u23F5,4293ac364be23533e3b0471a6e82fdce514754efcc75d6c65e3c48669f2a1c82 -\u2640,e61e5db705a31750a66dea3c4babddcb27b68312e5535efe063835dc6364322b -\u2642,ea886a8a70f90cf906d0851e62e2625dead7d8391ce5cbf239c1a1edb8fafb1d -\u2648,5f70c37fe2ba8ee0f66d6a7eb8fba5f26232887643fb2244682cfd6b568b54cc -\u2649,6172cc9e6f2fb099cbfb46e9da2fc050b9ab52d1fda6f8ffb846b7b13d72ab60 -\u264A,576688ec917a3062bc8eaf41bb7bd9849e97a6b7e32b10686b32b3593939a7a2 -\u264B,f38d9ca4c1e39820f2b83f9e333694e8a2121c7b436454548a2b5f9354255282 -\u264C,4ea3cd7bdff30defc6b5fc8482acf76f3f2214dc4b1bd01fb6a215da4dd41972 -\u264D,7c1264cfcbf6fc633e68d1db4b92049683bd94fbe6ad332f825702104f59bbbc -\u264E,af588420a4c646ed23f8e8c5f0db5c8c79dd7d8436a13e6558c0dcbed8ef4175 -\u264F,bbae76b803e1705afcc2cd115523d2b23a6a8e803070c015d1f84fff1edc46c9 -\u2650,26f634d22010918e181e64b15f55c22a14e64dc1bcf9602cdaa5c9cbfbe9cf1 -\u2651,348e1b9872f12f7789f3d61505f2d528d5010f438d97a6ac7a807415532fc32d -\u2652,97d7bb8c7c287a391e1ec26238ef08036c9289a612a3332539e886103a069c8d -\u2653,f692d65f06a6110f55a18bec96c0b1c629bbe8307a2000b27a05a3a1a8a8d947 -\u2665,c3b97bdff848f67e2bbfa66c5296d684a87ed1fadca366f924d25841621ffea -\u266A,5c27c58ea73d6311638d0456d5dafb7c368a5be704a49c4818887a3a2830d992 +" ",37cec86f55422e6ccf9836aba09591cf5841e379a9a4394830f180957edc4395 +!,777e58e6d08fbba0bf4a1ef76b5372cdfb127638b17d322372e4c2e9728fa +"""",28cee9b73cb422c55c921d776a02b6478037d6c841fad3a368aed36ed0f297 +#,b56797e277ade8b56c6587ad73c0f16ab91b5df111f45173a8c377ac96ab72db +$,4aa580b9f2e7e2247245863f16911365e166c3d7324401cc587552d2900e5093 +%,243dd8693c8cd3264db39a2367703aecd97b7899521b5e46c0c9ce23983f57 +&,57d3eaa0b766e4fda2fcd769e88f7999cf2fe8c4293b0487ce0f24eea91837a +',ee7c98d831d45a3fa5fd9a1f198db8c41e2c14c60119c9d4050755e45ca86cd +(,a3c691a4ab8083595426afaa557678a6af9e8f959707cb47281e7887de54bb +),c6109eac62dfcd66dad9d1a52ca590ba53633f2dfec2490523a4f94ea95a3cc ++,ccb3b9ffc5334eb6249c9964605e14e3692bd6b175d2a963ca317c7958ddb2 +",",54badc10fff188a5b8b58f25eda9abbdd097274535487f2c4f54b4ec1d9eda12 +-,b78666eaf42bfa6eec564a3dd7f986546da12c4ee0e5e72fbaa2c5aeb08f9c +.,36e82b51f26963ce64f09d9f503db9b221df2e54d621d3a9107b23d6d865d976 +/,566bd5b64735f3be6cbeb163890ec75522c94cc2d4c4c1a04ee2e7e43b9b +0,7bafba8a3d36476851e3655bbac87de2e718e85fc8466b2ba701aaad8cdb142 +1,3889921dfb3d93b10acc79dfbefed463c729e62b1f76a3dcce1b6c44012b +2,c6dde76e6f88665b681794b4b914ac513e57c272dd0b2f988f47b7482d4b177 +3,8b959649e1f9a20658c4142d181162014bf34710be91cb4d495bc74a7e127a +4,39240d3711b3f81134851b9228c5a3045788e7aba7014719b687f12857c538 +5,1926e41525d7219cfbf83b25c187251555dbf351369f95a25aadd70bc9dd7dd +6,905aaebbbc7fe93b6d51884bbded39f9a7c5467a86299f7fa0ffbd13e7b94e +7,dc4315942cb7ced179f13175951bd5ef91d42b534764b63bf840354086a5a7 +8,474ae33a4d1cf8a1bd2bc73e1361f5691cbcabb6d93c16b8c287bc757025 +9,b1d38a88cfa569f2a1545275fce4fd1869f75cb4853df510fc3dbe63be891e +:,8d89c095e48f93717888cff73ffc567f06baa2ef70296c7eadb915cdcd6ab4 +;,e46274c66453d6f3fab86197fe75fee12ab902532a5f36971712cb5e0a5 +=,98c8b7ceb1c32cb8997dd7f4bd73465e44f9f75a64057ee4fd6e55a71ce9a +?,6849ebf6d2ebde985d290787bcc4130b5b96ca3a96027a29cd545f911ebfbc6 +[,aa3dfbd967caab7bba68bc8d3e4adc7f19afa6023447ae245fafed3207a2bee +\,2a3f7ccf689343583f4b5aec3924865b827f92634c6d95a57903e6cb7d73b5 +],abf668e89301d1bffa0501f82aea8d84a379218cc2a512927a180d14dea39e3 +_,374fbb185ff6d1a5181db55818994883b263a835ed405a59d5d8b869eda8 +a,6f4b7b4494bd076832ff657ccd0da16327bb7beacd9a5ddf17d1db550cc7ee0 +b,f5c91616fd773b4a023640b8285e984d96f580e1322dd66732c3bd0a79e5 +c,8d2949f5c8fc51d18d71069ab15d22119a6222b56d783f6e6c5b36556b73dd +d,6e901368ccb5ce37c34ed78759381bd7a78db29ceda9b2c9eb72937b89ee6d7 +e,e4de2878f7414f91d48c69359c85939381a51a9d975f49135439d286c313e7 +f,324527c853e10b514cc95bb2352cd974e4aff1e341d0ee6a9d605746b9e013 +g,cfa5cc43ccb16946aad8cdd539821b3f5f0588bfc39eee29de9663a73375e40 +h,39b72c1c3a7aee2f3ee682a2ef8ccede14cbafbae1293dd5e34bf4c45c39b990 +i,bbb84e8f52e16e8883b5c4c846b4e942df7853339924f631e4e7047f647e1e9 +j,9112e2f34e56a9b90f781a5dc540ba7112b3ab47361c7cdf3a9d276135279 +k,bdcf90acba65c89cfc3260bfaccece74c02554696ffd2422cfd466149a262fa +l,3e98525d092e0eb946d3b9ae9c11d434b752b1060283dcab1acfaebfbaaa99 +m,8e5f8a61dce4b4ac909d84aa9d75ecfdad16d3bb97367078516668fabe8549 +n,aa590a15b4d23782db7889ce7f2c907bf4e18f0e57e9e0d3e52fd714b114 +o,4def6ac5f6b5664055f66fcd678bac5647633b6477822498ac14befd9ad5ba4a +p,edffeef89be11b325643c67bef559a33868c9d435de119477d56379591dd1c1 +q,31f0cc8a8db67e7d5f3180aac15b6f85cdfec9efa41a6ae3de248d445de33 +r,6f7dd78cdc1145e6b36d1e352b378f208f9b97d5fe2c1e50b919cc89adcdec +s,5aa0e68265c2a4e30e0859f51e8906133741b9a032c4b0103ced96e28c3bb +t,24d979e1ca980153fcd58155eeca87cfafaca31118c56bf4ad77284cc9e4bdf +u,2fe8aae1a85257733ca1365d245c8143d4c71460a571d9ad9c1f3a71e7e9463 +v,1e3f34be8f90d3c0efe87fea15f439a93d8be6e7e99c69b3a9d4cf4adbd5b68 +w,cbf68fdf363228d5144ef26157e7a8246786ba3b2edb3eb1cba3aa356015566a +x,41db2b5439101b95c6807053a1d69d8dffa7c4b8049c8810178fc4ba37a +y,ff2b399fc07f718a8416141ddaa49ab3ce7740c2b74c31d98cab8ff41bda90fd +z,e970194d73c85bb1dca424d0656e4bbc9467a67fc1edba1fc46834a37c1dd4f +{,fceebc9801ac5156940fbb4b76d255ddc9beb199dcdfd9e9eea92d944d0e7 +},9b3f8823cf9b48728bf47e76994c0a72c6b56de6d74c371dc7e1349a98550 +\u00A1,8d34f5e7c085d814f524302ce7490c435223f88b7dbccf852ff3afc9e987e1a9 +\u00BF,e665e065dd174f85e7bdb92854e3e561ab6eb3c5ee4a0ac7f7c4d1751713b1c +\u00E4,3222cea2906ff854c8efda071f1dd3ca062e7ee8a8a3ad965d6bfd266568 +\u00EB,68601f23a3c9a74d425da9b608cd0f5e7a9a16e273e9949351634999f3c32 +\u00F1,6a41a1e52ab6c0a49eee78ef65ff950887c439d1b3d315909baba636b9745e71 +\u00F6,7fa4ca50a45ee4e5b553f1313662c2c47da1e2b02f1b91e3e03eb9afce2033 +\u00FC,a7d1676c1570fe15dd71e9bcaf9447599ed546bac1436ec298afe0e8193af29f +\u0431,3d74b76bb413393acdda823f55773485397a86ace3ef898496168572c2c52 +\u0433,ab3ef6abc71972e3c1cb43e349a54bb7c7dd7fc5cf43562ac7a1824aadec176 +\u0434,12279af6dfe7babdbcfe060c456f4ef4725b9d673cc93595f2881c9feaa0b4 +\u0436,73a2db9ff069609840d54c992fa05683a5ae60b8f15ebdc1911d88cc9c49975 +\u0437,4b070e55ae46b3b18817acc34e86a1fcd9403e84ddd8df3703fb35b2f038 +\u0438,6e2cca17b0422671b91b4210851ec869b69bdbe5b4bbf495ccbac2de4990d1fd +\u0439,9791f4d0acd25582d28d9ca23d3facca3d1ff3930a0be423eacb7f32e83f34 +\u043B,e4163cce9fa563c7c3f4aa9e0872aa39770179f8e26a1ee08d70bd9d9dad3d +\u043F,14a5c4d333e6f68024818a14fcbbbda885fc7a331a1040ddedd6e54f687ff29 +\u0443,a9ce2dc1c72073a88421579f66c8899c75a877eaed02d7d6e59ae6523ce860 +\u0444,efc4a2c843cb8e36d802ddb71d7eacf85613791ea05e8eca7a642fd1a7ce38 +\u0446,fbe54386565c4f6875696b8d297629d63dcbfbcc1f5870fcac1e15a9d773e6 +\u0447,63cff2137b803e7189797dbffec745f6567e65c7a5ff4999104b43795b3cba99 +\u0448,317e6086827a28fff163291ccd954fb49d1e2973fed86da81cd14735e06662b +\u0449,a8f1e39a47215a5cba15eb8492eb11da829df28a3b8775c34b90c93951c9817e +\u044A,de28691a694d513bbe679a92ed9629b494bb7e8b5c612b64c6fe9e54999ce +\u044B,e6b2da3d73aab6e1250d9e23075bb37ccda4d58574b83b86052137c1a4b76d8 +\u044C,11d7414375a83dadbd4ae1de013765f094dcdc48a8eb9dc9c2ffbbc342093 +\u044D,8d1a5f3c6f6a5d1c778b51e3e248817a4b8028f4fb3299b8d02e7b56cac8e6 +\u044E,d6fcef514ad1e0ea780568b8116ef277b888abd67764a358558529ed21be1a7 +\u044F,27d5aa9a8fdfcfffbce1c5528e99f59f1a1c3d647c55e22c6126827fece68c7 +\u2190,5d4b334dc51156a8d8abc42c84b32c9ce8763c4204ca573bbd09fd037147b +\u2191,142413cb28cdcb7edd0deca654b26d584d81646d94b825e8529db2f2df30e0 +\u2192,b2825bca38e9a22edf5ec9e096a3f68f59ece8e4ec471f7cdca337096fefa83 +\u2193,53c1a4cf49514b57a78c15d484fc0eaa87f2fc6487cd54ac3b5807f64c6a72d +\u2196,8dcf932252c968e3e1b21a5cc778bbc8ccfd787f061116c7e4dbb07a60b3a +\u2197,8e4697895473ccd953699fa0e3a72fe1437814b0ea6035fd81012e42d16eb5 +\u2198,e03fd8d6b2a2bf1ba54570a1849953f8dcbf76e12a4c25695e5344af050a5 +\u2199,c123fbbff27bbf98ca6840b890dfb4667f0925d3ba91d853dfa26ba12d1d961 +\u23E9,779491c6df5ddbd4b3fa41e0aa3539162a6bd0aef748bb3e484fa677a925d9 +\u23EA,cf2b839e7689a050c41c5c76c78f5e66e743133ed96a69c735a6e8f388c9c4 +\u23F4,6a2f119ce0d3a9bf6bd02e8e8dcab217ae6c9e7484b73e5ad65e57ad6cabc0 +\u23F5,4293ac364be23533e3b0471a6e82fdce514754efcc75d6c65e3c48669f2a1c82 +\u2640,e61e5db705a31750a66dea3c4babddcb27b68312e5535efe063835dc6364322b +\u2642,ea886a8a70f90cf906d0851e62e2625dead7d8391ce5cbf239c1a1edb8fafb1d +\u2648,5f70c37fe2ba8ee0f66d6a7eb8fba5f26232887643fb2244682cfd6b568b54cc +\u2649,6172cc9e6f2fb099cbfb46e9da2fc050b9ab52d1fda6f8ffb846b7b13d72ab60 +\u264A,576688ec917a3062bc8eaf41bb7bd9849e97a6b7e32b10686b32b3593939a7a2 +\u264B,f38d9ca4c1e39820f2b83f9e333694e8a2121c7b436454548a2b5f9354255282 +\u264C,4ea3cd7bdff30defc6b5fc8482acf76f3f2214dc4b1bd01fb6a215da4dd41972 +\u264D,7c1264cfcbf6fc633e68d1db4b92049683bd94fbe6ad332f825702104f59bbbc +\u264E,af588420a4c646ed23f8e8c5f0db5c8c79dd7d8436a13e6558c0dcbed8ef4175 +\u264F,bbae76b803e1705afcc2cd115523d2b23a6a8e803070c015d1f84fff1edc46c9 +\u2650,26f634d22010918e181e64b15f55c22a14e64dc1bcf9602cdaa5c9cbfbe9cf1 +\u2651,348e1b9872f12f7789f3d61505f2d528d5010f438d97a6ac7a807415532fc32d +\u2652,97d7bb8c7c287a391e1ec26238ef08036c9289a612a3332539e886103a069c8d +\u2653,f692d65f06a6110f55a18bec96c0b1c629bbe8307a2000b27a05a3a1a8a8d947 +\u2665,c3b97bdff848f67e2bbfa66c5296d684a87ed1fadca366f924d25841621ffea +\u266A,5c27c58ea73d6311638d0456d5dafb7c368a5be704a49c4818887a3a2830d992 \u2713,8b1e9ae370f1a3ed575e6174569de448f2aff3f2c6d28678d26560f5e9ee3209 \ No newline at end of file diff --git a/src/main/resources/fonts/cobblestone.csv b/IF/src/main/resources/fonts/cobblestone.csv similarity index 98% rename from src/main/resources/fonts/cobblestone.csv rename to IF/src/main/resources/fonts/cobblestone.csv index 0722865c..d35ba8c3 100644 --- a/src/main/resources/fonts/cobblestone.csv +++ b/IF/src/main/resources/fonts/cobblestone.csv @@ -1,118 +1,118 @@ -" ",60161c8694cc8ecfe639d710e77239352d86ee2b6c40cd4daec21f798dcea7ca -!,27b0c69f185733bded26ff57f983ee38fa1fcf3e628be15d0af8c4dae626626 -"""",584fddd06d97be7c624fdcf5c2fdec02bef33c266bdca7a3e4e6af4e4bddfd7 -#,e457197dce6eb41a49f2ca956ce8be46ccf5725332b007abd986bb2fbd3b2 -$,ca9a759e6dbb876fe4b778611686c524516c17bad47cd87e1067ddaaf6b6fef1 -%,beb27e59c83414ea61d64254e85387592b91bac5f3425c348cad7b6d32bd18 -&,c8bcee842c9bf43ba68ac02e979119e02aaab6b581ead19efb58233a69247f6 -',3fbee52e1a1235cf7ad7be85b1fe5532afc8ccf6d8ccbe2ee05dc6711c5aed -(,2973e2623d5014a8258ac94feb39d9ed96a629ace4c3f3e3a4662e586ebf38f6 -),1ec7e1c935671282d35dca9d8d62bc9d96519b43af26b5efa818ff9df840 -+,55d58de8eb283eed0e4122f1c5113d0c3a229eec5b6d7c1481dd23520bc45db -",",f637b74ff2ad483795545cbd49be01d6011cb4832764ffb96a5247b6141d9 --,7b75ea4d37fca4bfa8f6a3ce56d1473607073a456d33b1227435b99ad71d147 -.,76f67c223b44ebe3ec08de32c9c42a151931b502bde9bdc24323d3329d29a -/,7f268d2141f9a82cf24daf85f91ec8a2cdfdb2a9bec9542c91688d3025cd17 -0,529ff1ce4b304942e15195611d3a8af16c413c6b8ee8aecb8d8cc79a644eb -1,ccd6469410f5f1629dc0de284fcebfff53c644f0cb5a4e2bba95a7f16f5d -2,6f91148767c38b5675d4b3687ab8fbf8a7ac80b5487bed881383d114f54df70 -3,4c42adb132d81c7bcc333698d2f7c7033fd8f38157b84a5a9e7307dfef911 -4,e912f259828f3d401398eb1c54a03ec209364e21b38518883bb54b67e75e1 -5,92731fb338a144822dd5373e6ad2455c99fafa21a9892ac8dd85396b872b8951 -6,9180db8effc073c679c5d4cfaced483fe5eb4d71edacd64611cdf735f12947 -7,0872de5e52a2e2b35fe92c93a5df6af6d3a96d77b1ed67d4d35d87539b456 -8,1bed8c503e6a74219cf63ba8124957494edc5fda1d4c13e310919d7cef875e -9,47d0b6e6dfaf6be27a37af1483e9de60ffff5e48f5fc7c25bd4884633aa3d -:,c791503c8fe4bbd6559fbc68f8e728acce4699b01b7d6b449559c5c3d33f493 -;,bcfb89bb7d1a75f25b9d903162df83f6f35a9d2ccb46eb1c5b1c3a6fc189c91 -=,8e1e4f0e3b513d886baceafc42f1b6605a8a9d510a2cdb49af6f6f2f2a2c -?,6640e1d11f92246726d68564f8cfe0699c2cd44cfd91c168712ba6356d8379 -[,31f35b715790273fc960319a8ca64fb988cd8148ad3db1d87ae258b7ec5852b -\,2888594cfdfc2211ed945389db9bb1d7d67b8df98c9f55e498de32fd3d -],1758d15dd16cc937adfc876365afa6ef854e64e085893aa7332b53d4e9ad93 -_,93cff83db679acde5467c12ed55c58f932c0e0de905285bfab9802d46510 -a,ced0edb0a641d229c817b33fa661712bb26ca526a23fd32bdabfcc9909ee4b1 -b,372c21bf23c27fc94d7888f0a557a3a265f0d954a991acff9908ffd568f3a64 -c,af8e6151a540394a7327c95d2a266bddc7564cfe2f8ee60f344c9581042dd27 -d,3173cbace887a31279f47b2c4b52367f4b2e6dc9872aa6733b3b24272f56c -e,76f081857a7c76dd1c35286468a63ca814a59335c7d923559ea7d7e9c01f1581 -f,93aeede074ef9c2e4fd0edd075ab6ced5b612c89f73d37b0b6cfb27fc31ad -g,d3a8f7d5402e5becfa0b87acba15eb3d4bc8c125d9cd3a2aa89ac0bfaca7 -h,3dcb76945ea4321fbd5863e5d75a55619dfd6d6945ab798470b1899054e0e18f -i,35bca5fc925b914ad9c8cc1b176766b13a7ff2dd7cded8dc5e6a9c65186 -j,56dfa0f75b3411349d5db4cab7fc3d2c314f5f74d47367855308e618d4e42e -k,974cf651cf896c61b279ad99b022fd4c78da9e3b2e94b62a6c196a1882b491 -l,5f1a8f576530a46fb8ca4bf69913467d80ffd4b29f1a41ae431411c528b07b95 -m,e365da9049fb9d26a7b0eca090578b4b5775f16477b39b49198271d5baea9f84 -n,78c471a7433a1108973832915d8e738e6552208e538a334f79517ada83df7 -o,5fe493d55d712528d9db743042e899b0c830498e93425ed9f679fe81de37e0 -p,41a6e75316b54efbf3ec46eeaa5b26b924eaef2b35231682a3e9cae4e93c2142 -q,51b04d35a2813055db195cbf30936e47a2f76b3719ef4f530b9912e6e9bdcd5 -r,856d692c61a025e9453aa16b13e49e42f4cbe14d1607d1a9b4f5537748be72 -s,c76ab3fc4b167f3c9857957cfacf344943fa0a87b8830dc54165d86dfc7 -t,513ab64d052f246b3fd67e78e5956f716da241d912878ebec4111e35174fbd -u,2baff3eb2002646cd8eab6f2ca52862722add642beef9ec8184cbed74f142c -v,564278c58d753c18837c98b9d377dc4e428b344a6c89d375af080137c65b437 -w,44aeee9e63ff4aea6768c35c9e1967b79428d3f64478282dc54697b3319df -x,512ba5e0e3c9b54b5c29d7cc63c899086c27126d73623ed73be9492238dc7 -y,a277a19c9cdc58cb9799304257dbd4c828964f5b70f854244f7516824bab02c -z,7ad4da216cc7ff358223d111a33c19c3f369b9b4682cd2b9d759c31ffe4549 -{,ddafc3e151b26be98e76c625c7f53d505673e8380c1affa4e9401a41786c75 -},d82ad6b434e63e41a64b277243e41b29fcbba29f2ad16f86fb04cd47c4db023 -\u00A1,47c833ef9d7ca8446630e065d517525b3dca7659b9339c04096e4a6c8dc34210 -\u00BF,18de706c7f713529670abeed32cac592eef33c20d63ddc9f81a3ee19aeb97877 -\u00E4,5ab27a5817431dd22383e7423b12b3ea3253bc94ff626e15fe88df4719eb4 -\u00EB,ec93c46e524474cd80fa4c1585fe18423ce21dd46c7084fc9f480de28a7c3 -\u00F1,550e28ed8c9ab81e42280040673a814c601915c99759f5e1adffe8bac6ea3999 -\u00F6,523313f08721c97ecfa48a6d10b3ad86b4996fbde860c16db9e8d7a04aafb0c8 -\u00FC,c231c432116ed4fb8c7226897c81e19a903b48c84b77d7da793f318566ce649 -\u0431,1a341ffbc65e28d22abd16a8b6786f47c14fd5cd18f465e267236067cc0 -\u0433,aeb2f3a323e9226654371a241e55b6f1d33bf5ed4a268f61f2dda73d3a4596 -\u0434,bf5ab6be754bff44da39d866fac57d901b6461885c49afa1cce05a3a936d68 -\u0436,8720cda495b6d4ea183e6328d61b6c5b522f56d4b7a04e20a161167f467e69 -\u0437,ac9acfdc191f641f1fbfc2f234098b5ea2a8adacf2695d2e16904d1a525f4 -\u0438,16f1661622c1458fd283cafaf42cbd1842ce74af2b431e44c54386369069 -\u0439,736a224acc7f112a9b206682a35fe09b789078cb2461323841ed232d4bb4fac -\u043B,61415db3e2168276993feeba02dcb11ffa61519b22128be3126b14ebafd0 -\u043F,7fe54b77c879b5b6033ba7c55a9c08eab75e1ab571179cff61b3c245dd563b -\u0443,74158289dad5b91a72b9a0a894ab8124a306039469d53eb9ab6d4b79197bd23 -\u0444,92ca649950678fba0595a2bb145a857d2a7e867cabf9cfe3bc4c0e710907c -\u0446,39ec2d2576743266523c6a9491e659f718a76ad2319cafb02b3c904f4424a -\u0447,1d7db379636dab7e3c83bec55ba0ce8d6eee2958db73ea14f31c7aae6a628c5f -\u0448,a21dc72975d45befa398673a07b90b97f31d06dfdeac09e643cc53f775e9af2 -\u0449,7bbe35d8f0f5367b5e4ee48f7aa8736ff16ae5d280525b8f868d3cbd81945f -\u044A,9d3ce0118171fc1cb18bf2495052c94a1324c7a425ad805efb6d42735c2e7158 -\u044B,df4289c0b1dd3b40ca40e2c52d15535964e1689b779a5e4c447a916c262bd16 -\u044C,a88215f6e2812b66469d76a284abefa06b9646ae86f69195edb691997b2554b1 -\u044D,e02cadad9f96525b7be75455d9f99e94683a8a5ede65db9c4be0697f61fababe -\u044E,3af0247439754de71cdf77cb4e3bebd714b8471ccb355f14ca8251ca97c66 -\u044F,397e206238477b195874871f17b3df5b1613562ef4aaeecea312794a4e72ef9 -\u2190,d2855a8ffa17e7cbca13dabad8ccf90e4de9748a2d2c31146468ef86608feb -\u2191,9c26876a4548844e28a6f7ba1f377c80e59495f7d32214bcc492804b16619339 -\u2192,3cb38fdf5ed04a49f21495f4d94835c8e6290abacd65c966c1c6cbefa66d84b -\u2193,7e8914dfca8c20943175c053331ae373a48af45ed5bd157c89495cae46ec98 -\u2196,9d79886974b1abc5c725975f8ec7e919b28ad241dd6f94f7675d68a7d8a5cbf2 -\u2197,67d196f5fbc31afee3372da4f9669dc9536ee3eb60c9161b11632a268bfdf467 -\u2198,6536b0eb75315b5a7e08ca1324d74363489abfe27e051d397965523de4ee8f -\u2199,bfa72f9b65b032c8c21ce2d6f8ee8e1aac7667f9d576a239fdbb47721f1390fa -\u23E9,d9d334bf33f2e5677fb174d472bb761d878d1a6579ec1e7b27d9dd545c973c -\u23EA,106536cb6de0d08c2d7012854efa28162251ee6e9f81fe6ccc29983c845d6b5 -\u23F4,dc1ca9dc5c7c941a677b40832757a909871a295e24c92c0c1e632c21d4f905c -\u23F5,93f5346d409ce3e06ba28d5b2c0161a213c8759b94b63b456e821c338095f3 -\u2640,782fbc3ba8138059123594515dd2aec0b9fddbdedceda148925736d1de109000 -\u2642,b38ec72cfafa5b5a793c8f2cf3dadcfa4fd26b38300138a8bb974c72d84894b0 -\u2648,6878d95d504ee1b512846153befe1940653e8f99ae7d1684dadea6737607ebd -\u2649,67f184ce1c9956c15856c37028f5316f86d7ac467823b4cff9defdc75a9c34ce -\u264A,1f3314dd6be99dc1e01a7974e6ca9368082b813a3c9bbb2f1ee859127ede2971 -\u264B,a6b711234bf1a2f9d4de5aed42dbda35d7f6418e1c26dcdd9248c20bf39c7071 -\u264C,d870fb19419c81e47e5b89d749f871f55204cb09a6f81a824494e3a1e1ebc22a -\u264D,fa277e55273c4df440610c9e93655a6fce62fcda46107a010434b160d7f164e3 -\u264E,bf6e96418ada5c89e93aea35b7824f014933033d99ea6ffce9f6b04809ec297b -\u264F,16acf45bf4683ec590254e91fe2ca150919141856376ccf163fd611eea8b9b8f -\u2650,888b3bb6f5442e65133f029ac9f013b701e4dda091ac18983089e48453e256bd -\u2651,8c530e855f0848830d8ec3eab16e57e50a41f367b6a25a6eb4fe2c9463a1b904 -\u2652,b0a805fb83fff2ab48da019e7315b10fe5418cc48e70935ad08fc3e856786d0a -\u2653,bb23b3f57e314dc14232451e295eba5222996c3d046d32a9250d2c8908904837 -\u2665,e547d18ef6a2c2eba281a94eebb8e979c47938d9d5477b973a52a1de8734e2 -\u266A,f05512674b1c07e880ea7c4a274b2ed7a1d4f5189fb1b8171d0855371a2ce722f05512674b1c07e880ea7c4a274b2ed7a1d4f5189fb1b8171d0855371a2ce722 +" ",60161c8694cc8ecfe639d710e77239352d86ee2b6c40cd4daec21f798dcea7ca +!,27b0c69f185733bded26ff57f983ee38fa1fcf3e628be15d0af8c4dae626626 +"""",584fddd06d97be7c624fdcf5c2fdec02bef33c266bdca7a3e4e6af4e4bddfd7 +#,e457197dce6eb41a49f2ca956ce8be46ccf5725332b007abd986bb2fbd3b2 +$,ca9a759e6dbb876fe4b778611686c524516c17bad47cd87e1067ddaaf6b6fef1 +%,beb27e59c83414ea61d64254e85387592b91bac5f3425c348cad7b6d32bd18 +&,c8bcee842c9bf43ba68ac02e979119e02aaab6b581ead19efb58233a69247f6 +',3fbee52e1a1235cf7ad7be85b1fe5532afc8ccf6d8ccbe2ee05dc6711c5aed +(,2973e2623d5014a8258ac94feb39d9ed96a629ace4c3f3e3a4662e586ebf38f6 +),1ec7e1c935671282d35dca9d8d62bc9d96519b43af26b5efa818ff9df840 ++,55d58de8eb283eed0e4122f1c5113d0c3a229eec5b6d7c1481dd23520bc45db +",",f637b74ff2ad483795545cbd49be01d6011cb4832764ffb96a5247b6141d9 +-,7b75ea4d37fca4bfa8f6a3ce56d1473607073a456d33b1227435b99ad71d147 +.,76f67c223b44ebe3ec08de32c9c42a151931b502bde9bdc24323d3329d29a +/,7f268d2141f9a82cf24daf85f91ec8a2cdfdb2a9bec9542c91688d3025cd17 +0,529ff1ce4b304942e15195611d3a8af16c413c6b8ee8aecb8d8cc79a644eb +1,ccd6469410f5f1629dc0de284fcebfff53c644f0cb5a4e2bba95a7f16f5d +2,6f91148767c38b5675d4b3687ab8fbf8a7ac80b5487bed881383d114f54df70 +3,4c42adb132d81c7bcc333698d2f7c7033fd8f38157b84a5a9e7307dfef911 +4,e912f259828f3d401398eb1c54a03ec209364e21b38518883bb54b67e75e1 +5,92731fb338a144822dd5373e6ad2455c99fafa21a9892ac8dd85396b872b8951 +6,9180db8effc073c679c5d4cfaced483fe5eb4d71edacd64611cdf735f12947 +7,0872de5e52a2e2b35fe92c93a5df6af6d3a96d77b1ed67d4d35d87539b456 +8,1bed8c503e6a74219cf63ba8124957494edc5fda1d4c13e310919d7cef875e +9,47d0b6e6dfaf6be27a37af1483e9de60ffff5e48f5fc7c25bd4884633aa3d +:,c791503c8fe4bbd6559fbc68f8e728acce4699b01b7d6b449559c5c3d33f493 +;,bcfb89bb7d1a75f25b9d903162df83f6f35a9d2ccb46eb1c5b1c3a6fc189c91 +=,8e1e4f0e3b513d886baceafc42f1b6605a8a9d510a2cdb49af6f6f2f2a2c +?,6640e1d11f92246726d68564f8cfe0699c2cd44cfd91c168712ba6356d8379 +[,31f35b715790273fc960319a8ca64fb988cd8148ad3db1d87ae258b7ec5852b +\,2888594cfdfc2211ed945389db9bb1d7d67b8df98c9f55e498de32fd3d +],1758d15dd16cc937adfc876365afa6ef854e64e085893aa7332b53d4e9ad93 +_,93cff83db679acde5467c12ed55c58f932c0e0de905285bfab9802d46510 +a,ced0edb0a641d229c817b33fa661712bb26ca526a23fd32bdabfcc9909ee4b1 +b,372c21bf23c27fc94d7888f0a557a3a265f0d954a991acff9908ffd568f3a64 +c,af8e6151a540394a7327c95d2a266bddc7564cfe2f8ee60f344c9581042dd27 +d,3173cbace887a31279f47b2c4b52367f4b2e6dc9872aa6733b3b24272f56c +e,76f081857a7c76dd1c35286468a63ca814a59335c7d923559ea7d7e9c01f1581 +f,93aeede074ef9c2e4fd0edd075ab6ced5b612c89f73d37b0b6cfb27fc31ad +g,d3a8f7d5402e5becfa0b87acba15eb3d4bc8c125d9cd3a2aa89ac0bfaca7 +h,3dcb76945ea4321fbd5863e5d75a55619dfd6d6945ab798470b1899054e0e18f +i,35bca5fc925b914ad9c8cc1b176766b13a7ff2dd7cded8dc5e6a9c65186 +j,56dfa0f75b3411349d5db4cab7fc3d2c314f5f74d47367855308e618d4e42e +k,974cf651cf896c61b279ad99b022fd4c78da9e3b2e94b62a6c196a1882b491 +l,5f1a8f576530a46fb8ca4bf69913467d80ffd4b29f1a41ae431411c528b07b95 +m,e365da9049fb9d26a7b0eca090578b4b5775f16477b39b49198271d5baea9f84 +n,78c471a7433a1108973832915d8e738e6552208e538a334f79517ada83df7 +o,5fe493d55d712528d9db743042e899b0c830498e93425ed9f679fe81de37e0 +p,41a6e75316b54efbf3ec46eeaa5b26b924eaef2b35231682a3e9cae4e93c2142 +q,51b04d35a2813055db195cbf30936e47a2f76b3719ef4f530b9912e6e9bdcd5 +r,856d692c61a025e9453aa16b13e49e42f4cbe14d1607d1a9b4f5537748be72 +s,c76ab3fc4b167f3c9857957cfacf344943fa0a87b8830dc54165d86dfc7 +t,513ab64d052f246b3fd67e78e5956f716da241d912878ebec4111e35174fbd +u,2baff3eb2002646cd8eab6f2ca52862722add642beef9ec8184cbed74f142c +v,564278c58d753c18837c98b9d377dc4e428b344a6c89d375af080137c65b437 +w,44aeee9e63ff4aea6768c35c9e1967b79428d3f64478282dc54697b3319df +x,512ba5e0e3c9b54b5c29d7cc63c899086c27126d73623ed73be9492238dc7 +y,a277a19c9cdc58cb9799304257dbd4c828964f5b70f854244f7516824bab02c +z,7ad4da216cc7ff358223d111a33c19c3f369b9b4682cd2b9d759c31ffe4549 +{,ddafc3e151b26be98e76c625c7f53d505673e8380c1affa4e9401a41786c75 +},d82ad6b434e63e41a64b277243e41b29fcbba29f2ad16f86fb04cd47c4db023 +\u00A1,47c833ef9d7ca8446630e065d517525b3dca7659b9339c04096e4a6c8dc34210 +\u00BF,18de706c7f713529670abeed32cac592eef33c20d63ddc9f81a3ee19aeb97877 +\u00E4,5ab27a5817431dd22383e7423b12b3ea3253bc94ff626e15fe88df4719eb4 +\u00EB,ec93c46e524474cd80fa4c1585fe18423ce21dd46c7084fc9f480de28a7c3 +\u00F1,550e28ed8c9ab81e42280040673a814c601915c99759f5e1adffe8bac6ea3999 +\u00F6,523313f08721c97ecfa48a6d10b3ad86b4996fbde860c16db9e8d7a04aafb0c8 +\u00FC,c231c432116ed4fb8c7226897c81e19a903b48c84b77d7da793f318566ce649 +\u0431,1a341ffbc65e28d22abd16a8b6786f47c14fd5cd18f465e267236067cc0 +\u0433,aeb2f3a323e9226654371a241e55b6f1d33bf5ed4a268f61f2dda73d3a4596 +\u0434,bf5ab6be754bff44da39d866fac57d901b6461885c49afa1cce05a3a936d68 +\u0436,8720cda495b6d4ea183e6328d61b6c5b522f56d4b7a04e20a161167f467e69 +\u0437,ac9acfdc191f641f1fbfc2f234098b5ea2a8adacf2695d2e16904d1a525f4 +\u0438,16f1661622c1458fd283cafaf42cbd1842ce74af2b431e44c54386369069 +\u0439,736a224acc7f112a9b206682a35fe09b789078cb2461323841ed232d4bb4fac +\u043B,61415db3e2168276993feeba02dcb11ffa61519b22128be3126b14ebafd0 +\u043F,7fe54b77c879b5b6033ba7c55a9c08eab75e1ab571179cff61b3c245dd563b +\u0443,74158289dad5b91a72b9a0a894ab8124a306039469d53eb9ab6d4b79197bd23 +\u0444,92ca649950678fba0595a2bb145a857d2a7e867cabf9cfe3bc4c0e710907c +\u0446,39ec2d2576743266523c6a9491e659f718a76ad2319cafb02b3c904f4424a +\u0447,1d7db379636dab7e3c83bec55ba0ce8d6eee2958db73ea14f31c7aae6a628c5f +\u0448,a21dc72975d45befa398673a07b90b97f31d06dfdeac09e643cc53f775e9af2 +\u0449,7bbe35d8f0f5367b5e4ee48f7aa8736ff16ae5d280525b8f868d3cbd81945f +\u044A,9d3ce0118171fc1cb18bf2495052c94a1324c7a425ad805efb6d42735c2e7158 +\u044B,df4289c0b1dd3b40ca40e2c52d15535964e1689b779a5e4c447a916c262bd16 +\u044C,a88215f6e2812b66469d76a284abefa06b9646ae86f69195edb691997b2554b1 +\u044D,e02cadad9f96525b7be75455d9f99e94683a8a5ede65db9c4be0697f61fababe +\u044E,3af0247439754de71cdf77cb4e3bebd714b8471ccb355f14ca8251ca97c66 +\u044F,397e206238477b195874871f17b3df5b1613562ef4aaeecea312794a4e72ef9 +\u2190,d2855a8ffa17e7cbca13dabad8ccf90e4de9748a2d2c31146468ef86608feb +\u2191,9c26876a4548844e28a6f7ba1f377c80e59495f7d32214bcc492804b16619339 +\u2192,3cb38fdf5ed04a49f21495f4d94835c8e6290abacd65c966c1c6cbefa66d84b +\u2193,7e8914dfca8c20943175c053331ae373a48af45ed5bd157c89495cae46ec98 +\u2196,9d79886974b1abc5c725975f8ec7e919b28ad241dd6f94f7675d68a7d8a5cbf2 +\u2197,67d196f5fbc31afee3372da4f9669dc9536ee3eb60c9161b11632a268bfdf467 +\u2198,6536b0eb75315b5a7e08ca1324d74363489abfe27e051d397965523de4ee8f +\u2199,bfa72f9b65b032c8c21ce2d6f8ee8e1aac7667f9d576a239fdbb47721f1390fa +\u23E9,d9d334bf33f2e5677fb174d472bb761d878d1a6579ec1e7b27d9dd545c973c +\u23EA,106536cb6de0d08c2d7012854efa28162251ee6e9f81fe6ccc29983c845d6b5 +\u23F4,dc1ca9dc5c7c941a677b40832757a909871a295e24c92c0c1e632c21d4f905c +\u23F5,93f5346d409ce3e06ba28d5b2c0161a213c8759b94b63b456e821c338095f3 +\u2640,782fbc3ba8138059123594515dd2aec0b9fddbdedceda148925736d1de109000 +\u2642,b38ec72cfafa5b5a793c8f2cf3dadcfa4fd26b38300138a8bb974c72d84894b0 +\u2648,6878d95d504ee1b512846153befe1940653e8f99ae7d1684dadea6737607ebd +\u2649,67f184ce1c9956c15856c37028f5316f86d7ac467823b4cff9defdc75a9c34ce +\u264A,1f3314dd6be99dc1e01a7974e6ca9368082b813a3c9bbb2f1ee859127ede2971 +\u264B,a6b711234bf1a2f9d4de5aed42dbda35d7f6418e1c26dcdd9248c20bf39c7071 +\u264C,d870fb19419c81e47e5b89d749f871f55204cb09a6f81a824494e3a1e1ebc22a +\u264D,fa277e55273c4df440610c9e93655a6fce62fcda46107a010434b160d7f164e3 +\u264E,bf6e96418ada5c89e93aea35b7824f014933033d99ea6ffce9f6b04809ec297b +\u264F,16acf45bf4683ec590254e91fe2ca150919141856376ccf163fd611eea8b9b8f +\u2650,888b3bb6f5442e65133f029ac9f013b701e4dda091ac18983089e48453e256bd +\u2651,8c530e855f0848830d8ec3eab16e57e50a41f367b6a25a6eb4fe2c9463a1b904 +\u2652,b0a805fb83fff2ab48da019e7315b10fe5418cc48e70935ad08fc3e856786d0a +\u2653,bb23b3f57e314dc14232451e295eba5222996c3d046d32a9250d2c8908904837 +\u2665,e547d18ef6a2c2eba281a94eebb8e979c47938d9d5477b973a52a1de8734e2 +\u266A,f05512674b1c07e880ea7c4a274b2ed7a1d4f5189fb1b8171d0855371a2ce722f05512674b1c07e880ea7c4a274b2ed7a1d4f5189fb1b8171d0855371a2ce722 \u2713,c39cbcb24ca3a9375ca38f4839e22d6174edce649b14e74bbbef6e253226bd96 \ No newline at end of file diff --git a/src/main/resources/fonts/cyan.csv b/IF/src/main/resources/fonts/cyan.csv similarity index 98% rename from src/main/resources/fonts/cyan.csv rename to IF/src/main/resources/fonts/cyan.csv index 38729587..1cd2a0b4 100644 --- a/src/main/resources/fonts/cyan.csv +++ b/IF/src/main/resources/fonts/cyan.csv @@ -1,118 +1,118 @@ -" ",9dab10a2f4f3702213a64cf941ed1f743b43135abc38ee11949d7272f36489 -!,167165228ece7aac876a1108f73c2b7604440be1dff43ebd2fa841954891d8c -"""",bc837b6878e09730374ab01686bf8e16aeebc13f77d9aa1d0ccd9e2f11a87e5 -#,4a3642ed39d5fa9f70e76d799b8389391ad2d10924f3fc7fd67aeca73b5ed -$,d07a38650ac9f2d15dbca04b9578d8f0d05a1f45c3828ac8b5820de3f39593b5 -%,7f3051b2e99991c8fd7b40f7607749d1799fcea16ccc5766634fa3af31a477c -&,e79ee94f9ab2b58fd9bea5bb43fa084364925958c525922d2d4a33bbfe8c64 -',4549c0355e48f9059d830edb711b96409ea678b49ba873f7849b1135c7365 -(,87f4a3bd1ecf9c432a361a08983d48ea1eaa3974f85d9414f38cc1868c2ad -),4ee4fcd2b5ce9c3b20dd1aa2b77a57807b4aede731fec6390a34d6e9dd72820 -+,dd8b7173d841f2563ec108888b0f797917efc18be27861f0a6761aa3ed91ce -",",3c6672ae33622e867ac74331dec7dd1b598c09ec6e55f6588e4fbe0554f7ce1 --,c67836f047d741ac4f7385f7c3dc48ba8df43732e5aeec3326829a7284737 -.,786abf7fd460a73f22a430c4182af747e25230873be716fa481edfa3424929b -/,2feabd08f759dc1b538eb9fd434bafb876ba99410f5a2f336d7cfaf85abef -0,7a132956bcbf95213a521aa93456d4a15c79cf1736ecbabfe81e5f5e44 -1,7347b7a5a6bb6419d33eb46102650cc91bfdc159d8ff1f55996d4f0ad5bc758 -2,20ba412aa76a8e119ae3eca071428f3d9e2042b4952bd83358d6296e812be8 -3,36dbfdfac15e284c2ec02e38911b4ec5d815bfb1e5eee522d557af35d840dc -4,a7ac53233ae842aebb38c13becce7c91f8d5f67976332ce1ba88dc0e682f8d4 -5,2a67144b323ad4dcebfd1c6a630743c702c4da4552289a92421eafc4c2d4b43 -6,412aab401d69a5f0c5cadcb3c1d137b10794c43b058f93630b8145b83497a40 -7,44e2824eed253ac932ca81df7efc5106bd465c349a18bde699638c1f146f54 -8,64588d8efd99511b8d2ca395648d322fa8cdc98d42bd79e3c0d6103c948e68 -9,7c2a51c4df7829b05bac9b38a99c7273b1a3b1d46bfb2a9c65e61740bf6244ac -:,108af4dc66995a96d3c55d50e7e38c2b480ba5383494d2e5469322789673 -;,249069893f517051711110f3644bb2c412a9a114f09118e6ef22ff479519 -=,b36425f806f92669991179c90a9b9d6a982bc3e1226a12fd9c4c7eb86f82 -?,c84c3d4da61357be5410d04e85f5c8ef1eb82169b72a86e05a32f997e6ab7 -[,ad1c237a2e9a615faa286126d43565db4b8b94e4f0286dbd6bc3de37383cba -\,5adebdde5c4112858dd921ce142d432722b25d94426fb86a5ea3116bab47b5 -],e9f1de76fab18d49c7d74539784ef1d7c5de402f8a762877654c725c96 -_,d54fb4a126e07db178a3e4ea863494d5599b1e9d67d21466e055ed8ab97cc963 -a,8108027353d6ee8d71f276b6a2679ee23316fb215de2503ed5ba6ccac4e0 -b,d01a1ef3d05cc146c8c24e1c75f8b7b662bffb12fbbac74252853859af32ca6 -c,5bcb43d9cba2817eddc1509d3cffc372f780d2721f47a52b42fed96a412f250 -d,8081c171fb4675f9cbb6cfbc297947f14049a6588d2870796d90d5b02c0 -e,d5616831dfdab31220ae01864456e7c6fa7dc4532bb013d3ff704229825ef9 -f,eee0f69fbbca7fbbf2a1c973cf76415d656826ae7f83abd4738fe72dc483951 -g,d98e9fa48cc99f3b124cef4e58e337e55aef94ababaca1a3415219a810bae4 -h,d82d9cf8577eb0a3d031eec370e879629b9af5a2fc292b52d5f2bf74bf94ff42 -i,61f07d1b9297141b3083fc8d156981c78dd6daecec5274eb0d87e3a8bde9bf8 -j,bd772fbfb3f7e8e4acc4724e7465b651e6dfe7bf9c6856de334fe7b2c0e3ad64 -k,1e69a398ec48aba23ce4ffdd796b46ff558d6d359271edc59b1e9098d25722c4 -l,57645bf8b35683a32e4de621b716ee24bbb032e6d02a90e369465a96f9f379 -m,b76db87a7283774d8a185e3d519eb7022edd534455e2cf378dc8bde7f82bc8 -n,109d3b13fe878a19f3659228db5aeab995d8f8b8af1757b0a89626b8e14bf -o,a5b94734c02e83d89ebca442ef731a6fcb53d1364aabb38264e8a080b35825 -p,799f1d8e5e53837ec5db9187812b1bb1a4899ae7baa15c1c4fe63e46271b612 -q,322b7bff4d4a5ef459317c3af8f2842f3cacc53e9a323d96c1c255b5d9d4 -r,1c86f2757e26b96d2718adb933141c17b7dfc622a03b79f12f0b7852e1fd -s,c92675b74daefd7ee86045fc6580fb6aa6c64f979a125b20ff6f8ea9496ce -t,d4688141ec78ded7baee5ffc97390224ae9e23278514dbf28458bfea62 -u,ff1325c87cb451e37685c325e018354d3e4d29beb46ee2b4e2dff12958da51 -v,63ae9302de8f78c1efe627fdde3372469eab91c8ecf4a2f3032c83d861944f2 -w,8740e4498519f874c7098e1fb6bd56d62201b81b6ccfa147e9feae9dfcb117 -x,7c68deb8bc576b4d631eadde89dc9cd946a3bb7e347b8c4da5d82c888ed15c3c -y,64176fd2bb7bfcace318de683f3c26b18bd652bf315afa11f6ad85794b1c4c -z,2b9f4582786330cebf7226b1ec64b055fb5118b081a2c74c3d46cb1b59ee971 -{,defea3fd4171668a289da9b68a7757b07757af9a5b0b61ad6bb2df5fe7d0 -},c950913b4b43abdf567fb0ffeedde88b65d5d893064e8a6e75debb3c4e7ff7 -\u00A1,abbe86f0040cb46de53c0cfe1ffecd4fa11f804e26f8c2ce6d864d0020027009 -\u00BF,c7ea2f89473a1c4fdb9a9b49e2412cd94bdeed327427edef440ff924e8db9088 -\u00E4,119beb3a19d252477db97232da277149f2fdea1474499da41c79598ab13753 -\u00EB,4c821e32eaa7dcbbc7ea5e4e57abedbe3db445a772a3afc3a245de4cf142380 -\u00F1,69acca72e42997b0dd05692dd122173373ee73fecf87658ba4af6ed16d25e8c3 -\u00F6,3be48c738b3084f26c687dd8a1c35ec37b1efa2f70c33e84c87d7f5654b67589 -\u00FC,fb4a6a27d9d6c3d3f45a182cc1febe1267fc51bf543ba8c0f2e30e7f6b6c1d9 -\u0431,ff7aaeb9c931aece6aedadf7bfa4d359d663614c6e7e11933c6b3bb163a20b1 -\u0433,cf2e7cc3246672978f44f926f61dd752884dcd3ff7c8cb438fb739f58149e -\u0434,e0bacc3992ae73586c56bcdb669961fb2918ab47f3ceaa67f754687abc8c -\u0436,bf8ae1e394c67fd9ae19cc393fbe25c8f734815ece6976e4654a998a0c77b -\u0437,1752a801ab967edff233048354c7a71606d4b6d8a7bb59ec2b97f6eab2afa85 -\u0438,6daa2b32904dea8647ba6ec4531e3a0ada8608f681e6b13d741fb2494bb9 -\u0439,75afa451696ab3573bc48ff93a372f928025c824b86729970247ca888698c1 -\u043B,84d4e6ccb93d8cafd0bb7f59a562540ecec50a4c221a0782176ed835e80c86 -\u043F,155571e34885475b55e1f28a4c5d46ad0aac4e65bdeafe5c58337434e8abc7c -\u0443,934c9ee8d5db3c333d78c25d5b1efcc091f049b4ba2837e14c6f747685 -\u0444,4f636848abeb720089a897499f2a7b35c5b9df54a3f317ed35645744c22f0 -\u0446,8da4dd0a264a7d8e5964fb9e4d925ac8f93a42e92f4468ee428e4781556eb -\u0447,1e937929c71cd55984141ba08dd5e1ab2b5158585346afaac1c499a0c2125 -\u0448,ca356b2714378a8c5ba11f351d7dd508433807adb5a2d2c374b44b8aec9da4 -\u0449,649160aa1672d25c128274841b13528e5fbbc5fd9958d5696b19aa8c99b3e7 -\u044A,30e0e6654796e747adb4f6e6ff7c695695d3bb93fa6d0c6e0187a5949fb6eb -\u044B,8a8d75b9b4efd75b530237d5b27ccd3258486dd924d399d9d8ea4d9921c71 -\u044C,453157d1a1e9f5b03d69dcb8a877855b7eb56c7b6727cad14b11f8b3b8e953d3 -\u044D,9332fd19196b69b23133decea86810517f96cff9f82e1709f28cfb81a96372d -\u044E,754d2f64575762866207bd9a8bbce8a95968cf636bbaebf57a423c193927a5 -\u044F,c6fce7df11cd6ad8d05619150e267d8af5a989c78537a974c841e5fe0aad8 -\u2190,6768edc28853c4244dbc6eeb63bd49ed568ca22a852a0a578b2f2f9fabe70 -\u2191,4b221cb9607c8a9bf02fef5d7614e3eb169cc219bf4250fd5715d5d2d6045f7 -\u2192,6ff55f1b32c3435ac1ab3e5e535c50b527285da716e54fe701c9b59352afc1c -\u2193,d8aab6d9a0bdb07c135c97862e4edf3631943851efc545463d68e793ab45a3d3 -\u2196,a2b8e3eaea558f86aeba322969d4eeb6b969434f5ad79266d5d968b28d9192e -\u2197,c830e87bb4477d2136ed43717849537f4d519b44d8fd6e9b4c2ebe52fa8f -\u2198,832e6a70cc1e6e6a2757cb91fb13c90e8fecdd791582d17c033ecf58c1d1f8c -\u2199,fc3be6b132012a0c2e062edeb251c5b5c14a3c93cfeca89250963c9cbd56ab -\u23E9,ba0bb777738f05c44148dc47453fce77e12aa41a10b11895bbe7e246982731 -\u23EA,f34939d26444a57327f064c3928da61f36caf622debe74c33f8f8a36da22 -\u23F4,be8f424e3697ba4aebfe67805719739565d5368665ab21af9ce2ebddd8945c8 -\u23F5,4542d0c7429387948cf99e8cb8c5559e733fc7dbfb184c2c0b7d9efd829ff -\u2640,3c8dd35d2ccab082b58a947df51961af4464f6027ce8c0d7ece3b7e055c7b55e -\u2642,b69d1498a404b7dac4c1cd3acdd9656e44515438dbf3ddf90e5a47da34a34217 -\u2648,c45d4317b9bd38f64ddc8354dd737a6ff14e3362c1d54296d367092077be75b8 -\u2649,a4d86ff2f392d8530c1c0f0f676cb778c6b54daf4bcf8adc2d44125cd3b79642 -\u264A,7b62234a0d0768921eb1761a930c88d55c48eeb514c3a2238214af3ee8d9ce05 -\u264B,b6b0531e9c6d5147ca921c0ae1a23015ffe4a0fcf84780cfbc84e963617829db -\u264C,70dc8588887b3267b06e70b00aa417c494ac1b9d749abb47baedcc8f46680a17 -\u264D,1e2c6e9b7d79e187b329023d3d2d0d341a457b6560e3e7ee4926f2560a5121c9 -\u264E,3cbe84048f30964b12f5dc343f9a3235c69308771e084bdf62560d3a7a8741d6 -\u264F,8a69984f802bcb00e0343b4ec89ab02375286077d14a5a2546df510696aa6c46 -\u2650,511d360ff70e5339bdf1131e1b87d9c0cf7baa11d31e9b278038881ff7baa649 -\u2651,753dfbbe06661e2de5db746f3baba65924cea1c25967aefaf3bf272c0c4321d2 -\u2652,d7e20947bbe43977f0b843ca0cb57782a22473b68d8d6b91a2144351bd594f72 -\u2653,1017306138fd0c93f9082b5cd3ca08614abc0d15906915168727e43340d14076 -\u2665,124a8aac165d7ae78ce5a14f948f1c66f8a27c8a5921fb57184a25ff4cc6ca -\u266A,9a25c29d4ad9236cf5d2224f80af9cd57cb1034083eacb191336b43a619ef740 +" ",9dab10a2f4f3702213a64cf941ed1f743b43135abc38ee11949d7272f36489 +!,167165228ece7aac876a1108f73c2b7604440be1dff43ebd2fa841954891d8c +"""",bc837b6878e09730374ab01686bf8e16aeebc13f77d9aa1d0ccd9e2f11a87e5 +#,4a3642ed39d5fa9f70e76d799b8389391ad2d10924f3fc7fd67aeca73b5ed +$,d07a38650ac9f2d15dbca04b9578d8f0d05a1f45c3828ac8b5820de3f39593b5 +%,7f3051b2e99991c8fd7b40f7607749d1799fcea16ccc5766634fa3af31a477c +&,e79ee94f9ab2b58fd9bea5bb43fa084364925958c525922d2d4a33bbfe8c64 +',4549c0355e48f9059d830edb711b96409ea678b49ba873f7849b1135c7365 +(,87f4a3bd1ecf9c432a361a08983d48ea1eaa3974f85d9414f38cc1868c2ad +),4ee4fcd2b5ce9c3b20dd1aa2b77a57807b4aede731fec6390a34d6e9dd72820 ++,dd8b7173d841f2563ec108888b0f797917efc18be27861f0a6761aa3ed91ce +",",3c6672ae33622e867ac74331dec7dd1b598c09ec6e55f6588e4fbe0554f7ce1 +-,c67836f047d741ac4f7385f7c3dc48ba8df43732e5aeec3326829a7284737 +.,786abf7fd460a73f22a430c4182af747e25230873be716fa481edfa3424929b +/,2feabd08f759dc1b538eb9fd434bafb876ba99410f5a2f336d7cfaf85abef +0,7a132956bcbf95213a521aa93456d4a15c79cf1736ecbabfe81e5f5e44 +1,7347b7a5a6bb6419d33eb46102650cc91bfdc159d8ff1f55996d4f0ad5bc758 +2,20ba412aa76a8e119ae3eca071428f3d9e2042b4952bd83358d6296e812be8 +3,36dbfdfac15e284c2ec02e38911b4ec5d815bfb1e5eee522d557af35d840dc +4,a7ac53233ae842aebb38c13becce7c91f8d5f67976332ce1ba88dc0e682f8d4 +5,2a67144b323ad4dcebfd1c6a630743c702c4da4552289a92421eafc4c2d4b43 +6,412aab401d69a5f0c5cadcb3c1d137b10794c43b058f93630b8145b83497a40 +7,44e2824eed253ac932ca81df7efc5106bd465c349a18bde699638c1f146f54 +8,64588d8efd99511b8d2ca395648d322fa8cdc98d42bd79e3c0d6103c948e68 +9,7c2a51c4df7829b05bac9b38a99c7273b1a3b1d46bfb2a9c65e61740bf6244ac +:,108af4dc66995a96d3c55d50e7e38c2b480ba5383494d2e5469322789673 +;,249069893f517051711110f3644bb2c412a9a114f09118e6ef22ff479519 +=,b36425f806f92669991179c90a9b9d6a982bc3e1226a12fd9c4c7eb86f82 +?,c84c3d4da61357be5410d04e85f5c8ef1eb82169b72a86e05a32f997e6ab7 +[,ad1c237a2e9a615faa286126d43565db4b8b94e4f0286dbd6bc3de37383cba +\,5adebdde5c4112858dd921ce142d432722b25d94426fb86a5ea3116bab47b5 +],e9f1de76fab18d49c7d74539784ef1d7c5de402f8a762877654c725c96 +_,d54fb4a126e07db178a3e4ea863494d5599b1e9d67d21466e055ed8ab97cc963 +a,8108027353d6ee8d71f276b6a2679ee23316fb215de2503ed5ba6ccac4e0 +b,d01a1ef3d05cc146c8c24e1c75f8b7b662bffb12fbbac74252853859af32ca6 +c,5bcb43d9cba2817eddc1509d3cffc372f780d2721f47a52b42fed96a412f250 +d,8081c171fb4675f9cbb6cfbc297947f14049a6588d2870796d90d5b02c0 +e,d5616831dfdab31220ae01864456e7c6fa7dc4532bb013d3ff704229825ef9 +f,eee0f69fbbca7fbbf2a1c973cf76415d656826ae7f83abd4738fe72dc483951 +g,d98e9fa48cc99f3b124cef4e58e337e55aef94ababaca1a3415219a810bae4 +h,d82d9cf8577eb0a3d031eec370e879629b9af5a2fc292b52d5f2bf74bf94ff42 +i,61f07d1b9297141b3083fc8d156981c78dd6daecec5274eb0d87e3a8bde9bf8 +j,bd772fbfb3f7e8e4acc4724e7465b651e6dfe7bf9c6856de334fe7b2c0e3ad64 +k,1e69a398ec48aba23ce4ffdd796b46ff558d6d359271edc59b1e9098d25722c4 +l,57645bf8b35683a32e4de621b716ee24bbb032e6d02a90e369465a96f9f379 +m,b76db87a7283774d8a185e3d519eb7022edd534455e2cf378dc8bde7f82bc8 +n,109d3b13fe878a19f3659228db5aeab995d8f8b8af1757b0a89626b8e14bf +o,a5b94734c02e83d89ebca442ef731a6fcb53d1364aabb38264e8a080b35825 +p,799f1d8e5e53837ec5db9187812b1bb1a4899ae7baa15c1c4fe63e46271b612 +q,322b7bff4d4a5ef459317c3af8f2842f3cacc53e9a323d96c1c255b5d9d4 +r,1c86f2757e26b96d2718adb933141c17b7dfc622a03b79f12f0b7852e1fd +s,c92675b74daefd7ee86045fc6580fb6aa6c64f979a125b20ff6f8ea9496ce +t,d4688141ec78ded7baee5ffc97390224ae9e23278514dbf28458bfea62 +u,ff1325c87cb451e37685c325e018354d3e4d29beb46ee2b4e2dff12958da51 +v,63ae9302de8f78c1efe627fdde3372469eab91c8ecf4a2f3032c83d861944f2 +w,8740e4498519f874c7098e1fb6bd56d62201b81b6ccfa147e9feae9dfcb117 +x,7c68deb8bc576b4d631eadde89dc9cd946a3bb7e347b8c4da5d82c888ed15c3c +y,64176fd2bb7bfcace318de683f3c26b18bd652bf315afa11f6ad85794b1c4c +z,2b9f4582786330cebf7226b1ec64b055fb5118b081a2c74c3d46cb1b59ee971 +{,defea3fd4171668a289da9b68a7757b07757af9a5b0b61ad6bb2df5fe7d0 +},c950913b4b43abdf567fb0ffeedde88b65d5d893064e8a6e75debb3c4e7ff7 +\u00A1,abbe86f0040cb46de53c0cfe1ffecd4fa11f804e26f8c2ce6d864d0020027009 +\u00BF,c7ea2f89473a1c4fdb9a9b49e2412cd94bdeed327427edef440ff924e8db9088 +\u00E4,119beb3a19d252477db97232da277149f2fdea1474499da41c79598ab13753 +\u00EB,4c821e32eaa7dcbbc7ea5e4e57abedbe3db445a772a3afc3a245de4cf142380 +\u00F1,69acca72e42997b0dd05692dd122173373ee73fecf87658ba4af6ed16d25e8c3 +\u00F6,3be48c738b3084f26c687dd8a1c35ec37b1efa2f70c33e84c87d7f5654b67589 +\u00FC,fb4a6a27d9d6c3d3f45a182cc1febe1267fc51bf543ba8c0f2e30e7f6b6c1d9 +\u0431,ff7aaeb9c931aece6aedadf7bfa4d359d663614c6e7e11933c6b3bb163a20b1 +\u0433,cf2e7cc3246672978f44f926f61dd752884dcd3ff7c8cb438fb739f58149e +\u0434,e0bacc3992ae73586c56bcdb669961fb2918ab47f3ceaa67f754687abc8c +\u0436,bf8ae1e394c67fd9ae19cc393fbe25c8f734815ece6976e4654a998a0c77b +\u0437,1752a801ab967edff233048354c7a71606d4b6d8a7bb59ec2b97f6eab2afa85 +\u0438,6daa2b32904dea8647ba6ec4531e3a0ada8608f681e6b13d741fb2494bb9 +\u0439,75afa451696ab3573bc48ff93a372f928025c824b86729970247ca888698c1 +\u043B,84d4e6ccb93d8cafd0bb7f59a562540ecec50a4c221a0782176ed835e80c86 +\u043F,155571e34885475b55e1f28a4c5d46ad0aac4e65bdeafe5c58337434e8abc7c +\u0443,934c9ee8d5db3c333d78c25d5b1efcc091f049b4ba2837e14c6f747685 +\u0444,4f636848abeb720089a897499f2a7b35c5b9df54a3f317ed35645744c22f0 +\u0446,8da4dd0a264a7d8e5964fb9e4d925ac8f93a42e92f4468ee428e4781556eb +\u0447,1e937929c71cd55984141ba08dd5e1ab2b5158585346afaac1c499a0c2125 +\u0448,ca356b2714378a8c5ba11f351d7dd508433807adb5a2d2c374b44b8aec9da4 +\u0449,649160aa1672d25c128274841b13528e5fbbc5fd9958d5696b19aa8c99b3e7 +\u044A,30e0e6654796e747adb4f6e6ff7c695695d3bb93fa6d0c6e0187a5949fb6eb +\u044B,8a8d75b9b4efd75b530237d5b27ccd3258486dd924d399d9d8ea4d9921c71 +\u044C,453157d1a1e9f5b03d69dcb8a877855b7eb56c7b6727cad14b11f8b3b8e953d3 +\u044D,9332fd19196b69b23133decea86810517f96cff9f82e1709f28cfb81a96372d +\u044E,754d2f64575762866207bd9a8bbce8a95968cf636bbaebf57a423c193927a5 +\u044F,c6fce7df11cd6ad8d05619150e267d8af5a989c78537a974c841e5fe0aad8 +\u2190,6768edc28853c4244dbc6eeb63bd49ed568ca22a852a0a578b2f2f9fabe70 +\u2191,4b221cb9607c8a9bf02fef5d7614e3eb169cc219bf4250fd5715d5d2d6045f7 +\u2192,6ff55f1b32c3435ac1ab3e5e535c50b527285da716e54fe701c9b59352afc1c +\u2193,d8aab6d9a0bdb07c135c97862e4edf3631943851efc545463d68e793ab45a3d3 +\u2196,a2b8e3eaea558f86aeba322969d4eeb6b969434f5ad79266d5d968b28d9192e +\u2197,c830e87bb4477d2136ed43717849537f4d519b44d8fd6e9b4c2ebe52fa8f +\u2198,832e6a70cc1e6e6a2757cb91fb13c90e8fecdd791582d17c033ecf58c1d1f8c +\u2199,fc3be6b132012a0c2e062edeb251c5b5c14a3c93cfeca89250963c9cbd56ab +\u23E9,ba0bb777738f05c44148dc47453fce77e12aa41a10b11895bbe7e246982731 +\u23EA,f34939d26444a57327f064c3928da61f36caf622debe74c33f8f8a36da22 +\u23F4,be8f424e3697ba4aebfe67805719739565d5368665ab21af9ce2ebddd8945c8 +\u23F5,4542d0c7429387948cf99e8cb8c5559e733fc7dbfb184c2c0b7d9efd829ff +\u2640,3c8dd35d2ccab082b58a947df51961af4464f6027ce8c0d7ece3b7e055c7b55e +\u2642,b69d1498a404b7dac4c1cd3acdd9656e44515438dbf3ddf90e5a47da34a34217 +\u2648,c45d4317b9bd38f64ddc8354dd737a6ff14e3362c1d54296d367092077be75b8 +\u2649,a4d86ff2f392d8530c1c0f0f676cb778c6b54daf4bcf8adc2d44125cd3b79642 +\u264A,7b62234a0d0768921eb1761a930c88d55c48eeb514c3a2238214af3ee8d9ce05 +\u264B,b6b0531e9c6d5147ca921c0ae1a23015ffe4a0fcf84780cfbc84e963617829db +\u264C,70dc8588887b3267b06e70b00aa417c494ac1b9d749abb47baedcc8f46680a17 +\u264D,1e2c6e9b7d79e187b329023d3d2d0d341a457b6560e3e7ee4926f2560a5121c9 +\u264E,3cbe84048f30964b12f5dc343f9a3235c69308771e084bdf62560d3a7a8741d6 +\u264F,8a69984f802bcb00e0343b4ec89ab02375286077d14a5a2546df510696aa6c46 +\u2650,511d360ff70e5339bdf1131e1b87d9c0cf7baa11d31e9b278038881ff7baa649 +\u2651,753dfbbe06661e2de5db746f3baba65924cea1c25967aefaf3bf272c0c4321d2 +\u2652,d7e20947bbe43977f0b843ca0cb57782a22473b68d8d6b91a2144351bd594f72 +\u2653,1017306138fd0c93f9082b5cd3ca08614abc0d15906915168727e43340d14076 +\u2665,124a8aac165d7ae78ce5a14f948f1c66f8a27c8a5921fb57184a25ff4cc6ca +\u266A,9a25c29d4ad9236cf5d2224f80af9cd57cb1034083eacb191336b43a619ef740 \u2713,8c813be108b31157fbb9b50d836caa0d2612f6bcfef4ae0c6b77ae3479e02a3e \ No newline at end of file diff --git a/src/main/resources/fonts/diamond.csv b/IF/src/main/resources/fonts/diamond.csv similarity index 98% rename from src/main/resources/fonts/diamond.csv rename to IF/src/main/resources/fonts/diamond.csv index 497ab4f5..007972e0 100644 --- a/src/main/resources/fonts/diamond.csv +++ b/IF/src/main/resources/fonts/diamond.csv @@ -1,118 +1,118 @@ -" ",83c7adfc3d864bea83bd776aca47917f12e65876b64d6c96822cfa6a368c2ea -!,68cc951bdc6b8ff3b8dd7443cc49d1f1b74c9f93cf0449f8c8a211b85e76b15 -"""",6ed07c9578387ae8e6cddade49474133e3a9d9d1748b4aa547fbc3a15c -#,715821c3f543bdd62b1156ec21df80f937ee8e9c124f7576731bc146df9c6aa -$,bf1ac7182f91efcc274d6dd387e75d21227f1ad0a06b07253d43ccc9dea29ff -%,92d9b37a8a5e136d35729725f6d103f2fde6c90d3dd5c1dda6a4ee26df3722 -&,2b7a4d2833427ea6cd3c75805c33d3239a17df11dd9bcfd44b1522b8b5622921 -',21ba3611a82bb8c446a7785a9db58664295c9e865be410d977bf5e1771 -(,4199b2ad5bf0828548db423d3e4fbfa477e833ae7d88a52c55d1ae552c3bffae -),8c80c03a58f6b4431b4bbd9cd18798acb36634d8d7e39c311ab96d7924bc -+,a8136fff2e9623810c78486a6ffe2f9aee5148f3b282f2fd207d255f58e0d1 -",",d8d5d144d097d21f9721cdbb9a639a0cfd54adfefefa4599f1271274e1a1 --,c9416b60d93d4f19fd8d6a6f877c6b6251d5e4f87e6484d05775b66b78c3e5 -.,bce723d94994f6cbc9c4cf863916aafb81a3c61f16c56661814108c9947552a -/,544851ed117276f0a79cb2ef745e2477494269f0de32b656d537726a423eff -0,988828c1d0af2d866084aaf5cf72961408fc54c18e15ed45259569736b199 -1,af3034d24a85da31d67932c33e5f1821e219d5dcd9c2ba4f2559df48deea -2,3a28a1353833f40a421cabaa3965b970ad9f62c1d962aca98414d2dec5c338 -3,a51c6da46f7585bf2fd5ca44c4abec568c23eaf67c3f681cd2bc1b3eb275a -4,0e934c0e0e56fb6591ca98d7c8a83fe386898cf64be314330bd8278d82a2 -5,34343eeb23d18ee37ba6eedd9db061a4705730e34dc8559646f729f95e50a37f -6,32e71b8f7e1bf49d5d892e42361c9d4093cee6413952e6a4db6464ff78aee8 -7,d8a3c5b122dff93636bdbcd6669b59cda3fcfae935ce7615a27e5dab17c75561 -8,859838237f889f5bcaaf26c756f64e816a1350c3c54aa7a0f728392265908e35 -9,fac3a94957532f2807611ac325bcdee4e4d7cb4a22122e420806ce6b0d7c3c1 -:,61418562825490eca67bb686d91aa98dd43ba8d71e8bfc7d8107231f3d6e34 -;,67eff9a1994b6acf543f4f96ec48861b7692835ef650c82d91afe6fe473eb -=,cb3ad8ac63fb65faa2387442b767b998cbac255a8883203b38a52dcf527ce62 -?,c064983c78ef587c5e574b080a8454ffd62cc329c683a68f62af7f92a1f4a -[,da68c79b9f6bb26e70303af5ca3db77ef094dbe59a6841cf3653d1e68cf873a -\,d421839f393d6644c35a77a7cb6ef63423272c34986cc8943ba6dc619b351a0 -],fd9c68b8d13c75e92a4a7e068a3f4a93e4bd1a3aef91480bfecf3e79b5d1 -_,1842218b4a9fe36147b094e6bf29a0963ac096d3637cb342f57ff357d2122 -a,f417618ca1f5031d1ab97ba3253d088f4da7a773bbb56f1dec9b999d71ec -b,25feb8157695a2594a5585b9def5f7827c6e5e8fcb2f23cc3d34d733ca635b -c,36fff52b417819aa1e805995c154b59bce77afb593de868c397312c3b5114b61 -d,63523ca4ec25a883936b3c7d902cd0dd0fc94b8fee619a99d715d2e277ddd -e,2fbc41ab6ee4f97c659d4f6e47c494e961255a06a496bd5c6638b339dc0 -f,d4fa96a3cf88561116d24e81adb4661f8bb7b42a4061f412bbd0365452669bee -g,5ebab6952a4e63568f6b581eef5c4c8aa6f4bd2dd2e14a4dca324257f33c5f -h,f8189f6d2450a91149ef2dfb9474232c6fced84cfff4e27787f5102197717b -i,f5edfab169748c55984bc8d6872c59658d33aa5ea22792cfe99b3dbab628d9fd -j,a2b18a2b87f577d3b038be168c252c1df19ebde2c45481fe435954ea1dfbd7 -k,d4e2899b68c1c12872e4e36897e472a9102fab8858b5630156d5b63be058ac -l,d1c2bbbf8f2b798eddf0c243ff789087c3ea969575f1c31a7972deb7f4f1f572 -m,2c79fe55827cba8dcbc19bdf93b5cd5d0416e5a8362e6683084a252334283 -n,cef89c21b7bccee362274160bd34a45ce2ab347b6df9b2689660f0e94adedd50 -o,6ede6082442383e5e1c28257b6db2613dc37f9749f48ea0b4f94af98ae0ce -p,5b1e42767090828970a9b432762062ff6df4cbc2311de23a1bb4253ecb1692c -q,c6933ecee27d3a7485c5db2e90439bd769412522a9915d234571b9a7b82a -r,c93ed807dbf147c5ef9b8ec46d3fa6e2d7b2dbd3431a23417c1354bb863c4 -s,9747418d86a6aa52fb98980b735b8d1d368882bc3f516b5a348d44df53de26 -t,fba915e3194b17456deb2ac7c8f8c62dca23e51a4562374b5228035efc1c8ac -u,e184ee71425d6b74c3e6872c3a1177dcbfb0fe799d2c47210b5a44672ce1fba -v,85727a84297c3342de233becfde73526d8d5605fda2529d2e1514938950e6a8 -w,9796b24c5fd7f5c58bc261a52a2eaf9674ee52a52468fc79fbe29c84447908c -x,fa4e1bb4eb76b712399592cb202f613b5b96283f22e41f4b959db7134ff72fa6 -y,516741a6597b683ccebe211f2f41f54d7f2254f58459adffea7d35c9da21b7 -z,10a6df3879b529a3494a5a9587656c8354af0bdcec67cd8cf7335f3d6a7f -{,817db25ad83d41b3d09df7f55a3715c6184e636b861b767fea74cca9747aec -},6e44d6b75348c322b4bb10d7cdcae17999f8fea460d45ea87466fd8868be1bc3 -\u00A1,80fae8030de781bb0008fb41d57973f79f9bd72904c4dce8554847820be3bc5d -\u00BF,75cffebd2cf05b424847edd30cc21eb8bba6d3af778bb0f2a2dae49815a5cb3 -\u00E4,7958e0c9738fa044b7125353e26ef8b51668ed9bcbfefa2234f4129a53f5cb1 -\u00EB,e8b1e692897790e4f4ec68dcbe17f052f3821bbd1c71670472cddc06ef965dc -\u00F1,c3d844564f29011aa2c859aae5770afcc72eb3ed9b339e12a4aa24e91af4e3bc -\u00F6,25d0ad77e8b9c8f6a490369522ae426a3d2f7c643343e7c13aeb5aca47e95d -\u00FC,317197c75ed6a02250f743bbc9b06ef2de79862235ce3370d9e33b117ae1bd -\u0431,c37044e17de1cac9322817a9ecbd4bc0b05199bada4acd6f58248fea4e2b71 -\u0433,e72e4de96eb94ca727ecd3e1d1fe653e88e7d9a576bd2e6a5e7789101f63eb -\u0434,cbf721841770c3ae867efe5aee122593ffd3017aeee5c7b182f0241672f11 -\u0436,7da71d5e69a798968f15a9918c8e3feff56e58c9e7f38535f9603cfff96fa8c6 -\u0437,24655c4bbfc6f18ddb7d4dac1988b91cfa7dd7c6aeb940c7a816d088efabcf -\u0438,6b27e4bf8babe2d9b9f0b27a42ed5edc83a4786d67e719606e89fd75ebd21338 -\u0439,33175ba32a738e6035b192f642786be3baa5ab9cbf73c03ab6e94bf5e41250 -\u043B,b77c7cd02c135568dfd23439aa04cade7cc566f239aaa2c0c3d9c112fde2 -\u043F,fc87629ad0873ed868da3818998c58b48d5a56cf4a6c8ed34966d45a50c55c -\u0443,73a218a2fc27e67477b9b82b7ae6b86ceb6a481a9e7f6343c53be52c5136bab -\u0444,dd91122f6931816b28b33d6d14be85d5282c7afa7acf113521cca2c7bb4b62d -\u0446,dc624883b5953df8aa13635d6d9d91f528972695b61d235fac260158c99f5d6 -\u0447,4d8144757cfd09547c6df9f2ed465c5bcecbaa0c24a46a95921b292adc539 -\u0448,2f36e8cd2f70dfd788dbd5f24db4e714625c2db13f59e347bcb6723bdd2ae078 -\u0449,cb234aab39e5cb586d8b9cf5ff86d9573832c64d56dd3ef7f3246820416d -\u044A,ab98739a4d86109af66f1f9fad642dc888a7c21e42bd4f2fcb3cb1f0bc1ad38b -\u044B,8a84d172c1088d770421be2cefc78b7dbcdbf3cf1af6733845fd9f69cc991 -\u044C,8fa6b342dc1140a280f1863fee17bc13794d96a946d36bbdd2c4a315ccddb9 -\u044D,c16f4cfa2e8445e5295f81c3565a6d40dba4e48aab614827a5b767ff3e9118 -\u044E,52b10735d333be84815b77a1a03b2ba749b5616133fc8e75f794e92aefba71 -\u044F,1c4c4b6eff2f1eee38bf80f39467ba5d7e5e798f7fd596fd177a689778b02533 -\u2190,1b6140af32cb364d9be3b94e93081d6cfc8c27d3cfe0b4dd45e785225eb -\u2191,7d695d335e6be8cb2a34e05e18ea2d12c3b17b8166ba62d6982a643df71ffac5 -\u2192,fca84267cb5a37d699abe7d6a03178de089d7cf2e726f37da3fe997fd7 -\u2193,437862cdc159998ed6b6fdccaaa4675867d4484db512a84c367fabf4caf60 -\u2196,929dbb081dabf71dd9ea061d4276a1ed48555b7f07acdadd33d27a8e149d9 -\u2197,a0ca169d1ca6546a23c8ee5b93f3a4e6983d14dc981e48048829c30d3132539 -\u2198,411b3214d3f8ae327cc0fcdca2d2d4a6b2dcf4af9ff23ee21a986c2ffd52d5d -\u2199,e9b718855d54fde26b061e1d35db9e16e2782be6820ae912e53e2cd3a1382fb -\u23E9,7d468bde84dacc11fb5526e534ca6abed69bbc343e87e9ea5f04bc64730ab -\u23EA,b272fa9d5d525bf4bdf533ec1b92b1d2ce24234a1e43ed5cde7d241e7ac0de -\u23F4,1894da69596548c74d964e99b7a4c9217610f1a27c991dfa44daa5da771d825 -\u23F5,c7453ac2d7a42a93674fbf62caf331c7143dcbbcc4f2babbc2f65b95174214 -\u2640,e1f1d44c772934ea9bd1127ac60cab3e8845929e2a753b369990d8ed8d9cdb03 -\u2642,e477ad6cda020281e8ee47c56336315ea8eeddd94c69b9bedf9bce1f56065b69 -\u2648,97a4726fef359d26b58d56f7748c8ed194e532051e87cc83751737ef95c2d2e2 -\u2649,8753bcf7fe8c55b05850073a94d9ad49043e999c5df1b4091a10cd7bbb5e8db0 -\u264A,8f333f6c0b5b00ac8345b71628b208703dde902e111a15c8689372584f59bf30 -\u264B,b6dbce83a1117405dedea876243a68bb3f5dc6b231f0e0229aa4e90ab05b74c8 -\u264C,5ee00652a8ead389f3d8b4751d4eb9e49f7bb7efb120df76f31d31e3e3acae57 -\u264D,7ff69bc1ab9fa153da3adef149c358a17b7adebebff73a329f2e5a410bff2544 -\u264E,81d30f8490c7f80fba56e57ac259c01a30d5f030e8bd4a7e0d0b274416d23c66 -\u264F,ac47bc011281bc493ebc057f1b9d33106c830cdd775959c2e6c29a1b284d3cdf -\u2650,5803d14b53a8affc924ebbeec21e8f8511c16a776082f11a6b8a6543ae755a33 -\u2651,8d82d46975843e3e2290e4ae77c747f16b4e1b3bbb84d60ea1c6468581eeda95 -\u2652,dc2541b5a46f859cea5b1bb51ea523f54a57902a7e69266670629cd980a4c117 -\u2653,5b3fb862fc74ac5607eb58d828dada38dc2666f1147041829602b160878bcd7 -\u2665,59e7eda54938b173946eca72cfa32993d99798c23915d3e68827d51f1ce789 -\u266A,21dc20a8b31fa060b49cebc34ebab6d0c8f62977dda3d75c11e46c4e03cf7baa +" ",83c7adfc3d864bea83bd776aca47917f12e65876b64d6c96822cfa6a368c2ea +!,68cc951bdc6b8ff3b8dd7443cc49d1f1b74c9f93cf0449f8c8a211b85e76b15 +"""",6ed07c9578387ae8e6cddade49474133e3a9d9d1748b4aa547fbc3a15c +#,715821c3f543bdd62b1156ec21df80f937ee8e9c124f7576731bc146df9c6aa +$,bf1ac7182f91efcc274d6dd387e75d21227f1ad0a06b07253d43ccc9dea29ff +%,92d9b37a8a5e136d35729725f6d103f2fde6c90d3dd5c1dda6a4ee26df3722 +&,2b7a4d2833427ea6cd3c75805c33d3239a17df11dd9bcfd44b1522b8b5622921 +',21ba3611a82bb8c446a7785a9db58664295c9e865be410d977bf5e1771 +(,4199b2ad5bf0828548db423d3e4fbfa477e833ae7d88a52c55d1ae552c3bffae +),8c80c03a58f6b4431b4bbd9cd18798acb36634d8d7e39c311ab96d7924bc ++,a8136fff2e9623810c78486a6ffe2f9aee5148f3b282f2fd207d255f58e0d1 +",",d8d5d144d097d21f9721cdbb9a639a0cfd54adfefefa4599f1271274e1a1 +-,c9416b60d93d4f19fd8d6a6f877c6b6251d5e4f87e6484d05775b66b78c3e5 +.,bce723d94994f6cbc9c4cf863916aafb81a3c61f16c56661814108c9947552a +/,544851ed117276f0a79cb2ef745e2477494269f0de32b656d537726a423eff +0,988828c1d0af2d866084aaf5cf72961408fc54c18e15ed45259569736b199 +1,af3034d24a85da31d67932c33e5f1821e219d5dcd9c2ba4f2559df48deea +2,3a28a1353833f40a421cabaa3965b970ad9f62c1d962aca98414d2dec5c338 +3,a51c6da46f7585bf2fd5ca44c4abec568c23eaf67c3f681cd2bc1b3eb275a +4,0e934c0e0e56fb6591ca98d7c8a83fe386898cf64be314330bd8278d82a2 +5,34343eeb23d18ee37ba6eedd9db061a4705730e34dc8559646f729f95e50a37f +6,32e71b8f7e1bf49d5d892e42361c9d4093cee6413952e6a4db6464ff78aee8 +7,d8a3c5b122dff93636bdbcd6669b59cda3fcfae935ce7615a27e5dab17c75561 +8,859838237f889f5bcaaf26c756f64e816a1350c3c54aa7a0f728392265908e35 +9,fac3a94957532f2807611ac325bcdee4e4d7cb4a22122e420806ce6b0d7c3c1 +:,61418562825490eca67bb686d91aa98dd43ba8d71e8bfc7d8107231f3d6e34 +;,67eff9a1994b6acf543f4f96ec48861b7692835ef650c82d91afe6fe473eb +=,cb3ad8ac63fb65faa2387442b767b998cbac255a8883203b38a52dcf527ce62 +?,c064983c78ef587c5e574b080a8454ffd62cc329c683a68f62af7f92a1f4a +[,da68c79b9f6bb26e70303af5ca3db77ef094dbe59a6841cf3653d1e68cf873a +\,d421839f393d6644c35a77a7cb6ef63423272c34986cc8943ba6dc619b351a0 +],fd9c68b8d13c75e92a4a7e068a3f4a93e4bd1a3aef91480bfecf3e79b5d1 +_,1842218b4a9fe36147b094e6bf29a0963ac096d3637cb342f57ff357d2122 +a,f417618ca1f5031d1ab97ba3253d088f4da7a773bbb56f1dec9b999d71ec +b,25feb8157695a2594a5585b9def5f7827c6e5e8fcb2f23cc3d34d733ca635b +c,36fff52b417819aa1e805995c154b59bce77afb593de868c397312c3b5114b61 +d,63523ca4ec25a883936b3c7d902cd0dd0fc94b8fee619a99d715d2e277ddd +e,2fbc41ab6ee4f97c659d4f6e47c494e961255a06a496bd5c6638b339dc0 +f,d4fa96a3cf88561116d24e81adb4661f8bb7b42a4061f412bbd0365452669bee +g,5ebab6952a4e63568f6b581eef5c4c8aa6f4bd2dd2e14a4dca324257f33c5f +h,f8189f6d2450a91149ef2dfb9474232c6fced84cfff4e27787f5102197717b +i,f5edfab169748c55984bc8d6872c59658d33aa5ea22792cfe99b3dbab628d9fd +j,a2b18a2b87f577d3b038be168c252c1df19ebde2c45481fe435954ea1dfbd7 +k,d4e2899b68c1c12872e4e36897e472a9102fab8858b5630156d5b63be058ac +l,d1c2bbbf8f2b798eddf0c243ff789087c3ea969575f1c31a7972deb7f4f1f572 +m,2c79fe55827cba8dcbc19bdf93b5cd5d0416e5a8362e6683084a252334283 +n,cef89c21b7bccee362274160bd34a45ce2ab347b6df9b2689660f0e94adedd50 +o,6ede6082442383e5e1c28257b6db2613dc37f9749f48ea0b4f94af98ae0ce +p,5b1e42767090828970a9b432762062ff6df4cbc2311de23a1bb4253ecb1692c +q,c6933ecee27d3a7485c5db2e90439bd769412522a9915d234571b9a7b82a +r,c93ed807dbf147c5ef9b8ec46d3fa6e2d7b2dbd3431a23417c1354bb863c4 +s,9747418d86a6aa52fb98980b735b8d1d368882bc3f516b5a348d44df53de26 +t,fba915e3194b17456deb2ac7c8f8c62dca23e51a4562374b5228035efc1c8ac +u,e184ee71425d6b74c3e6872c3a1177dcbfb0fe799d2c47210b5a44672ce1fba +v,85727a84297c3342de233becfde73526d8d5605fda2529d2e1514938950e6a8 +w,9796b24c5fd7f5c58bc261a52a2eaf9674ee52a52468fc79fbe29c84447908c +x,fa4e1bb4eb76b712399592cb202f613b5b96283f22e41f4b959db7134ff72fa6 +y,516741a6597b683ccebe211f2f41f54d7f2254f58459adffea7d35c9da21b7 +z,10a6df3879b529a3494a5a9587656c8354af0bdcec67cd8cf7335f3d6a7f +{,817db25ad83d41b3d09df7f55a3715c6184e636b861b767fea74cca9747aec +},6e44d6b75348c322b4bb10d7cdcae17999f8fea460d45ea87466fd8868be1bc3 +\u00A1,80fae8030de781bb0008fb41d57973f79f9bd72904c4dce8554847820be3bc5d +\u00BF,75cffebd2cf05b424847edd30cc21eb8bba6d3af778bb0f2a2dae49815a5cb3 +\u00E4,7958e0c9738fa044b7125353e26ef8b51668ed9bcbfefa2234f4129a53f5cb1 +\u00EB,e8b1e692897790e4f4ec68dcbe17f052f3821bbd1c71670472cddc06ef965dc +\u00F1,c3d844564f29011aa2c859aae5770afcc72eb3ed9b339e12a4aa24e91af4e3bc +\u00F6,25d0ad77e8b9c8f6a490369522ae426a3d2f7c643343e7c13aeb5aca47e95d +\u00FC,317197c75ed6a02250f743bbc9b06ef2de79862235ce3370d9e33b117ae1bd +\u0431,c37044e17de1cac9322817a9ecbd4bc0b05199bada4acd6f58248fea4e2b71 +\u0433,e72e4de96eb94ca727ecd3e1d1fe653e88e7d9a576bd2e6a5e7789101f63eb +\u0434,cbf721841770c3ae867efe5aee122593ffd3017aeee5c7b182f0241672f11 +\u0436,7da71d5e69a798968f15a9918c8e3feff56e58c9e7f38535f9603cfff96fa8c6 +\u0437,24655c4bbfc6f18ddb7d4dac1988b91cfa7dd7c6aeb940c7a816d088efabcf +\u0438,6b27e4bf8babe2d9b9f0b27a42ed5edc83a4786d67e719606e89fd75ebd21338 +\u0439,33175ba32a738e6035b192f642786be3baa5ab9cbf73c03ab6e94bf5e41250 +\u043B,b77c7cd02c135568dfd23439aa04cade7cc566f239aaa2c0c3d9c112fde2 +\u043F,fc87629ad0873ed868da3818998c58b48d5a56cf4a6c8ed34966d45a50c55c +\u0443,73a218a2fc27e67477b9b82b7ae6b86ceb6a481a9e7f6343c53be52c5136bab +\u0444,dd91122f6931816b28b33d6d14be85d5282c7afa7acf113521cca2c7bb4b62d +\u0446,dc624883b5953df8aa13635d6d9d91f528972695b61d235fac260158c99f5d6 +\u0447,4d8144757cfd09547c6df9f2ed465c5bcecbaa0c24a46a95921b292adc539 +\u0448,2f36e8cd2f70dfd788dbd5f24db4e714625c2db13f59e347bcb6723bdd2ae078 +\u0449,cb234aab39e5cb586d8b9cf5ff86d9573832c64d56dd3ef7f3246820416d +\u044A,ab98739a4d86109af66f1f9fad642dc888a7c21e42bd4f2fcb3cb1f0bc1ad38b +\u044B,8a84d172c1088d770421be2cefc78b7dbcdbf3cf1af6733845fd9f69cc991 +\u044C,8fa6b342dc1140a280f1863fee17bc13794d96a946d36bbdd2c4a315ccddb9 +\u044D,c16f4cfa2e8445e5295f81c3565a6d40dba4e48aab614827a5b767ff3e9118 +\u044E,52b10735d333be84815b77a1a03b2ba749b5616133fc8e75f794e92aefba71 +\u044F,1c4c4b6eff2f1eee38bf80f39467ba5d7e5e798f7fd596fd177a689778b02533 +\u2190,1b6140af32cb364d9be3b94e93081d6cfc8c27d3cfe0b4dd45e785225eb +\u2191,7d695d335e6be8cb2a34e05e18ea2d12c3b17b8166ba62d6982a643df71ffac5 +\u2192,fca84267cb5a37d699abe7d6a03178de089d7cf2e726f37da3fe997fd7 +\u2193,437862cdc159998ed6b6fdccaaa4675867d4484db512a84c367fabf4caf60 +\u2196,929dbb081dabf71dd9ea061d4276a1ed48555b7f07acdadd33d27a8e149d9 +\u2197,a0ca169d1ca6546a23c8ee5b93f3a4e6983d14dc981e48048829c30d3132539 +\u2198,411b3214d3f8ae327cc0fcdca2d2d4a6b2dcf4af9ff23ee21a986c2ffd52d5d +\u2199,e9b718855d54fde26b061e1d35db9e16e2782be6820ae912e53e2cd3a1382fb +\u23E9,7d468bde84dacc11fb5526e534ca6abed69bbc343e87e9ea5f04bc64730ab +\u23EA,b272fa9d5d525bf4bdf533ec1b92b1d2ce24234a1e43ed5cde7d241e7ac0de +\u23F4,1894da69596548c74d964e99b7a4c9217610f1a27c991dfa44daa5da771d825 +\u23F5,c7453ac2d7a42a93674fbf62caf331c7143dcbbcc4f2babbc2f65b95174214 +\u2640,e1f1d44c772934ea9bd1127ac60cab3e8845929e2a753b369990d8ed8d9cdb03 +\u2642,e477ad6cda020281e8ee47c56336315ea8eeddd94c69b9bedf9bce1f56065b69 +\u2648,97a4726fef359d26b58d56f7748c8ed194e532051e87cc83751737ef95c2d2e2 +\u2649,8753bcf7fe8c55b05850073a94d9ad49043e999c5df1b4091a10cd7bbb5e8db0 +\u264A,8f333f6c0b5b00ac8345b71628b208703dde902e111a15c8689372584f59bf30 +\u264B,b6dbce83a1117405dedea876243a68bb3f5dc6b231f0e0229aa4e90ab05b74c8 +\u264C,5ee00652a8ead389f3d8b4751d4eb9e49f7bb7efb120df76f31d31e3e3acae57 +\u264D,7ff69bc1ab9fa153da3adef149c358a17b7adebebff73a329f2e5a410bff2544 +\u264E,81d30f8490c7f80fba56e57ac259c01a30d5f030e8bd4a7e0d0b274416d23c66 +\u264F,ac47bc011281bc493ebc057f1b9d33106c830cdd775959c2e6c29a1b284d3cdf +\u2650,5803d14b53a8affc924ebbeec21e8f8511c16a776082f11a6b8a6543ae755a33 +\u2651,8d82d46975843e3e2290e4ae77c747f16b4e1b3bbb84d60ea1c6468581eeda95 +\u2652,dc2541b5a46f859cea5b1bb51ea523f54a57902a7e69266670629cd980a4c117 +\u2653,5b3fb862fc74ac5607eb58d828dada38dc2666f1147041829602b160878bcd7 +\u2665,59e7eda54938b173946eca72cfa32993d99798c23915d3e68827d51f1ce789 +\u266A,21dc20a8b31fa060b49cebc34ebab6d0c8f62977dda3d75c11e46c4e03cf7baa \u2713,d28872dc9d634d274c4c0e80de61763c22b6cbe49740e87e3657bc36d3ed4bea \ No newline at end of file diff --git a/src/main/resources/fonts/dirt.csv b/IF/src/main/resources/fonts/dirt.csv similarity index 98% rename from src/main/resources/fonts/dirt.csv rename to IF/src/main/resources/fonts/dirt.csv index 1755f546..48232430 100644 --- a/src/main/resources/fonts/dirt.csv +++ b/IF/src/main/resources/fonts/dirt.csv @@ -1,118 +1,118 @@ -" ",6036bf97926c02a6da524bf487db5b9742d5bc5884aa2faf94e576fc869 -!,d6e9f272dcb25b71f1ecf4b94ff7c3681bc5a7b5ac3434d689c9d1e36ae2e -"""",82c15d581197a1ec53dd57f32a2b7defdf6dd86efc61ab26e8d6c9a5c3d63a -#,27955f778bbf90374bb5ee16143a88f25ff8c22c9abe02d9975a097cff3b654 -$,6e053b8fee613ca242c0cb2c030253945b154122ab051af5d2036826977c0ade -%,fe4912259b847dbee73696ee1a5644df9281f6cf3a674d870e20dac7b86435 -&,7baedd41c4c124a6b6d73a8f5bcf88d6a3ce31e368cbb8eedb29a683645cd -',a2188bad3f277b353bde9f581b246377a469745cd9e5a44bc3933b0c0e610 -(,73fe0376d7b6bfb60d1b621e5eb2667beb59aa9c2067428532d7e629652b7c -),a3164a1797d7aa097bd3261761bdf9ded50e024b3104e5bfe06a7c33d4d9f6 -+,5a51a58967f3b7af026c9c289dfdca4c436268575166954a694921541ec0fc -",",7ddf408620ae4b8d88d2b84956d7e219152741aba6cd828e184adbe8d55f7f7 --,e6a8464990cd7666811d6f292fe869692a184e0c7446fa587ed1c9b1fea724 -.,c85535fea2ff52422af69cdae7bff84439308eb11bdc8b6c958ad52c4c9b1894 -/,1889017cb82e772edb84c177174d3c49169ca9c267a42d5fc87f8df6115c -0,ccfbf53883aaadf4708de7fa917edc32e8ac6f89539c16d9ba13aabe535557c -1,e6a20b939b28b2c32d7998582f41703c9ed837d0c90b7633145bec9dfa066 -2,daca8d3bda1325ba2ddcaa9aa15af73991b92918660b6946207bb0b4c0bdd6 -3,90774a3efbcaad9ce39a7e1422addeaf44efa788dbdfdcaf125496552e44880 -4,6b439d55b7e4ff8060af13bbd6448eda1d9c72854949d2c6517eb2088bb1 -5,92872945e4c2435cf794e5968baa592d17cbd663dcc96e3f6ccd321dfbe4c44d -6,3bb82ee5a57cc27028ffcd55af46b0f38b779f533a3c4de9fe26519330941b -7,a7c4afd1661d504d615f93c3e4377f69ec5b7a98b557a6388be113dd7c6c6322 -8,b2ff3a9ef9bcc12514a23cab3f53955f37c53c8d214acc8ba1bc2a80e2b7ae2 -9,2f7aec9cd9cb27fbeaa15e8dfe9b7d7c898507af67f3ded293a768470c2c7 -:,47c1b124a821eb64f4b4f77a4ae88ab133bed54d4cff7a27e4cd544030752f -;,38b9ec46878f68f569c2ddf3104eced799e24d8ba5211b74e8a38dc8da771d -=,fdd3d5d146c6153acc8bf1328a57e14481562990b3ea4eea368707ad8c97342 -?,e8c78f8ac9f40c53c463b963e84ab5c1eb883a46e3877caa80aa21744f1e52 -[,bcf117486eb4d5e5f7e18f5a052d0949d278a35666e1e2fd428fd038f5a64 -\,8b988bd0731c55ddf2c7c2a581e4059c2e66739777d6c7d3fcf183dbec5d -],9b342ec235c87734bac4f9f344a54ede7b377c28c52983a41dca196746dca5 -_,2e2f7b958f6b7b86b0441cc33dc56a511dc1eeef51215cdddc8442ebfacfc2 -a,37e8a2db7cc1b326abd99d238c7a544af8442334fbcd22751163959835b3754 -b,f5634f2fddb193c3a3f60564229adeaf2da416df046d0ad32d9b2cf4695b8 -c,6afdf174aa57cf18a8de5f7a836915f42aa601b55f3122ebed96cce93651a -d,bd1c82bd40c72631bc783f8986ccbb3fffccaa81afdf5365a353d6140bfca -e,6f758574a72c637a9bfc3778c6c8b7e154a01c5026d0e84156772080ed91319c -f,90f6d0fb7fd59cdd346162d44c2a3b5b4ae2ba75445e642a1efe965519194 -g,bb3da53dad804012b538c94cd559a4d588613de219a21e5781d6dd1dd8a2 -h,b0111c9be4ef68ba46fbaedf7f636a0cd51214dbbd2dfca7176752999852 -i,43a256d0513c1ea66afa964d61c68e9819b591362b031919a6fbb18433d242a -j,d87816b3637f816c1933a685f811559cb455d31deeceff97a451c642a9ef7 -k,e9dad060205fe442a911fddc4b46bc5c46af32bacb58d17085b9a37477af31 -l,7bba3ae253931e05bea50a116c6380dc7f48951bc7624c4d1527e24b8ad55 -m,84a4ede2ed21d7ecb9028c67671b3908cb29471bce2a63234cfe3d7939f3d0 -n,45113834129a210321dd52c52c4b0731ccfe04a46275b438d4049cbc4685719 -o,8f703638ead758aeb930b67b405ad9ec62de8e64a134e116b5939a280a84856 -p,b84636e63f2fc934444398083d56253155f13c1fe648a15472394325a5f66 -q,34f15b40b6a16f95c442ee65b47ebac17cb6f5e37ec15c7542fef31681fba -r,cec6a3db3bc27481113c589a2b954545c5b7a39d62bb17e512c1b995e69a5 -s,26b263efe75271689a1558d4a583762f8f2336e5773e198f21b2d65939f6f -t,785edb9cb426ae7052a05e544e7851b79a85aad99ac62db785b28d8e5b3 -u,32491a56baa87e7de510e17bdf76f0b649a28e4cbbdb77a76e411996f0e9f0 -v,3960a51ca156a311228d95d492b8981613ae1cc71362ea16187dc7ea4fad -w,70813a18491d4572ca4df09e9654a27e456b9d227e56e3f1a6d245fc5bd57b -x,4ed7b8986a91a7ede63c62cffea725b67e1e24c0c47dd07097bf9ae7215ecf8e -y,571688eb9ba17cca9e65385e726fb5d286887c8444cc381a67d6e91b91f9c -z,1556307bc0bd94b9bcf67d16d869524f2118ebda872d6d1636c4bddbf4e7122 -{,55b0d58e7c7a862d5ed3e13c71c1be9a83bfb3d5b9f6eda79d29ed5e7d212cd -},c6f02f4e519f4c643dc6757128d18b4535c4444ef42139580e8c6eedd1ec8ae -\u00A1,4cb86708ad9aced0e3c3f934403255ce1fa406b2a0930755e87bb5152a56fe58 -\u00BF,688eed46255bdc12b8fb8763e886b885e53e914006af358ec6363cfbede8e531 -\u00E4,f8532261da1b9327738165dbc3d775db2d5cd5952d8dee5c16ed58bf42c5c9 -\u00EB,d3fdef0ee5f811a2362d37fd25e1a8e4055ff42a477cdd437a7e51c09c6 -\u00F1,69399f8709506209a63630776ead607375661f4962e319f56c6e1f8766cf0f39 -\u00F6,9bda43ceed246adb64639b21d16a3876d41faf41aaf249fd2e8018e0fc18b -\u00FC,c72cdd21f350a81b946da932b99ba850f6ecbdffc413cf489814cb1842824d -\u0431,dd3ca93a7521bb664581c9661b4fe8788b7d3e683ca7231f1e4132cb937e4 -\u0433,3781de8c41c29fb24a1d3e912374866832886d658ce42adb21d669d8b185 -\u0434,7957968d49f4288699bcbf46e96a9b7d22129d4e83b3fadae803598e6e7 -\u0436,aec5f80fe8915e2e794ce543caaab778da5212c80b577a88ef8bc3cbc19eb -\u0437,9c645c67af969e5c9ad83f23dd8258e939f96e8c11bfdb3914b35f88cc8a241 -\u0438,1fea8340dad4b8e33fff4530db1cc78bdea7a171b8f7676d424389533edaf -\u0439,43dfdde55a4cce9019d56116c05bba4a933e5d22b3c5ede22dbae383140c6ec -\u043B,6c46187035e7bebb957a18bccd7eeab010eafb3d522479d23e96dbb7eab42 -\u043F,39f3b629c3dafa703b19f791a784ec1e60f740c98e59d88266971fe5a66ea931 -\u0443,093b97218f447bb2d8771ab739cc3b608bc619188ba86f50e65cd625dd5cf -\u0444,d0885293d4f468db1ff813376f9a942fda67e62cf646cfe544d4fe6833c61f -\u0446,5740126b117f5a95fb6b8af4a04a1557fcfc2fef6a279cdd20cf6f9f144c0a3 -\u0447,94afcf9ac673d7531dbdc779ede27aeb638bcb18189915c6dc18ffd754c55 -\u0448,386bdaedbf84ec144272e4047737f764a9f5e85b745a24fca04e1410d56a -\u0449,d61b66ac115e5cd171bf18bdaa753e572b8541eb52ed3b66a9a2b7f3ee7638f3 -\u044A,9652a2e44fd33a2e488f9d38523512e13dffecbd897982df9d873feb6259130 -\u044B,d3c7f76db7b3af3ae7e11352fb6fd8a42beb1a3d28fe481f68f93a5346469bb -\u044C,cadc6669ec77d57bd83ec2d125a536e32863d935b07dcdb6c60d34783519d -\u044D,b3d452a45c36888ae9b1ec1444d05ed402a466762b04283cb43cccf66fd6 -\u044E,5834ca3a37769e104fd9151346a22ffc848f7966cbd38c5c75be8465e41f9 -\u044F,e2a5d651291a83f8a4d48bff5e8f73be69d6d90f155fed1c235aba2fec2b224 -\u2190,ae7af5ad912da6d5cfb8ebce3d1e61411bbd25012c583f17d2e718f553671f -\u2191,92b6f1e2ac94841d6b6a9d4d7b5651839626f2b2591592f5e094b120f6c8ca9a -\u2192,d7a6df194fb4cd62773ef71640c36848cc27d9fdf7c451b311f26bf8dca4 -\u2193,92376eecab5f617b8c71cfcee4bdfc6cb1b671d7be4921474c9cb9fb134141 -\u2196,8daecaa5e4b44f978c88d3d01b1ebe739f8ab63bb99df3833a6e2f31dc165 -\u2197,8cca259d3ec8a9e26279a09c981fc57d46a74b27a27f2d8a1c4877867bb7899 -\u2198,ae1c3838fc63a9d5c9e2f58ffe889a2665343d33119e9da3480c554ff67ea74 -\u2199,0c1511d59f861d8fc561fcba88919b6af6ed8f02088d16497fd93ba4c794e20 -\u23E9,4749cae3d87b7641b7c704cd595f33c54aeadf1b9d2a4841b31ed3957793d54 -\u23EA,cef5e93262d6bb8783f717cd7fdd4b66cf8bd4b55e14f656ea97f2ff7417d31 -\u23F4,29bd81f920e95c53c379d059b2b1bc6aa7fb58ca4518701579bf45e04611 -\u23F5,765b787e9d60adc64d54b2423185c272a36fd4bd10eabe88ffa1246aa82080 -\u2640,2f4028efa8e763354669d6e8b479bd590ea1de42119234b43dbef361ee94c1b6 -\u2642,1c1ff85ab2bcd5d4bc679a023b6d8469f0f8941246e7a4d8670b780c9e2451ab -\u2648,4a88ac464cbe03da742d08be2c6f7ba913aaa6a2a63cf81d7ff4aa2ab9bf4a89 -\u2649,a48036a8cf6511db94c0ba420990c4dd7ed0a372535a33b2ce0b4169b2d627b1 -\u264A,9709d64ab98aa2e6d685d397516eb6fffab5d5a124a7f4a08ee689e318775eaf -\u264B,4a951aaecfd69e53ca5f26c8f5e4aeea19d54b41cd7217d1bf67b56999600537 -\u264C,d8d87cec312121bc3a0e2ce0539acaf9f0d05322a2d7594d62d5153a8e8e0cd0 -\u264D,d022dc71804e0e3c7eda030a2586106d1c6468f0c99057b0889caf767ecaa4b1 -\u264E,80a7da6ec085c119809947c299d99060a8dcac735dd989576fda4ffcef894e1b -\u264F,3685b6fb4c1ad963752609d7379351031c3070413faaa32485d747a9400b2cbe -\u2650,77121dd2d2a2d58497dfd5ea266c743324b87feb1fea660a67df1a27261ffe7a -\u2651,1417611a053c98a47530a593fc17a7e6fa7d0d55ec43eb1906a19129ec47a549 -\u2652,f21ba4b727f64c6302ee0b4b12266bc143e67524c548db2f3b2d4ec7688ae10a -\u2653,6cda859acbc9457ab4f2489817554d36f130ecc793f0a8345384ccd77e6b43fa -\u2665,b6c47b1aff976e7209c6d85d71422e73c2f69a3719f0f2a969a0c4eb31c619 -\u266A,2ac8c569f3956ebbd137cabd75709f1bdc7640f4ec00988ebbbf1f1a13e048b7 +" ",6036bf97926c02a6da524bf487db5b9742d5bc5884aa2faf94e576fc869 +!,d6e9f272dcb25b71f1ecf4b94ff7c3681bc5a7b5ac3434d689c9d1e36ae2e +"""",82c15d581197a1ec53dd57f32a2b7defdf6dd86efc61ab26e8d6c9a5c3d63a +#,27955f778bbf90374bb5ee16143a88f25ff8c22c9abe02d9975a097cff3b654 +$,6e053b8fee613ca242c0cb2c030253945b154122ab051af5d2036826977c0ade +%,fe4912259b847dbee73696ee1a5644df9281f6cf3a674d870e20dac7b86435 +&,7baedd41c4c124a6b6d73a8f5bcf88d6a3ce31e368cbb8eedb29a683645cd +',a2188bad3f277b353bde9f581b246377a469745cd9e5a44bc3933b0c0e610 +(,73fe0376d7b6bfb60d1b621e5eb2667beb59aa9c2067428532d7e629652b7c +),a3164a1797d7aa097bd3261761bdf9ded50e024b3104e5bfe06a7c33d4d9f6 ++,5a51a58967f3b7af026c9c289dfdca4c436268575166954a694921541ec0fc +",",7ddf408620ae4b8d88d2b84956d7e219152741aba6cd828e184adbe8d55f7f7 +-,e6a8464990cd7666811d6f292fe869692a184e0c7446fa587ed1c9b1fea724 +.,c85535fea2ff52422af69cdae7bff84439308eb11bdc8b6c958ad52c4c9b1894 +/,1889017cb82e772edb84c177174d3c49169ca9c267a42d5fc87f8df6115c +0,ccfbf53883aaadf4708de7fa917edc32e8ac6f89539c16d9ba13aabe535557c +1,e6a20b939b28b2c32d7998582f41703c9ed837d0c90b7633145bec9dfa066 +2,daca8d3bda1325ba2ddcaa9aa15af73991b92918660b6946207bb0b4c0bdd6 +3,90774a3efbcaad9ce39a7e1422addeaf44efa788dbdfdcaf125496552e44880 +4,6b439d55b7e4ff8060af13bbd6448eda1d9c72854949d2c6517eb2088bb1 +5,92872945e4c2435cf794e5968baa592d17cbd663dcc96e3f6ccd321dfbe4c44d +6,3bb82ee5a57cc27028ffcd55af46b0f38b779f533a3c4de9fe26519330941b +7,a7c4afd1661d504d615f93c3e4377f69ec5b7a98b557a6388be113dd7c6c6322 +8,b2ff3a9ef9bcc12514a23cab3f53955f37c53c8d214acc8ba1bc2a80e2b7ae2 +9,2f7aec9cd9cb27fbeaa15e8dfe9b7d7c898507af67f3ded293a768470c2c7 +:,47c1b124a821eb64f4b4f77a4ae88ab133bed54d4cff7a27e4cd544030752f +;,38b9ec46878f68f569c2ddf3104eced799e24d8ba5211b74e8a38dc8da771d +=,fdd3d5d146c6153acc8bf1328a57e14481562990b3ea4eea368707ad8c97342 +?,e8c78f8ac9f40c53c463b963e84ab5c1eb883a46e3877caa80aa21744f1e52 +[,bcf117486eb4d5e5f7e18f5a052d0949d278a35666e1e2fd428fd038f5a64 +\,8b988bd0731c55ddf2c7c2a581e4059c2e66739777d6c7d3fcf183dbec5d +],9b342ec235c87734bac4f9f344a54ede7b377c28c52983a41dca196746dca5 +_,2e2f7b958f6b7b86b0441cc33dc56a511dc1eeef51215cdddc8442ebfacfc2 +a,37e8a2db7cc1b326abd99d238c7a544af8442334fbcd22751163959835b3754 +b,f5634f2fddb193c3a3f60564229adeaf2da416df046d0ad32d9b2cf4695b8 +c,6afdf174aa57cf18a8de5f7a836915f42aa601b55f3122ebed96cce93651a +d,bd1c82bd40c72631bc783f8986ccbb3fffccaa81afdf5365a353d6140bfca +e,6f758574a72c637a9bfc3778c6c8b7e154a01c5026d0e84156772080ed91319c +f,90f6d0fb7fd59cdd346162d44c2a3b5b4ae2ba75445e642a1efe965519194 +g,bb3da53dad804012b538c94cd559a4d588613de219a21e5781d6dd1dd8a2 +h,b0111c9be4ef68ba46fbaedf7f636a0cd51214dbbd2dfca7176752999852 +i,43a256d0513c1ea66afa964d61c68e9819b591362b031919a6fbb18433d242a +j,d87816b3637f816c1933a685f811559cb455d31deeceff97a451c642a9ef7 +k,e9dad060205fe442a911fddc4b46bc5c46af32bacb58d17085b9a37477af31 +l,7bba3ae253931e05bea50a116c6380dc7f48951bc7624c4d1527e24b8ad55 +m,84a4ede2ed21d7ecb9028c67671b3908cb29471bce2a63234cfe3d7939f3d0 +n,45113834129a210321dd52c52c4b0731ccfe04a46275b438d4049cbc4685719 +o,8f703638ead758aeb930b67b405ad9ec62de8e64a134e116b5939a280a84856 +p,b84636e63f2fc934444398083d56253155f13c1fe648a15472394325a5f66 +q,34f15b40b6a16f95c442ee65b47ebac17cb6f5e37ec15c7542fef31681fba +r,cec6a3db3bc27481113c589a2b954545c5b7a39d62bb17e512c1b995e69a5 +s,26b263efe75271689a1558d4a583762f8f2336e5773e198f21b2d65939f6f +t,785edb9cb426ae7052a05e544e7851b79a85aad99ac62db785b28d8e5b3 +u,32491a56baa87e7de510e17bdf76f0b649a28e4cbbdb77a76e411996f0e9f0 +v,3960a51ca156a311228d95d492b8981613ae1cc71362ea16187dc7ea4fad +w,70813a18491d4572ca4df09e9654a27e456b9d227e56e3f1a6d245fc5bd57b +x,4ed7b8986a91a7ede63c62cffea725b67e1e24c0c47dd07097bf9ae7215ecf8e +y,571688eb9ba17cca9e65385e726fb5d286887c8444cc381a67d6e91b91f9c +z,1556307bc0bd94b9bcf67d16d869524f2118ebda872d6d1636c4bddbf4e7122 +{,55b0d58e7c7a862d5ed3e13c71c1be9a83bfb3d5b9f6eda79d29ed5e7d212cd +},c6f02f4e519f4c643dc6757128d18b4535c4444ef42139580e8c6eedd1ec8ae +\u00A1,4cb86708ad9aced0e3c3f934403255ce1fa406b2a0930755e87bb5152a56fe58 +\u00BF,688eed46255bdc12b8fb8763e886b885e53e914006af358ec6363cfbede8e531 +\u00E4,f8532261da1b9327738165dbc3d775db2d5cd5952d8dee5c16ed58bf42c5c9 +\u00EB,d3fdef0ee5f811a2362d37fd25e1a8e4055ff42a477cdd437a7e51c09c6 +\u00F1,69399f8709506209a63630776ead607375661f4962e319f56c6e1f8766cf0f39 +\u00F6,9bda43ceed246adb64639b21d16a3876d41faf41aaf249fd2e8018e0fc18b +\u00FC,c72cdd21f350a81b946da932b99ba850f6ecbdffc413cf489814cb1842824d +\u0431,dd3ca93a7521bb664581c9661b4fe8788b7d3e683ca7231f1e4132cb937e4 +\u0433,3781de8c41c29fb24a1d3e912374866832886d658ce42adb21d669d8b185 +\u0434,7957968d49f4288699bcbf46e96a9b7d22129d4e83b3fadae803598e6e7 +\u0436,aec5f80fe8915e2e794ce543caaab778da5212c80b577a88ef8bc3cbc19eb +\u0437,9c645c67af969e5c9ad83f23dd8258e939f96e8c11bfdb3914b35f88cc8a241 +\u0438,1fea8340dad4b8e33fff4530db1cc78bdea7a171b8f7676d424389533edaf +\u0439,43dfdde55a4cce9019d56116c05bba4a933e5d22b3c5ede22dbae383140c6ec +\u043B,6c46187035e7bebb957a18bccd7eeab010eafb3d522479d23e96dbb7eab42 +\u043F,39f3b629c3dafa703b19f791a784ec1e60f740c98e59d88266971fe5a66ea931 +\u0443,093b97218f447bb2d8771ab739cc3b608bc619188ba86f50e65cd625dd5cf +\u0444,d0885293d4f468db1ff813376f9a942fda67e62cf646cfe544d4fe6833c61f +\u0446,5740126b117f5a95fb6b8af4a04a1557fcfc2fef6a279cdd20cf6f9f144c0a3 +\u0447,94afcf9ac673d7531dbdc779ede27aeb638bcb18189915c6dc18ffd754c55 +\u0448,386bdaedbf84ec144272e4047737f764a9f5e85b745a24fca04e1410d56a +\u0449,d61b66ac115e5cd171bf18bdaa753e572b8541eb52ed3b66a9a2b7f3ee7638f3 +\u044A,9652a2e44fd33a2e488f9d38523512e13dffecbd897982df9d873feb6259130 +\u044B,d3c7f76db7b3af3ae7e11352fb6fd8a42beb1a3d28fe481f68f93a5346469bb +\u044C,cadc6669ec77d57bd83ec2d125a536e32863d935b07dcdb6c60d34783519d +\u044D,b3d452a45c36888ae9b1ec1444d05ed402a466762b04283cb43cccf66fd6 +\u044E,5834ca3a37769e104fd9151346a22ffc848f7966cbd38c5c75be8465e41f9 +\u044F,e2a5d651291a83f8a4d48bff5e8f73be69d6d90f155fed1c235aba2fec2b224 +\u2190,ae7af5ad912da6d5cfb8ebce3d1e61411bbd25012c583f17d2e718f553671f +\u2191,92b6f1e2ac94841d6b6a9d4d7b5651839626f2b2591592f5e094b120f6c8ca9a +\u2192,d7a6df194fb4cd62773ef71640c36848cc27d9fdf7c451b311f26bf8dca4 +\u2193,92376eecab5f617b8c71cfcee4bdfc6cb1b671d7be4921474c9cb9fb134141 +\u2196,8daecaa5e4b44f978c88d3d01b1ebe739f8ab63bb99df3833a6e2f31dc165 +\u2197,8cca259d3ec8a9e26279a09c981fc57d46a74b27a27f2d8a1c4877867bb7899 +\u2198,ae1c3838fc63a9d5c9e2f58ffe889a2665343d33119e9da3480c554ff67ea74 +\u2199,0c1511d59f861d8fc561fcba88919b6af6ed8f02088d16497fd93ba4c794e20 +\u23E9,4749cae3d87b7641b7c704cd595f33c54aeadf1b9d2a4841b31ed3957793d54 +\u23EA,cef5e93262d6bb8783f717cd7fdd4b66cf8bd4b55e14f656ea97f2ff7417d31 +\u23F4,29bd81f920e95c53c379d059b2b1bc6aa7fb58ca4518701579bf45e04611 +\u23F5,765b787e9d60adc64d54b2423185c272a36fd4bd10eabe88ffa1246aa82080 +\u2640,2f4028efa8e763354669d6e8b479bd590ea1de42119234b43dbef361ee94c1b6 +\u2642,1c1ff85ab2bcd5d4bc679a023b6d8469f0f8941246e7a4d8670b780c9e2451ab +\u2648,4a88ac464cbe03da742d08be2c6f7ba913aaa6a2a63cf81d7ff4aa2ab9bf4a89 +\u2649,a48036a8cf6511db94c0ba420990c4dd7ed0a372535a33b2ce0b4169b2d627b1 +\u264A,9709d64ab98aa2e6d685d397516eb6fffab5d5a124a7f4a08ee689e318775eaf +\u264B,4a951aaecfd69e53ca5f26c8f5e4aeea19d54b41cd7217d1bf67b56999600537 +\u264C,d8d87cec312121bc3a0e2ce0539acaf9f0d05322a2d7594d62d5153a8e8e0cd0 +\u264D,d022dc71804e0e3c7eda030a2586106d1c6468f0c99057b0889caf767ecaa4b1 +\u264E,80a7da6ec085c119809947c299d99060a8dcac735dd989576fda4ffcef894e1b +\u264F,3685b6fb4c1ad963752609d7379351031c3070413faaa32485d747a9400b2cbe +\u2650,77121dd2d2a2d58497dfd5ea266c743324b87feb1fea660a67df1a27261ffe7a +\u2651,1417611a053c98a47530a593fc17a7e6fa7d0d55ec43eb1906a19129ec47a549 +\u2652,f21ba4b727f64c6302ee0b4b12266bc143e67524c548db2f3b2d4ec7688ae10a +\u2653,6cda859acbc9457ab4f2489817554d36f130ecc793f0a8345384ccd77e6b43fa +\u2665,b6c47b1aff976e7209c6d85d71422e73c2f69a3719f0f2a969a0c4eb31c619 +\u266A,2ac8c569f3956ebbd137cabd75709f1bdc7640f4ec00988ebbbf1f1a13e048b7 \u2713,803fa22d9636b44b3bd2889e19f7bfb6502029bf0f83f5aac8407de338d82f19 \ No newline at end of file diff --git a/src/main/resources/fonts/gold.csv b/IF/src/main/resources/fonts/gold.csv similarity index 98% rename from src/main/resources/fonts/gold.csv rename to IF/src/main/resources/fonts/gold.csv index 86a9b292..520974a3 100644 --- a/src/main/resources/fonts/gold.csv +++ b/IF/src/main/resources/fonts/gold.csv @@ -1,118 +1,118 @@ -" ",351137e11443a8fbb05fcd3ccc1af9bd2303918f35448185e3ed96ef184da -!,24d67a3b4fbb671d845a9c842e9e86038acee17b95e6cacb2b02cb9c -"""",456723321971915a031d7a25c7630788c55e6569ef055f9583dcd78defdec7e -#,52779851bfcf9dc9e365fb481ebcad5944db8b71a41a18b4ccc6fb0e898 -$,f509de981a786a980b0bc871ad855b20ce0b701b7a2df14cfff6b3a6e4529723 -%,98c2bdf64d8196c546ca2c5628269b3955793570bfe7a54d98faa4f09fb24d -&,a5f61b8342b4134d17bb1c93dc77a079a9f5edf221173593ef13c1d3136cf1 -',d5133d10633576f1a495225a3c829ffa672f3d7485afbcf6899eb7dbb7701747 -(,4580bc1d57218121c97a46345f7417a8c0103a8baa7571add692c2eb1070441a -),d627dd4a8427af88e060bbfce0341097c9e1d62d2496a7a54cc1fc8f5a5c16cc -+,d362ac6d9ff8bfbc9badac35f627cbe917ac25af8e6e9d382ce3dd317ac0398 -",",11c61eae3bc18106a2ee202933d73fd93baef86d4fbb83c29aab91e93b27 --,9af23bb9a49125c2ce8caabd72242418b7724e48e8018f12322875b237dca -.,7044a3345444d99670a2ac80cbf942ff4864802def8c9a3449bd103ababcd2e7 -/,299532b86e41a42141c5fd7d1bb7f257808264822992be59bc9bc689ac57569b -0,71bd6a44ed3a9a86e5ecc2c51759c299561ae95fcce9b95252423ee636eb28 -1,d55fc2c1bae8e08d3e426c17c455d2ff9342286dffa3c7c23f4bd365e0c3fe -2,dc61b04e12a879767b3b72d69627f29a83bdeb6220f5dc7bea2eb2529d5b097 -3,6823f77558ca6060b6dc6a4d4b1d86c1a5bee7081677bbc336ccb92fbd3ee -4,91b9c4d6f7208b1424f8595bfc1b85ccaaee2c5b9b41e0f564d4e0aca959 -5,bc1415973b42f8286f948e2140992b9a29d80965593b14553d644f4feafb7 -6,16f5fbfbc8944a50777113798e9fe3aeac2e39648947b70cc103deb6c9e8661 -7,df3acd6dfd5bcbfa9fc84df3d704bbd9d1487ea87cf564427bb8ec95c65227 -8,deb115fa47a9d2d6d41e5aa7be4e1367ff92c4e9465897d5d62a765ef924f4 -9,5ab8a27aee4779f043a668c9e927a353e63ac791ed3f56a24f61d9439ccfd515 -:,b13f53b5d55ad78db71c59723e9d83be252f5ec9446929155872473b608d -;,474f4ec1f165cf07caccc6faeb533fc8ef1c6345ad90d9cd5fdf5b764ba5fb -=,eca2d23c032541b55b85add34898867b62be443892acb6912565896aeb -?,9e5bb8b31f46aa9af1baa88b74f0ff383518cd23faac52a3acb96cfe91e22ebc -[,ee2ad9745410f8662f194876d57816c8d8461c0d4a3f5439e495463907471f2 -\,b829c357da448e57972647ea55795281aea1747a78814ae5886bb9b9dbc44 -],209ff6bc86a8394ba0ffbc723964bf4ee354f93eb6a1b7889f2ac25bdab1e81 -_,e9435b42096f266efbc7f3695c93de8e0c88e35936b64528522b47c3ac9b462 -a,8073ae547e6daa9d2dc8cb90e78dd1c71cdfadb7401dc167d16819b173283c51 -b,b5162f3350bf396629940ebc92845cd3bcdfb9be772296c4ce90782b76a -c,7ca1b3c384d2d3636078dd3818457986f90c4a71118ab8dde83e15a39ed9fd -d,80a563166af45424afc5c6c8ec6151f5780945e9b97353ebd2bccd7135e4fa -e,7d7e39a0a47af42d95c0fdd8cecaf9682e2822b3371d9cbcf972932d3a61fc6 -f,70dc9420c14fcab98dcd6f5ad51e8ebe2bb97895976caa70578f73c66dfbd -g,1b575b5577ccb32e42d54304a1ef5f23ad6bad5a3456340a4912a62b3797bb5 -h,6c2899f956d9c87da118bb813aa8226f5f339591eee5fbf9bafcee59cd9e1df -i,feb79a7fc95428ca8c88d52028399cd1f3ad973769c3b91a836275519f4fb29 -j,f3de8282f06eb1e6a61773b2c662af797e87ad6d162039465a1cfe303de42 -k,b8824dcf4ba317533bf29dca18ce7c4fd328b42680e6c322f5f4ff1a394a887 -l,597463d7181e83a143a6ced1a1f77f66d1f28e6f272fe8cd95e7fb89ea0dc69 -m,a6b8b5eba44993697cb530c2fdb22ce4459bd5c9b36f6899fc1262c0f6ba30 -n,e4d29b1332afc4b1eb319a2df2eb9e2eb302f433cdff64095702af7e09b13f7 -o,52faf892cb57fa92c53baf57b8b6c2984c4f4c70aefeb6959ff2fadc6623f72 -p,e75cc5d47d5aa0a78d24fe49428e3a4b51c9217544fa07bc4cd77c2e5cb96a -q,e968808c1e4585ca87e5f0db8a2c12da0e69f11aed12441d01e1ef5946ac0 -r,df63223c671d33729f4c7f5077b3dd8a4f54e22330f35e821db039827d84d6 -s,dafe3fc91465f7504f2835345c569d98f9e28964936dda1110c856b092b1f0ba -t,d4ef0419c883dc114dae42d468c64fd3ecc492471a1dd6271569867a8d5469 -u,3d8ab4d6c48a3bad1a63711d51afdea6d9c62535c3878cedc859be63a867d -v,792e1e6075f4b2ea6c929a86d5836742998caba0c0a27379c681a7ce356fb23e -w,60dbb4ade8c99b1cd18c5c6bc24fbd36b65a8b66d283e71fd4ff9194d6ae7a4 -x,45996f7e1bd32278384a593f5e1b7d36b46c191f844d091dc6c226283255 -y,d6bcb954eba6f6d11d3a1e89d38e4c6641289fed2a62324906065fcf7407bc4 -z,d1a51a173d656c4250f51d2b88cc76d3b3d2c5a4fb125e23ec6779fcc6b9ae7e -{,1b75a1a91f2bc91724aebfaf36f55d1b6cf259bcf35448c4e16f92febc55b36 -},85c6b432d6605bde03df7514c0a55e15d97ae75a8059ccee52ef1e388eb -\u00A1,e0ee6862f418d66a5bdb0396a42d7ce3e4b2e81dc3006eb35b644c93df48dfb1 -\u00BF,c0ea2bb72d3779ef3caa615f9c57d794ae0ae647f66a9f04f3a87870e8308a07 -\u00E4,d4ea172e14ad1026f2b3399cbcfb84a8fefa84c78f84e8d9bbc53827d8 -\u00EB,811252448ca049897129238cb7b5386e4a42a981ecdc9e31f89696cbdb884b5 -\u00F1,55f6f37a5b56b16eeab3fba6d3a20e6e176dd471b73110fec3a7b2dee6dd79a5 -\u00F6,3a1e694ed374effbe9a67f686dff356cd54c70ba8b848bc769286634d1866393 -\u00FC,85562464b47d8dbd6dec7d45ea10c6c05965f996b4b9a8e678ea67584b5ffd -\u0431,fc1293c76a6011cfd8814ef5414a4ad61365d52afa76ae1943bd9d97ad163c -\u0433,1586a5d9f3cc783334ff1ad18a50b639e26aae40bdf72da6c1654c8aad825f4 -\u0434,f667c22f13a339a9b73f701067a139daf358f7aea152f709f515e9b834b9 -\u0436,cee8ea9f5048896beb8efbc262594ba0103ee784e81eaed235c3d40c46f653b -\u0437,f6689d26538f46713461963e39532290a695d165d4392c1dc672ec99cba735b5 -\u0438,2b48467be3fa4cfc1411f6c9430ec7b23a9d12fec77e4c82017eb32c9d943b5 -\u0439,f3e6c593843b62b35b6b8db2ae33cb3677c7ee8aa1235203753606f6b874 -\u043B,ded9b19222cce564d031bb3f7f4197fa870fb211bd3b5a4659c70abb33bb112 -\u043F,484e294269818b4f7c29b87e2ed4945461e346afbc5914c0e22ddf7cd525d -\u0443,33ef6d91f74db216323572c5af24027f44699f05251c37d41cac95ca38f975 -\u0444,35fca98b2cb5504e2f3a2ddc613817ec9787b46ee3bc7808475e3849afe74cc -\u0446,669d45d814fcb42256b9cb4576afd2ef31d9d465bfd5cf2a27d2fd4649e82c54 -\u0447,93a2c05cdc7a95c7a11c611ea35cbb43fec049be119944639768d4a476442 -\u0448,9dca7f843bef1e743dede6a875f63871a88479d6038bd9e8e86b21f5210ebc -\u0449,4cc8eb295691f0ec3975d27e779fdd2bf08666b2b9547055386b8bb12ced519f -\u044A,1e46df50c33e9e89cf65bb26187de484f68f49c3505d8bb2bbaeaa52279761 -\u044B,8f7fcb2b82653f7677a8cb23ceb11a6b6d35f85452d8c9b632f8dd14d7d -\u044C,e8639d383562af210e31ce823396045691213b387ee487f4ecc8024697ecba2 -\u044D,5c4d665266fbcf62db823669f8d169d0c7f7867e7653fe639fafcf1b1a75c5 -\u044E,6dc0747b9eb929f9fec86572ff6fcd16430403fe11e7ba26fda819778f689 -\u044F,e7566dc78e49deec3abdc74620a868478413e016f37146e58595c3d365b7b4 -\u2190,dfa605e25f4fc2cea5a766d79a8bfa290313e45d8f5e957d958a0f33fcb16 -\u2191,dfeb39d71ef8e6a42646593393a5753ce26a1bee27a0ca8a32cb637b1ffae -\u2192,5a92ad456f76ec7caa3595922d5fcc38dca928dc6715f752e74c8ddde344e -\u2193,99e938181d8c96b4f58f6332d3dd233ec5fb851b5a840438eacdbb619a3f5f -\u2196,4544fc7fe4724b4482b54b9bd8e9dc4c3f28810aec41584f67c8f709ad -\u2197,ac9f813ae82cd688574a849ab9ab441346763adb9ce7cf1b1c727de795df9b -\u2198,de4a2bf57bdc37afc39b46eec76f5e2528ee2b27cf3bcccaa274a2c95ac494 -\u2199,55669391635e67a6ee3420578e3fc4c03e69d9fe30377f0d24854418977c1c -\u23E9,9b718abe1024762c1c5225c9b3cf943a014f54dd8d4d464a2d61f098c07d9e -\u23EA,ed707db46a5acbfebf61239536d25648134bb43b65c16716ba329c6dbf412 -\u23F4,3162d42f4dba35488f4f66d673635bfc5619bdd513d02b4cc74f05ec8e956 -\u23F5,b813633bd60152d9df54b3d9d573a8bc36548b72dc1a30fb4cb9ec256d68ae -\u2640,34c0410d60fd41c69fc8b3c5f66800a9e43352c301cdf80a220f66ba3c7a6cad -\u2642,43fac6879f83eeab6db28d8e29ca8657a9834c8c06a03a39bc5493e5b0676436 -\u2648,a6883246f9a54556c1ef0f14b2786f0ffbdc037826b444f092c8f329d42ef46 -\u2649,30c4d4a509185f7ad3c5273dc29e3c2eb46da276f3494f2d60826d2fdb49c9d0 -\u264A,7c01cbe8539fe716cbce6c2b9237f495029356002a270ec272bdf13bbe021601 -\u264B,96cd2f52274079e6de0138ef592eb20d0033c883005084232fc57e701d7bcf60 -\u264C,17f3e59667db357271e77f2b3579bb4f9c3925f6103b2384585c10e4d3db2220 -\u264D,375aba3d3760f79d776f0584595322fa22307897c27cd9f9540275e8529aa715 -\u264E,7e502aa71f57caee69c43700e43cdaa71e2b4e90940629d5f6eb9c7cf17818a2 -\u264F,e39c8b664e06f667f7e94ffdeb9e3218d66ad6d554587f9d344a89a25094b887 -\u2650,710f61fe61821c8d7db8b25f992c8d3337baa5808f2b0ad3b5c2576e8f019497 -\u2651,5415168c8c62d66f125d96c2733f2114cbe2e727753f975c680be3b441b75b79 -\u2652,9feeda0e36af1aa848f93d5818df1db445d994b299caeaf4d4e1d7a9ad7b8a22 -\u2653,aca6b663e053e48128e293a1348ffc4aeddf86635c87fb266bd37a20a5a75dd4 -\u2665,4dfada67cb261410a24890ec74d1cb605517df1469c19bdc5fe3aa448877c621 -\u266A,269ae2ca3d74c4505f78ce9af4c7bef03086100dbc309cbb5eb41bca0c35e9f8 +" ",351137e11443a8fbb05fcd3ccc1af9bd2303918f35448185e3ed96ef184da +!,24d67a3b4fbb671d845a9c842e9e86038acee17b95e6cacb2b02cb9c +"""",456723321971915a031d7a25c7630788c55e6569ef055f9583dcd78defdec7e +#,52779851bfcf9dc9e365fb481ebcad5944db8b71a41a18b4ccc6fb0e898 +$,f509de981a786a980b0bc871ad855b20ce0b701b7a2df14cfff6b3a6e4529723 +%,98c2bdf64d8196c546ca2c5628269b3955793570bfe7a54d98faa4f09fb24d +&,a5f61b8342b4134d17bb1c93dc77a079a9f5edf221173593ef13c1d3136cf1 +',d5133d10633576f1a495225a3c829ffa672f3d7485afbcf6899eb7dbb7701747 +(,4580bc1d57218121c97a46345f7417a8c0103a8baa7571add692c2eb1070441a +),d627dd4a8427af88e060bbfce0341097c9e1d62d2496a7a54cc1fc8f5a5c16cc ++,d362ac6d9ff8bfbc9badac35f627cbe917ac25af8e6e9d382ce3dd317ac0398 +",",11c61eae3bc18106a2ee202933d73fd93baef86d4fbb83c29aab91e93b27 +-,9af23bb9a49125c2ce8caabd72242418b7724e48e8018f12322875b237dca +.,7044a3345444d99670a2ac80cbf942ff4864802def8c9a3449bd103ababcd2e7 +/,299532b86e41a42141c5fd7d1bb7f257808264822992be59bc9bc689ac57569b +0,71bd6a44ed3a9a86e5ecc2c51759c299561ae95fcce9b95252423ee636eb28 +1,d55fc2c1bae8e08d3e426c17c455d2ff9342286dffa3c7c23f4bd365e0c3fe +2,dc61b04e12a879767b3b72d69627f29a83bdeb6220f5dc7bea2eb2529d5b097 +3,6823f77558ca6060b6dc6a4d4b1d86c1a5bee7081677bbc336ccb92fbd3ee +4,91b9c4d6f7208b1424f8595bfc1b85ccaaee2c5b9b41e0f564d4e0aca959 +5,bc1415973b42f8286f948e2140992b9a29d80965593b14553d644f4feafb7 +6,16f5fbfbc8944a50777113798e9fe3aeac2e39648947b70cc103deb6c9e8661 +7,df3acd6dfd5bcbfa9fc84df3d704bbd9d1487ea87cf564427bb8ec95c65227 +8,deb115fa47a9d2d6d41e5aa7be4e1367ff92c4e9465897d5d62a765ef924f4 +9,5ab8a27aee4779f043a668c9e927a353e63ac791ed3f56a24f61d9439ccfd515 +:,b13f53b5d55ad78db71c59723e9d83be252f5ec9446929155872473b608d +;,474f4ec1f165cf07caccc6faeb533fc8ef1c6345ad90d9cd5fdf5b764ba5fb +=,eca2d23c032541b55b85add34898867b62be443892acb6912565896aeb +?,9e5bb8b31f46aa9af1baa88b74f0ff383518cd23faac52a3acb96cfe91e22ebc +[,ee2ad9745410f8662f194876d57816c8d8461c0d4a3f5439e495463907471f2 +\,b829c357da448e57972647ea55795281aea1747a78814ae5886bb9b9dbc44 +],209ff6bc86a8394ba0ffbc723964bf4ee354f93eb6a1b7889f2ac25bdab1e81 +_,e9435b42096f266efbc7f3695c93de8e0c88e35936b64528522b47c3ac9b462 +a,8073ae547e6daa9d2dc8cb90e78dd1c71cdfadb7401dc167d16819b173283c51 +b,b5162f3350bf396629940ebc92845cd3bcdfb9be772296c4ce90782b76a +c,7ca1b3c384d2d3636078dd3818457986f90c4a71118ab8dde83e15a39ed9fd +d,80a563166af45424afc5c6c8ec6151f5780945e9b97353ebd2bccd7135e4fa +e,7d7e39a0a47af42d95c0fdd8cecaf9682e2822b3371d9cbcf972932d3a61fc6 +f,70dc9420c14fcab98dcd6f5ad51e8ebe2bb97895976caa70578f73c66dfbd +g,1b575b5577ccb32e42d54304a1ef5f23ad6bad5a3456340a4912a62b3797bb5 +h,6c2899f956d9c87da118bb813aa8226f5f339591eee5fbf9bafcee59cd9e1df +i,feb79a7fc95428ca8c88d52028399cd1f3ad973769c3b91a836275519f4fb29 +j,f3de8282f06eb1e6a61773b2c662af797e87ad6d162039465a1cfe303de42 +k,b8824dcf4ba317533bf29dca18ce7c4fd328b42680e6c322f5f4ff1a394a887 +l,597463d7181e83a143a6ced1a1f77f66d1f28e6f272fe8cd95e7fb89ea0dc69 +m,a6b8b5eba44993697cb530c2fdb22ce4459bd5c9b36f6899fc1262c0f6ba30 +n,e4d29b1332afc4b1eb319a2df2eb9e2eb302f433cdff64095702af7e09b13f7 +o,52faf892cb57fa92c53baf57b8b6c2984c4f4c70aefeb6959ff2fadc6623f72 +p,e75cc5d47d5aa0a78d24fe49428e3a4b51c9217544fa07bc4cd77c2e5cb96a +q,e968808c1e4585ca87e5f0db8a2c12da0e69f11aed12441d01e1ef5946ac0 +r,df63223c671d33729f4c7f5077b3dd8a4f54e22330f35e821db039827d84d6 +s,dafe3fc91465f7504f2835345c569d98f9e28964936dda1110c856b092b1f0ba +t,d4ef0419c883dc114dae42d468c64fd3ecc492471a1dd6271569867a8d5469 +u,3d8ab4d6c48a3bad1a63711d51afdea6d9c62535c3878cedc859be63a867d +v,792e1e6075f4b2ea6c929a86d5836742998caba0c0a27379c681a7ce356fb23e +w,60dbb4ade8c99b1cd18c5c6bc24fbd36b65a8b66d283e71fd4ff9194d6ae7a4 +x,45996f7e1bd32278384a593f5e1b7d36b46c191f844d091dc6c226283255 +y,d6bcb954eba6f6d11d3a1e89d38e4c6641289fed2a62324906065fcf7407bc4 +z,d1a51a173d656c4250f51d2b88cc76d3b3d2c5a4fb125e23ec6779fcc6b9ae7e +{,1b75a1a91f2bc91724aebfaf36f55d1b6cf259bcf35448c4e16f92febc55b36 +},85c6b432d6605bde03df7514c0a55e15d97ae75a8059ccee52ef1e388eb +\u00A1,e0ee6862f418d66a5bdb0396a42d7ce3e4b2e81dc3006eb35b644c93df48dfb1 +\u00BF,c0ea2bb72d3779ef3caa615f9c57d794ae0ae647f66a9f04f3a87870e8308a07 +\u00E4,d4ea172e14ad1026f2b3399cbcfb84a8fefa84c78f84e8d9bbc53827d8 +\u00EB,811252448ca049897129238cb7b5386e4a42a981ecdc9e31f89696cbdb884b5 +\u00F1,55f6f37a5b56b16eeab3fba6d3a20e6e176dd471b73110fec3a7b2dee6dd79a5 +\u00F6,3a1e694ed374effbe9a67f686dff356cd54c70ba8b848bc769286634d1866393 +\u00FC,85562464b47d8dbd6dec7d45ea10c6c05965f996b4b9a8e678ea67584b5ffd +\u0431,fc1293c76a6011cfd8814ef5414a4ad61365d52afa76ae1943bd9d97ad163c +\u0433,1586a5d9f3cc783334ff1ad18a50b639e26aae40bdf72da6c1654c8aad825f4 +\u0434,f667c22f13a339a9b73f701067a139daf358f7aea152f709f515e9b834b9 +\u0436,cee8ea9f5048896beb8efbc262594ba0103ee784e81eaed235c3d40c46f653b +\u0437,f6689d26538f46713461963e39532290a695d165d4392c1dc672ec99cba735b5 +\u0438,2b48467be3fa4cfc1411f6c9430ec7b23a9d12fec77e4c82017eb32c9d943b5 +\u0439,f3e6c593843b62b35b6b8db2ae33cb3677c7ee8aa1235203753606f6b874 +\u043B,ded9b19222cce564d031bb3f7f4197fa870fb211bd3b5a4659c70abb33bb112 +\u043F,484e294269818b4f7c29b87e2ed4945461e346afbc5914c0e22ddf7cd525d +\u0443,33ef6d91f74db216323572c5af24027f44699f05251c37d41cac95ca38f975 +\u0444,35fca98b2cb5504e2f3a2ddc613817ec9787b46ee3bc7808475e3849afe74cc +\u0446,669d45d814fcb42256b9cb4576afd2ef31d9d465bfd5cf2a27d2fd4649e82c54 +\u0447,93a2c05cdc7a95c7a11c611ea35cbb43fec049be119944639768d4a476442 +\u0448,9dca7f843bef1e743dede6a875f63871a88479d6038bd9e8e86b21f5210ebc +\u0449,4cc8eb295691f0ec3975d27e779fdd2bf08666b2b9547055386b8bb12ced519f +\u044A,1e46df50c33e9e89cf65bb26187de484f68f49c3505d8bb2bbaeaa52279761 +\u044B,8f7fcb2b82653f7677a8cb23ceb11a6b6d35f85452d8c9b632f8dd14d7d +\u044C,e8639d383562af210e31ce823396045691213b387ee487f4ecc8024697ecba2 +\u044D,5c4d665266fbcf62db823669f8d169d0c7f7867e7653fe639fafcf1b1a75c5 +\u044E,6dc0747b9eb929f9fec86572ff6fcd16430403fe11e7ba26fda819778f689 +\u044F,e7566dc78e49deec3abdc74620a868478413e016f37146e58595c3d365b7b4 +\u2190,dfa605e25f4fc2cea5a766d79a8bfa290313e45d8f5e957d958a0f33fcb16 +\u2191,dfeb39d71ef8e6a42646593393a5753ce26a1bee27a0ca8a32cb637b1ffae +\u2192,5a92ad456f76ec7caa3595922d5fcc38dca928dc6715f752e74c8ddde344e +\u2193,99e938181d8c96b4f58f6332d3dd233ec5fb851b5a840438eacdbb619a3f5f +\u2196,4544fc7fe4724b4482b54b9bd8e9dc4c3f28810aec41584f67c8f709ad +\u2197,ac9f813ae82cd688574a849ab9ab441346763adb9ce7cf1b1c727de795df9b +\u2198,de4a2bf57bdc37afc39b46eec76f5e2528ee2b27cf3bcccaa274a2c95ac494 +\u2199,55669391635e67a6ee3420578e3fc4c03e69d9fe30377f0d24854418977c1c +\u23E9,9b718abe1024762c1c5225c9b3cf943a014f54dd8d4d464a2d61f098c07d9e +\u23EA,ed707db46a5acbfebf61239536d25648134bb43b65c16716ba329c6dbf412 +\u23F4,3162d42f4dba35488f4f66d673635bfc5619bdd513d02b4cc74f05ec8e956 +\u23F5,b813633bd60152d9df54b3d9d573a8bc36548b72dc1a30fb4cb9ec256d68ae +\u2640,34c0410d60fd41c69fc8b3c5f66800a9e43352c301cdf80a220f66ba3c7a6cad +\u2642,43fac6879f83eeab6db28d8e29ca8657a9834c8c06a03a39bc5493e5b0676436 +\u2648,a6883246f9a54556c1ef0f14b2786f0ffbdc037826b444f092c8f329d42ef46 +\u2649,30c4d4a509185f7ad3c5273dc29e3c2eb46da276f3494f2d60826d2fdb49c9d0 +\u264A,7c01cbe8539fe716cbce6c2b9237f495029356002a270ec272bdf13bbe021601 +\u264B,96cd2f52274079e6de0138ef592eb20d0033c883005084232fc57e701d7bcf60 +\u264C,17f3e59667db357271e77f2b3579bb4f9c3925f6103b2384585c10e4d3db2220 +\u264D,375aba3d3760f79d776f0584595322fa22307897c27cd9f9540275e8529aa715 +\u264E,7e502aa71f57caee69c43700e43cdaa71e2b4e90940629d5f6eb9c7cf17818a2 +\u264F,e39c8b664e06f667f7e94ffdeb9e3218d66ad6d554587f9d344a89a25094b887 +\u2650,710f61fe61821c8d7db8b25f992c8d3337baa5808f2b0ad3b5c2576e8f019497 +\u2651,5415168c8c62d66f125d96c2733f2114cbe2e727753f975c680be3b441b75b79 +\u2652,9feeda0e36af1aa848f93d5818df1db445d994b299caeaf4d4e1d7a9ad7b8a22 +\u2653,aca6b663e053e48128e293a1348ffc4aeddf86635c87fb266bd37a20a5a75dd4 +\u2665,4dfada67cb261410a24890ec74d1cb605517df1469c19bdc5fe3aa448877c621 +\u266A,269ae2ca3d74c4505f78ce9af4c7bef03086100dbc309cbb5eb41bca0c35e9f8 \u2713,61fe74f64abd1a8147c1370fcf312292801bf4c371f1564d8904dc1b7be64dc8 \ No newline at end of file diff --git a/src/main/resources/fonts/gray.csv b/IF/src/main/resources/fonts/gray.csv similarity index 98% rename from src/main/resources/fonts/gray.csv rename to IF/src/main/resources/fonts/gray.csv index 768829b4..c17eecc8 100644 --- a/src/main/resources/fonts/gray.csv +++ b/IF/src/main/resources/fonts/gray.csv @@ -1,118 +1,118 @@ -" ",6e5286c470f66ffa1a18331cbffb9a3c2a4424a8c7259c4436fd2e35582a522 -!,18be147df49091736964dab3569b61c9e6a341c9a48f4af84b51a63bb6e85 -"""",bd744bbed3df1126525a54a49f1e39d2373043e4ed4ae45fa9d97f5b3ba69 -#,c9327a4573977cd378f06d1f832e907f5f66dbe5ea88ff1c3689ad958b7e7 -$,34a9e5314842dd21411e95d93e37eb0b04025ee847036cae3cb9ea1a1d6c582a -%,bf2fbfdb132f149f78c479be43ba75d4ded3ebe4cb9ddce9b7b5768810d935 -&,861967db1d807bd07eb25fa078815c754069c21bf777c36cbb2bf6899d479f6 -',3e18b787ec3e17ce5dfc63b879f26444568b225a993d8a17eac0add1209dce41 -(,d84a79b29e390fde361ada79a33f497da7bb7111b7edef5821bfc74496db434 -),995923f74c5b6562e8c05402fde99443f485935c9dfa2b3d0a44b505c577731 -+,10c97e4b68aaaae8472e341b1d872b93b36d4eb6ea89ecec26a66e6c4e178 -",",6bc3ccd76b3ca98d835e99b6d678177b2efc3ced89bf531af6683cb38d78c --,c674b682b179d1d4fa791f92cdaf1c2f37fad4eadbc7dbdc060e8154d351482 -.,1fd52bea8fc6a9114c3c2d8762dbdcaf8b9df8edeb26fc4191e26ae8704493 -/,9cd7ab2e73c9f68494e285dcad9288387952b1e23033c4911c44c7b6e3d150a3 -0,a3a487b1f81c9ecc6e18857c6566529e7efa23eef59814fe57d64df8e2cf1 -1,bf61269735f1e446becff25f9cb3c823679719a15f7f0fbc9a03911a692bdd -2,7d81a32d978f933deb7ea26aa326e4174697595a426eaa9f2ae5f9c2e661290 -3,ceadaded81563f1c87769d6c04689dcdb9e8ca01da35281cd8fe251728d2d -4,6c608c2db525d6d77f7de4b961d67e53e9d7bacdaff31d4ca10fbbf92d66 -5,1144c5193435199c135bd47d166ef1b4e2d3218383df9d34e3bb20d9f8e593 -6,f61f7e38556856eae5566ef1c44a8cc64af8f3a58162b1dd8016a8778c71c -7,6e1cf31c49a24a8f37849fc3c5463ab64cc9bceb6f276a5c44aedd34fdf520 -8,61c9c09d52debc465c32542c68be42bda6f6753fe1deba257327ac5a0c3ad -9,2dcf39f4bcd98484b0b479a7992d9270fe3a59b9b1a806d7a64ffb5b551ad -:,a919fe599f98258ddff44c768137e2e9cbaf4b94f5a25233c27f3dd2f5359 -;,ea4e864afd4d232c2f86219551c9ba9819afa1aeca0278b1e05d98b1f -=,f63cb8b469fba4462bc95e6f34e48532d5ac03539b90bb3694b05e454fb5d0 -?,89a995928090d842d4afdb2296ffe24f2e944272205ceba848ee4046e01f3168 -[,bcaf1f9bb182cedbfcef26c9078467b8953e2aeaefc59e677dc8de21e7d5534 -\,5f701279b249c727dbb4fa3bf74ad403f25bd3f7d4b1e2d3617eee66e4a3 -],677a226be5b6fa9437c9d49667cd8e28eb1b5992b92fc72ce78e5665a7db -_,1bf4abbacaa527bd748059a241d470ceed63149960cd24464f7f524df5fc465e -a,1a74d9212e6491bc370caf025fd459fe632ca7c6ba4df7ebefafd489ab32fd -b,a01783f37c7b5f691c615130ab85e1e1ad25dffceafd7bb178b92173df2aaa -c,89b66dbf01c94aef7dca1abe8536c9e512969fa32f5707542979caf7258adc5 -d,1866b462b776374328d8daf2ce9e5abc3ecc64481d54a69cd4c2b25e7630c6af -e,5223afe895d3d4e32f393dd301989a317585d9ebe3f5d76d4380f5a06f95 -f,fceb2a4441b73d4e744aeecba9fe6afb18470b99a262bd1ba1bcc6913a2baaf -g,bd62d63cfb4b8731fcd2635dcf69203df393946e1aeca2605ab963e2829dab -h,8f5b871ae47eba146b5b4cf89fc20dc3236952a7ea867898bec1f3b719712a -i,e7a2f8bf7e138d6ba9246f7dc1ff144f43ed512e44892b1e316535ea882f7a5 -j,1df8b482ee76979fdb9467c8e666cc6aec5cb44859bb74579f016291ed01175 -k,5198fce7eafdaca15bd6e98ca94b4046583a8b2e5411cc8c944588fd7f1a5f97 -l,9f78466a7b5aae90884c6e2227d524978136354457382d3647b07d096c2a22e -m,f2f2d827495053557c52e55ccdd571bd33184fc14928441f3a97eab38922812c -n,651a7ee66f60237419917fdc75f5d341cfbb9f7ccaaef3aff2af419d588e701a -o,d97aa8b9f7ed8c38ae41f1bd6d9e10eb57bc87e18cac247e7bd2a4e0e588578a -p,72747139f338a46a45903b7633f270502d64f066515f4d2f9def80cff91150ff -q,e0fcfc742ceb9464efc971a31c5896d971e4772772745756225b0643e4e93 -r,d82e6f0f9eaef56f383a4c5a392b194bf1a1b63559ac36255ccef2463c38c -s,bcef333aaba242c6f28f49e96689ab4bf2bc126bbc298555b93da79328419d8 -t,e5bf4db51fab4aa279628dfb2a1720e01bf7e9b94bb8c7e702fb63757405d -u,3ade4661e998aeb20136396d94136c27d49902280ab7eecfa887db48a9b6cf -v,9df53a18c59683fd63f6822cd4464d12c862d7818c68b2302857b719f55e4fe9 -w,357b1f6eb7cf0fd20499a5be6b82b25cf5cbd8e57daac7351c85c45fb5fe5c -x,bcc5fae3b650e6edb3245fa41e5be2da79b0e17f22c4b4e1e59b32f573202d18 -y,367477f9cb5f036438ce98ce697b91358cb97641c5d153a7e3888dae32e215 -z,cfa730b5ec73ceaf4aad524e207ff31df785e7ab6db1aeb3f1aa4d245ed2e -{,4f3edebbdda39e10dd852c22a98aafd77ff729fd52dd122c27c3c63925ab -},fe69b854edead62acb813546447af6904d0332328b56414d54bb14ff9edd3cf -\u00A1,7f85372582546c021c89781914074d71d73565623ac38e04bebeda052d50214d -\u00BF,7b50ddb5fc118f69cbe778b38649b56ac4fb3123893270bfa2ffab2f97dac7fd -\u00E4,4933d1fd6cd48776df58841ecc47ce690c487152e294c263c8ec83a9da1e40 -\u00EB,659544fb35947037fb8ad8149fb10fd58dc7336ead4c71a5018d68f205d64b5 -\u00F1,2d2d27cbf5854fae94f088821bf4043a87bdc6a66b53229a8ac9473811d38d3 -\u00F6,bb9b316728683d3ef5fa4e82deb8e41aac2e3fd89ebb55e1e1c18f3591361b -\u00FC,d83ace21e1f3158574c8d289d7a49a5c6be12ecdffb66e32056fd2984c329ab -\u0431,dff5d36177c8695a51f74bffcc2dc3d1c399838367f16e8c7c91e67665d67 -\u0433,1dfde4b8b6a270d5ff53617986fe9eb18457deb2b223bca10108cb763fc3fc -\u0434,81de18563b89ebea6d7fd1b1176b7b0c245b0f070ce26e13631a6dc96d08371 -\u0436,80f295fe98de4287df365245db9333a8b42294442f123e40e886bb9ac687ba -\u0437,309e4aa9192ad6534dea89e5c9a85df0e6abce1c1557d54077296c8fbdcb5 -\u0438,1b71e881c497933edb51329abd465a7ac54c72ee6eefe5ae220d6d53959ae12 -\u0439,167041cc9a6ca93213d399ed8da4e4f71ef77205a22aed88a623a9d8d4e8963 -\u043B,f980bbd24bb6e1796f87a03fb76e62ce51e76871aa796d2678fc63dc2b -\u043F,f644fe1cc61c26c7c3da9f58f647912c8a6b364cf4bd5d704e7ef7f11d199d -\u0443,a3f56078d8a42b37dbb47491b7ec3e3616f91289f3e77bcbe5c4f25d5aea9da -\u0444,50c622f0bafd22734c3b389af9a6370c2ac5029989b9c682714b4398edcc8d -\u0446,a09d6089db44bf8fa41e3641ed656f5590842a1cbf7b6856b590e0e4985a5a -\u0447,fa3ef2fcd637477737fb7524cd5afe8a6512ebb14fa9d6819356fa6ad225 -\u0448,5f11ea4a532a486938b29f65a4716f4e091c2d35dcf486adb52dfc3210 -\u0449,3a5ce7a7cc8c34ae8db6cc824daab18c85a1525ee23b7543e412a9e3bd4b -\u044A,e9185e3994b4e94a63dea9594c49efe45fc6ea668cf19d6adf34ad5cf3d06c -\u044B,f9fced6ef9e9b81d988a247f1fc9ab2f6121aca9320419be9f7bc464c17321c -\u044C,ec1394d509c276bbdaab279473bf0faaa9756a7e4d54aaf58292b5f4aeb3615 -\u044D,e8d77e70607f97a5d07df87e4aa097112a2cd297606c2cd44fa250e44fe77a9 -\u044E,deaed89fb965570e517295c766e84d10b1bd44643de6886d0b63c5a8554 -\u044F,545f9e70432f7571f10855d5e866a17f7395351f4c9267eaeb2b5ebc34bdcb -\u2190,86971dd881dbaf4fd6bcaa93614493c612f869641ed59d1c9363a3666a5fa6 -\u2191,3f46abad924b22372bc966a6d517d2f1b8b57fdd262b4e04f48352e683fff92 -\u2192,f32ca66056b72863e98f7f32bd7d94c7a0d796af691c9ac3a9136331352288f9 -\u2193,be9ae7a4be65fcbaee65181389a2f7d47e2e326db59ea3eb789a92c85ea46 -\u2196,78cf444bc0e0ddc6a6a9d75951746e0955bd676c4a6771c1a5ed90e7827f -\u2197,676dcb274e2e23149f472781605b7c6f839931a4f1d2edbd1ff5463ab7c41246 -\u2198,1a103acc21ee0a1f87b5be8f3ec7bf47745ec992081be9b41548ee3e3682 -\u2199,56961ad1f5c76e97358c444fe0e83a39564e6b48109170984a84eca5dccd424 -\u23E9,dd993b8c13588919b9f8b42db065d5adfe78af182815b4e6f0f91ba683deac9 -\u23EA,f4bfef14e8420a256e457a4a7c88112e179485e523457e4385177bad -\u23F4,74133f6ac3be2e2499a784efadcfffeb9ace025c3646ada67f3414e5ef3394 -\u23F5,e02fa3b2dcb11c6639cc9b9146bea54fbc6646d855bdde1dc6435124a11215d -\u2640,93392f17442512f7f369aa535102979dacf588eae5d1cf128009083b7c417ba1 -\u2642,a692ec726cb8562c23e0bf2c447a1a995d59ba45f8634b7717ca41415f413945 -\u2648,d0c9e73a1c9603b63ec509b32c434af21931262eea9e9a755ab126e2bc06c90c -\u2649,b6a53a9fd6cd37fd1f2a9bdb9e0c9562cf883514415202909ff8124977e22093 -\u264A,8bf7d0b365a7b4c625a0480d81acfae40288cc313694bb8a69d601a9721b4240 -\u264B,a58e976ecfe4547c32bbabb4bf0108d519d0531e5d360fdc613809f9f46301f9 -\u264C,699507b650bf544abf2a364d6dbddb0f4e0c6f80723d87290b0a82b2453021e8 -\u264D,e78c1732ae4adf41f0a25a54cda5383a9c659a3303832938f203f713600c605a -\u264E,57bc97b3c053b8e34937ee79175df6f93728c556878c39f2b3adc38a13caf167 -\u264F,63d3458d9bfa072a07d1e562efc9a542e414d439a8fec99e69117cce2220a455 -\u2650,3c43ed33dba8423e22fa850c59f9988f6a101fef28c630b42230d7f5f82b7f68 -\u2651,a53deefb3d57edbf248c2f310f0e68a1687cf300a25b29bfdcf22550ee733a88 -\u2652,668fde03fef7e71bd4996ac65e9d1930a62b8fcae1d55e84d51c4a491c2d864d -\u2653,d33f49965f3ad95e4056629c967e7a584b44877a30384a0a5c42436c8d046366 -\u2665,fbefc867d847ab95e775e04aa5383b1670d38420a827b162d898b8f7ec148ec -\u266A,e2f841ce3028ff65d4f3a3dfb5eb4e1b0ecaf803b4fcc74d726aeaa2f4d7f5c +" ",6e5286c470f66ffa1a18331cbffb9a3c2a4424a8c7259c4436fd2e35582a522 +!,18be147df49091736964dab3569b61c9e6a341c9a48f4af84b51a63bb6e85 +"""",bd744bbed3df1126525a54a49f1e39d2373043e4ed4ae45fa9d97f5b3ba69 +#,c9327a4573977cd378f06d1f832e907f5f66dbe5ea88ff1c3689ad958b7e7 +$,34a9e5314842dd21411e95d93e37eb0b04025ee847036cae3cb9ea1a1d6c582a +%,bf2fbfdb132f149f78c479be43ba75d4ded3ebe4cb9ddce9b7b5768810d935 +&,861967db1d807bd07eb25fa078815c754069c21bf777c36cbb2bf6899d479f6 +',3e18b787ec3e17ce5dfc63b879f26444568b225a993d8a17eac0add1209dce41 +(,d84a79b29e390fde361ada79a33f497da7bb7111b7edef5821bfc74496db434 +),995923f74c5b6562e8c05402fde99443f485935c9dfa2b3d0a44b505c577731 ++,10c97e4b68aaaae8472e341b1d872b93b36d4eb6ea89ecec26a66e6c4e178 +",",6bc3ccd76b3ca98d835e99b6d678177b2efc3ced89bf531af6683cb38d78c +-,c674b682b179d1d4fa791f92cdaf1c2f37fad4eadbc7dbdc060e8154d351482 +.,1fd52bea8fc6a9114c3c2d8762dbdcaf8b9df8edeb26fc4191e26ae8704493 +/,9cd7ab2e73c9f68494e285dcad9288387952b1e23033c4911c44c7b6e3d150a3 +0,a3a487b1f81c9ecc6e18857c6566529e7efa23eef59814fe57d64df8e2cf1 +1,bf61269735f1e446becff25f9cb3c823679719a15f7f0fbc9a03911a692bdd +2,7d81a32d978f933deb7ea26aa326e4174697595a426eaa9f2ae5f9c2e661290 +3,ceadaded81563f1c87769d6c04689dcdb9e8ca01da35281cd8fe251728d2d +4,6c608c2db525d6d77f7de4b961d67e53e9d7bacdaff31d4ca10fbbf92d66 +5,1144c5193435199c135bd47d166ef1b4e2d3218383df9d34e3bb20d9f8e593 +6,f61f7e38556856eae5566ef1c44a8cc64af8f3a58162b1dd8016a8778c71c +7,6e1cf31c49a24a8f37849fc3c5463ab64cc9bceb6f276a5c44aedd34fdf520 +8,61c9c09d52debc465c32542c68be42bda6f6753fe1deba257327ac5a0c3ad +9,2dcf39f4bcd98484b0b479a7992d9270fe3a59b9b1a806d7a64ffb5b551ad +:,a919fe599f98258ddff44c768137e2e9cbaf4b94f5a25233c27f3dd2f5359 +;,ea4e864afd4d232c2f86219551c9ba9819afa1aeca0278b1e05d98b1f +=,f63cb8b469fba4462bc95e6f34e48532d5ac03539b90bb3694b05e454fb5d0 +?,89a995928090d842d4afdb2296ffe24f2e944272205ceba848ee4046e01f3168 +[,bcaf1f9bb182cedbfcef26c9078467b8953e2aeaefc59e677dc8de21e7d5534 +\,5f701279b249c727dbb4fa3bf74ad403f25bd3f7d4b1e2d3617eee66e4a3 +],677a226be5b6fa9437c9d49667cd8e28eb1b5992b92fc72ce78e5665a7db +_,1bf4abbacaa527bd748059a241d470ceed63149960cd24464f7f524df5fc465e +a,1a74d9212e6491bc370caf025fd459fe632ca7c6ba4df7ebefafd489ab32fd +b,a01783f37c7b5f691c615130ab85e1e1ad25dffceafd7bb178b92173df2aaa +c,89b66dbf01c94aef7dca1abe8536c9e512969fa32f5707542979caf7258adc5 +d,1866b462b776374328d8daf2ce9e5abc3ecc64481d54a69cd4c2b25e7630c6af +e,5223afe895d3d4e32f393dd301989a317585d9ebe3f5d76d4380f5a06f95 +f,fceb2a4441b73d4e744aeecba9fe6afb18470b99a262bd1ba1bcc6913a2baaf +g,bd62d63cfb4b8731fcd2635dcf69203df393946e1aeca2605ab963e2829dab +h,8f5b871ae47eba146b5b4cf89fc20dc3236952a7ea867898bec1f3b719712a +i,e7a2f8bf7e138d6ba9246f7dc1ff144f43ed512e44892b1e316535ea882f7a5 +j,1df8b482ee76979fdb9467c8e666cc6aec5cb44859bb74579f016291ed01175 +k,5198fce7eafdaca15bd6e98ca94b4046583a8b2e5411cc8c944588fd7f1a5f97 +l,9f78466a7b5aae90884c6e2227d524978136354457382d3647b07d096c2a22e +m,f2f2d827495053557c52e55ccdd571bd33184fc14928441f3a97eab38922812c +n,651a7ee66f60237419917fdc75f5d341cfbb9f7ccaaef3aff2af419d588e701a +o,d97aa8b9f7ed8c38ae41f1bd6d9e10eb57bc87e18cac247e7bd2a4e0e588578a +p,72747139f338a46a45903b7633f270502d64f066515f4d2f9def80cff91150ff +q,e0fcfc742ceb9464efc971a31c5896d971e4772772745756225b0643e4e93 +r,d82e6f0f9eaef56f383a4c5a392b194bf1a1b63559ac36255ccef2463c38c +s,bcef333aaba242c6f28f49e96689ab4bf2bc126bbc298555b93da79328419d8 +t,e5bf4db51fab4aa279628dfb2a1720e01bf7e9b94bb8c7e702fb63757405d +u,3ade4661e998aeb20136396d94136c27d49902280ab7eecfa887db48a9b6cf +v,9df53a18c59683fd63f6822cd4464d12c862d7818c68b2302857b719f55e4fe9 +w,357b1f6eb7cf0fd20499a5be6b82b25cf5cbd8e57daac7351c85c45fb5fe5c +x,bcc5fae3b650e6edb3245fa41e5be2da79b0e17f22c4b4e1e59b32f573202d18 +y,367477f9cb5f036438ce98ce697b91358cb97641c5d153a7e3888dae32e215 +z,cfa730b5ec73ceaf4aad524e207ff31df785e7ab6db1aeb3f1aa4d245ed2e +{,4f3edebbdda39e10dd852c22a98aafd77ff729fd52dd122c27c3c63925ab +},fe69b854edead62acb813546447af6904d0332328b56414d54bb14ff9edd3cf +\u00A1,7f85372582546c021c89781914074d71d73565623ac38e04bebeda052d50214d +\u00BF,7b50ddb5fc118f69cbe778b38649b56ac4fb3123893270bfa2ffab2f97dac7fd +\u00E4,4933d1fd6cd48776df58841ecc47ce690c487152e294c263c8ec83a9da1e40 +\u00EB,659544fb35947037fb8ad8149fb10fd58dc7336ead4c71a5018d68f205d64b5 +\u00F1,2d2d27cbf5854fae94f088821bf4043a87bdc6a66b53229a8ac9473811d38d3 +\u00F6,bb9b316728683d3ef5fa4e82deb8e41aac2e3fd89ebb55e1e1c18f3591361b +\u00FC,d83ace21e1f3158574c8d289d7a49a5c6be12ecdffb66e32056fd2984c329ab +\u0431,dff5d36177c8695a51f74bffcc2dc3d1c399838367f16e8c7c91e67665d67 +\u0433,1dfde4b8b6a270d5ff53617986fe9eb18457deb2b223bca10108cb763fc3fc +\u0434,81de18563b89ebea6d7fd1b1176b7b0c245b0f070ce26e13631a6dc96d08371 +\u0436,80f295fe98de4287df365245db9333a8b42294442f123e40e886bb9ac687ba +\u0437,309e4aa9192ad6534dea89e5c9a85df0e6abce1c1557d54077296c8fbdcb5 +\u0438,1b71e881c497933edb51329abd465a7ac54c72ee6eefe5ae220d6d53959ae12 +\u0439,167041cc9a6ca93213d399ed8da4e4f71ef77205a22aed88a623a9d8d4e8963 +\u043B,f980bbd24bb6e1796f87a03fb76e62ce51e76871aa796d2678fc63dc2b +\u043F,f644fe1cc61c26c7c3da9f58f647912c8a6b364cf4bd5d704e7ef7f11d199d +\u0443,a3f56078d8a42b37dbb47491b7ec3e3616f91289f3e77bcbe5c4f25d5aea9da +\u0444,50c622f0bafd22734c3b389af9a6370c2ac5029989b9c682714b4398edcc8d +\u0446,a09d6089db44bf8fa41e3641ed656f5590842a1cbf7b6856b590e0e4985a5a +\u0447,fa3ef2fcd637477737fb7524cd5afe8a6512ebb14fa9d6819356fa6ad225 +\u0448,5f11ea4a532a486938b29f65a4716f4e091c2d35dcf486adb52dfc3210 +\u0449,3a5ce7a7cc8c34ae8db6cc824daab18c85a1525ee23b7543e412a9e3bd4b +\u044A,e9185e3994b4e94a63dea9594c49efe45fc6ea668cf19d6adf34ad5cf3d06c +\u044B,f9fced6ef9e9b81d988a247f1fc9ab2f6121aca9320419be9f7bc464c17321c +\u044C,ec1394d509c276bbdaab279473bf0faaa9756a7e4d54aaf58292b5f4aeb3615 +\u044D,e8d77e70607f97a5d07df87e4aa097112a2cd297606c2cd44fa250e44fe77a9 +\u044E,deaed89fb965570e517295c766e84d10b1bd44643de6886d0b63c5a8554 +\u044F,545f9e70432f7571f10855d5e866a17f7395351f4c9267eaeb2b5ebc34bdcb +\u2190,86971dd881dbaf4fd6bcaa93614493c612f869641ed59d1c9363a3666a5fa6 +\u2191,3f46abad924b22372bc966a6d517d2f1b8b57fdd262b4e04f48352e683fff92 +\u2192,f32ca66056b72863e98f7f32bd7d94c7a0d796af691c9ac3a9136331352288f9 +\u2193,be9ae7a4be65fcbaee65181389a2f7d47e2e326db59ea3eb789a92c85ea46 +\u2196,78cf444bc0e0ddc6a6a9d75951746e0955bd676c4a6771c1a5ed90e7827f +\u2197,676dcb274e2e23149f472781605b7c6f839931a4f1d2edbd1ff5463ab7c41246 +\u2198,1a103acc21ee0a1f87b5be8f3ec7bf47745ec992081be9b41548ee3e3682 +\u2199,56961ad1f5c76e97358c444fe0e83a39564e6b48109170984a84eca5dccd424 +\u23E9,dd993b8c13588919b9f8b42db065d5adfe78af182815b4e6f0f91ba683deac9 +\u23EA,f4bfef14e8420a256e457a4a7c88112e179485e523457e4385177bad +\u23F4,74133f6ac3be2e2499a784efadcfffeb9ace025c3646ada67f3414e5ef3394 +\u23F5,e02fa3b2dcb11c6639cc9b9146bea54fbc6646d855bdde1dc6435124a11215d +\u2640,93392f17442512f7f369aa535102979dacf588eae5d1cf128009083b7c417ba1 +\u2642,a692ec726cb8562c23e0bf2c447a1a995d59ba45f8634b7717ca41415f413945 +\u2648,d0c9e73a1c9603b63ec509b32c434af21931262eea9e9a755ab126e2bc06c90c +\u2649,b6a53a9fd6cd37fd1f2a9bdb9e0c9562cf883514415202909ff8124977e22093 +\u264A,8bf7d0b365a7b4c625a0480d81acfae40288cc313694bb8a69d601a9721b4240 +\u264B,a58e976ecfe4547c32bbabb4bf0108d519d0531e5d360fdc613809f9f46301f9 +\u264C,699507b650bf544abf2a364d6dbddb0f4e0c6f80723d87290b0a82b2453021e8 +\u264D,e78c1732ae4adf41f0a25a54cda5383a9c659a3303832938f203f713600c605a +\u264E,57bc97b3c053b8e34937ee79175df6f93728c556878c39f2b3adc38a13caf167 +\u264F,63d3458d9bfa072a07d1e562efc9a542e414d439a8fec99e69117cce2220a455 +\u2650,3c43ed33dba8423e22fa850c59f9988f6a101fef28c630b42230d7f5f82b7f68 +\u2651,a53deefb3d57edbf248c2f310f0e68a1687cf300a25b29bfdcf22550ee733a88 +\u2652,668fde03fef7e71bd4996ac65e9d1930a62b8fcae1d55e84d51c4a491c2d864d +\u2653,d33f49965f3ad95e4056629c967e7a584b44877a30384a0a5c42436c8d046366 +\u2665,fbefc867d847ab95e775e04aa5383b1670d38420a827b162d898b8f7ec148ec +\u266A,e2f841ce3028ff65d4f3a3dfb5eb4e1b0ecaf803b4fcc74d726aeaa2f4d7f5c \u2713,85a3755a6fe019a173ce3a43070452e767768d57559d04b73e21b903eaa1bd82 \ No newline at end of file diff --git a/src/main/resources/fonts/green.csv b/IF/src/main/resources/fonts/green.csv similarity index 98% rename from src/main/resources/fonts/green.csv rename to IF/src/main/resources/fonts/green.csv index e1bf9cc7..a2ab7470 100644 --- a/src/main/resources/fonts/green.csv +++ b/IF/src/main/resources/fonts/green.csv @@ -1,118 +1,118 @@ -" ",ebc37c9b37f4df36e4e50435fd41ecd6a7a711d11b91a6e507d285e8e85bd -!,d7b4320ba2a89eb2b61560da52aefbc2cdd2dc2dfbd57e1b698641c754112 -"""",c376e491caf78b72374ea7ae5c448e8052d0a9472757cf98323f3f8565f5 -#,7bc3ec80dd7993581c970ce4394a4b9da98821bce7754844a17d5fa384f354 -$,9f262870866e361757ed8dcfabd103ebd64d5738455d0c929b266274e7c4c7dc -%,1cc034defbfeebc9d92d3285174e67da685832861e954d78f9cbada9d9526b -&,a92716c7dccd61823bc8c3dcd2f459c2f27a7ed213fb1637eaafd3ebe64f -',a482749c57a5c27805bac5fc93236813e9d8d915d7794e41ff21f68aabe10ac -(,2cc8dfae36b1b941b0d5ba4d5bd1f94a1018ace6b9907fcc2fdf6e9c7e56bd -),82548521445b5d7f6ccd506ba146aa52691360ef3ab93a3ad434d36d8169a4a5 -+,5ff31431d64587ff6ef98c0675810681f8c13bf96f51d9cb07ed7852b2ffd1 -",",2bd65071bb95e54744fb7f2fd14feaf90eda9d5b84168aed859e34ba0a21741 --,cd15b5d79bedadc145fa17cc36a2e0c9b088b4ee74f86ea588bd1ad8cdbd22 -.,54ddd9a2a0b830b3ae3fbb7431e6e381358686d2627c9a54ef6f9d49d66e -/,15ab1f56ddf16c11205bcbadd72e0af8d873eacc8fdb55c8f15e6a81f71b8a -0,24581d3955e9acd513d28dd32257ae51ff7fd6df05b5f4b921f1deae49b2172 -1,6d65ce83f1aa5b6e84f9b233595140d5b6beceb62b6d0c67d1a1d83625ffd -2,dd54d1f8fbf91b1e7f55f1bdb25e2e33baf6f46ad8afbe08ffe757d3075e3 -3,21e4ea59b54cc99416bc9f624548ddac2a38eea6a2dbf6e4ccd83cec7ac969 -4,8b527b24b5d2bcdc756f995d34eae579d7414b0a5f26c4ffa4a558ecaf6b7 -5,84c8c3710da2559a291adc39629e9ccea31ca9d3d3586bfea6e6e06124b3c -6,e2113c604a22b224fbd3597f904a7f9227a7c1ae53439c96994bfa23b52eb -7,24bde79f84fc5f3f1fbc5bc01071066bd20cd263a1654d64d60d84248ba9cd -8,f2ee1371d8f0f5a8b759c291863d704adc421ad519f17462b87704dbf1c78a4 -9,4378f2ed773cd6b2551819218bff87c374a4b7d6f3b2c236787ea79367bf6d1c -:,8e5a69bac5597e643dd2d99e25b0edb33e98f621611be58c2f3972b6e0ceeec6 -;,c947dfe74e734eab86b93a17d2773f8b57128f45d9dacb1a31568dca0e32 -=,f303d6756179abbb61bad3a9f71cf03bf426141723488d4784a2ac610fac7 -?,2370ca47b6173ab58e6a8018486e2f8baa8397ab614ae2e696849196baa7c -[,5d258fa6971d7adec6ac969732c0336034e27d581cdcb719d15bf735d6e5d3c -\,151d9ae0d35ec189b67859e1c28dd2df13333c9156ce22581c7b86cccd15a2 -],81fc8629e2a1501173131dbc1fc0cb9d2972ad187df1c567e0951460257947 -_,e1aa59b92daae06b6e60a087c0d99561b27721b96a8945efe438e31c59f4ef7 -a,20afd777d557a207bac7aad8421fdf788d6685873c49515d55291e930699f -b,747899d511ba3a3bfe14541a6a4b77b033e44acd956896e7b6567429bf18d83c -c,eac0da9494b974bdbcb78861df96aa5aaa5da35c658721718ab26dc2ff67d87 -d,8943124bf6d5792511bb8ac5a7978e236b74fc7fc1d39af955ecedf97ab4 -e,918641016d1d7cb406a863dde81f6bbd30371cf46d8f1420cd5ec6cdb64ef7 -f,3c4c399b5e7522a17d35eb53fe5eb767a3b38ea6e5cd33b4438020fc5a848a -g,a7ca8b9c7169a743f82e8e9fd68f11c0f31070a53c92863884e673137fbaf1 -h,41595773048de9c411896fae9ba9d48d55b71677199701064984b42cd2a17d8 -i,6e5dc3d67d7cc47ee95c20c4202ecd91d91dc63660d8144f81628881d7fde2 -j,27b38b21528f2c463a48ed5c8937f85dd16cb98bf96042897948e74b7cc631 -k,abe3ea814dbc707a39272d6ae336c068844ead52c7b7d2ee1ba4d50bbd9 -l,3bba9a55fee9cad05f1e947e6d475520fbe51137a532796135203ece3d269 -m,4c1713d90ca5998716eaa7dd302f6c8d672595dcc6956c2e20e94184bae2 -n,34ea15d10d167c355e941f98f8b5e1cf716d5dea7fafcc69f9bcdb52a8f34e -o,e8f47923861c275311ab69b03e2751224ff394e44e3b3c8db5225ff -p,4f5b409417ff2e777d5e83cecd2856d2ccc68dffdef940154e945ace6d9ccc -q,618c1061f62f98cfac3d7549b983c43f27c2da229ddc266f51677ca9337 -r,c91d46f1844341bc94d1f8f4519d3f7c6e2fa718b664b935661a2782a670e2 -s,3ed9d96c393e38a36b61aa3c859ede5eb744ef1e846d4f7d0ecbd6588a021 -t,d23bae41d1333426b625e141d9d4806b6f4641d6754d7e19e4bbefa37fe513 -u,f98edadf35c82be08cde43e52da8830f87f9288992088a699fd2ecc4be073 -v,a86c97159cd658858d12b833d1671b84529e1f116d8be379d43824cb17963bb -w,3d31ceb43e3908928c0ce9ceeecf79b8d33c54faeba8d6174d80ac3641c3ba -x,6e8646bb76f0c6d03a637a9b4975b3a85276eb20d6f16bdb91866c8c3c8285c5 -y,831d3df99578c79e0fd64b6115b6b44ed4dcab4a987be7c7e91baa61886e0eb -z,76157b9c101312838b128e71d55bfc9ad4e26b5919a73807b13466a76d5e0 -{,c8a296b9556ed3fd3b9b9d8afd26cf3b8951a604e87f42b3919f440a39d2c2b -},e5e0b2359d12af225248ae8c144047936b8b2534668e34b781c15f5899 -\u00A1,afa7f191cb959002a1fdf2c105e2fa61c2584a8c36be410f53104b9d284f20a2 -\u00BF,2dc5ad68fb1f9935091becce3e8d23909b4431a08b6cbdb9407d7e4c203ab4b2 -\u00E4,3c971aab3a348cdb799ef3e9893a07e22faf8a08484eb32838d68c9af30a520 -\u00EB,3fd267891973f26c17d7ac69a2dfbd6b74ad9244311eba30d3f371789fd4 -\u00F1,8436e13c716ad11b5ac5ac8c6af9a0612ff0c51eb6a8aa9b6653c18980e7e44e -\u00F6,1dc11338dde4fa4bc6a2c3f2901f18172b68b452efb828d611cc315d4784f7 -\u00FC,b32c24356a84ded9e222ccfde245d7af868de24c16f1de6dc5227dc4a37d529 -\u0431,db8a5adadb18aa96afbcc1c25c19840bc9b12c261515f5a6e26edd629e5c62 -\u0433,ad8afacc4f6fa4958edcac9ff3941bd134587bead0339056b04a93a7a367f0 -\u0434,e81bce69c636aa0c6ac64ca3701b7dc199ef7eafba3e31a4fc8f45cf30892e -\u0436,5f38bc79199bf1884eebf7313359a85bdcd77348db6a1ad31e16ff9daac81 -\u0437,7c18aca0c2bc6945bcd87897bd4415db5ce27fae642bfd4997c3119ad77b7e1 -\u0438,4149341d8922246b36611a794bc85e6f8c8e8e9993e379b8cc52fa469720d6 -\u0439,3c8c9d1aa955468a15a89564afafa3cf630897ab09938a632b0367c6b38e78 -\u043B,ff86cbf1d1b355e85371c9b6d81e31482b1f4af493a46796f27cc5ad322d7b -\u043F,8be110debf33db7418f4801b54e2731f22988f3c9ce5eea34e979d2997c21fa -\u0443,60ba8ba5209230a7185916dda96789d98c966f57bbca5a2a462625256ca3545e -\u0444,6e8654eb11b36a0cb8efa3ed6a51de9fc23938ff8e607a0182c9118d2fbf3 -\u0446,cecafcf83ec118a7387e8995578e7cd75e4937e086e587caefeec4f4b7175e0 -\u0447,5c8cc9fd19141af338a54338f2805b86edbf6f687669d1197755ff0f61c6d9 -\u0448,db7ca772f4d9bdd7582c15eb4c5899b6b62c693d5d82549a2712819c947 -\u0449,aeba40ba1099b3bcfa7f3a506ea5edc106bd2aeebc7d14eb1579e5c8d9f65 -\u044A,4a8c4ec65873fa6fc37a37dd9a60a7d6a65be403162ff55c8a1b6af845a19 -\u044B,a1f23b87219e67aef66db277c1676fb560e442bf6f44bcf507fe83b28298b58 -\u044C,3b83b28a0767b196710cc7dfdd9bf23cac12a4ba44a4d795235dc926f77911d -\u044D,14871c22c8d8339c3124f1f08a12beaa38c8bb78f0ef20426c4ae6f8681b27d8 -\u044E,2f439651253421993ac04de9abafd312cd5df6165eff79312f5a3eff965d9b -\u044F,36751dd3b4308311511b9b9b91747dd8e64958e34beaf13e07fccd7f1359839 -\u2190,8550b7f74e9ed7633aa274ea30cc3d2e87abb36d4d1f4ca608cd44590cce0b -\u2191,5da027477197c6fd7ad33014546de392b4a51c634ea68c8b7bcc0131c83e3f -\u2192,96339ff2e5342ba18bdc48a99cca65d123ce781d878272f9d964ead3b8ad370 -\u2193,ff7416ce9e826e4899b284bb0ab94843a8f7586e52b71fc3125e0286f926a -\u2196,3c24eca208f7dd6eeedcb8b81a42fdcd86c11a2eb377febcd6d5450ad6bb0 -\u2197,bf6b85f626444dbd5bddf7a521fe52748fe43564e03fbd35b6b5e797de942d -\u2198,65a3e52856574a7c83cd118b1a1360a7a8be85c8a4c6f86e068dc4f4b506b66 -\u2199,33658f9ed2145ef8323ec8dc2688197c58964510f3d29939238ce1b6e45af0ff -\u23E9,77b733e0ba964e8157476f3353426a87ceab3dbc3fb4bddaa2d57886df37ba6 -\u23EA,4a808a6c8d97dda2bd5d84642e1714c781294e9172b7c375cd9cfcf3c54f2ba -\u23F4,754aaab39764641ff8627932d2fe1a4ccced96537508d4abc6cd5fbbb87913 -\u23F5,61d0f82a2a4cdd85f79f4d9d9798f9c3a5bccbe9c7f2e27c5fc836651a8f3f45 -\u2640,a8818aff43597c163777aedc36e743983121493ba3368ee64cefca01c55ab68f -\u2642,6f9eb19ae50ba6d42fa00985bf803ee115c7ac17b00f8bdd1b1d47d0c8b9a401 -\u2648,da10836a81c9445357b1918687f1dbca1d83a692641dc4d37fc3450112b6d60c -\u2649,9b7c94bfac7d271641e3d7737e4c739de3b5647d4d8bc475cffc6ae7bb768351 -\u264A,58ef980f1abcdfca4111976073f6c4b001153ba1456daa65d85a22d58d841fa0 -\u264B,b429642b7be7f504e5934cc37d0c8ad41d3d269493ac32dd393026eaf501a41f -\u264C,91e68589fcaacdabdb922b2778d65e93a92f4a4545dc4f80069d0b5dc365d435 -\u264D,b0a7c5d7d975c418d908c18a73da090993939de130c02255a7007111a78e5c01 -\u264E,ac6868113c77b60955d3710264764e22129be89cdbf3501e1f4bec77256e5a2e -\u264F,eb990ac2aa036ddf2b87c1b856eb1057ae7dca42c0a943e44ba9ac71a813c62d -\u2650,41ad786891870838575180acd3b8230ffc1198e42642366cbc8f9b775ec333f0 -\u2651,2f3f6b281354983f93623846707680aed5e07ef138c32009800672aa777c233 -\u2652,f7a03a9ae85be8dfae02ed6f75bb3bccf1557c7d40efe0b6b344a00cf1957b70 -\u2653,18aa499fe3fcb5452989db7c177cc1ae5e4723e499f4a32e1b46af5bb2a53360 -\u2665,78432607e86b02ea3caaf9357066ca3f5e4edeef7be9edcbb5e45711c6557 -\u266A,8eb8bd18228493f0f139040f3bcef187abfa8217631d9e184f499bc6791878b1 +" ",ebc37c9b37f4df36e4e50435fd41ecd6a7a711d11b91a6e507d285e8e85bd +!,d7b4320ba2a89eb2b61560da52aefbc2cdd2dc2dfbd57e1b698641c754112 +"""",c376e491caf78b72374ea7ae5c448e8052d0a9472757cf98323f3f8565f5 +#,7bc3ec80dd7993581c970ce4394a4b9da98821bce7754844a17d5fa384f354 +$,9f262870866e361757ed8dcfabd103ebd64d5738455d0c929b266274e7c4c7dc +%,1cc034defbfeebc9d92d3285174e67da685832861e954d78f9cbada9d9526b +&,a92716c7dccd61823bc8c3dcd2f459c2f27a7ed213fb1637eaafd3ebe64f +',a482749c57a5c27805bac5fc93236813e9d8d915d7794e41ff21f68aabe10ac +(,2cc8dfae36b1b941b0d5ba4d5bd1f94a1018ace6b9907fcc2fdf6e9c7e56bd +),82548521445b5d7f6ccd506ba146aa52691360ef3ab93a3ad434d36d8169a4a5 ++,5ff31431d64587ff6ef98c0675810681f8c13bf96f51d9cb07ed7852b2ffd1 +",",2bd65071bb95e54744fb7f2fd14feaf90eda9d5b84168aed859e34ba0a21741 +-,cd15b5d79bedadc145fa17cc36a2e0c9b088b4ee74f86ea588bd1ad8cdbd22 +.,54ddd9a2a0b830b3ae3fbb7431e6e381358686d2627c9a54ef6f9d49d66e +/,15ab1f56ddf16c11205bcbadd72e0af8d873eacc8fdb55c8f15e6a81f71b8a +0,24581d3955e9acd513d28dd32257ae51ff7fd6df05b5f4b921f1deae49b2172 +1,6d65ce83f1aa5b6e84f9b233595140d5b6beceb62b6d0c67d1a1d83625ffd +2,dd54d1f8fbf91b1e7f55f1bdb25e2e33baf6f46ad8afbe08ffe757d3075e3 +3,21e4ea59b54cc99416bc9f624548ddac2a38eea6a2dbf6e4ccd83cec7ac969 +4,8b527b24b5d2bcdc756f995d34eae579d7414b0a5f26c4ffa4a558ecaf6b7 +5,84c8c3710da2559a291adc39629e9ccea31ca9d3d3586bfea6e6e06124b3c +6,e2113c604a22b224fbd3597f904a7f9227a7c1ae53439c96994bfa23b52eb +7,24bde79f84fc5f3f1fbc5bc01071066bd20cd263a1654d64d60d84248ba9cd +8,f2ee1371d8f0f5a8b759c291863d704adc421ad519f17462b87704dbf1c78a4 +9,4378f2ed773cd6b2551819218bff87c374a4b7d6f3b2c236787ea79367bf6d1c +:,8e5a69bac5597e643dd2d99e25b0edb33e98f621611be58c2f3972b6e0ceeec6 +;,c947dfe74e734eab86b93a17d2773f8b57128f45d9dacb1a31568dca0e32 +=,f303d6756179abbb61bad3a9f71cf03bf426141723488d4784a2ac610fac7 +?,2370ca47b6173ab58e6a8018486e2f8baa8397ab614ae2e696849196baa7c +[,5d258fa6971d7adec6ac969732c0336034e27d581cdcb719d15bf735d6e5d3c +\,151d9ae0d35ec189b67859e1c28dd2df13333c9156ce22581c7b86cccd15a2 +],81fc8629e2a1501173131dbc1fc0cb9d2972ad187df1c567e0951460257947 +_,e1aa59b92daae06b6e60a087c0d99561b27721b96a8945efe438e31c59f4ef7 +a,20afd777d557a207bac7aad8421fdf788d6685873c49515d55291e930699f +b,747899d511ba3a3bfe14541a6a4b77b033e44acd956896e7b6567429bf18d83c +c,eac0da9494b974bdbcb78861df96aa5aaa5da35c658721718ab26dc2ff67d87 +d,8943124bf6d5792511bb8ac5a7978e236b74fc7fc1d39af955ecedf97ab4 +e,918641016d1d7cb406a863dde81f6bbd30371cf46d8f1420cd5ec6cdb64ef7 +f,3c4c399b5e7522a17d35eb53fe5eb767a3b38ea6e5cd33b4438020fc5a848a +g,a7ca8b9c7169a743f82e8e9fd68f11c0f31070a53c92863884e673137fbaf1 +h,41595773048de9c411896fae9ba9d48d55b71677199701064984b42cd2a17d8 +i,6e5dc3d67d7cc47ee95c20c4202ecd91d91dc63660d8144f81628881d7fde2 +j,27b38b21528f2c463a48ed5c8937f85dd16cb98bf96042897948e74b7cc631 +k,abe3ea814dbc707a39272d6ae336c068844ead52c7b7d2ee1ba4d50bbd9 +l,3bba9a55fee9cad05f1e947e6d475520fbe51137a532796135203ece3d269 +m,4c1713d90ca5998716eaa7dd302f6c8d672595dcc6956c2e20e94184bae2 +n,34ea15d10d167c355e941f98f8b5e1cf716d5dea7fafcc69f9bcdb52a8f34e +o,e8f47923861c275311ab69b03e2751224ff394e44e3b3c8db5225ff +p,4f5b409417ff2e777d5e83cecd2856d2ccc68dffdef940154e945ace6d9ccc +q,618c1061f62f98cfac3d7549b983c43f27c2da229ddc266f51677ca9337 +r,c91d46f1844341bc94d1f8f4519d3f7c6e2fa718b664b935661a2782a670e2 +s,3ed9d96c393e38a36b61aa3c859ede5eb744ef1e846d4f7d0ecbd6588a021 +t,d23bae41d1333426b625e141d9d4806b6f4641d6754d7e19e4bbefa37fe513 +u,f98edadf35c82be08cde43e52da8830f87f9288992088a699fd2ecc4be073 +v,a86c97159cd658858d12b833d1671b84529e1f116d8be379d43824cb17963bb +w,3d31ceb43e3908928c0ce9ceeecf79b8d33c54faeba8d6174d80ac3641c3ba +x,6e8646bb76f0c6d03a637a9b4975b3a85276eb20d6f16bdb91866c8c3c8285c5 +y,831d3df99578c79e0fd64b6115b6b44ed4dcab4a987be7c7e91baa61886e0eb +z,76157b9c101312838b128e71d55bfc9ad4e26b5919a73807b13466a76d5e0 +{,c8a296b9556ed3fd3b9b9d8afd26cf3b8951a604e87f42b3919f440a39d2c2b +},e5e0b2359d12af225248ae8c144047936b8b2534668e34b781c15f5899 +\u00A1,afa7f191cb959002a1fdf2c105e2fa61c2584a8c36be410f53104b9d284f20a2 +\u00BF,2dc5ad68fb1f9935091becce3e8d23909b4431a08b6cbdb9407d7e4c203ab4b2 +\u00E4,3c971aab3a348cdb799ef3e9893a07e22faf8a08484eb32838d68c9af30a520 +\u00EB,3fd267891973f26c17d7ac69a2dfbd6b74ad9244311eba30d3f371789fd4 +\u00F1,8436e13c716ad11b5ac5ac8c6af9a0612ff0c51eb6a8aa9b6653c18980e7e44e +\u00F6,1dc11338dde4fa4bc6a2c3f2901f18172b68b452efb828d611cc315d4784f7 +\u00FC,b32c24356a84ded9e222ccfde245d7af868de24c16f1de6dc5227dc4a37d529 +\u0431,db8a5adadb18aa96afbcc1c25c19840bc9b12c261515f5a6e26edd629e5c62 +\u0433,ad8afacc4f6fa4958edcac9ff3941bd134587bead0339056b04a93a7a367f0 +\u0434,e81bce69c636aa0c6ac64ca3701b7dc199ef7eafba3e31a4fc8f45cf30892e +\u0436,5f38bc79199bf1884eebf7313359a85bdcd77348db6a1ad31e16ff9daac81 +\u0437,7c18aca0c2bc6945bcd87897bd4415db5ce27fae642bfd4997c3119ad77b7e1 +\u0438,4149341d8922246b36611a794bc85e6f8c8e8e9993e379b8cc52fa469720d6 +\u0439,3c8c9d1aa955468a15a89564afafa3cf630897ab09938a632b0367c6b38e78 +\u043B,ff86cbf1d1b355e85371c9b6d81e31482b1f4af493a46796f27cc5ad322d7b +\u043F,8be110debf33db7418f4801b54e2731f22988f3c9ce5eea34e979d2997c21fa +\u0443,60ba8ba5209230a7185916dda96789d98c966f57bbca5a2a462625256ca3545e +\u0444,6e8654eb11b36a0cb8efa3ed6a51de9fc23938ff8e607a0182c9118d2fbf3 +\u0446,cecafcf83ec118a7387e8995578e7cd75e4937e086e587caefeec4f4b7175e0 +\u0447,5c8cc9fd19141af338a54338f2805b86edbf6f687669d1197755ff0f61c6d9 +\u0448,db7ca772f4d9bdd7582c15eb4c5899b6b62c693d5d82549a2712819c947 +\u0449,aeba40ba1099b3bcfa7f3a506ea5edc106bd2aeebc7d14eb1579e5c8d9f65 +\u044A,4a8c4ec65873fa6fc37a37dd9a60a7d6a65be403162ff55c8a1b6af845a19 +\u044B,a1f23b87219e67aef66db277c1676fb560e442bf6f44bcf507fe83b28298b58 +\u044C,3b83b28a0767b196710cc7dfdd9bf23cac12a4ba44a4d795235dc926f77911d +\u044D,14871c22c8d8339c3124f1f08a12beaa38c8bb78f0ef20426c4ae6f8681b27d8 +\u044E,2f439651253421993ac04de9abafd312cd5df6165eff79312f5a3eff965d9b +\u044F,36751dd3b4308311511b9b9b91747dd8e64958e34beaf13e07fccd7f1359839 +\u2190,8550b7f74e9ed7633aa274ea30cc3d2e87abb36d4d1f4ca608cd44590cce0b +\u2191,5da027477197c6fd7ad33014546de392b4a51c634ea68c8b7bcc0131c83e3f +\u2192,96339ff2e5342ba18bdc48a99cca65d123ce781d878272f9d964ead3b8ad370 +\u2193,ff7416ce9e826e4899b284bb0ab94843a8f7586e52b71fc3125e0286f926a +\u2196,3c24eca208f7dd6eeedcb8b81a42fdcd86c11a2eb377febcd6d5450ad6bb0 +\u2197,bf6b85f626444dbd5bddf7a521fe52748fe43564e03fbd35b6b5e797de942d +\u2198,65a3e52856574a7c83cd118b1a1360a7a8be85c8a4c6f86e068dc4f4b506b66 +\u2199,33658f9ed2145ef8323ec8dc2688197c58964510f3d29939238ce1b6e45af0ff +\u23E9,77b733e0ba964e8157476f3353426a87ceab3dbc3fb4bddaa2d57886df37ba6 +\u23EA,4a808a6c8d97dda2bd5d84642e1714c781294e9172b7c375cd9cfcf3c54f2ba +\u23F4,754aaab39764641ff8627932d2fe1a4ccced96537508d4abc6cd5fbbb87913 +\u23F5,61d0f82a2a4cdd85f79f4d9d9798f9c3a5bccbe9c7f2e27c5fc836651a8f3f45 +\u2640,a8818aff43597c163777aedc36e743983121493ba3368ee64cefca01c55ab68f +\u2642,6f9eb19ae50ba6d42fa00985bf803ee115c7ac17b00f8bdd1b1d47d0c8b9a401 +\u2648,da10836a81c9445357b1918687f1dbca1d83a692641dc4d37fc3450112b6d60c +\u2649,9b7c94bfac7d271641e3d7737e4c739de3b5647d4d8bc475cffc6ae7bb768351 +\u264A,58ef980f1abcdfca4111976073f6c4b001153ba1456daa65d85a22d58d841fa0 +\u264B,b429642b7be7f504e5934cc37d0c8ad41d3d269493ac32dd393026eaf501a41f +\u264C,91e68589fcaacdabdb922b2778d65e93a92f4a4545dc4f80069d0b5dc365d435 +\u264D,b0a7c5d7d975c418d908c18a73da090993939de130c02255a7007111a78e5c01 +\u264E,ac6868113c77b60955d3710264764e22129be89cdbf3501e1f4bec77256e5a2e +\u264F,eb990ac2aa036ddf2b87c1b856eb1057ae7dca42c0a943e44ba9ac71a813c62d +\u2650,41ad786891870838575180acd3b8230ffc1198e42642366cbc8f9b775ec333f0 +\u2651,2f3f6b281354983f93623846707680aed5e07ef138c32009800672aa777c233 +\u2652,f7a03a9ae85be8dfae02ed6f75bb3bccf1557c7d40efe0b6b344a00cf1957b70 +\u2653,18aa499fe3fcb5452989db7c177cc1ae5e4723e499f4a32e1b46af5bb2a53360 +\u2665,78432607e86b02ea3caaf9357066ca3f5e4edeef7be9edcbb5e45711c6557 +\u266A,8eb8bd18228493f0f139040f3bcef187abfa8217631d9e184f499bc6791878b1 \u2713,4312ca4632def5ffaf2eb0d9d7cc7b55a50c4e3920d90372aab140781f5dfbc4 \ No newline at end of file diff --git a/src/main/resources/fonts/jungle-planks.csv b/IF/src/main/resources/fonts/jungle-planks.csv similarity index 98% rename from src/main/resources/fonts/jungle-planks.csv rename to IF/src/main/resources/fonts/jungle-planks.csv index 59a71aa1..b0112e64 100644 --- a/src/main/resources/fonts/jungle-planks.csv +++ b/IF/src/main/resources/fonts/jungle-planks.csv @@ -1,118 +1,118 @@ -" ",302ea41daf42d5ba133570cbfb5b42a268d36f05c4855f99a80e841ad8cb0 -!,e869dc405a3155f281c16a3e8d9ff54afc1599153b4d9385c9b7bab88680f0 -"""",f8f62658bad72d251cd23f2a74857a4af4326cd1f8b88624783df49b434aeae -#,337eb299d332ac3cb160acfcf889d78639d580624dd03af4d3535958eb8fa1d5 -$,3fa773f2163b63490b03e17798480154dfd1f9cf7662d3ef9844f6de6b9f5238 -%,39144e83e5b92249bf4299b32ae1b7a515dd34cd2a13f13572f6da59785fb74a -&,7840dd522304d26da39e65b8e1469fec4d164c3aa4aaa562a61e3c7873228dd -',7ee6cafeb7fed10684688dd9cb94df46bde51fcd46c3e52bd74dec8c3f738 -(,249db41cb873e69dee73a9966de7b2b54b7359b15035761360161a8efe7 -),99c0c739995baff84d69d5b5374f45d67a3b9d8198ac166d64ae76b36fa596 -+,2b9f2d4e87a25db4b5ee2f2f1077d7edbec864d991d1fd2feeb08b7841e -",",76aa9898cb95e65576c38dd4a8677091c44740d38f9c574786704ce4b0a82d85 --,4dfae43225a687237f8b583930d9ec6819927ab9e2aaff5d1b2a63add19468b -.,48f2ca5c3458cbec586e47bf099d99e9eb7f4bd77734b9d54a6167f22defd -/,a2ab0d4b84297683a3e7c43ba62538bb03b672dcb44b2fa7122a459265949c1 -0,9c23aa43895719a66f161a75dfd2394062a30773fcb5ad9b691fe4fb5ff8cc -1,6a592a9fc3d99fd093a8c153838afd97c5b4ac6d6b5b519bd5bd99e6ab55aa -2,4ad99f7df6dd31597dc741893566bf7cac7ede38347965d60aeaa4ddcf2ee -3,cbe55d2842d6d924901fd7b4835b6487372e7ad66947c6a1d448ab2db8c670ec -4,242490f585761e4766ab3012ba854af57cf5b5a2ba8041a23bffe2616a95ee5e -5,695f554877d0c496e18bca89112b6ba0cbbe983590e080529282bacb1ce156d8 -6,654226866c8903f6a4259202ab5f5b59134dc3ef7b284563a4baabfca28a84e -7,556f1835dccc5af02179a02b8414501454bcd2deda8b7331572443c5cdcb5eb -8,5ef860a65257177ee7432d7365045f363815ca8466b4c5dd37ba8d1a827b4c -9,6311fb95c0a85ee0f3e16b427c513f37b7d78cd13f8afe0d5dd4f4f1415ed38 -:,d464e1acb23ee7935823da88cefa5a97ae72045fec0b71ccc1eebf5cc76b98 -;,15deec19c1f91727b130a4afcce345e4d376aff3fd6786f26dca9e8633d71 -=,ddbf8d80ae9d87bc248b88da6ad47df46bef24b6ef70d926bf807b4f0437 -?,b4d7cc4dca986a53f1d6b52aaf376dc6acc73b8b287f42dc8fef5808bb5d76 -[,c2d4f1857487d4deefdab3a72c31be74ba76233fa3d90add3d495ee48534511 -\,3a2fc657e7dabe13c897e7bce0596a819f97a7da2592c4ca42bf07b1447af0 -],47a5f444929272f7992c96dd513a678664c17f1823494ec0e8acaad817b8fa -_,a843877ff4b53e67d2e315b53c83fcaab72b1eb44925e6821c96738449154a1 -a,ab8e662b37df7c48ae2a4d4afccce41fb622852559695dbf11933a90c1e0 -b,bce8c3db761fc9b97912b8102f28391157a380ffe01716e475e6e86a559b6cba -c,c11f3a6b19a12e56a9fcdbbd708e84e2af3b4d6eb18dbd2b57059144b6d16 -d,b71ecb86952ac619811b387d7883f8445df45b9fd3f25dea54ade3f6cf7e107b -e,47e4309477d728b2602391a7c4736ad391cc49a8107b3cbedf88234d732823 -f,f9cd78202a1d9d48ae1086a46b3eabc286e323bc76f4b221ed8a629319e2f -g,1073645e84217e666f1482ee11453e09958e7ec4d2e8635f450c2aec8dc8cad -h,7387cfb45c3cb1f05c9c2f5e4ff872980a1744324179ffb3d762cc1c04f71 -i,ecc581e6b7b6ade94a7c2bf518182ae1315f5a59edd6a5cd2e066253aba1d27 -j,44d36b86667cd671a9a66479d39f3242e7937de12deb381cc29e2187e898f -k,4edffe3fbd583f1a73bc5b51f2c67c19be9b49f2e7aa6cce944376f28329bb -l,39c029a8d2e7b27a2a6a8dc87bed0840ce51b0e8a47f80e2fb563d014bd57 -m,95cc792a20d2857d8017b8124a592e782e9a2a8d7d1fec51f4762319ad89418e -n,693ae9198f561940796e39cfc526e1cf9ec67f48ec2cbc196c3f13e38133f94 -o,c7c150567eb1775d791d7bb64d27c7764bbb72d6611c7b66f6879225a0e12c -p,c92d116e6b6ea3a4a14282abbfbc992f2a63544fd744254b302b86b2fd6e -q,fc518ede2a2024934258f3b873f47768c5b12147858df612f66147d03d96d42 -r,1b8f58e61536857c99a270fb45dc7cd2775f57544d5cb14a2b39bd4a4a767 -s,27f088c92fb21e9832122bf22559c34991b74cc50d8479865b73af5e187678b -t,d725ffa2e98486d61214bf9d7169fa33e50b2f5786decbf3e235852ed779381 -u,8df72786af49cbdddd4f536bbcc16df6261d78884fc53d16c277e2f7361e2 -v,9d45829c70c1dd7f3d9dcfac4050f6a694806180153e14609da8502a56759ed5 -w,7379ebd67b7a9cb26d15a11fe9b8652136e413e86b89258ccc59afced11d177f -x,6f3e8b8f3d98e9322a5a5982efe022635db160a66697b1a11a6d2848a7e06e -y,7419d0551fdfc7be7b88191131165693c02630c51f61f581ecf76c1768431cb -z,155bdcd6b4aff66f221512bb22eb6176649259e6bc30ea5e431eb98aa6af26 -{,e2442148684b996de39b3f96b7f6cfab492785ddb94294d7d86b02306ce5ad -},99c0c739995baff84d69d5b5374f45d67a3b9d8198ac166d64ae76b36fa596 -\u00A1,2f681006eb15a11b022038884959a42f97602246669d612bb833bc88ad3ebe5e -\u00BF,586ff595ecf4ca78f5234d41f3852081ba487f5ccc2240990bb530d652d6500c -\u00E4,949bd69409911f7c2af0530905e3bce2d4f9016b0a0d1bc8ac67a6362fc67 -\u00EB,8a93b8380e7ce12a3a115736793db84411c3c722cdb2b4c2694cebca5da -\u00F1,4c7ebefeb50bfa61a9e94db6e8cce9bcaa3e94d07d1229a2a271abbda189edef -\u00F6,5dc791f0131437ebafd8e5f32bfc5341b9dc1ff4e1a6efd52b22c7948d8a4 -\u00FC,484bb5ba7af0d92931b9c4347bf563e719a9307152df9095c2d42f702deb5c53 -\u0431,d54f5f299951e6fa6a16d239ef49da24daaa88a95e39118fd54d8d75715655 -\u0433,90d66fdd70a71f634a3d6b84b2bf349e139a4ad6ca33cca8954a8e959f2862 -\u0434,2873ff20d19e5c72b441e86e9d4497db47953e581cc657e5d62e527da012a34f -\u0436,8b92522d8fa42b54fc15e8e6ff2605e7a3b532b841da6cf868d2cd5a55285 -\u0437,e0e279d0b85ab4a3ca12d5ad0536edfbe4eb397b59c4a7c698c622b9ae40 -\u0438,4cc97e7dac91cc9acd7efd188693fee924b67c7d24ed3c3210ec9b8dfcaba413 -\u0439,eb701658309a92a27193ddbf14f28e2bb9355b6af16aae795ed754b9ef6b2bd -\u043B,9ebf3c10477b152ca852f7bea0a0ffe0773b4e9ac73d897276115162e7c5277 -\u043F,68d2693512a627322e22f6967c08faf86e05ad424ce9548683e33cde77821 -\u0443,4a1a81c29cdba3aea287513ba266e125f47658de2d6b983bf1084a1867f76d -\u0444,18ec54cdbbf31f71a2646fb138736824a597ba1c952b5ac3880cdac921e9b -\u0446,4f42d48033c6be585af3b9bec7b817ede267bf9489ca7c4d6c7c6d5cedb73bd -\u0447,4d14f7a4af947c58beaed75401966abc3d37cb76e1f5fdb8c8bb5d6782f39f -\u0448,f911484d482113d8095bebed6a3a038d48822f27f1e5673e572674e875722d7 -\u0449,9b4faeee46ee6ec0ace347f989ed47efd2d98fa46a46736e1b82b3291271da37 -\u044A,bca8e3caf76774724e5e584dca4735af11a9f91d4655c3ba47292e675b0df4c -\u044B,eb1825675c198694f39e4ecfcaac723985c2117781579a42af8fb8f4d43cb1 -\u044C,c9331dac924c6c8f788aa8ca4c2e4231038f0ea6fd9abb850f4e8b927ccabe2 -\u044D,eed1c465268c2386f6e0675de7e9ace618e922a58fe9b7037f1fdb233a1b -\u044E,e3c118d1b49117b190afa330648c5aa9e9cf8a7186d036d555325118f4c3 -\u044F,841cc563f8b625341a654d49ddf2e1536f85f9fa774f7f8771a65d531ed8f17 -\u2190,3625902b389ed6c147574e422da8f8f361c8eb57e7631676a72777e7b1d -\u2191,88c0f37dec764d6e26b57aa8212572fbace5ee8f27f7b61c1fdaa47dd4c893 -\u2192,d4be8aeec11849697adc6fd1f189b16642dff19f2955c05deaba68c9dff1be -\u2193,751ced2e647366f8f3ad2dfe415cca85651bfaf9739a95cd57b6f21cba053 -\u2196,4be29ffd23de112641c81a633b3a4ea6a6f738ee682f3ec5e4cff6c8d9c -\u2197,84e86b621947b50b87232c14d5399540d35dc74097294890ce669428539b15 -\u2198,4c967f9348f2f61fe1d278d6def7e4efc5c79c8f5bb27874c6bf7befcc34f64 -\u2199,bb5de992f0d32a91ef6d2cf25bb083249d76dcc577aeb7abf9f5eacfc05c8760 -\u23E9,ee17aa8e6cce4b3611aab84c47fdaa1198e6be55c84c393a2f5f589c42c24b -\u23EA,e12276f379cef83c1b4ad5d0a9870143c7d28b2d8b79324a5319d51533970 -\u23F4,a63efab67ecd9a69eee7c02e1194895ef2c2fdc3caeb319afea91ab999e7a0e0 -\u23F5,ff61868eb3c6d0a1348f82d982276863859fb459daefaeb9bdcd641e22b5a1 -\u2640,a3935c020cf9e040139a1d54224d567b5404e0cace5664a7c1115f3cf9a764cd -\u2642,eadb33a85467ffb3b5474e8cd6c3d421f8569fb9cb17f2ab4fcddb8949fbb782 -\u2648,4ec0570edeae29f35ca710b4277ab0a0198cacbab871b671f3fe2b8e1fdd93f2 -\u2649,caf39ccd56d71f34c416025b66231c09653df6c6117fd442c72e869166e5ba9f -\u264A,1add8e2d301cdcbde5db8208654633fdce07a14217f5c4be037652a11933a374 -\u264B,9997d8b31e43edd13e1b6974d9d13fce87e81e511b4b0bb83b1fe953ae0306cd -\u264C,b9f0166cee1b822b0af61e63914e84dc1464ecc0c0c096fdb69fb75ab3d44af2 -\u264D,d714a349be84cd908aaaa7664c9e1a58a4e4c11a50de873bfc0777d7d94add5c -\u264E,74a3d5dbfba9ee70d3c07ba8ce5577bdb2c2531c8a543159707d2c885de17a87 -\u264F,71ea456019410ff80a9af121abd52b95a134cc97d79a21c92d9e8e66727f16d3 -\u2650,9c3058d71cbe395cdc3bca74f295c288215694d3da54ecac2221cfc2060e3471 -\u2651,c4236850f71bab74ff55c6b56bd1a104f6607fbbed88590a492497e035852e07 -\u2652,8d52924c8d12446e079a41b0d41a5412933c38ff2a974e379f97c41e607acf37 -\u2653,be7162a2c22cd7073c5685dd359284661d88859997fdbe49620e68cc9fa3bee3 -\u2665,f074131b47ecc51a6984ac8d687e7f73f9d2c47204b8c5fb53c1dccbf6 -\u266A,17fa6641d3af6c5c2a4a3621266c3cd1a86457193a741695d7865cd2603e47b8 +" ",302ea41daf42d5ba133570cbfb5b42a268d36f05c4855f99a80e841ad8cb0 +!,e869dc405a3155f281c16a3e8d9ff54afc1599153b4d9385c9b7bab88680f0 +"""",f8f62658bad72d251cd23f2a74857a4af4326cd1f8b88624783df49b434aeae +#,337eb299d332ac3cb160acfcf889d78639d580624dd03af4d3535958eb8fa1d5 +$,3fa773f2163b63490b03e17798480154dfd1f9cf7662d3ef9844f6de6b9f5238 +%,39144e83e5b92249bf4299b32ae1b7a515dd34cd2a13f13572f6da59785fb74a +&,7840dd522304d26da39e65b8e1469fec4d164c3aa4aaa562a61e3c7873228dd +',7ee6cafeb7fed10684688dd9cb94df46bde51fcd46c3e52bd74dec8c3f738 +(,249db41cb873e69dee73a9966de7b2b54b7359b15035761360161a8efe7 +),99c0c739995baff84d69d5b5374f45d67a3b9d8198ac166d64ae76b36fa596 ++,2b9f2d4e87a25db4b5ee2f2f1077d7edbec864d991d1fd2feeb08b7841e +",",76aa9898cb95e65576c38dd4a8677091c44740d38f9c574786704ce4b0a82d85 +-,4dfae43225a687237f8b583930d9ec6819927ab9e2aaff5d1b2a63add19468b +.,48f2ca5c3458cbec586e47bf099d99e9eb7f4bd77734b9d54a6167f22defd +/,a2ab0d4b84297683a3e7c43ba62538bb03b672dcb44b2fa7122a459265949c1 +0,9c23aa43895719a66f161a75dfd2394062a30773fcb5ad9b691fe4fb5ff8cc +1,6a592a9fc3d99fd093a8c153838afd97c5b4ac6d6b5b519bd5bd99e6ab55aa +2,4ad99f7df6dd31597dc741893566bf7cac7ede38347965d60aeaa4ddcf2ee +3,cbe55d2842d6d924901fd7b4835b6487372e7ad66947c6a1d448ab2db8c670ec +4,242490f585761e4766ab3012ba854af57cf5b5a2ba8041a23bffe2616a95ee5e +5,695f554877d0c496e18bca89112b6ba0cbbe983590e080529282bacb1ce156d8 +6,654226866c8903f6a4259202ab5f5b59134dc3ef7b284563a4baabfca28a84e +7,556f1835dccc5af02179a02b8414501454bcd2deda8b7331572443c5cdcb5eb +8,5ef860a65257177ee7432d7365045f363815ca8466b4c5dd37ba8d1a827b4c +9,6311fb95c0a85ee0f3e16b427c513f37b7d78cd13f8afe0d5dd4f4f1415ed38 +:,d464e1acb23ee7935823da88cefa5a97ae72045fec0b71ccc1eebf5cc76b98 +;,15deec19c1f91727b130a4afcce345e4d376aff3fd6786f26dca9e8633d71 +=,ddbf8d80ae9d87bc248b88da6ad47df46bef24b6ef70d926bf807b4f0437 +?,b4d7cc4dca986a53f1d6b52aaf376dc6acc73b8b287f42dc8fef5808bb5d76 +[,c2d4f1857487d4deefdab3a72c31be74ba76233fa3d90add3d495ee48534511 +\,3a2fc657e7dabe13c897e7bce0596a819f97a7da2592c4ca42bf07b1447af0 +],47a5f444929272f7992c96dd513a678664c17f1823494ec0e8acaad817b8fa +_,a843877ff4b53e67d2e315b53c83fcaab72b1eb44925e6821c96738449154a1 +a,ab8e662b37df7c48ae2a4d4afccce41fb622852559695dbf11933a90c1e0 +b,bce8c3db761fc9b97912b8102f28391157a380ffe01716e475e6e86a559b6cba +c,c11f3a6b19a12e56a9fcdbbd708e84e2af3b4d6eb18dbd2b57059144b6d16 +d,b71ecb86952ac619811b387d7883f8445df45b9fd3f25dea54ade3f6cf7e107b +e,47e4309477d728b2602391a7c4736ad391cc49a8107b3cbedf88234d732823 +f,f9cd78202a1d9d48ae1086a46b3eabc286e323bc76f4b221ed8a629319e2f +g,1073645e84217e666f1482ee11453e09958e7ec4d2e8635f450c2aec8dc8cad +h,7387cfb45c3cb1f05c9c2f5e4ff872980a1744324179ffb3d762cc1c04f71 +i,ecc581e6b7b6ade94a7c2bf518182ae1315f5a59edd6a5cd2e066253aba1d27 +j,44d36b86667cd671a9a66479d39f3242e7937de12deb381cc29e2187e898f +k,4edffe3fbd583f1a73bc5b51f2c67c19be9b49f2e7aa6cce944376f28329bb +l,39c029a8d2e7b27a2a6a8dc87bed0840ce51b0e8a47f80e2fb563d014bd57 +m,95cc792a20d2857d8017b8124a592e782e9a2a8d7d1fec51f4762319ad89418e +n,693ae9198f561940796e39cfc526e1cf9ec67f48ec2cbc196c3f13e38133f94 +o,c7c150567eb1775d791d7bb64d27c7764bbb72d6611c7b66f6879225a0e12c +p,c92d116e6b6ea3a4a14282abbfbc992f2a63544fd744254b302b86b2fd6e +q,fc518ede2a2024934258f3b873f47768c5b12147858df612f66147d03d96d42 +r,1b8f58e61536857c99a270fb45dc7cd2775f57544d5cb14a2b39bd4a4a767 +s,27f088c92fb21e9832122bf22559c34991b74cc50d8479865b73af5e187678b +t,d725ffa2e98486d61214bf9d7169fa33e50b2f5786decbf3e235852ed779381 +u,8df72786af49cbdddd4f536bbcc16df6261d78884fc53d16c277e2f7361e2 +v,9d45829c70c1dd7f3d9dcfac4050f6a694806180153e14609da8502a56759ed5 +w,7379ebd67b7a9cb26d15a11fe9b8652136e413e86b89258ccc59afced11d177f +x,6f3e8b8f3d98e9322a5a5982efe022635db160a66697b1a11a6d2848a7e06e +y,7419d0551fdfc7be7b88191131165693c02630c51f61f581ecf76c1768431cb +z,155bdcd6b4aff66f221512bb22eb6176649259e6bc30ea5e431eb98aa6af26 +{,e2442148684b996de39b3f96b7f6cfab492785ddb94294d7d86b02306ce5ad +},99c0c739995baff84d69d5b5374f45d67a3b9d8198ac166d64ae76b36fa596 +\u00A1,2f681006eb15a11b022038884959a42f97602246669d612bb833bc88ad3ebe5e +\u00BF,586ff595ecf4ca78f5234d41f3852081ba487f5ccc2240990bb530d652d6500c +\u00E4,949bd69409911f7c2af0530905e3bce2d4f9016b0a0d1bc8ac67a6362fc67 +\u00EB,8a93b8380e7ce12a3a115736793db84411c3c722cdb2b4c2694cebca5da +\u00F1,4c7ebefeb50bfa61a9e94db6e8cce9bcaa3e94d07d1229a2a271abbda189edef +\u00F6,5dc791f0131437ebafd8e5f32bfc5341b9dc1ff4e1a6efd52b22c7948d8a4 +\u00FC,484bb5ba7af0d92931b9c4347bf563e719a9307152df9095c2d42f702deb5c53 +\u0431,d54f5f299951e6fa6a16d239ef49da24daaa88a95e39118fd54d8d75715655 +\u0433,90d66fdd70a71f634a3d6b84b2bf349e139a4ad6ca33cca8954a8e959f2862 +\u0434,2873ff20d19e5c72b441e86e9d4497db47953e581cc657e5d62e527da012a34f +\u0436,8b92522d8fa42b54fc15e8e6ff2605e7a3b532b841da6cf868d2cd5a55285 +\u0437,e0e279d0b85ab4a3ca12d5ad0536edfbe4eb397b59c4a7c698c622b9ae40 +\u0438,4cc97e7dac91cc9acd7efd188693fee924b67c7d24ed3c3210ec9b8dfcaba413 +\u0439,eb701658309a92a27193ddbf14f28e2bb9355b6af16aae795ed754b9ef6b2bd +\u043B,9ebf3c10477b152ca852f7bea0a0ffe0773b4e9ac73d897276115162e7c5277 +\u043F,68d2693512a627322e22f6967c08faf86e05ad424ce9548683e33cde77821 +\u0443,4a1a81c29cdba3aea287513ba266e125f47658de2d6b983bf1084a1867f76d +\u0444,18ec54cdbbf31f71a2646fb138736824a597ba1c952b5ac3880cdac921e9b +\u0446,4f42d48033c6be585af3b9bec7b817ede267bf9489ca7c4d6c7c6d5cedb73bd +\u0447,4d14f7a4af947c58beaed75401966abc3d37cb76e1f5fdb8c8bb5d6782f39f +\u0448,f911484d482113d8095bebed6a3a038d48822f27f1e5673e572674e875722d7 +\u0449,9b4faeee46ee6ec0ace347f989ed47efd2d98fa46a46736e1b82b3291271da37 +\u044A,bca8e3caf76774724e5e584dca4735af11a9f91d4655c3ba47292e675b0df4c +\u044B,eb1825675c198694f39e4ecfcaac723985c2117781579a42af8fb8f4d43cb1 +\u044C,c9331dac924c6c8f788aa8ca4c2e4231038f0ea6fd9abb850f4e8b927ccabe2 +\u044D,eed1c465268c2386f6e0675de7e9ace618e922a58fe9b7037f1fdb233a1b +\u044E,e3c118d1b49117b190afa330648c5aa9e9cf8a7186d036d555325118f4c3 +\u044F,841cc563f8b625341a654d49ddf2e1536f85f9fa774f7f8771a65d531ed8f17 +\u2190,3625902b389ed6c147574e422da8f8f361c8eb57e7631676a72777e7b1d +\u2191,88c0f37dec764d6e26b57aa8212572fbace5ee8f27f7b61c1fdaa47dd4c893 +\u2192,d4be8aeec11849697adc6fd1f189b16642dff19f2955c05deaba68c9dff1be +\u2193,751ced2e647366f8f3ad2dfe415cca85651bfaf9739a95cd57b6f21cba053 +\u2196,4be29ffd23de112641c81a633b3a4ea6a6f738ee682f3ec5e4cff6c8d9c +\u2197,84e86b621947b50b87232c14d5399540d35dc74097294890ce669428539b15 +\u2198,4c967f9348f2f61fe1d278d6def7e4efc5c79c8f5bb27874c6bf7befcc34f64 +\u2199,bb5de992f0d32a91ef6d2cf25bb083249d76dcc577aeb7abf9f5eacfc05c8760 +\u23E9,ee17aa8e6cce4b3611aab84c47fdaa1198e6be55c84c393a2f5f589c42c24b +\u23EA,e12276f379cef83c1b4ad5d0a9870143c7d28b2d8b79324a5319d51533970 +\u23F4,a63efab67ecd9a69eee7c02e1194895ef2c2fdc3caeb319afea91ab999e7a0e0 +\u23F5,ff61868eb3c6d0a1348f82d982276863859fb459daefaeb9bdcd641e22b5a1 +\u2640,a3935c020cf9e040139a1d54224d567b5404e0cace5664a7c1115f3cf9a764cd +\u2642,eadb33a85467ffb3b5474e8cd6c3d421f8569fb9cb17f2ab4fcddb8949fbb782 +\u2648,4ec0570edeae29f35ca710b4277ab0a0198cacbab871b671f3fe2b8e1fdd93f2 +\u2649,caf39ccd56d71f34c416025b66231c09653df6c6117fd442c72e869166e5ba9f +\u264A,1add8e2d301cdcbde5db8208654633fdce07a14217f5c4be037652a11933a374 +\u264B,9997d8b31e43edd13e1b6974d9d13fce87e81e511b4b0bb83b1fe953ae0306cd +\u264C,b9f0166cee1b822b0af61e63914e84dc1464ecc0c0c096fdb69fb75ab3d44af2 +\u264D,d714a349be84cd908aaaa7664c9e1a58a4e4c11a50de873bfc0777d7d94add5c +\u264E,74a3d5dbfba9ee70d3c07ba8ce5577bdb2c2531c8a543159707d2c885de17a87 +\u264F,71ea456019410ff80a9af121abd52b95a134cc97d79a21c92d9e8e66727f16d3 +\u2650,9c3058d71cbe395cdc3bca74f295c288215694d3da54ecac2221cfc2060e3471 +\u2651,c4236850f71bab74ff55c6b56bd1a104f6607fbbed88590a492497e035852e07 +\u2652,8d52924c8d12446e079a41b0d41a5412933c38ff2a974e379f97c41e607acf37 +\u2653,be7162a2c22cd7073c5685dd359284661d88859997fdbe49620e68cc9fa3bee3 +\u2665,f074131b47ecc51a6984ac8d687e7f73f9d2c47204b8c5fb53c1dccbf6 +\u266A,17fa6641d3af6c5c2a4a3621266c3cd1a86457193a741695d7865cd2603e47b8 \u2713,89a8e8e80059c2b10b80d9196151ae392362b767e0192f5fcb7ae8b88e1d8efe \ No newline at end of file diff --git a/src/main/resources/fonts/letter-cube.csv b/IF/src/main/resources/fonts/letter-cube.csv similarity index 98% rename from src/main/resources/fonts/letter-cube.csv rename to IF/src/main/resources/fonts/letter-cube.csv index 47a15a6f..4422ba7a 100644 --- a/src/main/resources/fonts/letter-cube.csv +++ b/IF/src/main/resources/fonts/letter-cube.csv @@ -1,95 +1,95 @@ -" ",829b4370cc816b588462ae9dbe1eeb4a15ddbed3bb8e60495ba178a817f2974 -!,f4c5d7a67361bebc49f88c725513c3638ad557a12a865857c2422863132565 -"""",9369dd71916275ad3da6f5e855bd831d3ff2e2d63ac99cae29325cc734352 -#,3b2c06e388237efa14246423653ef129f6bdb7d8d98daa140d3595bceebe4 -%,7957f48b075e5865020b96ab7fcb221fe3f3b69485b38147570b7aa156537d -',30d98534d5a8935aabbc9d59e0c8bad88bd7dd72ae91f75e0dfed9ad6838eb7 -(,1dbb2596dcb9a56182b643655a23ce9259c36dfc3f28d2476e1b5bc880a3e0b2 -),8795a55e9741e9318dd8ff9a9fd9f287eda5c7ad81c6655f808afa2ee949abb -+,122a2a511cb29defbe785b8c22654f46fc825ba25286c3e88b3d86b15c9c -",",6e8c387d5b7f5d3997f88ec4a5fbceae25d28685ae2e176bbfe39748982ee1a --,19ae956fb8a2935275306839539897b55d5e337fdc655da7c40823d859a -.,f9c5fd68afa154364ce8eabd659fd4b8303f1a866bfbf32dda5a7fb01e2bbf -/,6b912e159418ec2bb9aab5e3406a32f5b0c8309977e17d91393674b875858e -0,b04fa5ecbcc843807977221a1bb4b523a23cf518090f2a682af52d33e9b064 -1,d837a6d222013db4f13bd9049b1d6ef1592508dda7057420b954726375ade1 -2,e37b9d1d275e3e1e6f2adbe5a78389d26efed0bc2fdaebc27538a112a4acc77 -3,bf7d31383a80838d79a8745a495d1f67d3766a2622cb5f3db4ac3992f7f415 -4,b9ba8029b28254b6aef5397333138fa5d0abbf4c7dea9e667daed85873f45 -5,d246ac67620d3b5217c49d9c30173a3793d4d41f4f251c9f6232eec75a74 -6,16b7eb957bca6678cd0b63d84ea7bf28bf67eb8ab3f8f65beb461e236f429a -7,548782887434121a7cffd543d827282f73728851c4e3137dc3637f82b373a -8,bbf9a2e71692aa85d064baf06227fc1e5931a6827f3a6f7b7e38c279f5e75084 -9,36d6161c6f04def6481e03b4c2972798816ddc514aef4b11c2d7a5a8fc9fe -:,b2f788d00a51bd8d1a1b34bda73ed37d1673fe65a2cca538464d3924bc4f70 -;,86dbbd41b945754b132325a89942d7d42a2fa339e41239b59c52916492fb6d -=,208cd4597484656f69dd8773d528d5b4fd0d85c354bbf14228d4a6b23e4775 -?,19d9ea25428e534853d695039030a0a48b41481f7c9abc0a0c17c908f9792 -[,8c792feb28276496895f4d22b2fb76a9b18b67afd7d1c3e25cb542e4f74ee -\,3273a2cbb1dee5c22b64aa551e1bc105b3f819287d3567e697932be4f89d -],6b1ca395c695cc46824d2e211ed3f789d81183d4d21e9f3ad3b14e011709d1b -_,d5e5747bf4ddc56e2ab0c4952c31c97f37be6a654318bd184ed122e6c735d4d -a,bc35e72022e2249c9a13e5ed8a4583717a626026773f5416440d573a938c93 -b,5170bbc7943ac877cd93e937f0983c34409c28588c17f5fd68c21fffe088ce6b -c,4e32f4a4c36a21a83589132e599e7cc46af76f5d0d3efc92da3e0cbfe8dc7 -d,c772e4d7f699da64349f66511c265a6d3e206f9eca427eab3aed217dc2f0a0d -e,3d6bb8599617a11b4bfc2aa55786ea737ea445837bcea78294e5dca7138a667 -f,19592cad924d70a1f4af2738d4922e1abdc487dff68c0727d37ed9b2ab64071 -g,a1bfee8010c680a961bc83a25a54a5865b244b6d1cb7dc75b6219a93555296 -h,d034433d40351e954128e836f22d9bbf67ac13adfc7d652f63a42a7d788af1d -i,a37ca0d6d56fb3f39e7da1c015dd39f1ddfc45722697e78f8a1a62eb2b1ff -j,b81d2c1a5a59b575359482a8a33854cd3b1634dd54c45c4ca1ca10e8607d47 -k,80b13c71666287c5989d85101db7c6550e2e07076db52a7bbbbbddb8493129 -l,1bf072e296fdc8da3e04c563a3774d2ddbf3f86d36a2867d53e3ccd1c9d41 -m,ad75fed3649f87a48e51169b57dcce6d4a8dc97db418f22d60d96c2a62b3e -n,20a0b83be8c981cc9c87f3f9cae455de3a7b1684b0cc5e507b237e0438614 -o,dff363cb9f20b3e4810932c33b715ef97c1cc7df61c838719b5f72201381e8 -p,345b2edd9ec69a350a867db0e5b0b87551aff498a88e01e2bd6a036ff4d39 -q,98217837a63e74e24bafd6c7c500d3678a6838ed86215a79f16d4962701f3a -r,faca4d695e4e7f47fad58cf371c2c0e213fb3d10232611d73d075374c8980 -s,b946af388a41a13425d1f82da9bd12b6f965bc70a9b3f84e45d60d61731cd68 -t,12257a935f431bee585afd6c2f7fce46e1d9f5c68a5db80d56739aa2932a26c -u,410f3cced22d69124df895e928155a0788c1f4d5b7b82a3c2ca9a436de4ae -v,453da4cc842103c2051277878f4a52ed4c39a92f4bd644e8573f356f46baca -w,ff94cfc7bf49e47b448ccd5f8d6dfcf4070ee44e73c48d4b424cf1a2d3145 -x,7a254fc044efb84cd576a6c8f1144f83acdb14991232060ab486691a09b -y,96e2ef44a9a1bf52ebccbe3183f99ebd1bafbb24f2d555dfe8fbd2a310498745 -z,10adf5c297433ff1fe1221521d9ea6219163270726d881943882247293323 -{,4985d78defe7759cfa57554662588e11ea2dba2f090f375bb3f798d15 -},d1ce1071d9a543f117b8745a36b827c7f21222ae8f19df75b431f4df9bbc31 -\u00E4,73d4aa6e887bf9f62ef8bfcac65ba19f0deea496849add9aaa63963e2ac8456 -\u00EB,b4c41e5a5da5908dcbc33c481e798c215eeae26ecd62c8e57e135b6f2e8b1d6a -\u00F1,29079f7ba39c42ec142c752e8bb4a5105d1c79181b84e6ecf47a6cb2c4101565 -\u00F6,47edae25dd464585b27fc593124a26e4a855846e606245407ae5d1bd2a1a1a -\u00FC,97dd8be7d414bfc37e8396ed79aed0c525dc2eddaaa8d9bb9d492137a5966b4 -\u0431,55ebb091d929d0eaa43fcee41d9e0e13970e5b453c6e145b6c556e86b684972 -\u0433,b11369269697350ec92547d2544509aed3a7da752e172d942eb652a6328df98 -\u0434,39128457c21f42b284eecf68ecff885b2f95bfbc19c121178cd51242c5cd9 -\u0436,33269d43dc1a4823b58d3f6b987f8764ca433d0136962e799f4a26337581b7c -\u0437,c428fd2020a390ff99b94b5c45a057b5599e1bfc99ecd994c1c2e847fef6eb4 -\u0438,9bc6e79e1d1f76fb93df53e326fe9aa87f5a85c5dc6d2fa4196cbd3111b9cc2f -\u0439,695117cf886b629f1826e27c7658dd4ac8e5b965afc77d5a86daaf62d1f2f2 -\u043B,644df8a8da7a1354872bdd8f8a9647e9722a6449fbf47c17b2a5fc36eada54 -\u043F,eef373e308519b45cb152e2e883ecd13e96cc4f62b40561a6713c2e2c6e62 -\u0443,af8ea8a75674791ec6f037ab50a4b83f4eba33533e944aed57c23ec53d73e5 -\u0444,ccefe97acd1626664056aadc75cd235967c8395313ecac3b18630717b174 -\u0446,92b3dc36a8223b89665f642d8a45279b91e5ec5dafa5c0245f9a32ae2f6b8 -\u0447,35bd35edde8c29ca4a414b71e55c86c4494788988edc7c4dbdc7158867fe -\u0448,2c38e2c5a9220907561ac31f1e486b9a51ef42692a9d5a1ffb34a166d99a -\u0449,9b6ecf5648abf719fd1242fab6e129037cbafce89d9ea39f941acf03fd5228d -\u044A,c9ac6350f846d437db84d1e184426ec7fd86ef5f18e583374f6364d5ea13684 -\u044B,77a49f826a7e91d93da080a388c35af5743dcf92ec3a5664144a6a7a122044 -\u044C,8c9b6e146f7bf716a376ad91fd6b9ddf524bbb3ee68398f7d57433b7ba761 -\u044D,46e6d1f93fe3aed0bcacdda136a4f910f2ac243c5686e8511a1e271c64e621 -\u044E,7ecc18e794e848c26a4eb9231ad2854733e15db5bacc8bdafdbcd239bc569db -\u044F,7a50f5f3131bab0fa7c7d4c25fa6d14ad2b584491c52e958394ff3c926319 -\u2190,841dd127595a25c2439c5db31ccb4914507ae164921aafec2b979aad1cfe7 -\u2191,8f2ed4ef358bf9252ea73a6b0f4e868b27feebcae603ee5e5d0982b6d9e6690 -\u2192,d2d0313b6680141286396e71c361e5962a39baf596d7e54771775d5fa3d -\u2193,25ab271f77917745d2b5484b7ca42e52316e17de4f011b04a4f8a865ec56de7 -\u2196,6817626295c3b24af35548824ea351a54b8a1ccbd2e4b8894adc4439dcb336 -\u2197,9f9ba67b451994778c8ae4491bd361f16ff555c16b1992c16563c9118cacc2f -\u2198,46abe83a3aaa8fe98e7cfce3367bc35b40abca26a188dea52a1c1b79c19759 -\u2199,c24621c536b3f354888f958e5eb9d0c784a11ca5e12da2e029b2835f8d4a692 -\u2665,ac26fb89b8c6f691332637d2443f90e8c3353450bf385c599a16726dcfd9 +" ",829b4370cc816b588462ae9dbe1eeb4a15ddbed3bb8e60495ba178a817f2974 +!,f4c5d7a67361bebc49f88c725513c3638ad557a12a865857c2422863132565 +"""",9369dd71916275ad3da6f5e855bd831d3ff2e2d63ac99cae29325cc734352 +#,3b2c06e388237efa14246423653ef129f6bdb7d8d98daa140d3595bceebe4 +%,7957f48b075e5865020b96ab7fcb221fe3f3b69485b38147570b7aa156537d +',30d98534d5a8935aabbc9d59e0c8bad88bd7dd72ae91f75e0dfed9ad6838eb7 +(,1dbb2596dcb9a56182b643655a23ce9259c36dfc3f28d2476e1b5bc880a3e0b2 +),8795a55e9741e9318dd8ff9a9fd9f287eda5c7ad81c6655f808afa2ee949abb ++,122a2a511cb29defbe785b8c22654f46fc825ba25286c3e88b3d86b15c9c +",",6e8c387d5b7f5d3997f88ec4a5fbceae25d28685ae2e176bbfe39748982ee1a +-,19ae956fb8a2935275306839539897b55d5e337fdc655da7c40823d859a +.,f9c5fd68afa154364ce8eabd659fd4b8303f1a866bfbf32dda5a7fb01e2bbf +/,6b912e159418ec2bb9aab5e3406a32f5b0c8309977e17d91393674b875858e +0,b04fa5ecbcc843807977221a1bb4b523a23cf518090f2a682af52d33e9b064 +1,d837a6d222013db4f13bd9049b1d6ef1592508dda7057420b954726375ade1 +2,e37b9d1d275e3e1e6f2adbe5a78389d26efed0bc2fdaebc27538a112a4acc77 +3,bf7d31383a80838d79a8745a495d1f67d3766a2622cb5f3db4ac3992f7f415 +4,b9ba8029b28254b6aef5397333138fa5d0abbf4c7dea9e667daed85873f45 +5,d246ac67620d3b5217c49d9c30173a3793d4d41f4f251c9f6232eec75a74 +6,16b7eb957bca6678cd0b63d84ea7bf28bf67eb8ab3f8f65beb461e236f429a +7,548782887434121a7cffd543d827282f73728851c4e3137dc3637f82b373a +8,bbf9a2e71692aa85d064baf06227fc1e5931a6827f3a6f7b7e38c279f5e75084 +9,36d6161c6f04def6481e03b4c2972798816ddc514aef4b11c2d7a5a8fc9fe +:,b2f788d00a51bd8d1a1b34bda73ed37d1673fe65a2cca538464d3924bc4f70 +;,86dbbd41b945754b132325a89942d7d42a2fa339e41239b59c52916492fb6d +=,208cd4597484656f69dd8773d528d5b4fd0d85c354bbf14228d4a6b23e4775 +?,19d9ea25428e534853d695039030a0a48b41481f7c9abc0a0c17c908f9792 +[,8c792feb28276496895f4d22b2fb76a9b18b67afd7d1c3e25cb542e4f74ee +\,3273a2cbb1dee5c22b64aa551e1bc105b3f819287d3567e697932be4f89d +],6b1ca395c695cc46824d2e211ed3f789d81183d4d21e9f3ad3b14e011709d1b +_,d5e5747bf4ddc56e2ab0c4952c31c97f37be6a654318bd184ed122e6c735d4d +a,bc35e72022e2249c9a13e5ed8a4583717a626026773f5416440d573a938c93 +b,5170bbc7943ac877cd93e937f0983c34409c28588c17f5fd68c21fffe088ce6b +c,4e32f4a4c36a21a83589132e599e7cc46af76f5d0d3efc92da3e0cbfe8dc7 +d,c772e4d7f699da64349f66511c265a6d3e206f9eca427eab3aed217dc2f0a0d +e,3d6bb8599617a11b4bfc2aa55786ea737ea445837bcea78294e5dca7138a667 +f,19592cad924d70a1f4af2738d4922e1abdc487dff68c0727d37ed9b2ab64071 +g,a1bfee8010c680a961bc83a25a54a5865b244b6d1cb7dc75b6219a93555296 +h,d034433d40351e954128e836f22d9bbf67ac13adfc7d652f63a42a7d788af1d +i,a37ca0d6d56fb3f39e7da1c015dd39f1ddfc45722697e78f8a1a62eb2b1ff +j,b81d2c1a5a59b575359482a8a33854cd3b1634dd54c45c4ca1ca10e8607d47 +k,80b13c71666287c5989d85101db7c6550e2e07076db52a7bbbbbddb8493129 +l,1bf072e296fdc8da3e04c563a3774d2ddbf3f86d36a2867d53e3ccd1c9d41 +m,ad75fed3649f87a48e51169b57dcce6d4a8dc97db418f22d60d96c2a62b3e +n,20a0b83be8c981cc9c87f3f9cae455de3a7b1684b0cc5e507b237e0438614 +o,dff363cb9f20b3e4810932c33b715ef97c1cc7df61c838719b5f72201381e8 +p,345b2edd9ec69a350a867db0e5b0b87551aff498a88e01e2bd6a036ff4d39 +q,98217837a63e74e24bafd6c7c500d3678a6838ed86215a79f16d4962701f3a +r,faca4d695e4e7f47fad58cf371c2c0e213fb3d10232611d73d075374c8980 +s,b946af388a41a13425d1f82da9bd12b6f965bc70a9b3f84e45d60d61731cd68 +t,12257a935f431bee585afd6c2f7fce46e1d9f5c68a5db80d56739aa2932a26c +u,410f3cced22d69124df895e928155a0788c1f4d5b7b82a3c2ca9a436de4ae +v,453da4cc842103c2051277878f4a52ed4c39a92f4bd644e8573f356f46baca +w,ff94cfc7bf49e47b448ccd5f8d6dfcf4070ee44e73c48d4b424cf1a2d3145 +x,7a254fc044efb84cd576a6c8f1144f83acdb14991232060ab486691a09b +y,96e2ef44a9a1bf52ebccbe3183f99ebd1bafbb24f2d555dfe8fbd2a310498745 +z,10adf5c297433ff1fe1221521d9ea6219163270726d881943882247293323 +{,4985d78defe7759cfa57554662588e11ea2dba2f090f375bb3f798d15 +},d1ce1071d9a543f117b8745a36b827c7f21222ae8f19df75b431f4df9bbc31 +\u00E4,73d4aa6e887bf9f62ef8bfcac65ba19f0deea496849add9aaa63963e2ac8456 +\u00EB,b4c41e5a5da5908dcbc33c481e798c215eeae26ecd62c8e57e135b6f2e8b1d6a +\u00F1,29079f7ba39c42ec142c752e8bb4a5105d1c79181b84e6ecf47a6cb2c4101565 +\u00F6,47edae25dd464585b27fc593124a26e4a855846e606245407ae5d1bd2a1a1a +\u00FC,97dd8be7d414bfc37e8396ed79aed0c525dc2eddaaa8d9bb9d492137a5966b4 +\u0431,55ebb091d929d0eaa43fcee41d9e0e13970e5b453c6e145b6c556e86b684972 +\u0433,b11369269697350ec92547d2544509aed3a7da752e172d942eb652a6328df98 +\u0434,39128457c21f42b284eecf68ecff885b2f95bfbc19c121178cd51242c5cd9 +\u0436,33269d43dc1a4823b58d3f6b987f8764ca433d0136962e799f4a26337581b7c +\u0437,c428fd2020a390ff99b94b5c45a057b5599e1bfc99ecd994c1c2e847fef6eb4 +\u0438,9bc6e79e1d1f76fb93df53e326fe9aa87f5a85c5dc6d2fa4196cbd3111b9cc2f +\u0439,695117cf886b629f1826e27c7658dd4ac8e5b965afc77d5a86daaf62d1f2f2 +\u043B,644df8a8da7a1354872bdd8f8a9647e9722a6449fbf47c17b2a5fc36eada54 +\u043F,eef373e308519b45cb152e2e883ecd13e96cc4f62b40561a6713c2e2c6e62 +\u0443,af8ea8a75674791ec6f037ab50a4b83f4eba33533e944aed57c23ec53d73e5 +\u0444,ccefe97acd1626664056aadc75cd235967c8395313ecac3b18630717b174 +\u0446,92b3dc36a8223b89665f642d8a45279b91e5ec5dafa5c0245f9a32ae2f6b8 +\u0447,35bd35edde8c29ca4a414b71e55c86c4494788988edc7c4dbdc7158867fe +\u0448,2c38e2c5a9220907561ac31f1e486b9a51ef42692a9d5a1ffb34a166d99a +\u0449,9b6ecf5648abf719fd1242fab6e129037cbafce89d9ea39f941acf03fd5228d +\u044A,c9ac6350f846d437db84d1e184426ec7fd86ef5f18e583374f6364d5ea13684 +\u044B,77a49f826a7e91d93da080a388c35af5743dcf92ec3a5664144a6a7a122044 +\u044C,8c9b6e146f7bf716a376ad91fd6b9ddf524bbb3ee68398f7d57433b7ba761 +\u044D,46e6d1f93fe3aed0bcacdda136a4f910f2ac243c5686e8511a1e271c64e621 +\u044E,7ecc18e794e848c26a4eb9231ad2854733e15db5bacc8bdafdbcd239bc569db +\u044F,7a50f5f3131bab0fa7c7d4c25fa6d14ad2b584491c52e958394ff3c926319 +\u2190,841dd127595a25c2439c5db31ccb4914507ae164921aafec2b979aad1cfe7 +\u2191,8f2ed4ef358bf9252ea73a6b0f4e868b27feebcae603ee5e5d0982b6d9e6690 +\u2192,d2d0313b6680141286396e71c361e5962a39baf596d7e54771775d5fa3d +\u2193,25ab271f77917745d2b5484b7ca42e52316e17de4f011b04a4f8a865ec56de7 +\u2196,6817626295c3b24af35548824ea351a54b8a1ccbd2e4b8894adc4439dcb336 +\u2197,9f9ba67b451994778c8ae4491bd361f16ff555c16b1992c16563c9118cacc2f +\u2198,46abe83a3aaa8fe98e7cfce3367bc35b40abca26a188dea52a1c1b79c19759 +\u2199,c24621c536b3f354888f958e5eb9d0c784a11ca5e12da2e029b2835f8d4a692 +\u2665,ac26fb89b8c6f691332637d2443f90e8c3353450bf385c599a16726dcfd9 \u2713,b5a3b49beec3ab23ae0b60dab56e9cc8fa16769a25830b5d8d6c46378f54430 \ No newline at end of file diff --git a/src/main/resources/fonts/light-blue.csv b/IF/src/main/resources/fonts/light-blue.csv similarity index 98% rename from src/main/resources/fonts/light-blue.csv rename to IF/src/main/resources/fonts/light-blue.csv index e49766de..274d88bb 100644 --- a/src/main/resources/fonts/light-blue.csv +++ b/IF/src/main/resources/fonts/light-blue.csv @@ -1,118 +1,118 @@ -" ",fe21c9372ebb9e236f6d90c4afcd47b85a3fe55b53afd49224be9c8635b67e6 -!,83e279656bd74b681597fb443d19d4a220f350d66ba04f826dcc89ae125cd8 -"""",d9f887f4175fd60988a2af688aac496451a31bc9db393b271ae58766958a1 -#,a8a7c6556b1503b66ab3e509a12b54617f7c735b971e9b817e96776e0554b -$,7328d6d214da405b3482af4b2470bd53353cd94231f3c23a3211d98983332d5 -%,a0ca37bd87d2e543254389bef26fd1acaeb52b3533a78d87b8af75fbf61d188 -&,6fbf3a3de010de6bc55e5ef5f1f9f30cf6e5d0624a33c8f3153bd4344ab44 -',f8b48c3762378d43d3b72c3135986f559ad5296e109afed91c311554d5242d -(,f1221c95235be5f8d9727469063d4d3762a6116eceaeae5f72dbfc739ab81 -),8356ffbd7fd813cf59be216b3189f8b131bd75607387235fa83a5a902b86b -+,bd86db9a14d5879fa2811d301ccbd526994f871247b62f2d9a48183e9641ad69 -",",88f88073398b8ccc929aa46ec06d86c8eda16f716bad4326986e793df97cf2b --,10c34d5e85cf3aa31641993445fad6f5f1e01098e75caa56d9ae754026ca69 -.,bbdadc21773e9dd9914ce71d172aecb7cbed723aa8efbfd16b157dfc404c92bf -/,2ee3889a45729c6628483a71db4e1de2a5301ceff8dd76725543b225ed44a6 -0,6cf4c58b50a537b45ce7d511fdb2642e50ea36c2f9ef30dba8d63e35c542d59 -1,aebd85b7f9e6222b395451adb46b76a62f7e95da6fbf7efe715c783455140 -2,502eba83a6a953917f1d991bb379b36e7ff04a496d17f5424d04aa12efbab -3,e1ff52d15e7a7758b03c6fa861acbce93ae5662f7578261540b392de4157b29 -4,884b63d848dcbcf061e642f697b46d599a942e36e785347efec9534cc76d8a66 -5,9d3c54e9f12cd98449ddda0689bec179bd58e34fcf91d85809a9f96c68fe -6,3984b925c3cc38cfacafba753ebd1a39ea63f927310aee380e270fe2c2818 -7,2f9b635624136e418a636b6bf28e59d17f713763f82daf453676704be0e46581 -8,cc4856d4fe5a99c7235375d3b359eb191426843555e6da488e9fd5f837be55a -9,65871dd8827ea74896c712f3826efd806fd1f49d14926d0635a3be6b9cf3b -:,66d77c8f9b9f4d8e241003553bb760bd94f0711bee5aa241effafa3bba28f -;,cae77a95c08bc23dc3a21d4344f9816c44ff8f8aa7acb3e967ff2e1e441367b4 -=,5aa02088761cdb94b195269fc359be3afd8e8f4b389f7a0d7396b8a722f1e6f -?,c35ba393b8610b63ebee4c13c8358bc6c94a9dedc8e4d7d36b922257e65e8 -[,cb0a0ab60596648bd8293592699c138ffc0f97529618fc370886181cba6f63a -\,ae4409e45f019f6cddf3fc4d8b92a91d5c2af35e6ce9188b088f560d627 -],9fab62fee2e44e3a2dcf199fe2227ba6cf6cd3cd7da4c3df430bbaacfc8d6 -_,d13332c8672cafe6597c91cbefa7133ddb855ccf75f63df342158ead23ee89 -a,e48fe4a0cc5437364036adc1dfe2663c83ef8c6db86480525730c7957ccf3554 -b,fb7ef4d4f03e881938fc12bb69cbeb97533da528d4e340b856dd2f6bace4b45e -c,0b7a67087da884a25fc547ee1ba3d9bdcbf726bda6deb7744c6c52c264a -d,5b3a7fa89aa12a6576dfad1abd96f3a3627a42bedc8e333e5f47c11e4847eac -e,872967c93a91792dd116f0e4959ae18b163d70713eae548db9fa5edb55d459 -f,301c1e29bab272479c526f218f051586c22f29dc0928b6ca98ae14a3e07ad9 -g,78a3324c77fdccd597774304bbda15517ea2359de53897aed09528d1c6ec9 -h,4999f4afc0428e5d95651dc626ac3e2094d246bdd7f85fc6d7dd39ae9d2d19f2 -i,4e78708f252fbea16fd2539fe1ded81b865ff39124cdbb793ced3d99171b840 -j,b34d469e765187fe6120e4b1123fa7ea2a5736b60f0795cb79e16a9201b191c -k,1a9517849b5f29f9f13d2c5343bbaddac4db7876aef4fe352064becd5c7d6a6a -l,5336f6715fd60dd836f28e523c34345a454207ee4184d5b3dd4ce5293071c1 -m,47ad48f18cad99e06dfa4e59f7e486864f974daa985f6d6e657032b23eafca7 -n,8d9bd17d5399de9493d4d145d61c56afee7980466a7df5a78629fd8668abdb -o,7fdc65a62a2d7a117bdbf5cdd41994895b4a38ba91c1c71a3e7e583883fef4 -p,356c9635d734885ec5c3f2010868631aacaf45e4b47d7128a732a081f58ff3 -q,d44b36818fd3ce131892aff4cdfbbb78ae8348e1c6a8baa1d3c266ab98e6e52 -r,8d17b0e48c1dee2736269ebcbfa76028751aab101c9fa1c60256dd25c3241 -s,6795b66157b5d1e0757331d88976fcb6309de8d01b51e479b390b64e6fe552 -t,9fc32c914276f686141796a5a023c39efdfed14d3d7c9c42792513846f7fa4b3 -u,ceeb6fd733dc88711aacda43b42367fe513a7d743f308dd63318eb118c -v,1b419016dcd5256f464e36256d69c823890b923d1da4b8d45b0584cf3fa -w,ab21415f1ce6db677cad39c33b57d68dd8356c71be55cbc5e87a36b622a841f -x,fc68a342df6c9e711ec3bc138f91cdb1b0fa5e72f66e4251875d8bedd0553eb5 -y,7af28363be8175ba81f2a2dfc0b9d2855d0b7244a4dfda9fc795a62d68dfa69 -z,2a94faca32c55efc3d1988d8d4296fbba73b23287cc17cb92b5c45b9ca -{,bbd92f6957c23409b3592ef83249bc8c3872fbcf5516fda82b971efdf1c -},e7e16a29e4cd1bf9c9f44a89f70ed8150ddbb54488536fefe93fb4267b26a1 -\u00A1,f59eaaf0107a3ca8ad55780bf68bc8fd1cd9c28b095d6d97fc066ba2043c175a -\u00BF,496d1e3a56c75031ae0694bb2d8119ca516ff692889940df5d79af940e94ba3 -\u00E4,d7f0c3ed22a8f4a6d9388af6d13e08ebbc85a3730be5db45d3aef3d9fe3ba4f -\u00EB,e887fa2dffa7a8fc7d725b9e14723fabbc252263ab8de47ccd28611db786 -\u00F1,907c949c2cd0312f724e0572dbbe2dcb2642e3053304fa8506f6a25747f53ef6 -\u00F6,3cc3603e5a4b692dc07951e8270c976f5d0c8bff1d8cc9995cf32f1a64921b -\u00FC,c7b6abc56173b1e25085704016c6365d736e93ea18f58358c999eb14e430cd -\u0431,e348250781ff28f5d33d6f2b3dcae36f129eba91bd8d11217607881d23df -\u0433,b8e59849c1a45e229a29e1285e59b4fb1625bc92e475e7d05e8c10f3d52fdd -\u0434,7968196fbd4a0ff93a2a910851fd3ddba7965fd47f359254a42679ef418e -\u0436,fcfbd95b1b74ca16ffaafb9bffbf2e6efdfb881613d17d5bec33c9d6fa3462 -\u0437,d3512baf29f0321f953c70ac7df9f09c3633f43ebf768031ead65116262c86 -\u0438,cfd95c5a9e17ef73c0fc12f77068dec96628cb81a6754c6608df81d90645a -\u0439,24c8a5c5cd6360d0f48357a9aabb54923ffb279a2f856a75a7d5613aeefbd0 -\u043B,1d5278dc93d3eaf3867f7ee849d6ac2af6bb02e6450d7d9a2a298e6a1491352 -\u043F,3950cc6754863d8adb45f4d6725e17f5ce14b8b73ad4ff882f2381bd3492e956 -\u0443,972fd690b7aad0681bed2db7c5d86b78f82706d1517e2db983900a8a9aa51 -\u0444,34b3776fb1c31f3559c5cfedf18ac9b8d3c7d9d9044d479d2c372f3dbb4a -\u0446,5e3f7eeeba6c7eef0bbd2114a330ffbb21e475124296661361dcbc467d7b8a -\u0447,f5efdfeb752f2111c3dddeb322974b23a9702bdb35ebdf3ead83e4043bed1d -\u0448,71bd3134b78aa0569ae5f446a0fed11bc3348c68e9cfebce301b1944c240c6 -\u0449,3579881787b735b9efc4e98dae816c7428ca75040d2ae6b918b93b6faa4d2 -\u044A,a52dc3372854fdd8abd2bdb84ba3926d0c325f495f50401bd6eb2319eaad3 -\u044B,e126c7aeb5ae9daa580b79b89d5f9574c3c869e33facaa9a84d2e3da29551b -\u044C,f8b2720433fad38dda1ffbe77314eed16f52c13623f10fe76c78b1dd729465 -\u044D,c7c54d596e37df1cb97f8ce89ddbb2d8bd901cdd685233f55a2f4fdedd36e3 -\u044E,5b5691855c7b8c26c9e15a2e36cf46613bb7abd91654f42cc8957704ef9653f -\u044F,7934821f1a7384a2e96bce6a7c722dea97e333f4ed626c50fe21e0ac1c543975 -\u2190,93971124be89ac7dc9c929fe9b6efa7a07ce37ce1da2df691bf8663467477c7 -\u2191,f4628ace7c3afc61a476dc144893aaa642ba976d952b51ece26abafb896b8 -\u2192,2671c4c04337c38a5c7f31a5c751f991e96c03df730cdbee99320655c19d -\u2193,2ae425c5ba9f3c2962b38178cbc23172a6c6215a11accb92774a4716e96cada -\u2196,f2c39651d877bba2c47b13904f3c99b08967386f27f689f256fa299fc0cc -\u2197,298c77373229d28833c59849744554f9bf62a7bef785e5b618ea732aad3c834 -\u2198,229036a061a6bc98315b0daca7edf4cf0e33e6f95e877bfc36dc786614c2c8 -\u2199,42246c8abe7f3732cef758379353a28815a9c3707b321295731e2215abaf6faf -\u23E9,7472d245b2a8ab25bd4b9d32601d4aba2c53181ad2bde62c8ed71f8cae99543 -\u23EA,b4137232ab1911994481a72996b84bced8fa92821e4f763f13a23c8703cea -\u23F4,91459cfc44cc51ddf27988596d2de8ac8556e93d7946219cf64c90c8c05fca -\u23F5,63fabc3891c962c913959d65be90daa5de1211fa4087dae386ff4ed4248f -\u2640,32e52fe660c1d756099f4f349f288470684cf2404efb9c23c0578489d4f3d5aa -\u2642,e7fe6e2316ca384e0c85261b14fc066e231d6127e540dfeddb8b54d911b82831 -\u2648,d6d2a8d0fe60faa541941ff8eae6c6a86be31c7f12ae888dd45a43d7000c6acd -\u2649,c8325ea16d09ab4babc75c086ec5044d6d3c3ee78c4ac07973741ef3dec0e4eb -\u264A,8af4550654b052dc367549c0b0dc25b3b88214930197126500b5dc532fbe7c67 -\u264B,947396fae95556816ee31aba843d80d7ab2cfdbdb5d17247c9fc82584b411865 -\u264C,312a475d3a37a3c6f95822ff54d45ced7fdb4e5b132145dc6c45f981c76426f0 -\u264D,b3b8761d60bf018562c00e4161c6a74166ce464863ae4baa734b1b3fe9141c1 -\u264E,9ef0ac8ed075f6bba261e39af76e9f03b3f21c87ed01bf9f8dfb924f4929682c -\u264F,5418a8d1c1a3d325a22c9da5ccdb17958f2e50f072d672545b7faece14d9cd1f -\u2650,a6163fc0c45f45130c1c480bda0361af034648b0e9e75f0501fda0b5c236876e -\u2651,5e7d7c029be087c44fadc398e6001830bab0ba8498e8ceecb977316cfaf75784 -\u2652,b64f1b78aecbc20cb02a8b5520af06ac51b5dc726cc3761ba12ba92379cf0ce8 -\u2653,cd01857aa67c1102961f109cc68f30c5f7db5cfc46df4635dc42a8ac160efae2 -\u2665,d2e03c5d5c1779e7ce2d55a15412a28c9bc672774ea31c9e846a5bb28466 -\u266A,263ed2c2b1c966b156e98390642a2dc9ac89a72ebd50b6e7dc6b79636369aeb3 +" ",fe21c9372ebb9e236f6d90c4afcd47b85a3fe55b53afd49224be9c8635b67e6 +!,83e279656bd74b681597fb443d19d4a220f350d66ba04f826dcc89ae125cd8 +"""",d9f887f4175fd60988a2af688aac496451a31bc9db393b271ae58766958a1 +#,a8a7c6556b1503b66ab3e509a12b54617f7c735b971e9b817e96776e0554b +$,7328d6d214da405b3482af4b2470bd53353cd94231f3c23a3211d98983332d5 +%,a0ca37bd87d2e543254389bef26fd1acaeb52b3533a78d87b8af75fbf61d188 +&,6fbf3a3de010de6bc55e5ef5f1f9f30cf6e5d0624a33c8f3153bd4344ab44 +',f8b48c3762378d43d3b72c3135986f559ad5296e109afed91c311554d5242d +(,f1221c95235be5f8d9727469063d4d3762a6116eceaeae5f72dbfc739ab81 +),8356ffbd7fd813cf59be216b3189f8b131bd75607387235fa83a5a902b86b ++,bd86db9a14d5879fa2811d301ccbd526994f871247b62f2d9a48183e9641ad69 +",",88f88073398b8ccc929aa46ec06d86c8eda16f716bad4326986e793df97cf2b +-,10c34d5e85cf3aa31641993445fad6f5f1e01098e75caa56d9ae754026ca69 +.,bbdadc21773e9dd9914ce71d172aecb7cbed723aa8efbfd16b157dfc404c92bf +/,2ee3889a45729c6628483a71db4e1de2a5301ceff8dd76725543b225ed44a6 +0,6cf4c58b50a537b45ce7d511fdb2642e50ea36c2f9ef30dba8d63e35c542d59 +1,aebd85b7f9e6222b395451adb46b76a62f7e95da6fbf7efe715c783455140 +2,502eba83a6a953917f1d991bb379b36e7ff04a496d17f5424d04aa12efbab +3,e1ff52d15e7a7758b03c6fa861acbce93ae5662f7578261540b392de4157b29 +4,884b63d848dcbcf061e642f697b46d599a942e36e785347efec9534cc76d8a66 +5,9d3c54e9f12cd98449ddda0689bec179bd58e34fcf91d85809a9f96c68fe +6,3984b925c3cc38cfacafba753ebd1a39ea63f927310aee380e270fe2c2818 +7,2f9b635624136e418a636b6bf28e59d17f713763f82daf453676704be0e46581 +8,cc4856d4fe5a99c7235375d3b359eb191426843555e6da488e9fd5f837be55a +9,65871dd8827ea74896c712f3826efd806fd1f49d14926d0635a3be6b9cf3b +:,66d77c8f9b9f4d8e241003553bb760bd94f0711bee5aa241effafa3bba28f +;,cae77a95c08bc23dc3a21d4344f9816c44ff8f8aa7acb3e967ff2e1e441367b4 +=,5aa02088761cdb94b195269fc359be3afd8e8f4b389f7a0d7396b8a722f1e6f +?,c35ba393b8610b63ebee4c13c8358bc6c94a9dedc8e4d7d36b922257e65e8 +[,cb0a0ab60596648bd8293592699c138ffc0f97529618fc370886181cba6f63a +\,ae4409e45f019f6cddf3fc4d8b92a91d5c2af35e6ce9188b088f560d627 +],9fab62fee2e44e3a2dcf199fe2227ba6cf6cd3cd7da4c3df430bbaacfc8d6 +_,d13332c8672cafe6597c91cbefa7133ddb855ccf75f63df342158ead23ee89 +a,e48fe4a0cc5437364036adc1dfe2663c83ef8c6db86480525730c7957ccf3554 +b,fb7ef4d4f03e881938fc12bb69cbeb97533da528d4e340b856dd2f6bace4b45e +c,0b7a67087da884a25fc547ee1ba3d9bdcbf726bda6deb7744c6c52c264a +d,5b3a7fa89aa12a6576dfad1abd96f3a3627a42bedc8e333e5f47c11e4847eac +e,872967c93a91792dd116f0e4959ae18b163d70713eae548db9fa5edb55d459 +f,301c1e29bab272479c526f218f051586c22f29dc0928b6ca98ae14a3e07ad9 +g,78a3324c77fdccd597774304bbda15517ea2359de53897aed09528d1c6ec9 +h,4999f4afc0428e5d95651dc626ac3e2094d246bdd7f85fc6d7dd39ae9d2d19f2 +i,4e78708f252fbea16fd2539fe1ded81b865ff39124cdbb793ced3d99171b840 +j,b34d469e765187fe6120e4b1123fa7ea2a5736b60f0795cb79e16a9201b191c +k,1a9517849b5f29f9f13d2c5343bbaddac4db7876aef4fe352064becd5c7d6a6a +l,5336f6715fd60dd836f28e523c34345a454207ee4184d5b3dd4ce5293071c1 +m,47ad48f18cad99e06dfa4e59f7e486864f974daa985f6d6e657032b23eafca7 +n,8d9bd17d5399de9493d4d145d61c56afee7980466a7df5a78629fd8668abdb +o,7fdc65a62a2d7a117bdbf5cdd41994895b4a38ba91c1c71a3e7e583883fef4 +p,356c9635d734885ec5c3f2010868631aacaf45e4b47d7128a732a081f58ff3 +q,d44b36818fd3ce131892aff4cdfbbb78ae8348e1c6a8baa1d3c266ab98e6e52 +r,8d17b0e48c1dee2736269ebcbfa76028751aab101c9fa1c60256dd25c3241 +s,6795b66157b5d1e0757331d88976fcb6309de8d01b51e479b390b64e6fe552 +t,9fc32c914276f686141796a5a023c39efdfed14d3d7c9c42792513846f7fa4b3 +u,ceeb6fd733dc88711aacda43b42367fe513a7d743f308dd63318eb118c +v,1b419016dcd5256f464e36256d69c823890b923d1da4b8d45b0584cf3fa +w,ab21415f1ce6db677cad39c33b57d68dd8356c71be55cbc5e87a36b622a841f +x,fc68a342df6c9e711ec3bc138f91cdb1b0fa5e72f66e4251875d8bedd0553eb5 +y,7af28363be8175ba81f2a2dfc0b9d2855d0b7244a4dfda9fc795a62d68dfa69 +z,2a94faca32c55efc3d1988d8d4296fbba73b23287cc17cb92b5c45b9ca +{,bbd92f6957c23409b3592ef83249bc8c3872fbcf5516fda82b971efdf1c +},e7e16a29e4cd1bf9c9f44a89f70ed8150ddbb54488536fefe93fb4267b26a1 +\u00A1,f59eaaf0107a3ca8ad55780bf68bc8fd1cd9c28b095d6d97fc066ba2043c175a +\u00BF,496d1e3a56c75031ae0694bb2d8119ca516ff692889940df5d79af940e94ba3 +\u00E4,d7f0c3ed22a8f4a6d9388af6d13e08ebbc85a3730be5db45d3aef3d9fe3ba4f +\u00EB,e887fa2dffa7a8fc7d725b9e14723fabbc252263ab8de47ccd28611db786 +\u00F1,907c949c2cd0312f724e0572dbbe2dcb2642e3053304fa8506f6a25747f53ef6 +\u00F6,3cc3603e5a4b692dc07951e8270c976f5d0c8bff1d8cc9995cf32f1a64921b +\u00FC,c7b6abc56173b1e25085704016c6365d736e93ea18f58358c999eb14e430cd +\u0431,e348250781ff28f5d33d6f2b3dcae36f129eba91bd8d11217607881d23df +\u0433,b8e59849c1a45e229a29e1285e59b4fb1625bc92e475e7d05e8c10f3d52fdd +\u0434,7968196fbd4a0ff93a2a910851fd3ddba7965fd47f359254a42679ef418e +\u0436,fcfbd95b1b74ca16ffaafb9bffbf2e6efdfb881613d17d5bec33c9d6fa3462 +\u0437,d3512baf29f0321f953c70ac7df9f09c3633f43ebf768031ead65116262c86 +\u0438,cfd95c5a9e17ef73c0fc12f77068dec96628cb81a6754c6608df81d90645a +\u0439,24c8a5c5cd6360d0f48357a9aabb54923ffb279a2f856a75a7d5613aeefbd0 +\u043B,1d5278dc93d3eaf3867f7ee849d6ac2af6bb02e6450d7d9a2a298e6a1491352 +\u043F,3950cc6754863d8adb45f4d6725e17f5ce14b8b73ad4ff882f2381bd3492e956 +\u0443,972fd690b7aad0681bed2db7c5d86b78f82706d1517e2db983900a8a9aa51 +\u0444,34b3776fb1c31f3559c5cfedf18ac9b8d3c7d9d9044d479d2c372f3dbb4a +\u0446,5e3f7eeeba6c7eef0bbd2114a330ffbb21e475124296661361dcbc467d7b8a +\u0447,f5efdfeb752f2111c3dddeb322974b23a9702bdb35ebdf3ead83e4043bed1d +\u0448,71bd3134b78aa0569ae5f446a0fed11bc3348c68e9cfebce301b1944c240c6 +\u0449,3579881787b735b9efc4e98dae816c7428ca75040d2ae6b918b93b6faa4d2 +\u044A,a52dc3372854fdd8abd2bdb84ba3926d0c325f495f50401bd6eb2319eaad3 +\u044B,e126c7aeb5ae9daa580b79b89d5f9574c3c869e33facaa9a84d2e3da29551b +\u044C,f8b2720433fad38dda1ffbe77314eed16f52c13623f10fe76c78b1dd729465 +\u044D,c7c54d596e37df1cb97f8ce89ddbb2d8bd901cdd685233f55a2f4fdedd36e3 +\u044E,5b5691855c7b8c26c9e15a2e36cf46613bb7abd91654f42cc8957704ef9653f +\u044F,7934821f1a7384a2e96bce6a7c722dea97e333f4ed626c50fe21e0ac1c543975 +\u2190,93971124be89ac7dc9c929fe9b6efa7a07ce37ce1da2df691bf8663467477c7 +\u2191,f4628ace7c3afc61a476dc144893aaa642ba976d952b51ece26abafb896b8 +\u2192,2671c4c04337c38a5c7f31a5c751f991e96c03df730cdbee99320655c19d +\u2193,2ae425c5ba9f3c2962b38178cbc23172a6c6215a11accb92774a4716e96cada +\u2196,f2c39651d877bba2c47b13904f3c99b08967386f27f689f256fa299fc0cc +\u2197,298c77373229d28833c59849744554f9bf62a7bef785e5b618ea732aad3c834 +\u2198,229036a061a6bc98315b0daca7edf4cf0e33e6f95e877bfc36dc786614c2c8 +\u2199,42246c8abe7f3732cef758379353a28815a9c3707b321295731e2215abaf6faf +\u23E9,7472d245b2a8ab25bd4b9d32601d4aba2c53181ad2bde62c8ed71f8cae99543 +\u23EA,b4137232ab1911994481a72996b84bced8fa92821e4f763f13a23c8703cea +\u23F4,91459cfc44cc51ddf27988596d2de8ac8556e93d7946219cf64c90c8c05fca +\u23F5,63fabc3891c962c913959d65be90daa5de1211fa4087dae386ff4ed4248f +\u2640,32e52fe660c1d756099f4f349f288470684cf2404efb9c23c0578489d4f3d5aa +\u2642,e7fe6e2316ca384e0c85261b14fc066e231d6127e540dfeddb8b54d911b82831 +\u2648,d6d2a8d0fe60faa541941ff8eae6c6a86be31c7f12ae888dd45a43d7000c6acd +\u2649,c8325ea16d09ab4babc75c086ec5044d6d3c3ee78c4ac07973741ef3dec0e4eb +\u264A,8af4550654b052dc367549c0b0dc25b3b88214930197126500b5dc532fbe7c67 +\u264B,947396fae95556816ee31aba843d80d7ab2cfdbdb5d17247c9fc82584b411865 +\u264C,312a475d3a37a3c6f95822ff54d45ced7fdb4e5b132145dc6c45f981c76426f0 +\u264D,b3b8761d60bf018562c00e4161c6a74166ce464863ae4baa734b1b3fe9141c1 +\u264E,9ef0ac8ed075f6bba261e39af76e9f03b3f21c87ed01bf9f8dfb924f4929682c +\u264F,5418a8d1c1a3d325a22c9da5ccdb17958f2e50f072d672545b7faece14d9cd1f +\u2650,a6163fc0c45f45130c1c480bda0361af034648b0e9e75f0501fda0b5c236876e +\u2651,5e7d7c029be087c44fadc398e6001830bab0ba8498e8ceecb977316cfaf75784 +\u2652,b64f1b78aecbc20cb02a8b5520af06ac51b5dc726cc3761ba12ba92379cf0ce8 +\u2653,cd01857aa67c1102961f109cc68f30c5f7db5cfc46df4635dc42a8ac160efae2 +\u2665,d2e03c5d5c1779e7ce2d55a15412a28c9bc672774ea31c9e846a5bb28466 +\u266A,263ed2c2b1c966b156e98390642a2dc9ac89a72ebd50b6e7dc6b79636369aeb3 \u2713,3e1f0846c10e725da79eded6a01e8df6da0fd1196ed349927c646838269b5f37 \ No newline at end of file diff --git a/src/main/resources/fonts/light-gray.csv b/IF/src/main/resources/fonts/light-gray.csv similarity index 98% rename from src/main/resources/fonts/light-gray.csv rename to IF/src/main/resources/fonts/light-gray.csv index 6157e05e..7af41881 100644 --- a/src/main/resources/fonts/light-gray.csv +++ b/IF/src/main/resources/fonts/light-gray.csv @@ -1,118 +1,118 @@ -" ",81fb8ce6408a5851384e1c2ef753851eac18ba4018266cdd669dc944873d42 -!,aa936475c77652430bee72bf31e214dcd4759d4826abb85591e32e7b32b -"""",f7b6a1be1eab5a1ed532a76e8e4db74c09b5a196ed94c70575040d36b358d27 -#,51d4fa45d26d4c84284c184b4958b622ad3ea4112f4c4dced0c4969b37 -$,4836538f5555cc610388b97c6bd368e16aa1ffb5d7b4bd3c86fe092e8e0d4cc7 -%,58b568453c9db0476bba49cd14228f994d12698eda51ac851ed7f4da221fdb -&,1c56912e7096d66f5617738e5e8c841ab3e1cabd9b9f06ed369698ac5b1 -',1f202354614c2ed00133cc120411b6475dd405adf5d2e82a06bc4d57ed877f -(,45665d2d4560e03488106ad2a2b7df579dec21da8808d4498c18121caf871 -),a5489764c951121f09a9c918864cf4ed423c7cadfaf6980135d8c30ca3b1e -+,632fff163e235632f4047f4841592d46f85cbbfde89fc3df68771bff69a662 -",",6ec5e779d52534d2ef6392cf4d416b73b205bfd6d7dd248bb22851b8545ba --,da56dab53d4ea1a79a8e5ed6322c2d56cb714dd35edf478763ad1a84a8310 -.,d54eb01ae1dc15ada84efcfa18a15bafe4b9cc03fbc8256188dd66615b78e1 -/,e9d4aeec8f594236ee23db6e8cd01cf226c49651276337fc568a6147ce17484 -0,ffa45911b16298cfca4b2291eeda666113bc6f2a37dcb2ecd8c2754d24ef6 -1,caf1b280cab59f4469dab9f1a2af7927ed96a81df1e24d50a8e3984abfe4044 -2,e4b1e1d426123ce40cd6a54b0f876ad30c08539cf5a6ea63e847dc507950ff -3,904ccf8b5332c196c9ea02b22b39b99facd1cc82bfe3f7d7aeedc3c3329039 -4,6b4fc18e975f4f222d885216e363adc9e6d456aa29080e48eb47144dda436f7 -5,1d8b22239712e0ad579a62ae4c115103e7728825e17508acd6cc89174ee838 -6,9eefbad16712a05f98e4f0de5b4486af3987b46ea6ab4e3be93d14a832c56e -7,a3e69fa942df3d5ea53a3a97491617510924c6b8d7c4371197378a1cf2def27 -8,7d184fd4ab51d4622f49b54ce7a1395c29f02ad35ce5abd5d3c25638f3a82 -9,1b2454a5faa25f7c4f5771d52bb4f55deb1939f75efd8e0ac421812ba3dc7 -:,64953b65b130f928345c07388bcd9c7a8b8fed96ecabb4d6d0e493357f91f0 -;,9da1b4af636fca41ceb21fdf79af2085e7f73bf4b33712663be0318cfd3890 -=,a7ecbbd16040fb83a8bb6cc394d3ccaa4ecf26c0e0cab569adcb987ccd5a9c -?,1ab739f4cb028ef2acf34a6dc3b4ff85eac5ca987b5832bfdd0f3c3351aa443 -[,be1cf7c07a1c898f4fef716131c9f5b8e26c2afbddea98a4f6a84f1ee651ed -\,9d81538556afc37295ca18d371c2ae6f52b46263ba92a7fae46445f201b5ac2 -],3ce5cc7c457f1e19385a24d2de43d858cf553a5d7356442eb1d4d13513956b -_,738d663c471208dc267ca85331021c13e92bc9946a28921867cdabbfc6f13a0 -a,8cc95d7622ec32c5cc31ff7a9e2d545f951179a6c78af837b4e756c1f75a61 -b,1e5c65227cc46ea405b8a8b15d4ac9889446fe5d5fb0619f51398deb2411a -c,149e48c0df7995e91db5bd3c930e5bcc0abcfaf31273732aeabf33c5d86491 -d,27e8abb6786cf0c8b7f83da36bf5a452edf54d20e230963298ea77b8c3f2d015 -e,30d4f0b5a21da673641363bc468e201c472ccb9bbf112ac5b3cf31358e30cf4 -f,633c89a3c529d5136be6c49a62be0383fc3722cc990142e5cb3cc96db199d7d -g,5593da74e9688413c237f3ce324d7085aca88dfa4b7257c2da0bdfc34563077 -h,9e4cfd9d9d9c11b188c720e078becd26a8b64fe9dfe555b99652d8595f35d -i,a58561bf8fafc5de6ee2beaf4111ceeb3a8343272b8f3734dfee19d373228 -j,4cef7c3691caa8af9d09acd2beca675a24d1be7473e45cb6daf4ff26814d23 -k,5c92e9a67d5adcb9c8d42f118dde812ce96170b0f6da810322fd5fba9d6438 -l,d41d13a1855a75d6ae1ae2b2837d76d920c5f7739e64469841658f917fc0 -m,ddcd8fe8d4d5c05886db9f59127961549e602f30c51759998131b2ad25d264 -n,e9672e76eb69ab4b9292fa169cc2b189ef23151bb3ede238428fc6abdd060f6 -o,5a3bb59295e5c2ac020de7180b0b797c19ede6b258e457943b7a36f455f6892 -p,299c799b38ab1999c354332a74b3a49687012738225682d58159be2b8a2b -q,6f2a287706c895a1abcd89ca12f3b9c4745fff36fddcb69a2d88ca92224e99e -r,50f0fdd5d8dc6b54eab98f6f85ac14dbb3b588632962ec3d1a4c24c50bd4e3 -s,c2eb28cd6c7524b14d59f3b8c465dfc78be8e0dac843e682c4252ae9459c78e4 -t,367f15e2a8e9c0cbdd479810f7ee355c404c979f424d699679bb613cdf71758 -u,28158d853c948f3df72ed1d8938172c8ac8824b31d42ce4b5f048bd2b5679 -v,26b3f87b5d3cc4bcc4c605ce44e11e784a9af87c5c9c443e5fedd25216cd -w,8decf6eacc73734e1dc6b21573595ea0d9559146e29913a10552da5956acf7d -x,f5f3ea7c7b26a054a9fbbb28b97a608999c2c73df75bf6b2348d7fb1e59e855 -y,f8edd5369c287c74b8a1f6a5707f7a9b5b652a56d2066e89531efb7243acd24 -z,602eaa6089a869af95868af2f6709b526a981c473da50931b6ab4ed022f5 -{,45665d2d4560e03488106ad2a2b7df579dec21da8808d4498c18121caf871 -},63a52218705fea60ce353bf6e357b8afec58f5d9994534e5705a6eaea12268a3 -\u00A1,e128fa9b818a473628029bb461ebec32814cb2556b5f1e8a1c14d6adfce6d880 -\u00BF,77c17304c96bc78a0fdb9f9fbdd670475d3f51bc5e590e4182cb1772191547e6 -\u00E4,48d2b84355b2793cd27b5010d2d44f91a511ffe05ee0d8fec3ded91c137c0 -\u00EB,70a21bb5736aae8e8de891281fec6dc9c71ceadd0b1b2fc9ed95c639067564 -\u00F1,95e423205afbcc50420019edaec34d432f4d5f5d66d396cff0eb4ed620eef88d -\u00F6,c8f2b7a1e7f321ef70a5c0886ee915ceb6b9e386f746fb822396ce862145333d -\u00FC,653c7f75f5894e9be6e186fb4257b567b5a7fdbad9a87f2a23ae73db7454ac3 -\u0431,de5b7d7cb74d23abae0e4bfe1e69614c0b8d8ecd34e975570b3e4a96fe219 -\u0433,210ea7d2596cfb1ae9985d3376962b798fbe1d2b7035493f98b0c6ae34eed9 -\u0434,91c239daa8f87261843a1f2f727354a09c5084c0db1a1c59cb3fb83c4828f -\u0436,dbf33ed274de57d51bb89021cb4350d38ddf5985e77593f964bbfed2d33a31d5 -\u0437,d1914a6c5ba0814d3816c468c343a42bb47178b2855f9660cf595ee334834 -\u0438,b2718e0195fac4d4b32896b7601af1941779d0da149cab99efef1e2dc0948c -\u0439,d2ccbeaa9a783b70a7bc8768c7275cb7ed391bc7656cb1a1868d2bab85e6845 -\u043B,9e4acc63857963c93154b34da681c704930e0fe69219f943b8a4889ddcfa7 -\u043F,2c66daa6ccf7df5ae2faa7bb261861a4d27bcbfef8db9e319a966cde71c2a0 -\u0443,7296b44413acd3adbfd3b86cab40b4ed9576832eb9a2318c921a1a6fe556eef -\u0444,49897cab763bbcbdf2afcd361352d39b275888d6a4f9162f645467ee31374 -\u0446,9b8b3764ed74808a3d37cfb8ac083ef7d64574586b0b954228a9d31ba2c4e77 -\u0447,86e3bcb9401ad28878dfec4a34eb50cc5136781cc2206e53aeb9f283d637cb -\u0448,e14d59cf16450c2695a58505bde32474d80aa37c1f815d5ef3368c4e0e63832 -\u0449,e81284b0148ccc89bc3f83817ddbdbf57b59863ca71dccb3fcb358363e4175 -\u044A,66dcdd322447b9c1e19820a5bb88780647259a9cc29dc8bc5efe160f24e8b -\u044B,882c7eed1482e1da99c8dbdaff1e8b93df75ad2cc9d066396449464adf64a6 -\u044C,8046111fc7cd88f4a08b8743e4136cb933d193a1ac373ceed284fad2a64692 -\u044D,2eb7afde646c8be2db45cb9383b5938385df3ea4e4f6e99742645496ff466c -\u044E,db72ccb5ac886f9f33ceb498613d75447223f8dc6591344aeb4c3be6c5b69c4a -\u044F,fe7ff46335afcceac67f788b82b177456f42f90635f90df34e910f6a46cd5 -\u2190,542fde8b82e8c1b8c22b22679983fe35cb76a79778429bdadabc397fd15061 -\u2191,14a5667ef7285c9225fc267d45117eab5478c786bd5af0a199c29a2c14c1f -\u2192,406262af1d5f414c597055c22e39cce148e5edbec45559a2d6b88c8d67b92ea6 -\u2193,d1b62db5c0a3fa1ef441bf7044f511be58bedf9b6731853e50ce90cd44fb69 -\u2196,5c4fb3d43029c3d9966dc282fb73892d794474bc270ad04dc87064e967fc2 -\u2197,b6cf395a71d42f2b47f9849aaf8feda75abb4275d7d93a1bdc5c0e33c79c015 -\u2198,cb726da76df3cac623750d19fa920dff7c2e99c362726e7d16280f3461f74 -\u2199,11a68d5b87fba62476808a0d9a75c3ddf1bc26c0b0f4d2de36c78843af129 -\u23E9,fa78ad78a3bb6f33939df014546dff3a86f74d9b52b6eff669ecf00292dfb14 -\u23EA,419d862eb736f27774b75f2b48b643e8dbcad73c59493437da6312e4df62f9f -\u23F4,a89dd7af4c803b5287c433707c7c437cc28d521bb682c47a4d3d5d2a48afa6 -\u23F5,ea26e5ff186778eee6dbf98a15074384c3211d16be0f29460bbd964aeff -\u2640,e43bb82fddf85462a0ab683d579ee85537f992d10f0c780c373cb2638369d3c5 -\u2642,583cb52cd8a32cbaf43b75a67f0d7af5ee6227daf3a16644e3a7b98c53dd9244 -\u2648,45eca8eeda7a754b5767b60128eb12a02c0352f3bf8f4ffd60df8e2f5ff14067 -\u2649,9e049222d3dd3843135c4471d2829dcba2dbcd2086577dcd20ba027c9eb752fa -\u264A,2986c1b9f8b5c1e3f86285655a9ba5274fa2fe8bf504b5872d81e018a862e651 -\u264B,7185f77a1b2bdc643eca05dc6025a0bba94b8f9cb21764b6cf4f4dacea24a149 -\u264C,8855663b961f12f903a02f4d9394e727ee9738e6121649abf0172cf6941e74d1 -\u264D,26ec8fe0300c185b98d4c56554402ec180ca77fc84b15ce8abbda0c1311f922e -\u264E,1a9526b80e101d61a249f0ced3748be55436f427eadba8c7372548ceb5ab0288 -\u264F,6b873fdafb15aa354f59708252d1b43435b7a4d311eb1de847e36787bdf83469 -\u2650,6c39028f6c8bd53cbf163d96ab5f062a5d41dc868b6ff34a8592db30c3fd8a22 -\u2651,f9760a3c95c2c731dff27e06e054006f599699726aa797a8002c4a657b238039 -\u2652,1d4e7feef1e10f41422b3edda2b83bb133b7b83bd863934c9bab09abfeaea533 -\u2653,163d911dc61ad8676cccc34ea93e2dda357168f312a3c29dcd1f9e2e866d75e3 -\u2665,4dc8e7cc87d8ff30398fc514e45c78b2573533ee3b8ceba152fdba5183a83 -\u266A,b152208b731b9bda0b484a3cad7474befeed66a8ce64091fb4010a2382cd018a +" ",81fb8ce6408a5851384e1c2ef753851eac18ba4018266cdd669dc944873d42 +!,aa936475c77652430bee72bf31e214dcd4759d4826abb85591e32e7b32b +"""",f7b6a1be1eab5a1ed532a76e8e4db74c09b5a196ed94c70575040d36b358d27 +#,51d4fa45d26d4c84284c184b4958b622ad3ea4112f4c4dced0c4969b37 +$,4836538f5555cc610388b97c6bd368e16aa1ffb5d7b4bd3c86fe092e8e0d4cc7 +%,58b568453c9db0476bba49cd14228f994d12698eda51ac851ed7f4da221fdb +&,1c56912e7096d66f5617738e5e8c841ab3e1cabd9b9f06ed369698ac5b1 +',1f202354614c2ed00133cc120411b6475dd405adf5d2e82a06bc4d57ed877f +(,45665d2d4560e03488106ad2a2b7df579dec21da8808d4498c18121caf871 +),a5489764c951121f09a9c918864cf4ed423c7cadfaf6980135d8c30ca3b1e ++,632fff163e235632f4047f4841592d46f85cbbfde89fc3df68771bff69a662 +",",6ec5e779d52534d2ef6392cf4d416b73b205bfd6d7dd248bb22851b8545ba +-,da56dab53d4ea1a79a8e5ed6322c2d56cb714dd35edf478763ad1a84a8310 +.,d54eb01ae1dc15ada84efcfa18a15bafe4b9cc03fbc8256188dd66615b78e1 +/,e9d4aeec8f594236ee23db6e8cd01cf226c49651276337fc568a6147ce17484 +0,ffa45911b16298cfca4b2291eeda666113bc6f2a37dcb2ecd8c2754d24ef6 +1,caf1b280cab59f4469dab9f1a2af7927ed96a81df1e24d50a8e3984abfe4044 +2,e4b1e1d426123ce40cd6a54b0f876ad30c08539cf5a6ea63e847dc507950ff +3,904ccf8b5332c196c9ea02b22b39b99facd1cc82bfe3f7d7aeedc3c3329039 +4,6b4fc18e975f4f222d885216e363adc9e6d456aa29080e48eb47144dda436f7 +5,1d8b22239712e0ad579a62ae4c115103e7728825e17508acd6cc89174ee838 +6,9eefbad16712a05f98e4f0de5b4486af3987b46ea6ab4e3be93d14a832c56e +7,a3e69fa942df3d5ea53a3a97491617510924c6b8d7c4371197378a1cf2def27 +8,7d184fd4ab51d4622f49b54ce7a1395c29f02ad35ce5abd5d3c25638f3a82 +9,1b2454a5faa25f7c4f5771d52bb4f55deb1939f75efd8e0ac421812ba3dc7 +:,64953b65b130f928345c07388bcd9c7a8b8fed96ecabb4d6d0e493357f91f0 +;,9da1b4af636fca41ceb21fdf79af2085e7f73bf4b33712663be0318cfd3890 +=,a7ecbbd16040fb83a8bb6cc394d3ccaa4ecf26c0e0cab569adcb987ccd5a9c +?,1ab739f4cb028ef2acf34a6dc3b4ff85eac5ca987b5832bfdd0f3c3351aa443 +[,be1cf7c07a1c898f4fef716131c9f5b8e26c2afbddea98a4f6a84f1ee651ed +\,9d81538556afc37295ca18d371c2ae6f52b46263ba92a7fae46445f201b5ac2 +],3ce5cc7c457f1e19385a24d2de43d858cf553a5d7356442eb1d4d13513956b +_,738d663c471208dc267ca85331021c13e92bc9946a28921867cdabbfc6f13a0 +a,8cc95d7622ec32c5cc31ff7a9e2d545f951179a6c78af837b4e756c1f75a61 +b,1e5c65227cc46ea405b8a8b15d4ac9889446fe5d5fb0619f51398deb2411a +c,149e48c0df7995e91db5bd3c930e5bcc0abcfaf31273732aeabf33c5d86491 +d,27e8abb6786cf0c8b7f83da36bf5a452edf54d20e230963298ea77b8c3f2d015 +e,30d4f0b5a21da673641363bc468e201c472ccb9bbf112ac5b3cf31358e30cf4 +f,633c89a3c529d5136be6c49a62be0383fc3722cc990142e5cb3cc96db199d7d +g,5593da74e9688413c237f3ce324d7085aca88dfa4b7257c2da0bdfc34563077 +h,9e4cfd9d9d9c11b188c720e078becd26a8b64fe9dfe555b99652d8595f35d +i,a58561bf8fafc5de6ee2beaf4111ceeb3a8343272b8f3734dfee19d373228 +j,4cef7c3691caa8af9d09acd2beca675a24d1be7473e45cb6daf4ff26814d23 +k,5c92e9a67d5adcb9c8d42f118dde812ce96170b0f6da810322fd5fba9d6438 +l,d41d13a1855a75d6ae1ae2b2837d76d920c5f7739e64469841658f917fc0 +m,ddcd8fe8d4d5c05886db9f59127961549e602f30c51759998131b2ad25d264 +n,e9672e76eb69ab4b9292fa169cc2b189ef23151bb3ede238428fc6abdd060f6 +o,5a3bb59295e5c2ac020de7180b0b797c19ede6b258e457943b7a36f455f6892 +p,299c799b38ab1999c354332a74b3a49687012738225682d58159be2b8a2b +q,6f2a287706c895a1abcd89ca12f3b9c4745fff36fddcb69a2d88ca92224e99e +r,50f0fdd5d8dc6b54eab98f6f85ac14dbb3b588632962ec3d1a4c24c50bd4e3 +s,c2eb28cd6c7524b14d59f3b8c465dfc78be8e0dac843e682c4252ae9459c78e4 +t,367f15e2a8e9c0cbdd479810f7ee355c404c979f424d699679bb613cdf71758 +u,28158d853c948f3df72ed1d8938172c8ac8824b31d42ce4b5f048bd2b5679 +v,26b3f87b5d3cc4bcc4c605ce44e11e784a9af87c5c9c443e5fedd25216cd +w,8decf6eacc73734e1dc6b21573595ea0d9559146e29913a10552da5956acf7d +x,f5f3ea7c7b26a054a9fbbb28b97a608999c2c73df75bf6b2348d7fb1e59e855 +y,f8edd5369c287c74b8a1f6a5707f7a9b5b652a56d2066e89531efb7243acd24 +z,602eaa6089a869af95868af2f6709b526a981c473da50931b6ab4ed022f5 +{,45665d2d4560e03488106ad2a2b7df579dec21da8808d4498c18121caf871 +},63a52218705fea60ce353bf6e357b8afec58f5d9994534e5705a6eaea12268a3 +\u00A1,e128fa9b818a473628029bb461ebec32814cb2556b5f1e8a1c14d6adfce6d880 +\u00BF,77c17304c96bc78a0fdb9f9fbdd670475d3f51bc5e590e4182cb1772191547e6 +\u00E4,48d2b84355b2793cd27b5010d2d44f91a511ffe05ee0d8fec3ded91c137c0 +\u00EB,70a21bb5736aae8e8de891281fec6dc9c71ceadd0b1b2fc9ed95c639067564 +\u00F1,95e423205afbcc50420019edaec34d432f4d5f5d66d396cff0eb4ed620eef88d +\u00F6,c8f2b7a1e7f321ef70a5c0886ee915ceb6b9e386f746fb822396ce862145333d +\u00FC,653c7f75f5894e9be6e186fb4257b567b5a7fdbad9a87f2a23ae73db7454ac3 +\u0431,de5b7d7cb74d23abae0e4bfe1e69614c0b8d8ecd34e975570b3e4a96fe219 +\u0433,210ea7d2596cfb1ae9985d3376962b798fbe1d2b7035493f98b0c6ae34eed9 +\u0434,91c239daa8f87261843a1f2f727354a09c5084c0db1a1c59cb3fb83c4828f +\u0436,dbf33ed274de57d51bb89021cb4350d38ddf5985e77593f964bbfed2d33a31d5 +\u0437,d1914a6c5ba0814d3816c468c343a42bb47178b2855f9660cf595ee334834 +\u0438,b2718e0195fac4d4b32896b7601af1941779d0da149cab99efef1e2dc0948c +\u0439,d2ccbeaa9a783b70a7bc8768c7275cb7ed391bc7656cb1a1868d2bab85e6845 +\u043B,9e4acc63857963c93154b34da681c704930e0fe69219f943b8a4889ddcfa7 +\u043F,2c66daa6ccf7df5ae2faa7bb261861a4d27bcbfef8db9e319a966cde71c2a0 +\u0443,7296b44413acd3adbfd3b86cab40b4ed9576832eb9a2318c921a1a6fe556eef +\u0444,49897cab763bbcbdf2afcd361352d39b275888d6a4f9162f645467ee31374 +\u0446,9b8b3764ed74808a3d37cfb8ac083ef7d64574586b0b954228a9d31ba2c4e77 +\u0447,86e3bcb9401ad28878dfec4a34eb50cc5136781cc2206e53aeb9f283d637cb +\u0448,e14d59cf16450c2695a58505bde32474d80aa37c1f815d5ef3368c4e0e63832 +\u0449,e81284b0148ccc89bc3f83817ddbdbf57b59863ca71dccb3fcb358363e4175 +\u044A,66dcdd322447b9c1e19820a5bb88780647259a9cc29dc8bc5efe160f24e8b +\u044B,882c7eed1482e1da99c8dbdaff1e8b93df75ad2cc9d066396449464adf64a6 +\u044C,8046111fc7cd88f4a08b8743e4136cb933d193a1ac373ceed284fad2a64692 +\u044D,2eb7afde646c8be2db45cb9383b5938385df3ea4e4f6e99742645496ff466c +\u044E,db72ccb5ac886f9f33ceb498613d75447223f8dc6591344aeb4c3be6c5b69c4a +\u044F,fe7ff46335afcceac67f788b82b177456f42f90635f90df34e910f6a46cd5 +\u2190,542fde8b82e8c1b8c22b22679983fe35cb76a79778429bdadabc397fd15061 +\u2191,14a5667ef7285c9225fc267d45117eab5478c786bd5af0a199c29a2c14c1f +\u2192,406262af1d5f414c597055c22e39cce148e5edbec45559a2d6b88c8d67b92ea6 +\u2193,d1b62db5c0a3fa1ef441bf7044f511be58bedf9b6731853e50ce90cd44fb69 +\u2196,5c4fb3d43029c3d9966dc282fb73892d794474bc270ad04dc87064e967fc2 +\u2197,b6cf395a71d42f2b47f9849aaf8feda75abb4275d7d93a1bdc5c0e33c79c015 +\u2198,cb726da76df3cac623750d19fa920dff7c2e99c362726e7d16280f3461f74 +\u2199,11a68d5b87fba62476808a0d9a75c3ddf1bc26c0b0f4d2de36c78843af129 +\u23E9,fa78ad78a3bb6f33939df014546dff3a86f74d9b52b6eff669ecf00292dfb14 +\u23EA,419d862eb736f27774b75f2b48b643e8dbcad73c59493437da6312e4df62f9f +\u23F4,a89dd7af4c803b5287c433707c7c437cc28d521bb682c47a4d3d5d2a48afa6 +\u23F5,ea26e5ff186778eee6dbf98a15074384c3211d16be0f29460bbd964aeff +\u2640,e43bb82fddf85462a0ab683d579ee85537f992d10f0c780c373cb2638369d3c5 +\u2642,583cb52cd8a32cbaf43b75a67f0d7af5ee6227daf3a16644e3a7b98c53dd9244 +\u2648,45eca8eeda7a754b5767b60128eb12a02c0352f3bf8f4ffd60df8e2f5ff14067 +\u2649,9e049222d3dd3843135c4471d2829dcba2dbcd2086577dcd20ba027c9eb752fa +\u264A,2986c1b9f8b5c1e3f86285655a9ba5274fa2fe8bf504b5872d81e018a862e651 +\u264B,7185f77a1b2bdc643eca05dc6025a0bba94b8f9cb21764b6cf4f4dacea24a149 +\u264C,8855663b961f12f903a02f4d9394e727ee9738e6121649abf0172cf6941e74d1 +\u264D,26ec8fe0300c185b98d4c56554402ec180ca77fc84b15ce8abbda0c1311f922e +\u264E,1a9526b80e101d61a249f0ced3748be55436f427eadba8c7372548ceb5ab0288 +\u264F,6b873fdafb15aa354f59708252d1b43435b7a4d311eb1de847e36787bdf83469 +\u2650,6c39028f6c8bd53cbf163d96ab5f062a5d41dc868b6ff34a8592db30c3fd8a22 +\u2651,f9760a3c95c2c731dff27e06e054006f599699726aa797a8002c4a657b238039 +\u2652,1d4e7feef1e10f41422b3edda2b83bb133b7b83bd863934c9bab09abfeaea533 +\u2653,163d911dc61ad8676cccc34ea93e2dda357168f312a3c29dcd1f9e2e866d75e3 +\u2665,4dc8e7cc87d8ff30398fc514e45c78b2573533ee3b8ceba152fdba5183a83 +\u266A,b152208b731b9bda0b484a3cad7474befeed66a8ce64091fb4010a2382cd018a \u2713,6fffa602e368214dd62cecd6815f14926ee57b948143495e931a77636372be5a \ No newline at end of file diff --git a/src/main/resources/fonts/lime.csv b/IF/src/main/resources/fonts/lime.csv similarity index 98% rename from src/main/resources/fonts/lime.csv rename to IF/src/main/resources/fonts/lime.csv index dd77b71a..40e0131c 100644 --- a/src/main/resources/fonts/lime.csv +++ b/IF/src/main/resources/fonts/lime.csv @@ -1,118 +1,118 @@ -" ",3296d3e1493fa32d827a3635a683e5bded64914d75e73aacdccba46d8fd90 -!,9a26c45d4094268a534d4c3c5a1722e449aef3ea5dbc80251751a8de839eb50 -"""",44f08cafcb2aa85a55d536866424b6d1f9bac893bb3ddf10f4a69f9e30acc9d2 -#,5d9c43c23074ca538f9e75c685c1cd6d8743f7329f2baec69a23611cfb7224 -$,8eeb18e6695c39b441d04f7ca53eda1346a5a947d4fe8ba37b33b923288b4e30 -%,bc8cdcbb9893681d8584b31ea06433f9352480545ea938a9e6edea9ac4933f96 -&,1a48cad96e457534ec6ec47643f97e126d4a846a4a6fbbb583b1f3f2858ae -',b1dce0869edbd438de25f91af2cce5c890c24b971c7183db46bfb4f3544c9e6 -(,1d5aacbd2464585039fe7f89a41b2e929eb5aa93ce8aaae76b7733899675e8d6 -),906ae26bdddc73e4ba36271da2db153974d32bb86efd2b1f5f82f826ed02e4 -+,b056bc1244fcff99344f12aba42ac23fee6ef6e3351d27d273c1572531f -",",62bec4479d659d2f10aec5a719832e8654c02c4b9ac65e6942f9bf5710d53c --,5f67f77f9697255553fa17979cf7242ce7d75dd52fbf3cfb26c9ab54e2a71938 -.,b4ee1c91fc6e6c3bdbb553b4cfa2b9ad6b9883868c3ed64dff742e716698f -/,36c8abc8bcbe386ffcfb3acfe854c956a397fa580a814185f1f8c70dab53f64 -0,defa4a74447d0e2fa4c43f03d9661a7ee6dee51da82e02ea53aad93f715292 -1,88991697469653c9af8352fdf18d0cc9c67763cfe66175c1556aed33246c7 -2,5496c162d7c9e1bc8cf363f1bfa6f4b2ee5dec6226c228f52eb65d96a4635c -3,c4226f2eb64abc86b38b61d1497764cba03d178afc33b7b8023cf48b49311 -4,f920ecce1c8cde5dbca5938c5384f714e55bee4cca866b7283b95d69eed3d2c -5,a2c142af59f29eb35ab29c6a45e33635dcfc2a956dbd4d2e5572b0d38891b354 -6,24ddb03aa8c584168c63ece337aefb281774377db72337297de258b4cca6fba4 -7,d7de70b88368ce23a1ac6d1c4ad9131480f2ee205fd4a85ab2417af7f6bd90 -8,42647ae47b6b51f5a45eb3dcafa9b88f288ede9cebdb52a159e3110e6b8118e -9,dae461a4434196d37296ad5adf6d9d5744a0415dc61c475a6dfa6285814052 -:,d0ac7fc65a5436b7b5ae31e7d3256caf95886d98321c13a1c3fde239d471d6a -;,c692f839ea661ca6f9a6632ebc4a357e39a3b3fde26d36861b74b51e2d5a2964 -=,bd47dd856d64beef7b714e19d2947ee8ae8d999573d3fa3976877abd61121 -?,4c9269448affff444517752f725abb49b91ef380e9bd73f9bf9d83704ef3d6b5 -[,85a0f6334ad859e988be27d1671d8c6eaa246521be123379ac32a2f84777 -\,bcd72f25c8dd2b21a95b5483e6f231f02f96cfbb73a75676fafb5946781c091 -],1b52363eefb986f28979d245f5eebd4f6d6d6c131e5dfe1c831728f58138cd31 -_,d1c89d7f91942fb72d01b1368475d3322685e4da3e0cb5321622035c476843c -a,789f073e0f87d508396356f8af8dc762c531e6686bbbedea598927211f9cbb5 -b,8c361bce781d1abcfd1612e5a7e2407c5bdd29b68fcfd501ea4cb8013fcd64 -c,efe6a4f7fc31954ac7d17f702f22835e325f8bb5326cff6273c7b9cc1921ca1 -d,69c5f5d046bdee6c3996d5c4deab28b39cd0fa2d934cc2733f149d6bcbdf8ca -e,e776ffb3e81918c3a552434bd15a29cf9715794e779f0744146fc12d231347d -f,a4413bdb2a7ea27cf303d799ddc627d6feed71b01876b9b1b0e013a8e1c624 -g,af0a8a0be5d3f3f94bd32a3ed9262e662a5da911919fee91ebccf3b79bf658 -h,6728820b62115484ea4dd86f4922e2344bbcdcf9b57a8430641a53525c4e25 -i,dd9a08bd74024ac162efbf882737d7bf9ca32893ce7ac697833ed218523f11 -j,8596a936f61eaea5a254a8ea3ef4bb7ed2c03883372ba490afc05f39969ffab3 -k,d42a4802b6b2deb49cfbb4b7e267e2f9ad45da24c73286f97bef91d21616496 -l,8831ca2dc68a161e75c3edda1c6349d41f55e57c71e967d451f4f881d7876a5 -m,d8a4abe1781042452e7b8689101757fed5728316cd7f53955be8832c485eb0 -n,a0a55e9bbbfbc589f62fb7c13c4fa1614aea7e83ebfecc7bb6b2e12895aefb78 -o,a25f813f63c7429a67bb75f7a787db4f366192b60f543410a13f9c838953dc -p,c75a5dc31087f3a16f27a4ffcf2542ee8d522f25eb19d0895efc32cb9c2548 -q,2e9cd4d81ea9c65e4f54a7dfaf85a0a178bc4e16d63e28eaa48bc9b73ad034d3 -r,66362ba4b2c7b05314bf25e95f760b99fe4b341dc841770a27c244bcebfd5e8 -s,8d359aeb767e914521ff5b9d2c685db54871dc3f7e8f72f6eb8c1f2ca8c2d2 -t,47588f1a176abc5e58c5c4f8737d5e95b99a97f3b5f514e4e33beee043d37b -u,1f5efe243611d748e6509617429d7d84afcb85c5e2516d8bd5a011b5deb0b373 -v,90c23bafdfab5a331321e139427fd7b75d6ff573ab8c9584f677149e129a2ca -w,ff35777e1635a5f2fd2b822b8569783fec033bcdf44f1aa378896fdc5b536a -x,caba2d5a5ca842a2da7d25a259e77b6cba5ae655dddc24ea495641d29efc -y,651448f59b07e6e9de8b186af59b8fc7612d62b4382ae976bdfb14daf949898 -z,305a5ec074ce32498d484a919c1ef0a13163153a23554c6f2a31d10e1b2d7 -{,52a59bf723e17a9fd82f1d98307603cc593f98a74168d53a44cbb184e17dc -},e386e7e7fd923537adb88e976b931529ea61b8959b38f2bcb048f63b44443ed -\u00A1,21faf6ac6c3de0969614fdda7fb47bb81db7754cfb6f4d1c7ecd143e555b39da -\u00BF,94ae7f993907f2cc1337eeec130bc6c42eaf9f29a7a39bda39796d27032e630a -\u00E4,1fb5cfac99e2ad961bcbbb902d599dd978ae128d5fdc581a7a10f2d859 -\u00EB,cdb1213c9710519df9e637b8c3337568924e2a419b673acc18b16e61cfc15d95 -\u00F1,c97bc63fc716fafa7ee7bd37a95eca78f62b753359d4a3b0e08aceb19c41491 -\u00F6,8f2c061f954a25258b92ab2599362b40ce38d526b1e4364fcdcb7c81d245 -\u00FC,89bcaf348df57d5a7b242656cf1d75672dfeb4c53de8649739de5a82a7cc5e7 -\u0431,45ca4c9e486f74e2811f809f8dbea5d0b1498978f78f533b4458a697cb9f8 -\u0433,69753a4ae315fc6372ba5977d47c49b91f734b097e521e6f7cdf7ae843b466 -\u0434,3d2793ebb9c6925fd819d8cc71d9204995de29d9ada561f9fcd24db78771722 -\u0436,6ef7d56613dc61ca6872a197e7e9afd59ea4a1107f48d3f84f644fc1896 -\u0437,79e171c791ede18c4960f9546cb3dbd333518a6e8cf92f67052ffec3cf37613 -\u0438,9fcbeefa2af5ec7dad2d4365c4a8547288ed71702fda95c6606642db8f2c -\u0439,4aa6272b6ae387661e3bc4a7bdfd1e23fb8f0702fb3ca9b3a1fba16be960 -\u043B,dc9e587118965c9afbaf03c9a37b0a92a20a8d9176776cf8c94f57fb5c86033 -\u043F,181f3bb4afeba98ed5db88fca9b4b52e243fd5e93246961ec8738c2b7e7e5a8 -\u0443,8ea36ccca66e83922de5e4648bb754b0123e47ac0f122cb79838b447dc88 -\u0444,246a757a472892f0dd50b8f6d72b4accfc4d72ea8de8d94bd94c8823a7f8a -\u0446,f6484130c771c5acec99a91aacfe8fe2dca56046b695c406d6b333e2d5b37fc -\u0447,9461bff3b39e1cd8e4fd3c4368eb96533cd540569d0f3b91604571a5c44d9f -\u0448,9b1f88415c8c446311b0263d1b81267dbec2073bb4325d8abdedffee5d7d42 -\u0449,813d49167596dbfd563e7d7baa93dbee1ab2f815566c615889c6f4a2b9dc -\u044A,a93a37bf63fa5dc5a0cf7fb711d56a0819262dfb21d133de3eef438464f -\u044B,9aa6b535623f5eda8d2814bae7b42bb80bdf16ee55b66c94fb7ac5d3cd99b -\u044C,41fdf4f4e94e62581177c3a544c5b978d1d8f6de79ebc48b71ab3d959e5c95 -\u044D,7a9ac0551e662bd75ec432386a111f2ee5abadf01df92f95566bb5be636fa0 -\u044E,d68be52b44a83f70b5dbe55957feab1575158cdfc8ea27bacaf2e8d4e3332f73 -\u044F,1f963db6fce1325f5899015e4a99da0aa643b28ba124f50eb5256c012d342 -\u2190,f5347423ee55daa7923668fca8581985ff5389a45435321efad537af23d -\u2191,b221da4418bd3bfb42eb64d2ab429c61decb8f4bf7d4cfb77a162be3dcb0b927 -\u2192,4ef356ad2aa7b1678aecb88290e5fa5a3427e5e456ff42fb515690c67517b8 -\u2193,3b83bbccf4f0c86b12f6f79989d159454bf9281955d7e2411ce98c1b8aa38d8 -\u2196,64d06e1e25c6c675ef59f1fd69d0384f9ed055a04b112590c8a402ebade -\u2197,ae0404a389bc74b15825a72f3f1fe51439c379424894b332df952a8464 -\u2198,6eb0b57afe3ed2de68aa7e2fc1db40af576bf9dd8f0daed4d68f6b1d091b155 -\u2199,f1fc97a7a286f69c8f9ae596113a5797d59accb253155451dbd3ced1c35c44 -\u23E9,fb4c1dbd8544cfaed963df4d139bc8bac4b76ac4bbb30ab86f76fbc31ab9a70 -\u23EA,e4c41746af557a24be8a090369a591ae63d5ce9c4bf405d354247d810c7c7 -\u23F4,e5da4847272582265bdaca367237c96122b139f4e597fbc6667d3fb75fea7cf6 -\u23F5,6527ebae9f153154a7ed49c88c02b5a9a9ca7cb1618d9914a3d9df8ccb3c84 -\u2640,caaa696c0d30f8e10f462722d092b5bb51422126658c02506bc110206b465e15 -\u2642,adb25fedc616cb86047f668a4c858caca1cc0470f712423dd4aba6c3271b45d1 -\u2648,ba3654c9d6d7df1fe6d4e64c6b43dbce864213a8ad3beecfe241919270a63fe8 -\u2649,b32cf4a9690ce567421728bd49a9664dbdddf20f105dac43368851a0fb532144 -\u264A,84061722575a03f0de63039a831b6a46f364ecc1af26756c72588ecc9b2856a5 -\u264B,e86d719bedfe37e3d75c5723d75e507f8d2478625bd78b31f42234d1d51676ec -\u264C,f59f05fcb13dee75516a2ede79d28bf71a39bcff0ebbf5e967727d5291b7eb16 -\u264D,7b77da3816a6a98c741768710baf62e669679da8f9e72ead6032332a08742914 -\u264E,e2f4c8141968c618e7af8cdfbc344a2a68eaefc4d28d898a180d6954e423b0c9 -\u264F,bf17442276ba58708022f8c1b43ed372c32e27d0c35f5c3d69d38fdab3471d9e -\u2650,1d84252d9076a8e07a82bd7c5727b57a5bf1ae41feac466c76cd9b81ad916160 -\u2651,512fc704445184eb69a2327f48257d4716f7ad7fcfb04d58eeeabd510c9c6d19 -\u2652,7e8aaafeb47ad0f904a34160d950042cf80933f2bf8c805e1632901c6a8f2960 -\u2653,31dcfb4db8b62402c5da1375a5e0a5ffe683f1c2761d0951d573e15796716b3 -\u2665,da481866e6a84f21612eff2902979e9dd885f8018d9e0c4904b4db73d2ea647 -\u266A,c044d78573fac065eb066690f806561702eb14eff53e5c761d13ad1a7f627ee7 +" ",3296d3e1493fa32d827a3635a683e5bded64914d75e73aacdccba46d8fd90 +!,9a26c45d4094268a534d4c3c5a1722e449aef3ea5dbc80251751a8de839eb50 +"""",44f08cafcb2aa85a55d536866424b6d1f9bac893bb3ddf10f4a69f9e30acc9d2 +#,5d9c43c23074ca538f9e75c685c1cd6d8743f7329f2baec69a23611cfb7224 +$,8eeb18e6695c39b441d04f7ca53eda1346a5a947d4fe8ba37b33b923288b4e30 +%,bc8cdcbb9893681d8584b31ea06433f9352480545ea938a9e6edea9ac4933f96 +&,1a48cad96e457534ec6ec47643f97e126d4a846a4a6fbbb583b1f3f2858ae +',b1dce0869edbd438de25f91af2cce5c890c24b971c7183db46bfb4f3544c9e6 +(,1d5aacbd2464585039fe7f89a41b2e929eb5aa93ce8aaae76b7733899675e8d6 +),906ae26bdddc73e4ba36271da2db153974d32bb86efd2b1f5f82f826ed02e4 ++,b056bc1244fcff99344f12aba42ac23fee6ef6e3351d27d273c1572531f +",",62bec4479d659d2f10aec5a719832e8654c02c4b9ac65e6942f9bf5710d53c +-,5f67f77f9697255553fa17979cf7242ce7d75dd52fbf3cfb26c9ab54e2a71938 +.,b4ee1c91fc6e6c3bdbb553b4cfa2b9ad6b9883868c3ed64dff742e716698f +/,36c8abc8bcbe386ffcfb3acfe854c956a397fa580a814185f1f8c70dab53f64 +0,defa4a74447d0e2fa4c43f03d9661a7ee6dee51da82e02ea53aad93f715292 +1,88991697469653c9af8352fdf18d0cc9c67763cfe66175c1556aed33246c7 +2,5496c162d7c9e1bc8cf363f1bfa6f4b2ee5dec6226c228f52eb65d96a4635c +3,c4226f2eb64abc86b38b61d1497764cba03d178afc33b7b8023cf48b49311 +4,f920ecce1c8cde5dbca5938c5384f714e55bee4cca866b7283b95d69eed3d2c +5,a2c142af59f29eb35ab29c6a45e33635dcfc2a956dbd4d2e5572b0d38891b354 +6,24ddb03aa8c584168c63ece337aefb281774377db72337297de258b4cca6fba4 +7,d7de70b88368ce23a1ac6d1c4ad9131480f2ee205fd4a85ab2417af7f6bd90 +8,42647ae47b6b51f5a45eb3dcafa9b88f288ede9cebdb52a159e3110e6b8118e +9,dae461a4434196d37296ad5adf6d9d5744a0415dc61c475a6dfa6285814052 +:,d0ac7fc65a5436b7b5ae31e7d3256caf95886d98321c13a1c3fde239d471d6a +;,c692f839ea661ca6f9a6632ebc4a357e39a3b3fde26d36861b74b51e2d5a2964 +=,bd47dd856d64beef7b714e19d2947ee8ae8d999573d3fa3976877abd61121 +?,4c9269448affff444517752f725abb49b91ef380e9bd73f9bf9d83704ef3d6b5 +[,85a0f6334ad859e988be27d1671d8c6eaa246521be123379ac32a2f84777 +\,bcd72f25c8dd2b21a95b5483e6f231f02f96cfbb73a75676fafb5946781c091 +],1b52363eefb986f28979d245f5eebd4f6d6d6c131e5dfe1c831728f58138cd31 +_,d1c89d7f91942fb72d01b1368475d3322685e4da3e0cb5321622035c476843c +a,789f073e0f87d508396356f8af8dc762c531e6686bbbedea598927211f9cbb5 +b,8c361bce781d1abcfd1612e5a7e2407c5bdd29b68fcfd501ea4cb8013fcd64 +c,efe6a4f7fc31954ac7d17f702f22835e325f8bb5326cff6273c7b9cc1921ca1 +d,69c5f5d046bdee6c3996d5c4deab28b39cd0fa2d934cc2733f149d6bcbdf8ca +e,e776ffb3e81918c3a552434bd15a29cf9715794e779f0744146fc12d231347d +f,a4413bdb2a7ea27cf303d799ddc627d6feed71b01876b9b1b0e013a8e1c624 +g,af0a8a0be5d3f3f94bd32a3ed9262e662a5da911919fee91ebccf3b79bf658 +h,6728820b62115484ea4dd86f4922e2344bbcdcf9b57a8430641a53525c4e25 +i,dd9a08bd74024ac162efbf882737d7bf9ca32893ce7ac697833ed218523f11 +j,8596a936f61eaea5a254a8ea3ef4bb7ed2c03883372ba490afc05f39969ffab3 +k,d42a4802b6b2deb49cfbb4b7e267e2f9ad45da24c73286f97bef91d21616496 +l,8831ca2dc68a161e75c3edda1c6349d41f55e57c71e967d451f4f881d7876a5 +m,d8a4abe1781042452e7b8689101757fed5728316cd7f53955be8832c485eb0 +n,a0a55e9bbbfbc589f62fb7c13c4fa1614aea7e83ebfecc7bb6b2e12895aefb78 +o,a25f813f63c7429a67bb75f7a787db4f366192b60f543410a13f9c838953dc +p,c75a5dc31087f3a16f27a4ffcf2542ee8d522f25eb19d0895efc32cb9c2548 +q,2e9cd4d81ea9c65e4f54a7dfaf85a0a178bc4e16d63e28eaa48bc9b73ad034d3 +r,66362ba4b2c7b05314bf25e95f760b99fe4b341dc841770a27c244bcebfd5e8 +s,8d359aeb767e914521ff5b9d2c685db54871dc3f7e8f72f6eb8c1f2ca8c2d2 +t,47588f1a176abc5e58c5c4f8737d5e95b99a97f3b5f514e4e33beee043d37b +u,1f5efe243611d748e6509617429d7d84afcb85c5e2516d8bd5a011b5deb0b373 +v,90c23bafdfab5a331321e139427fd7b75d6ff573ab8c9584f677149e129a2ca +w,ff35777e1635a5f2fd2b822b8569783fec033bcdf44f1aa378896fdc5b536a +x,caba2d5a5ca842a2da7d25a259e77b6cba5ae655dddc24ea495641d29efc +y,651448f59b07e6e9de8b186af59b8fc7612d62b4382ae976bdfb14daf949898 +z,305a5ec074ce32498d484a919c1ef0a13163153a23554c6f2a31d10e1b2d7 +{,52a59bf723e17a9fd82f1d98307603cc593f98a74168d53a44cbb184e17dc +},e386e7e7fd923537adb88e976b931529ea61b8959b38f2bcb048f63b44443ed +\u00A1,21faf6ac6c3de0969614fdda7fb47bb81db7754cfb6f4d1c7ecd143e555b39da +\u00BF,94ae7f993907f2cc1337eeec130bc6c42eaf9f29a7a39bda39796d27032e630a +\u00E4,1fb5cfac99e2ad961bcbbb902d599dd978ae128d5fdc581a7a10f2d859 +\u00EB,cdb1213c9710519df9e637b8c3337568924e2a419b673acc18b16e61cfc15d95 +\u00F1,c97bc63fc716fafa7ee7bd37a95eca78f62b753359d4a3b0e08aceb19c41491 +\u00F6,8f2c061f954a25258b92ab2599362b40ce38d526b1e4364fcdcb7c81d245 +\u00FC,89bcaf348df57d5a7b242656cf1d75672dfeb4c53de8649739de5a82a7cc5e7 +\u0431,45ca4c9e486f74e2811f809f8dbea5d0b1498978f78f533b4458a697cb9f8 +\u0433,69753a4ae315fc6372ba5977d47c49b91f734b097e521e6f7cdf7ae843b466 +\u0434,3d2793ebb9c6925fd819d8cc71d9204995de29d9ada561f9fcd24db78771722 +\u0436,6ef7d56613dc61ca6872a197e7e9afd59ea4a1107f48d3f84f644fc1896 +\u0437,79e171c791ede18c4960f9546cb3dbd333518a6e8cf92f67052ffec3cf37613 +\u0438,9fcbeefa2af5ec7dad2d4365c4a8547288ed71702fda95c6606642db8f2c +\u0439,4aa6272b6ae387661e3bc4a7bdfd1e23fb8f0702fb3ca9b3a1fba16be960 +\u043B,dc9e587118965c9afbaf03c9a37b0a92a20a8d9176776cf8c94f57fb5c86033 +\u043F,181f3bb4afeba98ed5db88fca9b4b52e243fd5e93246961ec8738c2b7e7e5a8 +\u0443,8ea36ccca66e83922de5e4648bb754b0123e47ac0f122cb79838b447dc88 +\u0444,246a757a472892f0dd50b8f6d72b4accfc4d72ea8de8d94bd94c8823a7f8a +\u0446,f6484130c771c5acec99a91aacfe8fe2dca56046b695c406d6b333e2d5b37fc +\u0447,9461bff3b39e1cd8e4fd3c4368eb96533cd540569d0f3b91604571a5c44d9f +\u0448,9b1f88415c8c446311b0263d1b81267dbec2073bb4325d8abdedffee5d7d42 +\u0449,813d49167596dbfd563e7d7baa93dbee1ab2f815566c615889c6f4a2b9dc +\u044A,a93a37bf63fa5dc5a0cf7fb711d56a0819262dfb21d133de3eef438464f +\u044B,9aa6b535623f5eda8d2814bae7b42bb80bdf16ee55b66c94fb7ac5d3cd99b +\u044C,41fdf4f4e94e62581177c3a544c5b978d1d8f6de79ebc48b71ab3d959e5c95 +\u044D,7a9ac0551e662bd75ec432386a111f2ee5abadf01df92f95566bb5be636fa0 +\u044E,d68be52b44a83f70b5dbe55957feab1575158cdfc8ea27bacaf2e8d4e3332f73 +\u044F,1f963db6fce1325f5899015e4a99da0aa643b28ba124f50eb5256c012d342 +\u2190,f5347423ee55daa7923668fca8581985ff5389a45435321efad537af23d +\u2191,b221da4418bd3bfb42eb64d2ab429c61decb8f4bf7d4cfb77a162be3dcb0b927 +\u2192,4ef356ad2aa7b1678aecb88290e5fa5a3427e5e456ff42fb515690c67517b8 +\u2193,3b83bbccf4f0c86b12f6f79989d159454bf9281955d7e2411ce98c1b8aa38d8 +\u2196,64d06e1e25c6c675ef59f1fd69d0384f9ed055a04b112590c8a402ebade +\u2197,ae0404a389bc74b15825a72f3f1fe51439c379424894b332df952a8464 +\u2198,6eb0b57afe3ed2de68aa7e2fc1db40af576bf9dd8f0daed4d68f6b1d091b155 +\u2199,f1fc97a7a286f69c8f9ae596113a5797d59accb253155451dbd3ced1c35c44 +\u23E9,fb4c1dbd8544cfaed963df4d139bc8bac4b76ac4bbb30ab86f76fbc31ab9a70 +\u23EA,e4c41746af557a24be8a090369a591ae63d5ce9c4bf405d354247d810c7c7 +\u23F4,e5da4847272582265bdaca367237c96122b139f4e597fbc6667d3fb75fea7cf6 +\u23F5,6527ebae9f153154a7ed49c88c02b5a9a9ca7cb1618d9914a3d9df8ccb3c84 +\u2640,caaa696c0d30f8e10f462722d092b5bb51422126658c02506bc110206b465e15 +\u2642,adb25fedc616cb86047f668a4c858caca1cc0470f712423dd4aba6c3271b45d1 +\u2648,ba3654c9d6d7df1fe6d4e64c6b43dbce864213a8ad3beecfe241919270a63fe8 +\u2649,b32cf4a9690ce567421728bd49a9664dbdddf20f105dac43368851a0fb532144 +\u264A,84061722575a03f0de63039a831b6a46f364ecc1af26756c72588ecc9b2856a5 +\u264B,e86d719bedfe37e3d75c5723d75e507f8d2478625bd78b31f42234d1d51676ec +\u264C,f59f05fcb13dee75516a2ede79d28bf71a39bcff0ebbf5e967727d5291b7eb16 +\u264D,7b77da3816a6a98c741768710baf62e669679da8f9e72ead6032332a08742914 +\u264E,e2f4c8141968c618e7af8cdfbc344a2a68eaefc4d28d898a180d6954e423b0c9 +\u264F,bf17442276ba58708022f8c1b43ed372c32e27d0c35f5c3d69d38fdab3471d9e +\u2650,1d84252d9076a8e07a82bd7c5727b57a5bf1ae41feac466c76cd9b81ad916160 +\u2651,512fc704445184eb69a2327f48257d4716f7ad7fcfb04d58eeeabd510c9c6d19 +\u2652,7e8aaafeb47ad0f904a34160d950042cf80933f2bf8c805e1632901c6a8f2960 +\u2653,31dcfb4db8b62402c5da1375a5e0a5ffe683f1c2761d0951d573e15796716b3 +\u2665,da481866e6a84f21612eff2902979e9dd885f8018d9e0c4904b4db73d2ea647 +\u266A,c044d78573fac065eb066690f806561702eb14eff53e5c761d13ad1a7f627ee7 \u2713,a92e31ffb59c90ab08fc9dc1fe26802035a3a47c42fee63423bcdb4262ecb9b6 \ No newline at end of file diff --git a/src/main/resources/fonts/magenta.csv b/IF/src/main/resources/fonts/magenta.csv similarity index 98% rename from src/main/resources/fonts/magenta.csv rename to IF/src/main/resources/fonts/magenta.csv index 48f70e4c..1edf0898 100644 --- a/src/main/resources/fonts/magenta.csv +++ b/IF/src/main/resources/fonts/magenta.csv @@ -1,118 +1,118 @@ -" ",fb109ffef636153f5bb8c045b0f910b870e4d15c26a9f9670a8bfa879cedbd8 -!,35245a63a7d1629c58c9123253f1f178bfe99e834bddb1c2699e9cbb4d3df1fb -"""",202690acd38be51f42c9a11796d2d4274991c75f61c8ba6ea96bc3bc255e787 -#,762637164b431299b82017e4a843aebb4069786bd89e8806a7e885b5a5f85 -$,ac6867e884f599e238a134d4706516d57baf2ed77797bf43d946d39708247236 -%,54f662959451cef32ea54967157d42e937943faea48facf3533dba8a96a6d4 -&,81378d6af95951de5e0c8d0ff6de1795d297f2563d568306c9a4644542991c7 -',e8db8ffa5f88908c6287b69fb78a92d7fc08cae5bf1b54b29973938be9463 -(,c91c92e932fcbb121437f2761dfba7af90f51f649cc2b8e61ce50e2a69f -),b238031344d05330288bb8e9dc1d3fba59d5fe4b13481214914c6475146 -+,11715becc4b7eb1768d4a0376f7759ffbcc57909f8fd414d05a4094b6b3abf0 -",",494513fb692dad4b39b82bb32bb53274c02546c52b672cb58ee7f329f4f14 --,e62e124f3c457b4061cd87a37198b2fbebdbe5b044fa6cce45e7d82ab25df471 -.,7ed67bb0595d2945341f3afe7e88712724b9d5ca148bc5c8fcd3e291e47c3e0 -/,4028e0971672d9280183617128833be843be62cd437dda53b1d487f71299cc -0,f94385dfe58cf1a73cc60949cc680e36556d1b8ff83f9e18197364d3c78a3 -1,872f454c72178181f86ae7d2fbbbc11eaa65e9ae39b9dd77dd803c1f44b6c -2,1577c294e23df158904a582ed1991a5a30c0657e78e2ed43e126f8d5ad21ce8b -3,149eeb7546fccd145254c5682497b8a9a82297c9b60567230f3d17f7dc258 -4,2850327173de9782fffd37442cebf478d6cdbe671731421fbad0dc2b35d588a8 -5,58787fdc93ea2a7251b13e29823227ee4e2915a8ba6d399ea8dd19e5da87c5e -6,83e8a2c8c3f5ea4ae1599e0c17052c5443e736a233b4ee3c9641f3b9cc9d -7,68c9849a03d54b12ef9a4c6f92946ed94d4b2a884eec2b4289ed1dd7cb7128 -8,4badf86af5a6797fc5f8d340ed914ec042881610a5e8b8f9c4f0f4cdd722 -9,b96727df2d4c14b1b367e0376d8ad2c11953673a1647a3196a51fd4322a4 -:,b540284f8d611218e5338b5bc86e362f4db1b6e41a948df18aecf1e5dc3d175 -;,896cd87bc781c26fac5f84b7fdbfec27633d6f9becd87e7fe5e0feed579c30b1 -=,255c3eeff32e7cdd42865c8d06339a6d92ca5b8b2dbaa569a671cd8215e5015 -?,a3f08b148a06ddc8581977917e1b9dca4e22da36591bb4a5949563593e8bd -[,173bb246fcd48c92a95d8ed80d3d5b4107f41d85b874b7b7e35d56e9e7cf62e -\,da478ce03b596dcf4f69341b93d172c5d830ea2e3467162efe76e2d2295dda33 -],4472665e327434998a46c6cb3e9f688cd5ee7982d44fda9c4a5e9b56ac5ded -_,82dab6160ca1c6f1becdac1857975bdce271e5bf64cac11d6a1469215d1c3a -a,6926631f5be0d5a941c6fd98c72fb34879245fa9ffb14cf80d6259a6a46632b -b,8f3aa89413f893f96872239c83d16f842ca90d54a21bdafbc7e8675d0ff9a -c,5931b97de7a253b63dff567ea95077df93d4b11c6325f6435f6a9103b7122f0 -d,4f91579afcb365b76f23c427a5641a697e956ccfdce25be1c62c7c4ef556d1 -e,b37c252bb665df7eea53d0589f73bdbc7c8672886c2ba65de35adbe0f1fcd75f -f,a9f9d1b2de7cdb71cf1968b64f9bccfdfd739fb006d62db78a73c567060f761 -g,586ca01be0c28c56c53ad793e7794136b91a6ffee94404546d6756a781788e0 -h,fba82c11ab9bf33b436c9aa87624922522b416d8b500e812d225a7528d7ec5 -i,fd9f71fca90adc16b75a8f121b9b7c2edc34f364dc9e8833ce8e3ac34d67cbf -j,2d322d4ef7f90f4754375638a58d3255b143f203176335b41dc518a6a96aa1 -k,326c8bde15079e380485dfe624f979a6927f8248af8b8e1ef47ea3fa0f126db -l,3bfc5b56b8403c951a71f6bd391bfbe2cce8a657f106d711b6a18552e7253 -m,2a3ba8f6ff60ad17a912521811d3ff80ea80e0d67dba94308bbb5e58aa2a1b9 -n,e592c9ca37756a4d0371068f2d39b37497de79f541eddc9561e2726d029def8 -o,fac07cdf289a0331b92d4e3ad8f603e16d529a130f1fb4db0fd27ac585e537 -p,9281fb7eff54af7f9f318d8abd397b82b6f157447deadafa18b88ab3536f7b -q,b36e2bc36634a5da41e77ad346be84f39d6ac9b3b93ac15419d8b245783a2b5e -r,c13f5fb5883e328caaba25f4fe993877ebbb24cd3a9db2e1ddac1fef0cbbc -s,d432e7dc658180aea492fa263f82a3b7b64555abd125fdac4e247d8770bb03a -t,6d2e55ddd8413696addc64d4b237e2ef13d4fb732af23ff8e9e11b9cfc1d7a88 -u,fff8c43f3ba46e790dba9cded2466f7e466e1b57913b217ce529152b252e1 -v,9289af4e9223cfb9a7fca11b4d2934ec8f3967d2e9d25c01dad35f54e8e89 -w,70c1cd5ef99b5a23b537d66cfbb5ccac8f6d365a3ac69d41e63abe578a93a -x,f9982618aa5c8b94372a16c6662cb2f3e977412e701ec6c2376ccf39fddbb -y,fb8b566d1d61ed28aba15bef951345a88bedf8cb45244ea8c4f65a8315d84 -z,5c15c631df6946ee46061e7743ef1e016d11c64fa8f4a8a5e38f4a45aca4d -{,55a0b9ea616ea14463f4d3434ebbce2e9b0c3a1b29892cd1d4c939138d0d71c -},9918499317920d9b361a632b69fc2b3ab4b722992e3c51ce1c299d04a4b89a9 -\u00A1,1fff26b2edb795d4794badd6b72f7b7cc71aa8c068768e77970dcf1daa401184 -\u00BF,23b434d8e40d8cbadff6825c61c9a1fdf248efe306641f301c549f811121da34 -\u00E4,6b8b60d5a9e7cfc4a4c7c4e825a69d477a6b2479dca1b9127cc9b5dfad2b -\u00EB,bdab3cabc694ea945ac7723cae2ce25f237798dec7e3a9368e3c2d9c498ec -\u00F1,dc54a3a7ea2461c73c6f68fc712b851d853fe8434b8a86b381346321a5f81350 -\u00F6,6a4b95c19d24308ce333346d41825e9c7ce5e25f4bc0745cf8549186ab62b475 -\u00FC,2978c8cebce12c617c99113220c71d6abfb7c4a86121ca621871e77e76b63e64 -\u0431,e9a69e6bf01a3e15733975e119bcfdbde26fb96d55813ed8d13f87e46223287 -\u0433,9336f3423c816dec8f5a2daa0b728d7f53ce4c752aede8061aeafa3b9652d -\u0434,3db8682a58c2f38bab75598bcbffc4736219e9ed032548c359d789e2e987d54 -\u0436,cb95c1f36b378f1bf1208a34a78c6eef93bbb579e6a9476884f89bf7cbb2eeb1 -\u0437,74168aa3332b4ebe23fd2ba8e0ea9ecde63be35649f678d2d01dc84be663219 -\u0438,e481f42e3172cb91afaec14b40c01b82a12aacc9ed2dda4d277d6cd92f870 -\u0439,798b9f05b62701e6a27982d80d429fa3b0ed2349b78231dcb8ad6bf7991e7f -\u043B,c12385505991b6e8fcb7fcf781baf7f4abc060a09a3648ec7653df7a823 -\u043F,27cd9a56f61dd1a8fbb8741ff7137a14306152b924565498a8136c5cd8763 -\u0443,d5f26155def51e4a752333aea3a94a03d7329b359ab2886c66aa9176b9d636e -\u0444,383087a15dee6cfc9a8e3d299698ba3fc03af1f372e39a506fba40462ec5bd -\u0446,9f941b7ea7758b8fb5bf89e3d999d5d5f2f40c7bf1ac1cba9897020d851e -\u0447,7f10a4602602caab127f9a2ce4bcf442dbcdbae7d9f745d988dbe3a27e239f -\u0448,a2e264ec67b74ac3c7d627bbe421dc5ae9f9910daaf253ea05c73f08c4c3727 -\u0449,c1d4ff13d09716b8fd30d75e1d121f544878f66161a9a1a24221e852921c815 -\u044A,d57398d05fade095811eee8636105b8a715b8722709e5a876eb893ed3f786b -\u044B,bacc49d5b3a0f8743ac55699287f5b59c7abf63440f56d9d94c24fab13f3ffed -\u044C,63feca9efc7db43f6aaad3ed3436f099f56df57186b264c4cb10b675ab957d4 -\u044D,9119677532b4e7408756cedbc3a605bbf943a3583f9388c9a9979cc576dc59 -\u044E,47a56de0178dcbf91ee6bd673374e7f68b5780df1f737a223eeead82b5f5 -\u044F,f718617477d629691044df13285049156252bd13e69bf3f59c4458498894455c -\u2190,9dbd8ec46192a955c6bd651ab4d86f9867e4d4bd99af21ca92ec9d26f86da91 -\u2191,cf114bec6a6fddea37d2b8767ace26b0d18283075ffd85d5687c55a7b4f1e8c -\u2192,8078e16892a2c9c02305213cce60483ab7ada47f13af9b8da87ce63dd8347 -\u2193,7db9629cab72e021c8b561650c586b99bfdb3f6a9a962cc6e5611222d3558ef -\u2196,767c2145d396715a34c113ef57fc8cb5b09b6f61fc36fe92eccdd9be1aae3 -\u2197,35957b3fb0378676adbfee1be2fe982e744d7d7c8a48a3b73a9bd4c99bd94eb -\u2198,7b8f23d1e79979256af290925aa03fb999819032ca2c4196740acfc9e9c969c -\u2199,6c75d5e2595bf928b544cd945bd6478fe39bf5b7c631ee3a2ff7724b4477f3 -\u23E9,3d3374fe170eec4f11b3291459ccc4bd3aacc21e2d88fd5b7218a2e06099 -\u23EA,8be6d327dd61931153c5ff7cb9be9b350cd12359d94473018156b26f2dd8e -\u23F4,8f9994a477768d035e1b48dbbc0f6cddab16e8df9bd897ad353adead9226 -\u23F5,a0f3103ebbcb34d73f1fe28b1fe8d8fac088aeb4e9e950bc37a132f17dc430 -\u2640,260420fd427c3fdab8a788caf679c370a0937239f3c0c5600c4d106a1827b7ff -\u2642,77cb3b85c14d9ae5ff0bb81545e820eac7db6832812303487594625f4f8219d7 -\u2648,f0fd56c4ac5bd90341ca2a0a1f4b5c2a04c7a718ececa223ae0c28966a7b61ad -\u2649,5b7acb11da58c799f34827c75f7b61b64b3566ad5f5c4e3491784f93c393bd11 -\u264A,edd858b7a80e6b25a565dee6ebc3a593e1790f9d0026d42da636d55771abd1b8 -\u264B,4fdf65b5fb4eba6d6bb08d3682d5d9cd4ba8042a445d390f30845afa2cbee58b -\u264C,83d14162d88bc001ff764e46b9e3a58d9c0ceca7f3db4c0d330b118db182ba88 -\u264D,4faaf74315ef95555efa060349d066627a84dde471d58a814d8171cb282ffaa0 -\u264E,fdd4d6d32ac9342af516dd89477a7c6e52d96b94139b2c4fa9089718453246c2 -\u264F,9864389a94dfd3b16035e72741912448a2378fddee46744134e258de388cba1c -\u2650,20a716c278b43f268a3d6f25de1f6c4d0c8977e9528a559bdcff2281c8e98a27 -\u2651,392ddb9c75c81cd540d0e82833a33bf64eced259dfa22e41f1fe19ec5600bb6d -\u2652,d0ded982d28acb916469ab10ebd2b8902827ea6ae9154ba4e720db991a980651 -\u2653,20031cf347f6079b4d18ddf4b11e26604b34029185b8c4e35e2ee24059af518e -\u2665,5fee29ba57abbe05ce2c2ce36cc9719db7a5c6a14416488354fe9a842c29 -\u266A,b4469b39fe2bbb46883d0d2090437b18c885b82ee6ac8cab74f7606afc41ab50 +" ",fb109ffef636153f5bb8c045b0f910b870e4d15c26a9f9670a8bfa879cedbd8 +!,35245a63a7d1629c58c9123253f1f178bfe99e834bddb1c2699e9cbb4d3df1fb +"""",202690acd38be51f42c9a11796d2d4274991c75f61c8ba6ea96bc3bc255e787 +#,762637164b431299b82017e4a843aebb4069786bd89e8806a7e885b5a5f85 +$,ac6867e884f599e238a134d4706516d57baf2ed77797bf43d946d39708247236 +%,54f662959451cef32ea54967157d42e937943faea48facf3533dba8a96a6d4 +&,81378d6af95951de5e0c8d0ff6de1795d297f2563d568306c9a4644542991c7 +',e8db8ffa5f88908c6287b69fb78a92d7fc08cae5bf1b54b29973938be9463 +(,c91c92e932fcbb121437f2761dfba7af90f51f649cc2b8e61ce50e2a69f +),b238031344d05330288bb8e9dc1d3fba59d5fe4b13481214914c6475146 ++,11715becc4b7eb1768d4a0376f7759ffbcc57909f8fd414d05a4094b6b3abf0 +",",494513fb692dad4b39b82bb32bb53274c02546c52b672cb58ee7f329f4f14 +-,e62e124f3c457b4061cd87a37198b2fbebdbe5b044fa6cce45e7d82ab25df471 +.,7ed67bb0595d2945341f3afe7e88712724b9d5ca148bc5c8fcd3e291e47c3e0 +/,4028e0971672d9280183617128833be843be62cd437dda53b1d487f71299cc +0,f94385dfe58cf1a73cc60949cc680e36556d1b8ff83f9e18197364d3c78a3 +1,872f454c72178181f86ae7d2fbbbc11eaa65e9ae39b9dd77dd803c1f44b6c +2,1577c294e23df158904a582ed1991a5a30c0657e78e2ed43e126f8d5ad21ce8b +3,149eeb7546fccd145254c5682497b8a9a82297c9b60567230f3d17f7dc258 +4,2850327173de9782fffd37442cebf478d6cdbe671731421fbad0dc2b35d588a8 +5,58787fdc93ea2a7251b13e29823227ee4e2915a8ba6d399ea8dd19e5da87c5e +6,83e8a2c8c3f5ea4ae1599e0c17052c5443e736a233b4ee3c9641f3b9cc9d +7,68c9849a03d54b12ef9a4c6f92946ed94d4b2a884eec2b4289ed1dd7cb7128 +8,4badf86af5a6797fc5f8d340ed914ec042881610a5e8b8f9c4f0f4cdd722 +9,b96727df2d4c14b1b367e0376d8ad2c11953673a1647a3196a51fd4322a4 +:,b540284f8d611218e5338b5bc86e362f4db1b6e41a948df18aecf1e5dc3d175 +;,896cd87bc781c26fac5f84b7fdbfec27633d6f9becd87e7fe5e0feed579c30b1 +=,255c3eeff32e7cdd42865c8d06339a6d92ca5b8b2dbaa569a671cd8215e5015 +?,a3f08b148a06ddc8581977917e1b9dca4e22da36591bb4a5949563593e8bd +[,173bb246fcd48c92a95d8ed80d3d5b4107f41d85b874b7b7e35d56e9e7cf62e +\,da478ce03b596dcf4f69341b93d172c5d830ea2e3467162efe76e2d2295dda33 +],4472665e327434998a46c6cb3e9f688cd5ee7982d44fda9c4a5e9b56ac5ded +_,82dab6160ca1c6f1becdac1857975bdce271e5bf64cac11d6a1469215d1c3a +a,6926631f5be0d5a941c6fd98c72fb34879245fa9ffb14cf80d6259a6a46632b +b,8f3aa89413f893f96872239c83d16f842ca90d54a21bdafbc7e8675d0ff9a +c,5931b97de7a253b63dff567ea95077df93d4b11c6325f6435f6a9103b7122f0 +d,4f91579afcb365b76f23c427a5641a697e956ccfdce25be1c62c7c4ef556d1 +e,b37c252bb665df7eea53d0589f73bdbc7c8672886c2ba65de35adbe0f1fcd75f +f,a9f9d1b2de7cdb71cf1968b64f9bccfdfd739fb006d62db78a73c567060f761 +g,586ca01be0c28c56c53ad793e7794136b91a6ffee94404546d6756a781788e0 +h,fba82c11ab9bf33b436c9aa87624922522b416d8b500e812d225a7528d7ec5 +i,fd9f71fca90adc16b75a8f121b9b7c2edc34f364dc9e8833ce8e3ac34d67cbf +j,2d322d4ef7f90f4754375638a58d3255b143f203176335b41dc518a6a96aa1 +k,326c8bde15079e380485dfe624f979a6927f8248af8b8e1ef47ea3fa0f126db +l,3bfc5b56b8403c951a71f6bd391bfbe2cce8a657f106d711b6a18552e7253 +m,2a3ba8f6ff60ad17a912521811d3ff80ea80e0d67dba94308bbb5e58aa2a1b9 +n,e592c9ca37756a4d0371068f2d39b37497de79f541eddc9561e2726d029def8 +o,fac07cdf289a0331b92d4e3ad8f603e16d529a130f1fb4db0fd27ac585e537 +p,9281fb7eff54af7f9f318d8abd397b82b6f157447deadafa18b88ab3536f7b +q,b36e2bc36634a5da41e77ad346be84f39d6ac9b3b93ac15419d8b245783a2b5e +r,c13f5fb5883e328caaba25f4fe993877ebbb24cd3a9db2e1ddac1fef0cbbc +s,d432e7dc658180aea492fa263f82a3b7b64555abd125fdac4e247d8770bb03a +t,6d2e55ddd8413696addc64d4b237e2ef13d4fb732af23ff8e9e11b9cfc1d7a88 +u,fff8c43f3ba46e790dba9cded2466f7e466e1b57913b217ce529152b252e1 +v,9289af4e9223cfb9a7fca11b4d2934ec8f3967d2e9d25c01dad35f54e8e89 +w,70c1cd5ef99b5a23b537d66cfbb5ccac8f6d365a3ac69d41e63abe578a93a +x,f9982618aa5c8b94372a16c6662cb2f3e977412e701ec6c2376ccf39fddbb +y,fb8b566d1d61ed28aba15bef951345a88bedf8cb45244ea8c4f65a8315d84 +z,5c15c631df6946ee46061e7743ef1e016d11c64fa8f4a8a5e38f4a45aca4d +{,55a0b9ea616ea14463f4d3434ebbce2e9b0c3a1b29892cd1d4c939138d0d71c +},9918499317920d9b361a632b69fc2b3ab4b722992e3c51ce1c299d04a4b89a9 +\u00A1,1fff26b2edb795d4794badd6b72f7b7cc71aa8c068768e77970dcf1daa401184 +\u00BF,23b434d8e40d8cbadff6825c61c9a1fdf248efe306641f301c549f811121da34 +\u00E4,6b8b60d5a9e7cfc4a4c7c4e825a69d477a6b2479dca1b9127cc9b5dfad2b +\u00EB,bdab3cabc694ea945ac7723cae2ce25f237798dec7e3a9368e3c2d9c498ec +\u00F1,dc54a3a7ea2461c73c6f68fc712b851d853fe8434b8a86b381346321a5f81350 +\u00F6,6a4b95c19d24308ce333346d41825e9c7ce5e25f4bc0745cf8549186ab62b475 +\u00FC,2978c8cebce12c617c99113220c71d6abfb7c4a86121ca621871e77e76b63e64 +\u0431,e9a69e6bf01a3e15733975e119bcfdbde26fb96d55813ed8d13f87e46223287 +\u0433,9336f3423c816dec8f5a2daa0b728d7f53ce4c752aede8061aeafa3b9652d +\u0434,3db8682a58c2f38bab75598bcbffc4736219e9ed032548c359d789e2e987d54 +\u0436,cb95c1f36b378f1bf1208a34a78c6eef93bbb579e6a9476884f89bf7cbb2eeb1 +\u0437,74168aa3332b4ebe23fd2ba8e0ea9ecde63be35649f678d2d01dc84be663219 +\u0438,e481f42e3172cb91afaec14b40c01b82a12aacc9ed2dda4d277d6cd92f870 +\u0439,798b9f05b62701e6a27982d80d429fa3b0ed2349b78231dcb8ad6bf7991e7f +\u043B,c12385505991b6e8fcb7fcf781baf7f4abc060a09a3648ec7653df7a823 +\u043F,27cd9a56f61dd1a8fbb8741ff7137a14306152b924565498a8136c5cd8763 +\u0443,d5f26155def51e4a752333aea3a94a03d7329b359ab2886c66aa9176b9d636e +\u0444,383087a15dee6cfc9a8e3d299698ba3fc03af1f372e39a506fba40462ec5bd +\u0446,9f941b7ea7758b8fb5bf89e3d999d5d5f2f40c7bf1ac1cba9897020d851e +\u0447,7f10a4602602caab127f9a2ce4bcf442dbcdbae7d9f745d988dbe3a27e239f +\u0448,a2e264ec67b74ac3c7d627bbe421dc5ae9f9910daaf253ea05c73f08c4c3727 +\u0449,c1d4ff13d09716b8fd30d75e1d121f544878f66161a9a1a24221e852921c815 +\u044A,d57398d05fade095811eee8636105b8a715b8722709e5a876eb893ed3f786b +\u044B,bacc49d5b3a0f8743ac55699287f5b59c7abf63440f56d9d94c24fab13f3ffed +\u044C,63feca9efc7db43f6aaad3ed3436f099f56df57186b264c4cb10b675ab957d4 +\u044D,9119677532b4e7408756cedbc3a605bbf943a3583f9388c9a9979cc576dc59 +\u044E,47a56de0178dcbf91ee6bd673374e7f68b5780df1f737a223eeead82b5f5 +\u044F,f718617477d629691044df13285049156252bd13e69bf3f59c4458498894455c +\u2190,9dbd8ec46192a955c6bd651ab4d86f9867e4d4bd99af21ca92ec9d26f86da91 +\u2191,cf114bec6a6fddea37d2b8767ace26b0d18283075ffd85d5687c55a7b4f1e8c +\u2192,8078e16892a2c9c02305213cce60483ab7ada47f13af9b8da87ce63dd8347 +\u2193,7db9629cab72e021c8b561650c586b99bfdb3f6a9a962cc6e5611222d3558ef +\u2196,767c2145d396715a34c113ef57fc8cb5b09b6f61fc36fe92eccdd9be1aae3 +\u2197,35957b3fb0378676adbfee1be2fe982e744d7d7c8a48a3b73a9bd4c99bd94eb +\u2198,7b8f23d1e79979256af290925aa03fb999819032ca2c4196740acfc9e9c969c +\u2199,6c75d5e2595bf928b544cd945bd6478fe39bf5b7c631ee3a2ff7724b4477f3 +\u23E9,3d3374fe170eec4f11b3291459ccc4bd3aacc21e2d88fd5b7218a2e06099 +\u23EA,8be6d327dd61931153c5ff7cb9be9b350cd12359d94473018156b26f2dd8e +\u23F4,8f9994a477768d035e1b48dbbc0f6cddab16e8df9bd897ad353adead9226 +\u23F5,a0f3103ebbcb34d73f1fe28b1fe8d8fac088aeb4e9e950bc37a132f17dc430 +\u2640,260420fd427c3fdab8a788caf679c370a0937239f3c0c5600c4d106a1827b7ff +\u2642,77cb3b85c14d9ae5ff0bb81545e820eac7db6832812303487594625f4f8219d7 +\u2648,f0fd56c4ac5bd90341ca2a0a1f4b5c2a04c7a718ececa223ae0c28966a7b61ad +\u2649,5b7acb11da58c799f34827c75f7b61b64b3566ad5f5c4e3491784f93c393bd11 +\u264A,edd858b7a80e6b25a565dee6ebc3a593e1790f9d0026d42da636d55771abd1b8 +\u264B,4fdf65b5fb4eba6d6bb08d3682d5d9cd4ba8042a445d390f30845afa2cbee58b +\u264C,83d14162d88bc001ff764e46b9e3a58d9c0ceca7f3db4c0d330b118db182ba88 +\u264D,4faaf74315ef95555efa060349d066627a84dde471d58a814d8171cb282ffaa0 +\u264E,fdd4d6d32ac9342af516dd89477a7c6e52d96b94139b2c4fa9089718453246c2 +\u264F,9864389a94dfd3b16035e72741912448a2378fddee46744134e258de388cba1c +\u2650,20a716c278b43f268a3d6f25de1f6c4d0c8977e9528a559bdcff2281c8e98a27 +\u2651,392ddb9c75c81cd540d0e82833a33bf64eced259dfa22e41f1fe19ec5600bb6d +\u2652,d0ded982d28acb916469ab10ebd2b8902827ea6ae9154ba4e720db991a980651 +\u2653,20031cf347f6079b4d18ddf4b11e26604b34029185b8c4e35e2ee24059af518e +\u2665,5fee29ba57abbe05ce2c2ce36cc9719db7a5c6a14416488354fe9a842c29 +\u266A,b4469b39fe2bbb46883d0d2090437b18c885b82ee6ac8cab74f7606afc41ab50 \u2713,77420f8cc510ebdcc9becf60b3500627fd715a32305088907824710604b87d56 \ No newline at end of file diff --git a/src/main/resources/fonts/monitor.csv b/IF/src/main/resources/fonts/monitor.csv similarity index 98% rename from src/main/resources/fonts/monitor.csv rename to IF/src/main/resources/fonts/monitor.csv index 4e0b8837..5b011922 100644 --- a/src/main/resources/fonts/monitor.csv +++ b/IF/src/main/resources/fonts/monitor.csv @@ -1,147 +1,147 @@ -" ",2fd253c4c6d66ed6694bec818aac1be7594a3dd8e59438d01cb76737f959 -!,c415aace88a32b9ef223746e4af85ecd64ddd78653cbc6cd0f125635767 -"""",9afa262136b81f31f864af1a6e975a8e4bc87cd5b592738ec34bcc5ed35cb1 -#,8928ef335313214bb8cc137df153c1bee7b7a9d1e8e6281fe9d362d91fe9d89 -$,7c261b18e8b1710e86fa67edc918aff0703e3a137325f1826608578c87a38c7c -%,91f4c4dad810a2156871403effe9678ce91b28adaae05dc55ccbb199c1533c6 -&,a86b6c29f82bd47c67a3939dafcdee17aa9d3a01c8eb599e15eb908b70335e35 -',e5709bb39d44b0863ffb18c2661317e3b995198bc6bd95ccda8f7de5cc31b6 -(,9f51baecc99e111fb27cdca5479a84663d4b83f821ec02018b9d7c82df6655 -),fb7fe8bc73432154458a53fbb434539cd5d3dc69a3e99a5a929ae66e45746c -+,5c52364520b3a9bb8ed515c01f80ab7b977025cd0b0ff6d86468a5164c6fb78 -",",7a4e15c32fd16e20fa4e46322730294879fb83e23bdda6cdaadfbf12cedb5 --,c99bc7dfd3cad70ebe12fc35db6fd3f1d652c6fea9929fa3b22fe6eef5c1 -.,01afd801443d4c4b98c6daf84aa8d2b0c2b48a4f7161ad54e6fd55734945 -/,712f05e103bed4f58e48de572d6886567dcc17b248535902ac277cb30cfca6 -0,118977cf8f2ff0ea92e6db6a56cea1f5f8ae44c7ca937afae7e526cc98dbd8 -1,bf9694a52212719e113dc7e6af698a9fc3ab63c74995ffadc57d346face4e75 -2,40ebc3352c252d235713d5cbcbca879025221caaae9c4ae0cab792d974e65 -3,5079c9ee988b57b2d232680f8bca9606c49adfdc9cc18e0fc8c228f93ccf -4,8f3c55e7951b484d194f6f4af16f5a6adf586b258579df3b8be2b385691e5527 -5,41205fd686863479c216b2d84c7c6189d292ffbe7331ac3b7696abdeb23494 -6,2b88618becf61abc5bc94c115bca13dca3e2b9bd9d0ccb6856612ba8419f -7,a83147e25484477e1be63edeab28bd5b4e8adebc8bc83e19d52b17253c4f -8,d7a033ea86a2a923901a64a9dca08c2e254c17118aae592bf81e95f70156e35 -9,59b99057bd24bf38d9aa5e19f8a742ac3418596ac7203282c7e01fd7c730e0e1 -:,3ab03d3ecb6d6df720168dfbbabcb2638db5c563a5d4475979334d3b83520ee -;,199960cb695c60103c3ff6e3971e36dbce2d55781227ccdd1fac411ddbbd7b -=,7aad7ef306def67f97deba90a85f65118abe6b4154d96b767e3b4f39bc6dc -?,4b7f663d65cded7bd3651bddd6db546360dd773abbdaf48b83aee08e1cbe14 -A,18fabedcd35a75129f87d0dc231f1ebc6650274f5b692ec5a372ab9b5339d1f -B,63f3821523855fcd40f39368dd5bab644d3224bb4f291f9cd33ec6c3d8a49d24 -C,5f1a954f8577a33e51251e465c7d7212ff67c01ed0fad255ca05aff5a229a -D,94e5312e7db6494891f4cc45a1cc493429bb3666783d7bd459010c22b9b82a4 -E,b821d7684b699d5767986dbefa67d03fb391a563be9866ea2918259142d9a5 -F,c6623627c3f5297bff95f742b8aff8e5be3b1d78b5dd6c693314da11a7eb9058 -G,54eff07b361a94d4059bb76c2d49475f6d3e8c194f0a35cc130521b0f9fd -H,e66027789d2dbf542ae16c26a882475cd0784acf4fd7b0b5f4226e5f1c6f62e -I,bcaa55fede2cc4b0560d5a1e4eee73e9a353b63443ca83ac7db5fae2dd4e939 -J,5e8f6864deaf7a65d9d0eacc2920799093dfd34248dc4b7eef6492c6211314d5 -K,2d87f872bc5a587b7d1a49d39d7ebf1d18b70e6998be922c241bf298e79b6 -L,7a41e1defe955dcfbb47ae47361697ad16b8688a936581d3d3a6dad18229324 -M,bc7ed44bdabf4b6cf1c514417382f9158240e7a89d7289f4c27bb26df9f8 -N,666eb97a1311b27126b2c7b1a77fb68cc674d13de58b270cff69b4c7fa6713 -O,b8d519b619952f1a1097f9245a81b57dba97149e4fdad6ef8bf4842543f3ce8b -P,727d942d5c95a7395b45a9c711b35f6e62baebe49b817c6ee55145d4a70 -Q,5861e1edfdd5109dbd54cdde28d4512cd61631d1f467bf1e8fe2196ab7adf54a -R,c9731704b6973ab0e4beb8d81be782fdbf6fe4d7ac54b84a94317ab37c17 -S,df8844cda8995edc47641681b89cd5a22858b78ff5641d282633232dc8ca -T,5025c0424973b359c9b21d49229edf7f57741d8f78a640a942ae25db183eb7e -U,e6a4d81af3bcb6416c15945ef690d7409293c75d7959eba9b2c11c7fb896e75 -V,39a3bdce1c593941a33d8eb8f56e4f662ada2bc1415db3eeab4bd3214472270 -W,84f019236531899d6c151874e3c1fcf863717dd696a3b697318262060ae055 -X,dc9549491828e8e90dcce44ced058e1d42337a2bf325efc42ce42fbdaca82 -Y,88cf879d46a4b3674edfcf82f9ed74dd677e774f558e2f51ff9bd7ec65d8 -Z,8516b423b445d0de9533cd66a86171e327860c657e9cdbae286697363bd7739 -[,cbe12c7a52109f99ac1790a72a1aea1bb95469eab8e736f190702a4d1e69f747 -\,4abf8a76d3b34396197e82499e3aa465ffbe561426573a4e5f63b9f3866754 -],28e146a7d7294cd32665a9cd8e4577de7131135e849146eec0e19bdbcd44a0 -_,70818a84e5e8890954ac6cbe9098b85a159444d4d82eac90663578bdda540 -a,f748f213588dbf4415ce24fe66de3526816bf35df8e398f98efec2fb08956a3 -b,10dcdca2a45e3abf88d63c416faecea9ac285484bebedecbebb80779228417f -c,3234103821e7cc45cff9f4cdabf15bb6788b82655ab036f2a0a1f9d47013be2f -d,7725c32c336f75f79e660a6feeb375ecd61fc8bcc5e7a7decf4855c995890 -e,ed8115b1adbb39cdbcbcd034e9560de7dab4025bb4bc43c49b43d15dd8a77 -f,7bb75a3ea33fb6636f2bfafe897638bb2df912f26f5a24b699b50b31b547a -g,7c423ab8df97bf1b9a9c1d0e471690cf677e4fca10b376c5e6c07692b55d14 -h,ee9ae3e7e7cbd739525189a7ac3c91d261fc29d2efedb702264d749aed3d92a -i,e37889b98f351c2db12bf1ffa57d08cb6460c649c902135b133e26961b -j,bbfa2f65e540f876cc999466d9f596ea1f9934f62583ccf4679abf6b18d44389 -k,ffdce233aeabf2915f3a6875d268228ff908236a563e1fdd14d59b931d499b -l,baeaa9ef47caf6e44e59aae99bedd8949e14236230801f39ed2a2e29783 -m,5aa54d742492989f739deb7222a23bcfcf85e6c782fe2ce0cdeee0f3f2b0eb -n,77d8f27f57ff3626a11d7bc5456683f2c892486c2d96e8e856d62cb79aa4a05b -o,b899f4368f6236b99d5f479186ea6a39d1083ff207eaca71af10745c4e -p,af2adce09524168e84ac6c8b7f29c9e8745712c73158b8d5a1c6b12df87cce0 -q,43c1ac6dc0ebfbf4e3ad3e8e883556397d6cca77e2d5a9a437bbc62658086 -r,5deca6f91150d18c9b68a14d63d382e9c42132eee43d6a786a115f255cfd7 -s,274d273dd7b38417151825f1fb2450c9468ac64c146f1bad24416edb19b5 -t,af66782045fabd495b97a886a266fda9f66a52be79acedabdea8710358e2285 -u,c5f5e4bb891e5b6d60135dd6721cc631c4764ac8a934207f31d9eeb2bc49a7a -v,fd4b453118b7ae9ddcc79a82841d81ed3ab7fa87ff28eff41f48675fd4d -w,c93e755cbb6f6c2da3bf169a2e75eff34151637d2391a41e861735eb9ea0675 -x,89ba3b834755de24da6a83ce1fb7f971f7abb205585ef823b2fc47abd5028 -y,684b96f1c113665e39a3c28ea185b36dd5a75c7d650f2c944171dae99dfb -z,dcdb80175169613280a8a06a1c751fb71b6689edc8ce3d8b9d96bd450cc81 -{,8738622598ec8a2b5e6292aec2e8b5f8fe2752d6e478fd284c37d2cd72ac83 -},121f83a2f72190324c46b796ed9bc77c1a11382f5590308e4425511ab9282163 -\u00A1,3fdfd1d694c2b4368fec021b954f2e899c6c5d308e402a6a197bf4057d6da50 -\u00BF,a1a4e1cc7b88eed2117abfb3c7034d674ded2d9960d1edd7f235792555808912 -\u00E4,879e97bf19a5dae848257eec388b4646463961ff4da0b72292f6838de21c1ab -\u00EB,54fffa7cbcb948c119c3c9885af817b305dd6285c01c6f186c8c7b28208d71 -\u00F1,23e9502a865ea58f1128d9415c090a8e17ed5cffda456d3a199318e77e36ee5c -\u00F6,f2e7f65cdbdac17742eac6acdf237b2dd4a8332452c5017c9719a27bb192d58 -\u00FC,8e4db166618e3ac16c6b2c259b9fb118b59c9268448d2c1bc775feb57f94ab1 -\u0431,56b564a4992f2c39daaf1ddf2e4377489f8e8b5ec86ddcf153360b67b802325 -\u0433,4f276b6f18672c21d6d1b05249613cb55147e26220883358d3109131a87d28eb -\u0434,184b97377f7ed57e7dba1f2a2ebc17196889f0965edf3732b02f5b44b2bc -\u0436,a81787ae671a4c06b52c1f751f6d0cc3f2cfedc16854b2faa1cb6cb023f1a9 -\u0437,23da32b68f922695b4ff457b68c49755b22eba70f143e9e428d9985124b855d3 -\u0438,f975c6a8da76571fa370b1bfb9f321692ffb6d2b84b3999a117fdadf1dcbc -\u0439,26defe06bd7175ebbb242420cb4413ef4f88881238c9c141ee9ac91695e7d -\u043B,a7aeec927145864c98a14b63ad6aaf2ff4a6f255cc89682f88bae61cf43836ce -\u043F,d93e3c8f7a854ee1eff761ae2b631de2788d9ae2a2bc6a7321f7c68493d37d -\u0443,4282b150d386bec92172e9e079ddee91b1cf36cb7bc22c587cbe9363a7cfb7 -\u0444,338c4c921b77c4501a427b614a1d1fbf6e56165abed07fa0d35714e26ddfe -\u0446,823aaccb635942d8228668ac0dbf48cd492e871cdd8c497f57e7c6f74861715 -\u0447,6ad1f7692e4057849c6f4a296b63c6e60a5bc937d6d53dd297672252e68591 -\u0448,90a509b56f1625d45e67284632790f06c814f1ea199edfc311959ef717b60a3 -\u0449,477a1721b53aec354f4e954477aea7d6daca8bdea11dedd1ff818c84e540a4 -\u044A,763c9e5ef2891e89c3bcd7a4a71e60ff9b798d56c0de4be54d6ebc2bc4df90 -\u044B,e263dd56c6b9e1f6123914f2fe539780a0615315e66ca197fd67041bd41bc91 -\u044C,bb32a26f55f9dc4fe973277496b578be9baef27a593f3ab1080ed98463039 -\u044D,4040eb31edd725b8addb9fb578ff74e693cffa1a1c40b74137d97fb766ce1 -\u044E,5baf19c1ed3e45ecfe1e6403f118169715deb7e5bca8fe7304fce735c73ce6 -\u044F,c426ac23aed697bf4aecc241c433b1cf8bf447e7566b17524ff495ba9f9604d -\u2049,8f5b6f9db8b237b5ec67b58a1efbf8a1a5dcf813d3d869b232847f21c298948 -\u2190,ba6caa1e1e9d9aef59278711422787a017993c5b292518c9f632d412f5a659 -\u2191,45c0cd717ca9228849652a8ccdf5281a860cb2e79646b56a22bc59110f361da -\u2192,e99ab441fc97f609081ad3ce33d598291d51bef8cb7ad2484b5c1387c7a84 -\u2193,7f39ccb5a5cd9babb13097b4f8dbc9f14dc38ac1702a30d97e2aabf907bf15c -\u2196,bf9c74796cdb0e95bdab9b48b12fb9452f940c02217ed78d5c8f6baf61810d2 -\u2197,ea2ce193e85529d3b8d4aea2d365e298543f334c36b566fe2e53844f915ed2ed -\u2198,55e351f26b8c353e614b73aad0e2dbfd17273ceca443de676e6c7cd0fac -\u2199,e82cfb188db47c165d40ec133a5778236facd31d8aa42a5a48e8628435f4355e -\u23E9,8f808b532e4129e3bf2ae4cc834fa7a5ae8e2dbbe6a162a87e8583e9f23717 -\u23EA,649e5c6887c7d434b8a20975dedcaf55b6737367fe64b688fed23ed52cdb -\u23F4,43c5ceac4f5b7f3d8e3517eb57d977fc6de414a2cbe1849c1632dc08f52fd8 -\u23F5,18ba5ee894e2c70d254f0f11cca356822b09eb9e6dc40811ac1b4671cca46b -\u2639,7455aeae53488bdc8bd73fc0776c386b6f9819c3c556b82d94ad20ddab9c2a4 -\u263A,39ff5f7f9376a697d827742ec3baaddbb8763622dadaaafa9abdd788919a874b -\u2640,ce9f84880e98bdf1cecbbf6bc7a777cb0bd6108a0213139132734a5f852348ab -\u2642,5226ce62f792351464022b05ec5901bafdc13ce82377bdcd4f21a80b888c2932 -\u2648,ae08d93b72ebe429f291cdbf7ab1e3f00070705189e03f674ca48fb1bc25b098 -\u2649,d6276429313c115f8453feae6c6b0783fb4d79ee629237b78e4b178eb774a16f -\u264A,53ff804dd06e71e2adec9506afd5d2349302553e0183c2008c7a6ead7edffebb -\u264B,ccc4ca8bd79ceb4c5257f8b727cf474a86c5d3c73540deea08414bff59af7cff -\u264C,d68adb819235cb36788622a5622cee2dfe82c24873400cbab62f3ac7b63a4627 -\u264D,e43a4736a5ab2ed70e011b10e55d479c2bb8c090c700b8b8013071afc101988d -\u264E,221f6952843842dc5e3c28b538582265fa404afb26180ef43ee8411c0871a546 -\u264F,8dd965f4d1ab72b765ed7fd8a095f7413e246de0a91f68dffa5530b2c892b77b -\u2650,480f8e2c5ef41fa288600f610b7dc84218c8437df70390fd1f3d4167edbe8c6a -\u2651,31ba2c539cbe0ba6ce7f0dcec6b5000cb55b80c5d838947908f7118f7001a31c -\u2652,a58c38a590bcdf4292b85ad1cda66aa76bbc8b6434170ef30e6fffe87656d2bd -\u2653,e5f12b9eea8ab561a790bfac345f0924dc4e1e0af8452c5f23af251e733823f9 -\u2665,523158e5a6d963c55a86b9d4483e5a65a3cfa694e2ae7c6c27bc826b2cc7f71d -\u266A,f9177260941894871543f5f1d06888cf52553c8687ccdbe899a9ee784d16a16e +" ",2fd253c4c6d66ed6694bec818aac1be7594a3dd8e59438d01cb76737f959 +!,c415aace88a32b9ef223746e4af85ecd64ddd78653cbc6cd0f125635767 +"""",9afa262136b81f31f864af1a6e975a8e4bc87cd5b592738ec34bcc5ed35cb1 +#,8928ef335313214bb8cc137df153c1bee7b7a9d1e8e6281fe9d362d91fe9d89 +$,7c261b18e8b1710e86fa67edc918aff0703e3a137325f1826608578c87a38c7c +%,91f4c4dad810a2156871403effe9678ce91b28adaae05dc55ccbb199c1533c6 +&,a86b6c29f82bd47c67a3939dafcdee17aa9d3a01c8eb599e15eb908b70335e35 +',e5709bb39d44b0863ffb18c2661317e3b995198bc6bd95ccda8f7de5cc31b6 +(,9f51baecc99e111fb27cdca5479a84663d4b83f821ec02018b9d7c82df6655 +),fb7fe8bc73432154458a53fbb434539cd5d3dc69a3e99a5a929ae66e45746c ++,5c52364520b3a9bb8ed515c01f80ab7b977025cd0b0ff6d86468a5164c6fb78 +",",7a4e15c32fd16e20fa4e46322730294879fb83e23bdda6cdaadfbf12cedb5 +-,c99bc7dfd3cad70ebe12fc35db6fd3f1d652c6fea9929fa3b22fe6eef5c1 +.,01afd801443d4c4b98c6daf84aa8d2b0c2b48a4f7161ad54e6fd55734945 +/,712f05e103bed4f58e48de572d6886567dcc17b248535902ac277cb30cfca6 +0,118977cf8f2ff0ea92e6db6a56cea1f5f8ae44c7ca937afae7e526cc98dbd8 +1,bf9694a52212719e113dc7e6af698a9fc3ab63c74995ffadc57d346face4e75 +2,40ebc3352c252d235713d5cbcbca879025221caaae9c4ae0cab792d974e65 +3,5079c9ee988b57b2d232680f8bca9606c49adfdc9cc18e0fc8c228f93ccf +4,8f3c55e7951b484d194f6f4af16f5a6adf586b258579df3b8be2b385691e5527 +5,41205fd686863479c216b2d84c7c6189d292ffbe7331ac3b7696abdeb23494 +6,2b88618becf61abc5bc94c115bca13dca3e2b9bd9d0ccb6856612ba8419f +7,a83147e25484477e1be63edeab28bd5b4e8adebc8bc83e19d52b17253c4f +8,d7a033ea86a2a923901a64a9dca08c2e254c17118aae592bf81e95f70156e35 +9,59b99057bd24bf38d9aa5e19f8a742ac3418596ac7203282c7e01fd7c730e0e1 +:,3ab03d3ecb6d6df720168dfbbabcb2638db5c563a5d4475979334d3b83520ee +;,199960cb695c60103c3ff6e3971e36dbce2d55781227ccdd1fac411ddbbd7b +=,7aad7ef306def67f97deba90a85f65118abe6b4154d96b767e3b4f39bc6dc +?,4b7f663d65cded7bd3651bddd6db546360dd773abbdaf48b83aee08e1cbe14 +A,18fabedcd35a75129f87d0dc231f1ebc6650274f5b692ec5a372ab9b5339d1f +B,63f3821523855fcd40f39368dd5bab644d3224bb4f291f9cd33ec6c3d8a49d24 +C,5f1a954f8577a33e51251e465c7d7212ff67c01ed0fad255ca05aff5a229a +D,94e5312e7db6494891f4cc45a1cc493429bb3666783d7bd459010c22b9b82a4 +E,b821d7684b699d5767986dbefa67d03fb391a563be9866ea2918259142d9a5 +F,c6623627c3f5297bff95f742b8aff8e5be3b1d78b5dd6c693314da11a7eb9058 +G,54eff07b361a94d4059bb76c2d49475f6d3e8c194f0a35cc130521b0f9fd +H,e66027789d2dbf542ae16c26a882475cd0784acf4fd7b0b5f4226e5f1c6f62e +I,bcaa55fede2cc4b0560d5a1e4eee73e9a353b63443ca83ac7db5fae2dd4e939 +J,5e8f6864deaf7a65d9d0eacc2920799093dfd34248dc4b7eef6492c6211314d5 +K,2d87f872bc5a587b7d1a49d39d7ebf1d18b70e6998be922c241bf298e79b6 +L,7a41e1defe955dcfbb47ae47361697ad16b8688a936581d3d3a6dad18229324 +M,bc7ed44bdabf4b6cf1c514417382f9158240e7a89d7289f4c27bb26df9f8 +N,666eb97a1311b27126b2c7b1a77fb68cc674d13de58b270cff69b4c7fa6713 +O,b8d519b619952f1a1097f9245a81b57dba97149e4fdad6ef8bf4842543f3ce8b +P,727d942d5c95a7395b45a9c711b35f6e62baebe49b817c6ee55145d4a70 +Q,5861e1edfdd5109dbd54cdde28d4512cd61631d1f467bf1e8fe2196ab7adf54a +R,c9731704b6973ab0e4beb8d81be782fdbf6fe4d7ac54b84a94317ab37c17 +S,df8844cda8995edc47641681b89cd5a22858b78ff5641d282633232dc8ca +T,5025c0424973b359c9b21d49229edf7f57741d8f78a640a942ae25db183eb7e +U,e6a4d81af3bcb6416c15945ef690d7409293c75d7959eba9b2c11c7fb896e75 +V,39a3bdce1c593941a33d8eb8f56e4f662ada2bc1415db3eeab4bd3214472270 +W,84f019236531899d6c151874e3c1fcf863717dd696a3b697318262060ae055 +X,dc9549491828e8e90dcce44ced058e1d42337a2bf325efc42ce42fbdaca82 +Y,88cf879d46a4b3674edfcf82f9ed74dd677e774f558e2f51ff9bd7ec65d8 +Z,8516b423b445d0de9533cd66a86171e327860c657e9cdbae286697363bd7739 +[,cbe12c7a52109f99ac1790a72a1aea1bb95469eab8e736f190702a4d1e69f747 +\,4abf8a76d3b34396197e82499e3aa465ffbe561426573a4e5f63b9f3866754 +],28e146a7d7294cd32665a9cd8e4577de7131135e849146eec0e19bdbcd44a0 +_,70818a84e5e8890954ac6cbe9098b85a159444d4d82eac90663578bdda540 +a,f748f213588dbf4415ce24fe66de3526816bf35df8e398f98efec2fb08956a3 +b,10dcdca2a45e3abf88d63c416faecea9ac285484bebedecbebb80779228417f +c,3234103821e7cc45cff9f4cdabf15bb6788b82655ab036f2a0a1f9d47013be2f +d,7725c32c336f75f79e660a6feeb375ecd61fc8bcc5e7a7decf4855c995890 +e,ed8115b1adbb39cdbcbcd034e9560de7dab4025bb4bc43c49b43d15dd8a77 +f,7bb75a3ea33fb6636f2bfafe897638bb2df912f26f5a24b699b50b31b547a +g,7c423ab8df97bf1b9a9c1d0e471690cf677e4fca10b376c5e6c07692b55d14 +h,ee9ae3e7e7cbd739525189a7ac3c91d261fc29d2efedb702264d749aed3d92a +i,e37889b98f351c2db12bf1ffa57d08cb6460c649c902135b133e26961b +j,bbfa2f65e540f876cc999466d9f596ea1f9934f62583ccf4679abf6b18d44389 +k,ffdce233aeabf2915f3a6875d268228ff908236a563e1fdd14d59b931d499b +l,baeaa9ef47caf6e44e59aae99bedd8949e14236230801f39ed2a2e29783 +m,5aa54d742492989f739deb7222a23bcfcf85e6c782fe2ce0cdeee0f3f2b0eb +n,77d8f27f57ff3626a11d7bc5456683f2c892486c2d96e8e856d62cb79aa4a05b +o,b899f4368f6236b99d5f479186ea6a39d1083ff207eaca71af10745c4e +p,af2adce09524168e84ac6c8b7f29c9e8745712c73158b8d5a1c6b12df87cce0 +q,43c1ac6dc0ebfbf4e3ad3e8e883556397d6cca77e2d5a9a437bbc62658086 +r,5deca6f91150d18c9b68a14d63d382e9c42132eee43d6a786a115f255cfd7 +s,274d273dd7b38417151825f1fb2450c9468ac64c146f1bad24416edb19b5 +t,af66782045fabd495b97a886a266fda9f66a52be79acedabdea8710358e2285 +u,c5f5e4bb891e5b6d60135dd6721cc631c4764ac8a934207f31d9eeb2bc49a7a +v,fd4b453118b7ae9ddcc79a82841d81ed3ab7fa87ff28eff41f48675fd4d +w,c93e755cbb6f6c2da3bf169a2e75eff34151637d2391a41e861735eb9ea0675 +x,89ba3b834755de24da6a83ce1fb7f971f7abb205585ef823b2fc47abd5028 +y,684b96f1c113665e39a3c28ea185b36dd5a75c7d650f2c944171dae99dfb +z,dcdb80175169613280a8a06a1c751fb71b6689edc8ce3d8b9d96bd450cc81 +{,8738622598ec8a2b5e6292aec2e8b5f8fe2752d6e478fd284c37d2cd72ac83 +},121f83a2f72190324c46b796ed9bc77c1a11382f5590308e4425511ab9282163 +\u00A1,3fdfd1d694c2b4368fec021b954f2e899c6c5d308e402a6a197bf4057d6da50 +\u00BF,a1a4e1cc7b88eed2117abfb3c7034d674ded2d9960d1edd7f235792555808912 +\u00E4,879e97bf19a5dae848257eec388b4646463961ff4da0b72292f6838de21c1ab +\u00EB,54fffa7cbcb948c119c3c9885af817b305dd6285c01c6f186c8c7b28208d71 +\u00F1,23e9502a865ea58f1128d9415c090a8e17ed5cffda456d3a199318e77e36ee5c +\u00F6,f2e7f65cdbdac17742eac6acdf237b2dd4a8332452c5017c9719a27bb192d58 +\u00FC,8e4db166618e3ac16c6b2c259b9fb118b59c9268448d2c1bc775feb57f94ab1 +\u0431,56b564a4992f2c39daaf1ddf2e4377489f8e8b5ec86ddcf153360b67b802325 +\u0433,4f276b6f18672c21d6d1b05249613cb55147e26220883358d3109131a87d28eb +\u0434,184b97377f7ed57e7dba1f2a2ebc17196889f0965edf3732b02f5b44b2bc +\u0436,a81787ae671a4c06b52c1f751f6d0cc3f2cfedc16854b2faa1cb6cb023f1a9 +\u0437,23da32b68f922695b4ff457b68c49755b22eba70f143e9e428d9985124b855d3 +\u0438,f975c6a8da76571fa370b1bfb9f321692ffb6d2b84b3999a117fdadf1dcbc +\u0439,26defe06bd7175ebbb242420cb4413ef4f88881238c9c141ee9ac91695e7d +\u043B,a7aeec927145864c98a14b63ad6aaf2ff4a6f255cc89682f88bae61cf43836ce +\u043F,d93e3c8f7a854ee1eff761ae2b631de2788d9ae2a2bc6a7321f7c68493d37d +\u0443,4282b150d386bec92172e9e079ddee91b1cf36cb7bc22c587cbe9363a7cfb7 +\u0444,338c4c921b77c4501a427b614a1d1fbf6e56165abed07fa0d35714e26ddfe +\u0446,823aaccb635942d8228668ac0dbf48cd492e871cdd8c497f57e7c6f74861715 +\u0447,6ad1f7692e4057849c6f4a296b63c6e60a5bc937d6d53dd297672252e68591 +\u0448,90a509b56f1625d45e67284632790f06c814f1ea199edfc311959ef717b60a3 +\u0449,477a1721b53aec354f4e954477aea7d6daca8bdea11dedd1ff818c84e540a4 +\u044A,763c9e5ef2891e89c3bcd7a4a71e60ff9b798d56c0de4be54d6ebc2bc4df90 +\u044B,e263dd56c6b9e1f6123914f2fe539780a0615315e66ca197fd67041bd41bc91 +\u044C,bb32a26f55f9dc4fe973277496b578be9baef27a593f3ab1080ed98463039 +\u044D,4040eb31edd725b8addb9fb578ff74e693cffa1a1c40b74137d97fb766ce1 +\u044E,5baf19c1ed3e45ecfe1e6403f118169715deb7e5bca8fe7304fce735c73ce6 +\u044F,c426ac23aed697bf4aecc241c433b1cf8bf447e7566b17524ff495ba9f9604d +\u2049,8f5b6f9db8b237b5ec67b58a1efbf8a1a5dcf813d3d869b232847f21c298948 +\u2190,ba6caa1e1e9d9aef59278711422787a017993c5b292518c9f632d412f5a659 +\u2191,45c0cd717ca9228849652a8ccdf5281a860cb2e79646b56a22bc59110f361da +\u2192,e99ab441fc97f609081ad3ce33d598291d51bef8cb7ad2484b5c1387c7a84 +\u2193,7f39ccb5a5cd9babb13097b4f8dbc9f14dc38ac1702a30d97e2aabf907bf15c +\u2196,bf9c74796cdb0e95bdab9b48b12fb9452f940c02217ed78d5c8f6baf61810d2 +\u2197,ea2ce193e85529d3b8d4aea2d365e298543f334c36b566fe2e53844f915ed2ed +\u2198,55e351f26b8c353e614b73aad0e2dbfd17273ceca443de676e6c7cd0fac +\u2199,e82cfb188db47c165d40ec133a5778236facd31d8aa42a5a48e8628435f4355e +\u23E9,8f808b532e4129e3bf2ae4cc834fa7a5ae8e2dbbe6a162a87e8583e9f23717 +\u23EA,649e5c6887c7d434b8a20975dedcaf55b6737367fe64b688fed23ed52cdb +\u23F4,43c5ceac4f5b7f3d8e3517eb57d977fc6de414a2cbe1849c1632dc08f52fd8 +\u23F5,18ba5ee894e2c70d254f0f11cca356822b09eb9e6dc40811ac1b4671cca46b +\u2639,7455aeae53488bdc8bd73fc0776c386b6f9819c3c556b82d94ad20ddab9c2a4 +\u263A,39ff5f7f9376a697d827742ec3baaddbb8763622dadaaafa9abdd788919a874b +\u2640,ce9f84880e98bdf1cecbbf6bc7a777cb0bd6108a0213139132734a5f852348ab +\u2642,5226ce62f792351464022b05ec5901bafdc13ce82377bdcd4f21a80b888c2932 +\u2648,ae08d93b72ebe429f291cdbf7ab1e3f00070705189e03f674ca48fb1bc25b098 +\u2649,d6276429313c115f8453feae6c6b0783fb4d79ee629237b78e4b178eb774a16f +\u264A,53ff804dd06e71e2adec9506afd5d2349302553e0183c2008c7a6ead7edffebb +\u264B,ccc4ca8bd79ceb4c5257f8b727cf474a86c5d3c73540deea08414bff59af7cff +\u264C,d68adb819235cb36788622a5622cee2dfe82c24873400cbab62f3ac7b63a4627 +\u264D,e43a4736a5ab2ed70e011b10e55d479c2bb8c090c700b8b8013071afc101988d +\u264E,221f6952843842dc5e3c28b538582265fa404afb26180ef43ee8411c0871a546 +\u264F,8dd965f4d1ab72b765ed7fd8a095f7413e246de0a91f68dffa5530b2c892b77b +\u2650,480f8e2c5ef41fa288600f610b7dc84218c8437df70390fd1f3d4167edbe8c6a +\u2651,31ba2c539cbe0ba6ce7f0dcec6b5000cb55b80c5d838947908f7118f7001a31c +\u2652,a58c38a590bcdf4292b85ad1cda66aa76bbc8b6434170ef30e6fffe87656d2bd +\u2653,e5f12b9eea8ab561a790bfac345f0924dc4e1e0af8452c5f23af251e733823f9 +\u2665,523158e5a6d963c55a86b9d4483e5a65a3cfa694e2ae7c6c27bc826b2cc7f71d +\u266A,f9177260941894871543f5f1d06888cf52553c8687ccdbe899a9ee784d16a16e \u2713,958b0ef5057d5c31acf12ae419f5be71494bcfb1b07ad781785dacff2ce616e3 \ No newline at end of file diff --git a/src/main/resources/fonts/oak-log.csv b/IF/src/main/resources/fonts/oak-log.csv similarity index 98% rename from src/main/resources/fonts/oak-log.csv rename to IF/src/main/resources/fonts/oak-log.csv index eeee2a11..e5828a6c 100644 --- a/src/main/resources/fonts/oak-log.csv +++ b/IF/src/main/resources/fonts/oak-log.csv @@ -1,118 +1,118 @@ -" ",54301aa8a87e2188ce867040253f76663b3e47f6c86fdd6cdb670c9984653 -!,6d5cc35775a9c97d134945cd8c6184b487eb12e0ec7fbbf0421935bff36ec438 -"""",a6182fbe4bbf2bc6dc947fe69aeef49dba9073d49e808e2d7a80d487bab2fb -#,f14457a1c05e19346f4b3bf649df7b84c56c314357f47af2c9c559dd16135e8 -$,f740aba43f0c96461f3286d8fc54e75bbe21394840f86cf931c624b5b1d41bde -%,f135cc2a0e984572ac6e836c6ee793297613fadceac7ba4a45364a07dc4c9e8 -&,ad99b2f258e7362ba3ac6ff7977beb409cc7ae8aed2b7960b25382449e65d95 -',5eb88ed417a4e2ae9a9f56f617dfeedb4dbcc77f691987933efd07fdf84a5 -(,5822f77873b0d0537c8047255ccdb0514effd5506e9d41b1fca2152b6aa288 -),50f33ed12f7231a554dfc962b50a5795f6921c5e1e1439cd9f6d71b04e -+,19123a068dacfc43964ec886976c4b08875687316fc1eed2711a11d65fa712 -",",2e5bc37a98c14fe761222cea3827112f6ff73780b4ae27627f93ece8b5899d6a --,7f85bff3a2c1527f85274374c870c73d2efef6be7713eea569d3a1bc4a5efc49 -.,47a7f426514e9e4c6a91d567967f0e0f5fad9d72d843dfe9125152f3ca2dcc -/,572e615f2113f416c462172f034aea656aebddce976352bcaddf46ede234 -0,a98fb91c925a6d4cc227cab254782cc3ed436dcf37e6b67c88a9c2688487 -1,955dc7704e6db04de6651985d64af5048aef3837ca8d7984f8af68f058cae5 -2,f897769d1672f04f1a36ed7d0afd635fb5645f3953429dc30fb7f3e818dcdd5 -3,82e510b0f9969089da14422bd8b291b2d2e4654de6918bb9fa6d771c8b645f33 -4,61dd840d985d6875a1c10fb63637ec32e4eca9dbd685d1349c264d6ac3a8d26 -5,2b7cc6cab53cd630eab3077b91c52afe216fbf75ff7d47f3ae9c49ccc8ffd30 -6,4f87ba8263d65754fd755319aac8f90e0a8be1021fe421ac16afef911128fb7 -7,e7caa11f281879ffc3533284075db012d97026336a3938eb5fc76d578f5d -8,8d11c5ca2fd8ca0d1d921f8f2b9c3d37091fff3b48954e024e3bca12ed179b4 -9,31d8f2f6ee4d67d82e1fd4f976cef366bab62da91de9171c47ea081b17dcc4b -:,6e75d84199ee453668263a195bae8d5da325446ea6b5d89727a0681778f7 -;,e66b9dc1aa33a34e475665cfa2a120617553a395cc3ffa962f057acd9e7 -=,95ffa5a559164ae65c8d420bf377271861739484ae9e37e25c292ebdb2b37fe -?,4e435652835592b46a24148b4ca742a4bdf8f678d7d70a38792738b85cd33 -[,fbd3cfc8237f3ccd8a90574e35b348ef82bf363467e3ed8bd65b5863474ecfd -\,41f9824fd6f9e0803f9c3abdaa46ca2f7368874c7fb637b1beb525ad3c236 -],fb9fc1fd11c07992c34995c495c66f7bcbf085cdc74ae86e4c9c8df7843a7e -_,215c574ecd5bf9561aded51ffae2bb5f928d39bf1ca89492bf2efc57c94ad3 -a,33ea60ea60c05d70205317943377762b8dc52dc623fb77fdcf6b3dac25f2e32 -b,4a71598a984bd2fcbbd4c13124fc2bc6be4ae442b85d57b6df394143195a16b1 -c,fe2e505e42ecd3a9f0211d5efa6e586c42f82bb6389ca03bad5633e6667 -d,8411a7e1bc7b9b97623e0478219b1a32383ee07eb0e6a66f5ef9f855593df0 -e,f14a4c3b4163c75c38677c58dfd6af15c639d69137a2c1ccd886a364f8eacf7 -f,315dee5f8fd4069955157f2d851315fc43b813d6248b49c98632de3be677cb -g,3d574d62c23b4611979915bd3e7fade912e97083acad5f35faa3967e2cbc8c -h,2098491a1dab30cff74cd9c758c75242fa997bf4f214c0525c2ea4417678f733 -i,1a68f7f737dd86a5e7697e5245ac8ebfdcf9125db6fa284c1652142fdf2db6e -j,7db15036cc627d985bed2a14226bae1a29fec2b2e9ec685d77f5f95e399 -k,82ff49d2c620c1366845c930ad305d956dd02d8548e7273e184fc1bb984564 -l,d0f4373f9a87727b34535bc733b9eee305cf1d3ced198551557883a616ecc40 -m,829263a2941aca12622de187af9bf840d393a08a45b3b45a855e88b3c5ba -n,fcd1c3224b6f35fdb7231b5a524b8d4ffbdc542dbe8d7ad70d78e8db68d6bc -o,559201d8f66f1ec13c18223f36368324ce68f206a28144fd3db15a343516a -p,2593a6f23f5b110ec1c7ab66c40fbc9b82f4f5c987265aa67c95a2d3f4c97 -q,9c58866d687de6a817832f143efd1314cf44f8787766517e9866cc799615 -r,3a5792be86f8732eb4e3c62e59496ba25d04029f645de3db15ff1d3c65e068 -s,6657bd1868da6736cc4c4353989e6a457437bddd392c82c248d142070a8dd83 -t,3897ae54c1d3de2ce4a5f0f4943982538a8a7c69f174be57d74a33ee9bc5f67 -u,a2c3f27665e14524699a92bca21fa22421da1b2696ab496b4580c451c7a1 -v,5a7765615ac14126d6eae9d4edb2778d0828fc140804a5cf2bfad14ddc9fe5 -w,f754a3d3f781312d2afe9129fc3ef192f647598b6cbd9d2f982ee84b46112f0 -x,97a817d9a8b5e2ee25efb46b4d7bb45108eccae2db1d09a3af5f89fb51e5 -y,16a746ed076bf801166c02866dd265033491dd4de7b96ef7a6e4ff96f33b6 -z,304ad14352add1a67395e012f667846df14d5515d8163dafdd806ee5748d666 -{,ed46d575ea54246108e4dfb9ca6dc9773627905e649d10e09da9af5 -},382f9ffe64d6d25ff320b513daa26d1d995db5541c2b6193c88460d68562a7ef -\u00A1,3c0decad82ee093d1a68f9365052664f1c673999f27257ec5b71e61151564535 -\u00BF,73be84a16389afe917bb6c25aa53a2d787df5aabed36ef766e25339cc0ac0efa -\u00E4,dadb86f02a7cc36c56ed7b08f3545879de8d9cf3f21c18f16bc126f70b9bcf -\u00EB,76a59ef79a5b80f33d777df95376e3438293db613c75f5f34ee854f625645 -\u00F1,7795149aacbac4519e42509706961c54939cfa58fe7c7310cb90179640e208ce -\u00F6,661899dc8c58827b2a596f664c8ece8f3e72f61ffc23a751ede4465c4a25f39 -\u00FC,ecd559ba382427617f3662983ed6b10a35fe8a85ebdb61ec538c25418786 -\u0431,cc3821edf5b357f42aabc5d258e6de5a3a9dff7d4de6373ffc62beb475221b -\u0433,ea1c5ab7c8b76ec4725a204012179abc90c339cac734ab3bdd7c1128773a52 -\u0434,a9f098d4887a45db8ca5c066413cfd1d7327b5503edfd99a1f1f40c5bf9a4d -\u0436,2f1d9ea93869adc91775d5c14a2bbb89df11d57494d4e49c8d8554574088212a -\u0437,3e99e7803122ded0258adad31542794d949a23eefe3da81f4cec09d7b2332 -\u0438,51deffaf8c581b4f721d8e23b19519d4c1c3453ecdd470efe33b2d7a8317c4 -\u0439,d34d5c74bf9ea96244786edf48b4f2defc13a4e24a242fa5e6b89eb533daf5dc -\u043B,697681ab5873976658b4733bcc414a925d4b1991808c7294d2a2dba36ddd4 -\u043F,51bbfb69978cc53afc84e7d5439139eedd4fba26e94926e2c5d5b2a3d3d34 -\u0443,5c6bee2f3755e4b446190dd4fa71975dcc641815fe6d6581eb6817a3faebd8 -\u0444,f574bbfcff41bd35f6bf26ac4f68be23773b6a2b8a0f75734d7176cc792521a -\u0446,366a3f7459cfee9dcd44ca1abee64345baee48b49d51e24f93a168ebd1cc443d -\u0447,d9dfce5768e44df838d4ccb19d9c5d097e879c4723e61349e5d4a38cc0fca2 -\u0448,c08aef30bdf1c57838a2cb6605af4c71fb8306bb852130db20db9b92e8a5f2 -\u0449,9921ccc03e58679bef5dfe819a72fa96326174ec69a88d26655c5c5eb54290cc -\u044A,44fb2dbcf4ddf9060a8c8595da4c7784d90392b8c24e7647c55685ac8eeb8be -\u044B,37405effa7f2fcfa2e70aae7511173a72151b73b87fbcee685bc14e3969f91 -\u044C,4349c3ada099102ebbaba43a1a7d91927bdb05b2fa7cc8b6038544cb4fc24 -\u044D,5b5aacf3ade93f2f1974c1b64552c56745ad62d47b92df906779ec476a3ee3 -\u044E,4d51a18ad1f42a77bc88d5d5a98ac8f3b5961bbd71bbce5a3dc815925dd9b1 -\u044F,cd1f44a478744f95d3e98c35447b891f7423c3d95c9450268e589177a76c27b -\u2190,eed78822576317b048eea92227cd85f7afcc44148dcb832733baccb8eb56fa1 -\u2191,8a801e2adc59aac66d8f59dbc35fabac2cf5b611be7b21759418555137ff42a2 -\u2192,715445da16fab67fcd827f71bae9c1d2f90c73eb2c1bd1ef8d8396cd8e8 -\u2193,719386af62e7697493dd4b42af03c5de6e48dbd26b7284888d9435f27840b9 -\u2196,fec611305fdd8a2ebaf492b6fed2ab92c25a58557aa7645b949a5a95b1919e23 -\u2197,7fed778897472dc4963d994af65ab3ec4212a1fc72fda4b1d6a7de0614724d6 -\u2198,a599522a38ca248735460caa54b954a25102a9f78b626ff3d3bbe811d78 -\u2199,363ec7e847b08325d795a7cb738b10fcc719fa21c9ea9aceed185976788d2a -\u23E9,11c1f5dcf56b19d9f6d180e9205da9d760c14ca55817fb7cf9cd1db17728551 -\u23EA,a3b4dcf9c62520c9d1966d876d734ae72d781cf47b6470c7c78dd3d7c52 -\u23F4,7392623cafdf745bfcb31d05dbcd247d571d897f22ace38ee54eed3fb9636 -\u23F5,9bca90ebafdf57df4c380cf2655aa7b4ec6a4bdbd15516ebfde4327a1e27 -\u2640,c71b0c14bed3f4ef7b5ed048fe02bddc3df4b8bb325e2f04b619490326c5e046 -\u2642,6e248c45b068cb171c04963166c943120fb97ae35f00901ffc979671dfa699e0 -\u2648,4eb1be9f6825fa8579c457ec5eb92cc57e4693a8c92ae7cb7f42c1c6231fb3cf -\u2649,77462e601dd1883980ccd46cb1b9b3289e92c7ca6578a90252089f58a9bf65b8 -\u264A,7f6043fbafdf968c90c61ad80833b3f67bdbd99f0be9ebc1b9eb4516bb32691a -\u264B,6d2245ccd712a6768c87205d000897c4e7fdf5aa0649d239d17f93d88fddfa82 -\u264C,35cb1b4e2fe120f1cc7aefad4a30b330f9644eb383c9a9e83d2021dc6d77dd0c -\u264D,e3fb0b4c419c2f9c2d35619cd5690c2701da6f3a6e57f4bd754755b5df93b82e -\u264E,a37bbbd00300f1f0490ae99dbc731b0edf052718cd8f3862643f1a57e324b5e1 -\u264F,68adbdedb4500a8deebd91caa8d99d7b176e3c3b5345038008fe1931a0c524e7 -\u2650,386e57af3ff9e4dfeb7d838c53ab70f5812a4f45e0155831d84f3cf2b3285e91 -\u2651,574eb0e3b94562278ab1a17607703d7772274ebc26953efb97f750a5ae717bea -\u2652,253d2ab17ab8250194a7564f775c2285dee4d23295ef692c3c3afc3a1c1dbe88 -\u2653,cdda22aea06b61ba2ba21b15633012e621ec0bfe4d146201c210767553b25768 -\u2665,f11ab366d1c0b9fe3c4685d3c6ac12b566501111f2a704d8378517e37ee26bf -\u266A,10384c074a416a0dc22a18ba234575ba131a4ea28fc5905ea3d4ab84f841fc33 +" ",54301aa8a87e2188ce867040253f76663b3e47f6c86fdd6cdb670c9984653 +!,6d5cc35775a9c97d134945cd8c6184b487eb12e0ec7fbbf0421935bff36ec438 +"""",a6182fbe4bbf2bc6dc947fe69aeef49dba9073d49e808e2d7a80d487bab2fb +#,f14457a1c05e19346f4b3bf649df7b84c56c314357f47af2c9c559dd16135e8 +$,f740aba43f0c96461f3286d8fc54e75bbe21394840f86cf931c624b5b1d41bde +%,f135cc2a0e984572ac6e836c6ee793297613fadceac7ba4a45364a07dc4c9e8 +&,ad99b2f258e7362ba3ac6ff7977beb409cc7ae8aed2b7960b25382449e65d95 +',5eb88ed417a4e2ae9a9f56f617dfeedb4dbcc77f691987933efd07fdf84a5 +(,5822f77873b0d0537c8047255ccdb0514effd5506e9d41b1fca2152b6aa288 +),50f33ed12f7231a554dfc962b50a5795f6921c5e1e1439cd9f6d71b04e ++,19123a068dacfc43964ec886976c4b08875687316fc1eed2711a11d65fa712 +",",2e5bc37a98c14fe761222cea3827112f6ff73780b4ae27627f93ece8b5899d6a +-,7f85bff3a2c1527f85274374c870c73d2efef6be7713eea569d3a1bc4a5efc49 +.,47a7f426514e9e4c6a91d567967f0e0f5fad9d72d843dfe9125152f3ca2dcc +/,572e615f2113f416c462172f034aea656aebddce976352bcaddf46ede234 +0,a98fb91c925a6d4cc227cab254782cc3ed436dcf37e6b67c88a9c2688487 +1,955dc7704e6db04de6651985d64af5048aef3837ca8d7984f8af68f058cae5 +2,f897769d1672f04f1a36ed7d0afd635fb5645f3953429dc30fb7f3e818dcdd5 +3,82e510b0f9969089da14422bd8b291b2d2e4654de6918bb9fa6d771c8b645f33 +4,61dd840d985d6875a1c10fb63637ec32e4eca9dbd685d1349c264d6ac3a8d26 +5,2b7cc6cab53cd630eab3077b91c52afe216fbf75ff7d47f3ae9c49ccc8ffd30 +6,4f87ba8263d65754fd755319aac8f90e0a8be1021fe421ac16afef911128fb7 +7,e7caa11f281879ffc3533284075db012d97026336a3938eb5fc76d578f5d +8,8d11c5ca2fd8ca0d1d921f8f2b9c3d37091fff3b48954e024e3bca12ed179b4 +9,31d8f2f6ee4d67d82e1fd4f976cef366bab62da91de9171c47ea081b17dcc4b +:,6e75d84199ee453668263a195bae8d5da325446ea6b5d89727a0681778f7 +;,e66b9dc1aa33a34e475665cfa2a120617553a395cc3ffa962f057acd9e7 +=,95ffa5a559164ae65c8d420bf377271861739484ae9e37e25c292ebdb2b37fe +?,4e435652835592b46a24148b4ca742a4bdf8f678d7d70a38792738b85cd33 +[,fbd3cfc8237f3ccd8a90574e35b348ef82bf363467e3ed8bd65b5863474ecfd +\,41f9824fd6f9e0803f9c3abdaa46ca2f7368874c7fb637b1beb525ad3c236 +],fb9fc1fd11c07992c34995c495c66f7bcbf085cdc74ae86e4c9c8df7843a7e +_,215c574ecd5bf9561aded51ffae2bb5f928d39bf1ca89492bf2efc57c94ad3 +a,33ea60ea60c05d70205317943377762b8dc52dc623fb77fdcf6b3dac25f2e32 +b,4a71598a984bd2fcbbd4c13124fc2bc6be4ae442b85d57b6df394143195a16b1 +c,fe2e505e42ecd3a9f0211d5efa6e586c42f82bb6389ca03bad5633e6667 +d,8411a7e1bc7b9b97623e0478219b1a32383ee07eb0e6a66f5ef9f855593df0 +e,f14a4c3b4163c75c38677c58dfd6af15c639d69137a2c1ccd886a364f8eacf7 +f,315dee5f8fd4069955157f2d851315fc43b813d6248b49c98632de3be677cb +g,3d574d62c23b4611979915bd3e7fade912e97083acad5f35faa3967e2cbc8c +h,2098491a1dab30cff74cd9c758c75242fa997bf4f214c0525c2ea4417678f733 +i,1a68f7f737dd86a5e7697e5245ac8ebfdcf9125db6fa284c1652142fdf2db6e +j,7db15036cc627d985bed2a14226bae1a29fec2b2e9ec685d77f5f95e399 +k,82ff49d2c620c1366845c930ad305d956dd02d8548e7273e184fc1bb984564 +l,d0f4373f9a87727b34535bc733b9eee305cf1d3ced198551557883a616ecc40 +m,829263a2941aca12622de187af9bf840d393a08a45b3b45a855e88b3c5ba +n,fcd1c3224b6f35fdb7231b5a524b8d4ffbdc542dbe8d7ad70d78e8db68d6bc +o,559201d8f66f1ec13c18223f36368324ce68f206a28144fd3db15a343516a +p,2593a6f23f5b110ec1c7ab66c40fbc9b82f4f5c987265aa67c95a2d3f4c97 +q,9c58866d687de6a817832f143efd1314cf44f8787766517e9866cc799615 +r,3a5792be86f8732eb4e3c62e59496ba25d04029f645de3db15ff1d3c65e068 +s,6657bd1868da6736cc4c4353989e6a457437bddd392c82c248d142070a8dd83 +t,3897ae54c1d3de2ce4a5f0f4943982538a8a7c69f174be57d74a33ee9bc5f67 +u,a2c3f27665e14524699a92bca21fa22421da1b2696ab496b4580c451c7a1 +v,5a7765615ac14126d6eae9d4edb2778d0828fc140804a5cf2bfad14ddc9fe5 +w,f754a3d3f781312d2afe9129fc3ef192f647598b6cbd9d2f982ee84b46112f0 +x,97a817d9a8b5e2ee25efb46b4d7bb45108eccae2db1d09a3af5f89fb51e5 +y,16a746ed076bf801166c02866dd265033491dd4de7b96ef7a6e4ff96f33b6 +z,304ad14352add1a67395e012f667846df14d5515d8163dafdd806ee5748d666 +{,ed46d575ea54246108e4dfb9ca6dc9773627905e649d10e09da9af5 +},382f9ffe64d6d25ff320b513daa26d1d995db5541c2b6193c88460d68562a7ef +\u00A1,3c0decad82ee093d1a68f9365052664f1c673999f27257ec5b71e61151564535 +\u00BF,73be84a16389afe917bb6c25aa53a2d787df5aabed36ef766e25339cc0ac0efa +\u00E4,dadb86f02a7cc36c56ed7b08f3545879de8d9cf3f21c18f16bc126f70b9bcf +\u00EB,76a59ef79a5b80f33d777df95376e3438293db613c75f5f34ee854f625645 +\u00F1,7795149aacbac4519e42509706961c54939cfa58fe7c7310cb90179640e208ce +\u00F6,661899dc8c58827b2a596f664c8ece8f3e72f61ffc23a751ede4465c4a25f39 +\u00FC,ecd559ba382427617f3662983ed6b10a35fe8a85ebdb61ec538c25418786 +\u0431,cc3821edf5b357f42aabc5d258e6de5a3a9dff7d4de6373ffc62beb475221b +\u0433,ea1c5ab7c8b76ec4725a204012179abc90c339cac734ab3bdd7c1128773a52 +\u0434,a9f098d4887a45db8ca5c066413cfd1d7327b5503edfd99a1f1f40c5bf9a4d +\u0436,2f1d9ea93869adc91775d5c14a2bbb89df11d57494d4e49c8d8554574088212a +\u0437,3e99e7803122ded0258adad31542794d949a23eefe3da81f4cec09d7b2332 +\u0438,51deffaf8c581b4f721d8e23b19519d4c1c3453ecdd470efe33b2d7a8317c4 +\u0439,d34d5c74bf9ea96244786edf48b4f2defc13a4e24a242fa5e6b89eb533daf5dc +\u043B,697681ab5873976658b4733bcc414a925d4b1991808c7294d2a2dba36ddd4 +\u043F,51bbfb69978cc53afc84e7d5439139eedd4fba26e94926e2c5d5b2a3d3d34 +\u0443,5c6bee2f3755e4b446190dd4fa71975dcc641815fe6d6581eb6817a3faebd8 +\u0444,f574bbfcff41bd35f6bf26ac4f68be23773b6a2b8a0f75734d7176cc792521a +\u0446,366a3f7459cfee9dcd44ca1abee64345baee48b49d51e24f93a168ebd1cc443d +\u0447,d9dfce5768e44df838d4ccb19d9c5d097e879c4723e61349e5d4a38cc0fca2 +\u0448,c08aef30bdf1c57838a2cb6605af4c71fb8306bb852130db20db9b92e8a5f2 +\u0449,9921ccc03e58679bef5dfe819a72fa96326174ec69a88d26655c5c5eb54290cc +\u044A,44fb2dbcf4ddf9060a8c8595da4c7784d90392b8c24e7647c55685ac8eeb8be +\u044B,37405effa7f2fcfa2e70aae7511173a72151b73b87fbcee685bc14e3969f91 +\u044C,4349c3ada099102ebbaba43a1a7d91927bdb05b2fa7cc8b6038544cb4fc24 +\u044D,5b5aacf3ade93f2f1974c1b64552c56745ad62d47b92df906779ec476a3ee3 +\u044E,4d51a18ad1f42a77bc88d5d5a98ac8f3b5961bbd71bbce5a3dc815925dd9b1 +\u044F,cd1f44a478744f95d3e98c35447b891f7423c3d95c9450268e589177a76c27b +\u2190,eed78822576317b048eea92227cd85f7afcc44148dcb832733baccb8eb56fa1 +\u2191,8a801e2adc59aac66d8f59dbc35fabac2cf5b611be7b21759418555137ff42a2 +\u2192,715445da16fab67fcd827f71bae9c1d2f90c73eb2c1bd1ef8d8396cd8e8 +\u2193,719386af62e7697493dd4b42af03c5de6e48dbd26b7284888d9435f27840b9 +\u2196,fec611305fdd8a2ebaf492b6fed2ab92c25a58557aa7645b949a5a95b1919e23 +\u2197,7fed778897472dc4963d994af65ab3ec4212a1fc72fda4b1d6a7de0614724d6 +\u2198,a599522a38ca248735460caa54b954a25102a9f78b626ff3d3bbe811d78 +\u2199,363ec7e847b08325d795a7cb738b10fcc719fa21c9ea9aceed185976788d2a +\u23E9,11c1f5dcf56b19d9f6d180e9205da9d760c14ca55817fb7cf9cd1db17728551 +\u23EA,a3b4dcf9c62520c9d1966d876d734ae72d781cf47b6470c7c78dd3d7c52 +\u23F4,7392623cafdf745bfcb31d05dbcd247d571d897f22ace38ee54eed3fb9636 +\u23F5,9bca90ebafdf57df4c380cf2655aa7b4ec6a4bdbd15516ebfde4327a1e27 +\u2640,c71b0c14bed3f4ef7b5ed048fe02bddc3df4b8bb325e2f04b619490326c5e046 +\u2642,6e248c45b068cb171c04963166c943120fb97ae35f00901ffc979671dfa699e0 +\u2648,4eb1be9f6825fa8579c457ec5eb92cc57e4693a8c92ae7cb7f42c1c6231fb3cf +\u2649,77462e601dd1883980ccd46cb1b9b3289e92c7ca6578a90252089f58a9bf65b8 +\u264A,7f6043fbafdf968c90c61ad80833b3f67bdbd99f0be9ebc1b9eb4516bb32691a +\u264B,6d2245ccd712a6768c87205d000897c4e7fdf5aa0649d239d17f93d88fddfa82 +\u264C,35cb1b4e2fe120f1cc7aefad4a30b330f9644eb383c9a9e83d2021dc6d77dd0c +\u264D,e3fb0b4c419c2f9c2d35619cd5690c2701da6f3a6e57f4bd754755b5df93b82e +\u264E,a37bbbd00300f1f0490ae99dbc731b0edf052718cd8f3862643f1a57e324b5e1 +\u264F,68adbdedb4500a8deebd91caa8d99d7b176e3c3b5345038008fe1931a0c524e7 +\u2650,386e57af3ff9e4dfeb7d838c53ab70f5812a4f45e0155831d84f3cf2b3285e91 +\u2651,574eb0e3b94562278ab1a17607703d7772274ebc26953efb97f750a5ae717bea +\u2652,253d2ab17ab8250194a7564f775c2285dee4d23295ef692c3c3afc3a1c1dbe88 +\u2653,cdda22aea06b61ba2ba21b15633012e621ec0bfe4d146201c210767553b25768 +\u2665,f11ab366d1c0b9fe3c4685d3c6ac12b566501111f2a704d8378517e37ee26bf +\u266A,10384c074a416a0dc22a18ba234575ba131a4ea28fc5905ea3d4ab84f841fc33 \u2713,a9e1f657af8fef912f253a167bdc681dc560e6ceac73557de68f69017ed15a2a \ No newline at end of file diff --git a/src/main/resources/fonts/oak-planks.csv b/IF/src/main/resources/fonts/oak-planks.csv similarity index 98% rename from src/main/resources/fonts/oak-planks.csv rename to IF/src/main/resources/fonts/oak-planks.csv index 1545f32f..8360c06d 100644 --- a/src/main/resources/fonts/oak-planks.csv +++ b/IF/src/main/resources/fonts/oak-planks.csv @@ -1,119 +1,119 @@ -" ",5db532b5cced46b4b535ece16eced7bbc5cac55594d61e8b8f8eac4299c9fc -!,2e3f50ba62cbda3ecf5479b62fedebd61d76589771cc19286bf2745cd71e47c6 -"""",4757e972c763149476bc556cfbad3614c1d49954f13f8893eb9d105845753f2e -#,9ae85f74f8e2c054b781a29fa9b25934ba63bb79f1de8a95b436d9bfdcaf4cd -$,b7fc4dfa5f652f6e1c1b19fb87655967eb82fb5fa719042f8c805cad7f01e487 -%,50851cf062548c436253c337a4112cfc985443a748d931cf201d1e84fc72b12c -&,e1a3dcafc933b9e577c07e74884bf75519818b61426658d059d44ac6352 -',5458845f6513f4eecffaf6bb1fdc4148631eeb1bd885257c617ca7a1faafd1 -(,727d27b5047e09e80532aaa1669e893dc4cb35f2515acd052bed4d04bc4c088 -),659d3a66f6cf7e254168fabfff45449e951f4af64cb4e6f357321793c3d1379 -+,3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716 -",",7840b4e7a680434857427111bdaf64e7fba912ea5707182e98bc585ccb53 --,bd8a99db2c37ec71d7199cd52639981a7513ce9cca9626a3936f965b131193 -.,7456485aa2361434cb3be531bc121659f555a4aaf261d21a06d7afde5aa60b2 -/,7f95d7c1bbf3afa285d8d96757bb5572259a3ae854f5389dc53207699d94fd8 -0,0ebe7e5215169a699acc6cefa7b73fdb108db87bb6dae2849fbe24714b27 -1,71bc2bcfb2bd3759e6b1e86fc7a79585e1127dd357fc202893f9de241bc9e530 -2,4cd9eeee883468881d83848a46bf3012485c23f75753b8fbe8487341419847 -3,1d4eae13933860a6df5e8e955693b95a8c3b15c36b8b587532ac0996bc37e5 -4,d2e78fb22424232dc27b81fbcb47fd24c1acf76098753f2d9c28598287db5 -5,6d57e3bc88a65730e31a14e3f41e038a5ecf0891a6c243643b8e5476ae2 -6,334b36de7d679b8bbc725499adaef24dc518f5ae23e716981e1dcc6b2720ab -7,6db6eb25d1faabe30cf444dc633b5832475e38096b7e2402a3ec476dd7b9 -8,59194973a3f17bda9978ed6273383997222774b454386c8319c04f1f4f74c2b5 -9,e67caf7591b38e125a8017d58cfc6433bfaf84cd499d794f41d10bff2e5b840 -:,ccbee28e2c79db138f3977ba472dfae6b11a9bb82d5b3d7f25479338fff1fe92 -;,971f4d2bffb594c158c6ce1ef9d982b6fd2458275e7f89655bb74ede768ded -=,787689f833436aa711abbd45168856775a2b114656cdf4dc5a6c6f1afae520 -?,badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a -[,2cc6bd13a61fcba4a3859ec06bb8c823739b6beacba8cfa0152e8c60db94 -\,c362daa41a1254b2ed6e9fd3a015b4d7a419ba2920de10b478251f49aaca19 -],a6507336e35066daa8e4e6e624f93f65e35ee974e9e8b64d2dd9904ecefda2 -_,7966f891c1546aecbfcc3baedcfb67079d7f2a6a8b739ed5bac2bb3cf308d38 -a,a67d813ae7ffe5be951a4f41f2aa619a5e3894e85ea5d4986f84949c63d7672e -b,50c1b584f13987b466139285b2f3f28df6787123d0b32283d8794e3374e23 -c,abe983ec478024ec6fd046fcdfa4842676939551b47350447c77c13af18e6f -d,3193dc0d4c5e80ff9a8a05d2fcfe269539cb3927190bac19da2fce61d71 -e,dbb2737ecbf910efe3b267db7d4b327f360abc732c77bd0e4eff1d510cdef -f,b183bab50a3224024886f25251d24b6db93d73c2432559ff49e459b4cd6a -g,1ca3f324beeefb6a0e2c5b3c46abc91ca91c14eba419fa4768ac3023dbb4b2 -h,31f3462a473549f1469f897f84a8d4119bc71d4a5d852e85c26b588a5c0c72f -i,46178ad51fd52b19d0a3888710bd92068e933252aac6b13c76e7e6ea5d3226 -j,3a79db9923867e69c1dbf17151e6f4ad92ce681bcedd3977eebbc44c206f49 -k,9461b38c8e45782ada59d16132a4222c193778e7d70c4542c9536376f37be42 -l,319f50b432d868ae358e16f62ec26f35437aeb9492bce1356c9aa6bb19a386 -m,49c45a24aaabf49e217c15483204848a73582aba7fae10ee2c57bdb76482f -n,35b8b3d8c77dfb8fbd2495c842eac94fffa6f593bf15a2574d854dff3928 -o,d11de1cadb2ade61149e5ded1bd885edf0df6259255b33b587a96f983b2a1 -p,a0a7989b5d6e621a121eedae6f476d35193c97c1a7cb8ecd43622a485dc2e912 -q,43609f1faf81ed49c5894ac14c94ba52989fda4e1d2a52fd945a55ed719ed4 -r,a5ced9931ace23afc351371379bf05c635ad186943bc136474e4e5156c4c37 -s,3e41c60572c533e93ca421228929e54d6c856529459249c25c32ba33a1b1517 -t,1562e8c1d66b21e459be9a24e5c027a34d269bdce4fbee2f7678d2d3ee4718 -u,607fbc339ff241ac3d6619bcb68253dfc3c98782baf3f1f4efdb954f9c26 -v,cc9a138638fedb534d79928876baba261c7a64ba79c424dcbafcc9bac7010b8 -w,269ad1a88ed2b074e1303a129f94e4b710cf3e5b4d995163567f68719c3d9792 -x,5a6787ba32564e7c2f3a0ce64498ecbb23b89845e5a66b5cec7736f729ed37 -y,c52fb388e33212a2478b5e15a96f27aca6c62ac719e1e5f87a1cf0de7b15e918 -z,90582b9b5d97974b11461d63eced85f438a3eef5dc3279f9c47e1e38ea54ae8d -{,83b13ff8e7a3fab5ff1e98e8fd939cc097b6b45c85240d32450994f7671439d -},6176ef0558815b7f05c153cf4cdc69f9ba4ba1c10ea1a8749aeb8c2b977e -\u00A1,3327009cd471884115203860c1daf6d825c0845f8a528c6ef6bd24eb86b4b38b -\u00BF,cb7980afb86d71c080a2505281d14a8661b0902ddb8301bfb7a81eaf5dddf3ab -\u00E4,15cd6db9ec3c7d9113e6dd49a16f99a326b9f594ce987f919559ac7dbd3b555 -\u00EB,d68fbce93ca686e1d96fbd466f74523bce879ccf455e7db23c995f08983d7 -\u00F1,a2291248117a3c3a15bcace021a43f36bfd74579cbd0bf8766c2b57c18ce81fe -\u00F6,6edbb44c639b95308ffcdf8c4770dfe8b02d752dec4b3196f4a8f9ac2315393a -\u00FC,7b52b94c6516cbe461fea621d316cee0b875f0fbc239d25273e824b613e73dd4 -\u0431,e7e08f58efdff8e8e9d4ace13c58abf319ed1ec89682b7024f2452d5b8f6 -\u0433,f107c4854e36719dc7f25ddabaa8839522ca29daf51e672498ef8e441ea6 -\u0434,e5fbfb3ec3a28af1be51220ce9259bb6fe5b7d79765f2ee870e7b4c4b1f5 -\u0436,55f19f9d5d76b17152fec7d06ed8f59011d647a669536186434cad9fef834 -\u0437,ab4d3ab8e05c49bf6ef882d28a31e14f3f0a6c3c388c991146bd4217e7b683b -\u0438,a46a5881a0a3848eddd5387cc9db30ee9f12907af941f2961a3fdb1236f9281 -\u0439,6fc9985fc7f0bb44fd7b2ecdf48ca5e8cc5053e16d4d9d44781cdc9208aedd1 -\u043B,c04fae8a7ade804b962b3c3b2e53d6f1c8f8ec68652d274e4afe697ac525fe -\u043F,bfd454ecc6cdefebcdfa9b2e21b80196da31441ea7cb9733beddc32d49d6534 -\u0443,6f9a4c7334bd45ae94968b7be8c2503476b96d03789b2c8d0542c20cbf68a5b -\u0444,68a9d3b6f3655854dc8aac7963069a673be588bee2273d861b15049eae8fd9d -\u0446,3e58c54ba2f61161ede7d8fad331eac26648256ac44794ce9ef33c29276883b -\u0447,373b4884632e8fa11b996952b141e7ebf961d8221ab57a1b3b61e89bee4e916 -\u0448,295ff4d08b7b996d1b248815fb18156a671b2a4101291f12156721e8ea595d -\u0449,be9eb7657f674783b4caf9e68334a8854bedbcb83c643824111c38e548e8cc2 -\u044A,fdf2dcfe3f3bc83c042e771b5ab3b0bfdf32a9bb221309392cd493a95d4 -\u044B,64266684d086753a543a2b78468364bbdc7ca618e24a56266504d41c424 -\u044C,697c1baf3e65ef9338dc27ea31adefe91b43116927fb73402c6f42d4d6e9a -\u044D,143e7ce5d9984f4f63e21e171a595824645f22642e3392adf9768b57e03f0 -\u044E,62b017b61a80955b60f3d329fe5c3fe62e6396e5a8fd7347338c7d52a3717 -\u044F,c1dd2fedb288b256bccbc6eede3c9548c719f0adee564e649f95eb3b644c70d4 -\u2190,bd69e06e5dadfd84e5f3d1c21063f2553b2fa945ee1d4d7152fdc5425bc12a9 -\u2191,3040fe836a6c2fbd2c7a9c8ec6be5174fddf1ac20f55e366156fa5f712e10 -\u2192,19bf3292e126a105b54eba713aa1b152d541a1d8938829c56364d178ed22bf -\u2193,7437346d8bda78d525d19f540a95e4e79daeda795cbc5a13256236312cf -\u2196,865426a33df58b465f0601dd8b9bec3690b2193d1f9503c2caab78f6c2438 -\u2197,90e0a4d48cd829a6d5868909d643fa4affd39e8ae6caaf6ec79609cf7649b1c -\u2198,35cbdb28991a16eb2c793474ef7d0f458a5d13fffc283c4d74d929941bb1989 -\u2199,354ce8157e71dcd5b6b1674ac5bd55490702027c675e5cdceac55d2fbbd5a -\u2211,ea11e1295f6e4bdde54a3d60f258308c02b6d05067acb43547cd4966e3dfe24 -\u23E9,9c9ec71c1068ec6e03d2c9287f9da9193639f3a635e2fbd5d87c2fabe6499 -\u23EA,816ea34a6a6ec5c051e6932f1c471b7012b298d38d179f1b487c413f51959cd4 -\u23F4,8652e2b936ca8026bd28651d7c9f2819d2e923697734d18dfdb13550f8fdad5f -\u23F5,2a3b8f681daad8bf436cae8da3fe8131f62a162ab81af639c3e0644aa6abac2f -\u2640,1a220682ab7f20fbce9130660ec98229b3320a239a4782eb153385eda9bfbfd8 -\u2642,3a08d0dabc434a093f098baf505b165c14cbe964573ed8e9e61851589179570 -\u2648,ca971f4de43c164a936b552bc658b966e6b4eb5eb7963746324d2e29c64a7b8a -\u2649,3b706f91d8f76d5682f0c58b7a47e233e5178fb13b7865165aa13a9636c76f7 -\u264A,b6bf637aa199712a639224a1c5f9fa045b21e57b8cc6cd920839da74622e56 -\u264B,d763afc8eac63e2d4ff1e6c0504fa4db09aaf6ec11be6d0c26b8a7e98a1a83f -\u264C,1e18b683e42f4ee71cfc1efd1bb8a64d6a5ba3e3747f310f3661086edf5f379 -\u264D,d0dd21f453b853dfb9734bc2b097891366cb5ddb7af0b920b8cd934b2db1f5a8 -\u264E,e0de746e73dcd0e849a1cafaca1b4bd299407d513bd47630ab51c9662e4485 -\u264F,2fe431db4e3fba6e17bcdbd048952b54e9c9ca7423d4ea7463babeb7101f073a -\u2650,49c3886f1e5168843c2d0a96aae29a372f6746f5573188ec54386f086ef8f -\u2651,54ab7f578d9779b8f209f4de3fbee968885b0ddaa5afc59c6b18c3221e147b2f -\u2652,d2cd9a11ad2e4d955479fed92be78dfa5184a252ec1afcdb73d3a323939fc -\u2653,1fe38ea66e926633bacc014a264cd251e1634f1f9c9481ff679c457744118 -\u2665,336febeca7c488a6671dc071655dde2a1b65c3ccb20b6e8eaf9bfb08e64b80 -\u266A,5f00f57dd69d81cea076dd1cd2d70169ae91cbcb46c0f1c712bf0bde8bf54181 +" ",5db532b5cced46b4b535ece16eced7bbc5cac55594d61e8b8f8eac4299c9fc +!,2e3f50ba62cbda3ecf5479b62fedebd61d76589771cc19286bf2745cd71e47c6 +"""",4757e972c763149476bc556cfbad3614c1d49954f13f8893eb9d105845753f2e +#,9ae85f74f8e2c054b781a29fa9b25934ba63bb79f1de8a95b436d9bfdcaf4cd +$,b7fc4dfa5f652f6e1c1b19fb87655967eb82fb5fa719042f8c805cad7f01e487 +%,50851cf062548c436253c337a4112cfc985443a748d931cf201d1e84fc72b12c +&,e1a3dcafc933b9e577c07e74884bf75519818b61426658d059d44ac6352 +',5458845f6513f4eecffaf6bb1fdc4148631eeb1bd885257c617ca7a1faafd1 +(,727d27b5047e09e80532aaa1669e893dc4cb35f2515acd052bed4d04bc4c088 +),659d3a66f6cf7e254168fabfff45449e951f4af64cb4e6f357321793c3d1379 ++,3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716 +",",7840b4e7a680434857427111bdaf64e7fba912ea5707182e98bc585ccb53 +-,bd8a99db2c37ec71d7199cd52639981a7513ce9cca9626a3936f965b131193 +.,7456485aa2361434cb3be531bc121659f555a4aaf261d21a06d7afde5aa60b2 +/,7f95d7c1bbf3afa285d8d96757bb5572259a3ae854f5389dc53207699d94fd8 +0,0ebe7e5215169a699acc6cefa7b73fdb108db87bb6dae2849fbe24714b27 +1,71bc2bcfb2bd3759e6b1e86fc7a79585e1127dd357fc202893f9de241bc9e530 +2,4cd9eeee883468881d83848a46bf3012485c23f75753b8fbe8487341419847 +3,1d4eae13933860a6df5e8e955693b95a8c3b15c36b8b587532ac0996bc37e5 +4,d2e78fb22424232dc27b81fbcb47fd24c1acf76098753f2d9c28598287db5 +5,6d57e3bc88a65730e31a14e3f41e038a5ecf0891a6c243643b8e5476ae2 +6,334b36de7d679b8bbc725499adaef24dc518f5ae23e716981e1dcc6b2720ab +7,6db6eb25d1faabe30cf444dc633b5832475e38096b7e2402a3ec476dd7b9 +8,59194973a3f17bda9978ed6273383997222774b454386c8319c04f1f4f74c2b5 +9,e67caf7591b38e125a8017d58cfc6433bfaf84cd499d794f41d10bff2e5b840 +:,ccbee28e2c79db138f3977ba472dfae6b11a9bb82d5b3d7f25479338fff1fe92 +;,971f4d2bffb594c158c6ce1ef9d982b6fd2458275e7f89655bb74ede768ded +=,787689f833436aa711abbd45168856775a2b114656cdf4dc5a6c6f1afae520 +?,badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a +[,2cc6bd13a61fcba4a3859ec06bb8c823739b6beacba8cfa0152e8c60db94 +\,c362daa41a1254b2ed6e9fd3a015b4d7a419ba2920de10b478251f49aaca19 +],a6507336e35066daa8e4e6e624f93f65e35ee974e9e8b64d2dd9904ecefda2 +_,7966f891c1546aecbfcc3baedcfb67079d7f2a6a8b739ed5bac2bb3cf308d38 +a,a67d813ae7ffe5be951a4f41f2aa619a5e3894e85ea5d4986f84949c63d7672e +b,50c1b584f13987b466139285b2f3f28df6787123d0b32283d8794e3374e23 +c,abe983ec478024ec6fd046fcdfa4842676939551b47350447c77c13af18e6f +d,3193dc0d4c5e80ff9a8a05d2fcfe269539cb3927190bac19da2fce61d71 +e,dbb2737ecbf910efe3b267db7d4b327f360abc732c77bd0e4eff1d510cdef +f,b183bab50a3224024886f25251d24b6db93d73c2432559ff49e459b4cd6a +g,1ca3f324beeefb6a0e2c5b3c46abc91ca91c14eba419fa4768ac3023dbb4b2 +h,31f3462a473549f1469f897f84a8d4119bc71d4a5d852e85c26b588a5c0c72f +i,46178ad51fd52b19d0a3888710bd92068e933252aac6b13c76e7e6ea5d3226 +j,3a79db9923867e69c1dbf17151e6f4ad92ce681bcedd3977eebbc44c206f49 +k,9461b38c8e45782ada59d16132a4222c193778e7d70c4542c9536376f37be42 +l,319f50b432d868ae358e16f62ec26f35437aeb9492bce1356c9aa6bb19a386 +m,49c45a24aaabf49e217c15483204848a73582aba7fae10ee2c57bdb76482f +n,35b8b3d8c77dfb8fbd2495c842eac94fffa6f593bf15a2574d854dff3928 +o,d11de1cadb2ade61149e5ded1bd885edf0df6259255b33b587a96f983b2a1 +p,a0a7989b5d6e621a121eedae6f476d35193c97c1a7cb8ecd43622a485dc2e912 +q,43609f1faf81ed49c5894ac14c94ba52989fda4e1d2a52fd945a55ed719ed4 +r,a5ced9931ace23afc351371379bf05c635ad186943bc136474e4e5156c4c37 +s,3e41c60572c533e93ca421228929e54d6c856529459249c25c32ba33a1b1517 +t,1562e8c1d66b21e459be9a24e5c027a34d269bdce4fbee2f7678d2d3ee4718 +u,607fbc339ff241ac3d6619bcb68253dfc3c98782baf3f1f4efdb954f9c26 +v,cc9a138638fedb534d79928876baba261c7a64ba79c424dcbafcc9bac7010b8 +w,269ad1a88ed2b074e1303a129f94e4b710cf3e5b4d995163567f68719c3d9792 +x,5a6787ba32564e7c2f3a0ce64498ecbb23b89845e5a66b5cec7736f729ed37 +y,c52fb388e33212a2478b5e15a96f27aca6c62ac719e1e5f87a1cf0de7b15e918 +z,90582b9b5d97974b11461d63eced85f438a3eef5dc3279f9c47e1e38ea54ae8d +{,83b13ff8e7a3fab5ff1e98e8fd939cc097b6b45c85240d32450994f7671439d +},6176ef0558815b7f05c153cf4cdc69f9ba4ba1c10ea1a8749aeb8c2b977e +\u00A1,3327009cd471884115203860c1daf6d825c0845f8a528c6ef6bd24eb86b4b38b +\u00BF,cb7980afb86d71c080a2505281d14a8661b0902ddb8301bfb7a81eaf5dddf3ab +\u00E4,15cd6db9ec3c7d9113e6dd49a16f99a326b9f594ce987f919559ac7dbd3b555 +\u00EB,d68fbce93ca686e1d96fbd466f74523bce879ccf455e7db23c995f08983d7 +\u00F1,a2291248117a3c3a15bcace021a43f36bfd74579cbd0bf8766c2b57c18ce81fe +\u00F6,6edbb44c639b95308ffcdf8c4770dfe8b02d752dec4b3196f4a8f9ac2315393a +\u00FC,7b52b94c6516cbe461fea621d316cee0b875f0fbc239d25273e824b613e73dd4 +\u0431,e7e08f58efdff8e8e9d4ace13c58abf319ed1ec89682b7024f2452d5b8f6 +\u0433,f107c4854e36719dc7f25ddabaa8839522ca29daf51e672498ef8e441ea6 +\u0434,e5fbfb3ec3a28af1be51220ce9259bb6fe5b7d79765f2ee870e7b4c4b1f5 +\u0436,55f19f9d5d76b17152fec7d06ed8f59011d647a669536186434cad9fef834 +\u0437,ab4d3ab8e05c49bf6ef882d28a31e14f3f0a6c3c388c991146bd4217e7b683b +\u0438,a46a5881a0a3848eddd5387cc9db30ee9f12907af941f2961a3fdb1236f9281 +\u0439,6fc9985fc7f0bb44fd7b2ecdf48ca5e8cc5053e16d4d9d44781cdc9208aedd1 +\u043B,c04fae8a7ade804b962b3c3b2e53d6f1c8f8ec68652d274e4afe697ac525fe +\u043F,bfd454ecc6cdefebcdfa9b2e21b80196da31441ea7cb9733beddc32d49d6534 +\u0443,6f9a4c7334bd45ae94968b7be8c2503476b96d03789b2c8d0542c20cbf68a5b +\u0444,68a9d3b6f3655854dc8aac7963069a673be588bee2273d861b15049eae8fd9d +\u0446,3e58c54ba2f61161ede7d8fad331eac26648256ac44794ce9ef33c29276883b +\u0447,373b4884632e8fa11b996952b141e7ebf961d8221ab57a1b3b61e89bee4e916 +\u0448,295ff4d08b7b996d1b248815fb18156a671b2a4101291f12156721e8ea595d +\u0449,be9eb7657f674783b4caf9e68334a8854bedbcb83c643824111c38e548e8cc2 +\u044A,fdf2dcfe3f3bc83c042e771b5ab3b0bfdf32a9bb221309392cd493a95d4 +\u044B,64266684d086753a543a2b78468364bbdc7ca618e24a56266504d41c424 +\u044C,697c1baf3e65ef9338dc27ea31adefe91b43116927fb73402c6f42d4d6e9a +\u044D,143e7ce5d9984f4f63e21e171a595824645f22642e3392adf9768b57e03f0 +\u044E,62b017b61a80955b60f3d329fe5c3fe62e6396e5a8fd7347338c7d52a3717 +\u044F,c1dd2fedb288b256bccbc6eede3c9548c719f0adee564e649f95eb3b644c70d4 +\u2190,bd69e06e5dadfd84e5f3d1c21063f2553b2fa945ee1d4d7152fdc5425bc12a9 +\u2191,3040fe836a6c2fbd2c7a9c8ec6be5174fddf1ac20f55e366156fa5f712e10 +\u2192,19bf3292e126a105b54eba713aa1b152d541a1d8938829c56364d178ed22bf +\u2193,7437346d8bda78d525d19f540a95e4e79daeda795cbc5a13256236312cf +\u2196,865426a33df58b465f0601dd8b9bec3690b2193d1f9503c2caab78f6c2438 +\u2197,90e0a4d48cd829a6d5868909d643fa4affd39e8ae6caaf6ec79609cf7649b1c +\u2198,35cbdb28991a16eb2c793474ef7d0f458a5d13fffc283c4d74d929941bb1989 +\u2199,354ce8157e71dcd5b6b1674ac5bd55490702027c675e5cdceac55d2fbbd5a +\u2211,ea11e1295f6e4bdde54a3d60f258308c02b6d05067acb43547cd4966e3dfe24 +\u23E9,9c9ec71c1068ec6e03d2c9287f9da9193639f3a635e2fbd5d87c2fabe6499 +\u23EA,816ea34a6a6ec5c051e6932f1c471b7012b298d38d179f1b487c413f51959cd4 +\u23F4,8652e2b936ca8026bd28651d7c9f2819d2e923697734d18dfdb13550f8fdad5f +\u23F5,2a3b8f681daad8bf436cae8da3fe8131f62a162ab81af639c3e0644aa6abac2f +\u2640,1a220682ab7f20fbce9130660ec98229b3320a239a4782eb153385eda9bfbfd8 +\u2642,3a08d0dabc434a093f098baf505b165c14cbe964573ed8e9e61851589179570 +\u2648,ca971f4de43c164a936b552bc658b966e6b4eb5eb7963746324d2e29c64a7b8a +\u2649,3b706f91d8f76d5682f0c58b7a47e233e5178fb13b7865165aa13a9636c76f7 +\u264A,b6bf637aa199712a639224a1c5f9fa045b21e57b8cc6cd920839da74622e56 +\u264B,d763afc8eac63e2d4ff1e6c0504fa4db09aaf6ec11be6d0c26b8a7e98a1a83f +\u264C,1e18b683e42f4ee71cfc1efd1bb8a64d6a5ba3e3747f310f3661086edf5f379 +\u264D,d0dd21f453b853dfb9734bc2b097891366cb5ddb7af0b920b8cd934b2db1f5a8 +\u264E,e0de746e73dcd0e849a1cafaca1b4bd299407d513bd47630ab51c9662e4485 +\u264F,2fe431db4e3fba6e17bcdbd048952b54e9c9ca7423d4ea7463babeb7101f073a +\u2650,49c3886f1e5168843c2d0a96aae29a372f6746f5573188ec54386f086ef8f +\u2651,54ab7f578d9779b8f209f4de3fbee968885b0ddaa5afc59c6b18c3221e147b2f +\u2652,d2cd9a11ad2e4d955479fed92be78dfa5184a252ec1afcdb73d3a323939fc +\u2653,1fe38ea66e926633bacc014a264cd251e1634f1f9c9481ff679c457744118 +\u2665,336febeca7c488a6671dc071655dde2a1b65c3ccb20b6e8eaf9bfb08e64b80 +\u266A,5f00f57dd69d81cea076dd1cd2d70169ae91cbcb46c0f1c712bf0bde8bf54181 \u2713,930f4537d214d38666e6304e9c851cd6f7e41a0eb7c25049c9d22c8c5f6545df \ No newline at end of file diff --git a/src/main/resources/fonts/orange.csv b/IF/src/main/resources/fonts/orange.csv similarity index 98% rename from src/main/resources/fonts/orange.csv rename to IF/src/main/resources/fonts/orange.csv index 97ba36db..dde09bdb 100644 --- a/src/main/resources/fonts/orange.csv +++ b/IF/src/main/resources/fonts/orange.csv @@ -1,118 +1,118 @@ -" ",a9db1760dab1ed801a594a63cdc4a2e3b3e1d12e8056a702044774a52b1d18 -!,66245fb397b7c2b3a36e2a24d496be258f1cdf41054f99e9c65e1a673add7b4 -"""",226020c8b8d29efb659f47e2de8aafda84e5a30046bbe01a4f6c84ec19af56 -#,aab985c34435b38a74f63ee6851f659dafe8c682692d6228f50b7d84c27bd1 -$,ffab03da25f1e2d9915e9c75e8f7be3c0a09d39ed0d2229defb7d05cf0f9014 -%,892f9956766774e189677edf378bbd44b72a3fe5511b3ac5d2601ec3bf3fa0 -&,c7959f69c7c5cabb6ebf6226b18095b22d17be8e1873da6cd2b461a3674fe4de -',c5bc44222ec0e6bde0c3ce6a2a185d25af525c32b49747b6c0ea3c36babe2 -(,27bcf15a549c6b4df5bd949f7c432ce036fcceefddcd3e08ed78f1e68eedb -),ab1f891f3bfa695ae18f87a02275706fac7d908871a963db654a6e2c399336 -+,5250b3cce76635ef4c7a88b2c597bd2749868d78f5afa566157c2612ae4120 -",",67f2e81cf6c2cdf16649491390ca77fb6bc0a14dbdf4aba33537c6e4a6570b8 --,acff91dc99d5828023eedf873799d25535dade64a2e16a3b498b4113eafd4966 -.,1cd6bd9883b2fa33d1eb11cca35b5b83eeb63048cf9589ae5ff08199b05eae -/,e561a7a4a8c5f3f226bcb9324e7b088b85685d06913f464ad34efbc12ff817 -0,5bfa63a0a5428b273453ffe784d3e489cbcf6d12b78450a3515716ce724f4 -1,bcfaffa8c6c7f62621682fe56711dc3b894465fdf7a62f43b31a0d3403f34e7 -2,7410db623735c146c7c487e3692d1c5b5e23bf691ef0665c2e9549479d828f -3,ef8e7acf7242afa586c3d095f87fe9de7b7ca24c4a28a56040347c657960e36 -4,947c73d7d2ef14712ae59c57d64e512a7f9c527746b8bc424270f9e37c181c78 -5,75aff92de892d5922ad753dad5ae3479ab150af4ed284abfa75ca7a995c1893 -6,f16d423c7fd64c5c7f408546da4b787e93dbeac0e77b19c49b9ad4ff418f2d1 -7,7487e912a8e9bfc4912436af56c46c2e6a15a1d22d1ad18d46a229d7648e -8,1101d4b47dccb7612ac5efde5ae2441c82c3f0a684041aed38276dbdf94 -9,ba46857441caae6e16c9296fb571482aa5136268d39e35b7acfbf5139a37e03d -:,915cb8d76f5b7afb6a9532c084441c68a2f6efeb5db0da1af6c832f8293ffca -;,fc9ad39078751e0ed2757a1d023395dd0ef961e791a10914c29b2a3e8aaf27 -=,74e36cf3fb537892db2ce2981ff593d6da419e58b92fb86f9a3bde041d6cc96 -?,c8d2901337361e191da33543a2927dfa011f5eb694e31d501bcca15281d4a -[,d8aaa7d790bcbabd5c9b8e8476c9e35b94e062fdc4ab9acb34d889b48b3b0e -\,a121a2ae68c49f77e416c875437135379863e84952de7b89d7c8a1ef17becd -],5c087bb41612c488eabf1a6f2911ab2697aaee87f75e16a7474d6dd3bde1cc -_,2b57901b6cc73ceba4e563c960f98b8c15db99db873b58cd27ee52187d1b53 -a,78fe70b7731ac2f5b3d026eb1ab6a923a8c58b4bf6d3acbe145b10c36e6cf898 -b,1829ab7a6c2a598b77dd3758a06d753b2e7f11d4e73e2b4be3135d8e256283 -c,2bd98d493ea88b12e4f37ceeae0ceeaca756b57211d7ca409d1b26deee4e82 -d,753983105f922e2527f7e1788e63d92947049b91e211bb131e4c414a989e042 -e,4f662f35301f933915bad2b397d6da6cf12f58f4bd4fc757cd74f364695158 -f,a61d4586bbd1fc9fe466618a8f457c2056b1032e6dea7455edc3237e18fd17 -g,81d1437d1713c5f2e880dc95c39459710dbcb4f73b5104d688dfda77bc8bb9 -h,4acda887385a70d526748089e3aee465867cef9d37db4d6c5d21db8e775a2 -i,858e63db9c887196f91f3520bef5b1b31bb9821125ed4aabac3053ecd9e088 -j,db54ef191fb8f5a8aaaa26c8ce1272877edd8de62e915814eccd8c92d4cf61 -k,3b511cb4fa5f4ba66c9229575190df34a93b232141b69d3effaf2b7e512cd -l,2410464797bdfc1ab3125502143f160a8dded4a96133d112b55bd115ac746e4 -m,1b5fc06f72598e84fc75dd649b50838c5393c56af98ecaee468ce132f9483f -n,d39814e9d17f79f9f8ba6e1b9115c51aee4a9fe329aee4a5a475bdf3678c3b -o,71c53f70ba64cfc3ec3f41fe6f6c749e6bc132ac0fcd1dccd554bcf89e5cd2 -p,e7d3881f23ff9fb14db64e41fefbd85e5258f884f9a55ab6a865aae5da55fcdc -q,a080a921223d45f2b9fbcd234993d53e734669f7d67e28b73119eb7725326a -r,adc3a4ea4b9dc41daeb83f142baae74836b1b970824c5bb0a738253ed870a23d -s,f6ac1e61cfc35b47302f5ddf2f21933813549aa666a68fc32a4116c682c837 -t,8cc414fbb6a9359783318ca0bf17a8688f92bfa3980277abbfdf69f1edeb34 -u,60f5d0157e67289a7f01cecd14aec4aac6afdd8c35e9b874cb27d0b85e78ce -v,73ae6cbfe792cbb4f88bf425bdd3add9942f750673c344dd34af6d42c593ef -w,a0fff144ef4350e28fcf14768a246eb4a10b27c3b3627b69fe24eed2412cf88 -x,7fe1d222eb1a35d733fbde7c1342efa821898b56c7c28a69b6878920b511 -y,9660481aae446f23604622c25133bd22b99b56a1c28fcda2d91560efdaadeda -z,79bf6dbb47f986e825ddb588b5519283c2f03860fda81847d511e1d5966e8cfa -{,d524c5f0b91677ca24c711461467a6b3c052fcbe7a7d2f9e5d561439dff6b4 -},f789665979d5743db7639fab5279e70b740fb31e5a7c7ce3fbb164b2e4ece39 -\u00A1,89ef3ebc4e9f5dabb87639352b485bcf53ddab54aa1c8b0529a16363a98d1417 -\u00BF,331acd5f00903e11f99e3b04ea7e40e441bf52c37b838429a44c44f5157ba0d5 -\u00E4,3bbcb8a66125e3be64b18c2a681032e2a4e418af4d77a5fc73ca8d6c44ad96d -\u00EB,349bed3f951a09959d147e8d22814ca48b972b31ae3c9fd431fd23e44ce155 -\u00F1,1e9e729433e230a2d1a2ed36c7e6d1404e43d70d07c6c17b8e0c3b33c5a159af -\u00F6,ecffd7e7de32c66aba9827d940b14ec657471a924da2e846ae771d9a5ffd96 -\u00FC,4e9ee42350e91f287b2b4de84243c7ca6aed61789ea2c0d0322eac70b04adcbf -\u0431,d284ed4d176778d826261c787f10604cb3b2dacec29ef392b19af921259df -\u0433,ed411ee9b1fc50941a12ee8eaa66b77d4a14756cc1c3e6785d9e1e17e5c8cdb -\u0434,ae386fd2a71f2731bbfe764fd7b0a88899388290fbd37b6187bf127e804fe -\u0436,f5d5d3a36f55224bc88d7f9454b685811f16970ceb4b768172b57c33a15d -\u0437,967d27eeb73aafa18984626ca6af3cd178cf33e6f2af765d0a0f5d77a311e -\u0438,57292935ceec8d4b744ff157c5e7c754f505e4397f5bfb2ea406d4db8174441 -\u0439,ad5ccb946388394762abdb536cc2d79c29e755ed12cdf22c6b2fb0bb4da1a2 -\u043B,f8d38f467b7237a4dd977737a1b552519afd1f677566495b1f24b9b611c8b4 -\u043F,bbdaee197ebd3b081582dfd2bac195ab3484adc5e6bb4ce05ad685fc78d3 -\u0443,baba31a149fd6e66a922f3c6e458ba39172f4169b27565389b666f58d5b1e23 -\u0444,26cd6b8943676bebe5d64c257a3b2b44ee6db4a96484904bb4194a88dd7b38 -\u0446,9219ced1ff98e275e2d416f6db9c192e1573dccdcc23382746e6df82160fc -\u0447,3f3f9fa5c4a9f6efbd8baa56a19a69714c24de614abc9b2a9779dec7b1647df8 -\u0448,9dcda1bea0ac9884955a2fae77e57f33de67c13855b3af4588f896fb9216dc20 -\u0449,6db427ff36de8c6fe75b454dcc914770f341d0aa5bd2d576234622bdf44a44b -\u044A,f5d4c578cebdaa7c357d178668142e167775bda0641da8ff7b36273694f171cd -\u044B,4f5d2a7fc336194fbc716c0eda1f92fd4b81d66e15ba1f4f8c5dfee373b3ea5 -\u044C,c391f53b4c1656f693f9e332c80a577e203bb63310978788bdd3f8aa57e1f0 -\u044D,81c77563ee13881cf42e294c6357dd328a4cad443313d23fa4ee9564c83799 -\u044E,5e8577da896126263e94d35b309bfafb6c2bd2fcff0663f4693295c488fa91 -\u044F,2b68a09e248ef5132dc28e82bb3e5d638bf9fc64e5b9e17db24c0cfd935e261 -\u2190,6e8c3ce2aee6cf2faade7db37bbae73a36627ac1473fef75b410a0af97659f -\u2191,881bdcd562fb61ef66b8fe975a854ed19f657d17dadc647da79888566a8b2 -\u2192,6e8cd53664d9307b6869b9abbae2b7737ab762bb18bb34f31c5ca8f3edb63b6 -\u2193,741941e7e7e914a115c342d6d38a22931e138b3da1eeb4e998571e90f871517 -\u2196,696a7727582b25e0c7f4e9b48d89753361a27a6b70ed79bf23f3194eccdd6 -\u2197,7b5d9e49834fe31b35a667bb06cb24c2e13bd9fec1df6e0598eb425e81baa52 -\u2198,e63a644cfbb3bcbc4544c6c6a478d38f60cea76c6421a356f774d4be6395e51 -\u2199,1457df509d865ca67d29bd5b42312a3365246f2edbef1c1fd7b8974b25dca2 -\u23E9,114c26ce7855d6522bfa86b77a74a9fdc79127513b2b78abe4781ad66676133 -\u23EA,4c93259c91647ad3af5f5ebf511b81a91312e8a2be5e55fc7897cde7c5efa1 -\u23F4,3d4deef18397ded73888f2a44b1dba6e85c953b8afe7221deeff0ceeb6ac5e3 -\u23F5,69f61acec3aadc5e518259d5c1131ac149b427beeff5e57d879bd3131a172a7 -\u2640,99feb2ebf265757e82624c7a02679770e0130bcda5b3e7a4f9e0610e55de589c -\u2642,33655e71e275433df72bb8e1c2dc6a5126974ba8c59715ca5b129049f0271c26 -\u2648,a0982e6ef2977ed19ca92b01c8671a2d5587a588bcc942862914de8b098ac06 -\u2649,971de60e156881d7a02dfb99af893a9ece72843da16165b5b1e6df36d584ddc9 -\u264A,28cddc3d0538aa3b6bc5692b41223b336e7b616b82271aea33187c1e51bba7f7 -\u264B,35f28e175870d584ac604ed7ebf4cf51d77b02458c424026387f0149dd832e7a -\u264C,711b94447e4daded578816f3fdf7a09e3543e216d9ee9f2f8eb60ad858f9e0b0 -\u264D,cfc2a47aeff4edf284e25eea018c42f7bf8b86c4c947973a4d3fce69aafb08e3 -\u264E,5868ee4788cefd5f95b01ebb21518a4129573b970f5f47ba4cb949de92b436ed -\u264F,ae085dd6cd8fd0b4e15cb349a7156547fad3106f79674db672a3810168cea5ae -\u2650,f35c7dd482de7f6c2891038de48a45c4a2b3361ae2e98eac318960d336846e97 -\u2651,116ef991a24c7426614380f3e9625a4e1e48f7b768ba5b37d126f73b562a03b0 -\u2652,a4947bfcae00d1151aae63c0658223f061e72883bcda3bbad6a61f30a404aadd -\u2653,77e5917de0c1025db7fbfbd77b1ecce19105ab73c5c18d59ae3ab530de16c82b -\u2665,5b64f2ea2ba7e6243bf73a6e3b99a2d14b6348e2ff28d9e8c19bd47f33386a -\u266A,68f23bcf5d44cfb427c6dfcc91bc71b26633d2eb8af34532758762c59cb0082f +" ",a9db1760dab1ed801a594a63cdc4a2e3b3e1d12e8056a702044774a52b1d18 +!,66245fb397b7c2b3a36e2a24d496be258f1cdf41054f99e9c65e1a673add7b4 +"""",226020c8b8d29efb659f47e2de8aafda84e5a30046bbe01a4f6c84ec19af56 +#,aab985c34435b38a74f63ee6851f659dafe8c682692d6228f50b7d84c27bd1 +$,ffab03da25f1e2d9915e9c75e8f7be3c0a09d39ed0d2229defb7d05cf0f9014 +%,892f9956766774e189677edf378bbd44b72a3fe5511b3ac5d2601ec3bf3fa0 +&,c7959f69c7c5cabb6ebf6226b18095b22d17be8e1873da6cd2b461a3674fe4de +',c5bc44222ec0e6bde0c3ce6a2a185d25af525c32b49747b6c0ea3c36babe2 +(,27bcf15a549c6b4df5bd949f7c432ce036fcceefddcd3e08ed78f1e68eedb +),ab1f891f3bfa695ae18f87a02275706fac7d908871a963db654a6e2c399336 ++,5250b3cce76635ef4c7a88b2c597bd2749868d78f5afa566157c2612ae4120 +",",67f2e81cf6c2cdf16649491390ca77fb6bc0a14dbdf4aba33537c6e4a6570b8 +-,acff91dc99d5828023eedf873799d25535dade64a2e16a3b498b4113eafd4966 +.,1cd6bd9883b2fa33d1eb11cca35b5b83eeb63048cf9589ae5ff08199b05eae +/,e561a7a4a8c5f3f226bcb9324e7b088b85685d06913f464ad34efbc12ff817 +0,5bfa63a0a5428b273453ffe784d3e489cbcf6d12b78450a3515716ce724f4 +1,bcfaffa8c6c7f62621682fe56711dc3b894465fdf7a62f43b31a0d3403f34e7 +2,7410db623735c146c7c487e3692d1c5b5e23bf691ef0665c2e9549479d828f +3,ef8e7acf7242afa586c3d095f87fe9de7b7ca24c4a28a56040347c657960e36 +4,947c73d7d2ef14712ae59c57d64e512a7f9c527746b8bc424270f9e37c181c78 +5,75aff92de892d5922ad753dad5ae3479ab150af4ed284abfa75ca7a995c1893 +6,f16d423c7fd64c5c7f408546da4b787e93dbeac0e77b19c49b9ad4ff418f2d1 +7,7487e912a8e9bfc4912436af56c46c2e6a15a1d22d1ad18d46a229d7648e +8,1101d4b47dccb7612ac5efde5ae2441c82c3f0a684041aed38276dbdf94 +9,ba46857441caae6e16c9296fb571482aa5136268d39e35b7acfbf5139a37e03d +:,915cb8d76f5b7afb6a9532c084441c68a2f6efeb5db0da1af6c832f8293ffca +;,fc9ad39078751e0ed2757a1d023395dd0ef961e791a10914c29b2a3e8aaf27 +=,74e36cf3fb537892db2ce2981ff593d6da419e58b92fb86f9a3bde041d6cc96 +?,c8d2901337361e191da33543a2927dfa011f5eb694e31d501bcca15281d4a +[,d8aaa7d790bcbabd5c9b8e8476c9e35b94e062fdc4ab9acb34d889b48b3b0e +\,a121a2ae68c49f77e416c875437135379863e84952de7b89d7c8a1ef17becd +],5c087bb41612c488eabf1a6f2911ab2697aaee87f75e16a7474d6dd3bde1cc +_,2b57901b6cc73ceba4e563c960f98b8c15db99db873b58cd27ee52187d1b53 +a,78fe70b7731ac2f5b3d026eb1ab6a923a8c58b4bf6d3acbe145b10c36e6cf898 +b,1829ab7a6c2a598b77dd3758a06d753b2e7f11d4e73e2b4be3135d8e256283 +c,2bd98d493ea88b12e4f37ceeae0ceeaca756b57211d7ca409d1b26deee4e82 +d,753983105f922e2527f7e1788e63d92947049b91e211bb131e4c414a989e042 +e,4f662f35301f933915bad2b397d6da6cf12f58f4bd4fc757cd74f364695158 +f,a61d4586bbd1fc9fe466618a8f457c2056b1032e6dea7455edc3237e18fd17 +g,81d1437d1713c5f2e880dc95c39459710dbcb4f73b5104d688dfda77bc8bb9 +h,4acda887385a70d526748089e3aee465867cef9d37db4d6c5d21db8e775a2 +i,858e63db9c887196f91f3520bef5b1b31bb9821125ed4aabac3053ecd9e088 +j,db54ef191fb8f5a8aaaa26c8ce1272877edd8de62e915814eccd8c92d4cf61 +k,3b511cb4fa5f4ba66c9229575190df34a93b232141b69d3effaf2b7e512cd +l,2410464797bdfc1ab3125502143f160a8dded4a96133d112b55bd115ac746e4 +m,1b5fc06f72598e84fc75dd649b50838c5393c56af98ecaee468ce132f9483f +n,d39814e9d17f79f9f8ba6e1b9115c51aee4a9fe329aee4a5a475bdf3678c3b +o,71c53f70ba64cfc3ec3f41fe6f6c749e6bc132ac0fcd1dccd554bcf89e5cd2 +p,e7d3881f23ff9fb14db64e41fefbd85e5258f884f9a55ab6a865aae5da55fcdc +q,a080a921223d45f2b9fbcd234993d53e734669f7d67e28b73119eb7725326a +r,adc3a4ea4b9dc41daeb83f142baae74836b1b970824c5bb0a738253ed870a23d +s,f6ac1e61cfc35b47302f5ddf2f21933813549aa666a68fc32a4116c682c837 +t,8cc414fbb6a9359783318ca0bf17a8688f92bfa3980277abbfdf69f1edeb34 +u,60f5d0157e67289a7f01cecd14aec4aac6afdd8c35e9b874cb27d0b85e78ce +v,73ae6cbfe792cbb4f88bf425bdd3add9942f750673c344dd34af6d42c593ef +w,a0fff144ef4350e28fcf14768a246eb4a10b27c3b3627b69fe24eed2412cf88 +x,7fe1d222eb1a35d733fbde7c1342efa821898b56c7c28a69b6878920b511 +y,9660481aae446f23604622c25133bd22b99b56a1c28fcda2d91560efdaadeda +z,79bf6dbb47f986e825ddb588b5519283c2f03860fda81847d511e1d5966e8cfa +{,d524c5f0b91677ca24c711461467a6b3c052fcbe7a7d2f9e5d561439dff6b4 +},f789665979d5743db7639fab5279e70b740fb31e5a7c7ce3fbb164b2e4ece39 +\u00A1,89ef3ebc4e9f5dabb87639352b485bcf53ddab54aa1c8b0529a16363a98d1417 +\u00BF,331acd5f00903e11f99e3b04ea7e40e441bf52c37b838429a44c44f5157ba0d5 +\u00E4,3bbcb8a66125e3be64b18c2a681032e2a4e418af4d77a5fc73ca8d6c44ad96d +\u00EB,349bed3f951a09959d147e8d22814ca48b972b31ae3c9fd431fd23e44ce155 +\u00F1,1e9e729433e230a2d1a2ed36c7e6d1404e43d70d07c6c17b8e0c3b33c5a159af +\u00F6,ecffd7e7de32c66aba9827d940b14ec657471a924da2e846ae771d9a5ffd96 +\u00FC,4e9ee42350e91f287b2b4de84243c7ca6aed61789ea2c0d0322eac70b04adcbf +\u0431,d284ed4d176778d826261c787f10604cb3b2dacec29ef392b19af921259df +\u0433,ed411ee9b1fc50941a12ee8eaa66b77d4a14756cc1c3e6785d9e1e17e5c8cdb +\u0434,ae386fd2a71f2731bbfe764fd7b0a88899388290fbd37b6187bf127e804fe +\u0436,f5d5d3a36f55224bc88d7f9454b685811f16970ceb4b768172b57c33a15d +\u0437,967d27eeb73aafa18984626ca6af3cd178cf33e6f2af765d0a0f5d77a311e +\u0438,57292935ceec8d4b744ff157c5e7c754f505e4397f5bfb2ea406d4db8174441 +\u0439,ad5ccb946388394762abdb536cc2d79c29e755ed12cdf22c6b2fb0bb4da1a2 +\u043B,f8d38f467b7237a4dd977737a1b552519afd1f677566495b1f24b9b611c8b4 +\u043F,bbdaee197ebd3b081582dfd2bac195ab3484adc5e6bb4ce05ad685fc78d3 +\u0443,baba31a149fd6e66a922f3c6e458ba39172f4169b27565389b666f58d5b1e23 +\u0444,26cd6b8943676bebe5d64c257a3b2b44ee6db4a96484904bb4194a88dd7b38 +\u0446,9219ced1ff98e275e2d416f6db9c192e1573dccdcc23382746e6df82160fc +\u0447,3f3f9fa5c4a9f6efbd8baa56a19a69714c24de614abc9b2a9779dec7b1647df8 +\u0448,9dcda1bea0ac9884955a2fae77e57f33de67c13855b3af4588f896fb9216dc20 +\u0449,6db427ff36de8c6fe75b454dcc914770f341d0aa5bd2d576234622bdf44a44b +\u044A,f5d4c578cebdaa7c357d178668142e167775bda0641da8ff7b36273694f171cd +\u044B,4f5d2a7fc336194fbc716c0eda1f92fd4b81d66e15ba1f4f8c5dfee373b3ea5 +\u044C,c391f53b4c1656f693f9e332c80a577e203bb63310978788bdd3f8aa57e1f0 +\u044D,81c77563ee13881cf42e294c6357dd328a4cad443313d23fa4ee9564c83799 +\u044E,5e8577da896126263e94d35b309bfafb6c2bd2fcff0663f4693295c488fa91 +\u044F,2b68a09e248ef5132dc28e82bb3e5d638bf9fc64e5b9e17db24c0cfd935e261 +\u2190,6e8c3ce2aee6cf2faade7db37bbae73a36627ac1473fef75b410a0af97659f +\u2191,881bdcd562fb61ef66b8fe975a854ed19f657d17dadc647da79888566a8b2 +\u2192,6e8cd53664d9307b6869b9abbae2b7737ab762bb18bb34f31c5ca8f3edb63b6 +\u2193,741941e7e7e914a115c342d6d38a22931e138b3da1eeb4e998571e90f871517 +\u2196,696a7727582b25e0c7f4e9b48d89753361a27a6b70ed79bf23f3194eccdd6 +\u2197,7b5d9e49834fe31b35a667bb06cb24c2e13bd9fec1df6e0598eb425e81baa52 +\u2198,e63a644cfbb3bcbc4544c6c6a478d38f60cea76c6421a356f774d4be6395e51 +\u2199,1457df509d865ca67d29bd5b42312a3365246f2edbef1c1fd7b8974b25dca2 +\u23E9,114c26ce7855d6522bfa86b77a74a9fdc79127513b2b78abe4781ad66676133 +\u23EA,4c93259c91647ad3af5f5ebf511b81a91312e8a2be5e55fc7897cde7c5efa1 +\u23F4,3d4deef18397ded73888f2a44b1dba6e85c953b8afe7221deeff0ceeb6ac5e3 +\u23F5,69f61acec3aadc5e518259d5c1131ac149b427beeff5e57d879bd3131a172a7 +\u2640,99feb2ebf265757e82624c7a02679770e0130bcda5b3e7a4f9e0610e55de589c +\u2642,33655e71e275433df72bb8e1c2dc6a5126974ba8c59715ca5b129049f0271c26 +\u2648,a0982e6ef2977ed19ca92b01c8671a2d5587a588bcc942862914de8b098ac06 +\u2649,971de60e156881d7a02dfb99af893a9ece72843da16165b5b1e6df36d584ddc9 +\u264A,28cddc3d0538aa3b6bc5692b41223b336e7b616b82271aea33187c1e51bba7f7 +\u264B,35f28e175870d584ac604ed7ebf4cf51d77b02458c424026387f0149dd832e7a +\u264C,711b94447e4daded578816f3fdf7a09e3543e216d9ee9f2f8eb60ad858f9e0b0 +\u264D,cfc2a47aeff4edf284e25eea018c42f7bf8b86c4c947973a4d3fce69aafb08e3 +\u264E,5868ee4788cefd5f95b01ebb21518a4129573b970f5f47ba4cb949de92b436ed +\u264F,ae085dd6cd8fd0b4e15cb349a7156547fad3106f79674db672a3810168cea5ae +\u2650,f35c7dd482de7f6c2891038de48a45c4a2b3361ae2e98eac318960d336846e97 +\u2651,116ef991a24c7426614380f3e9625a4e1e48f7b768ba5b37d126f73b562a03b0 +\u2652,a4947bfcae00d1151aae63c0658223f061e72883bcda3bbad6a61f30a404aadd +\u2653,77e5917de0c1025db7fbfbd77b1ecce19105ab73c5c18d59ae3ab530de16c82b +\u2665,5b64f2ea2ba7e6243bf73a6e3b99a2d14b6348e2ff28d9e8c19bd47f33386a +\u266A,68f23bcf5d44cfb427c6dfcc91bc71b26633d2eb8af34532758762c59cb0082f \u2713,4c4d5461361b99793ea1c0498b807d6613b7b2c46a7a77b3d6d602be92ace343 \ No newline at end of file diff --git a/src/main/resources/fonts/pink.csv b/IF/src/main/resources/fonts/pink.csv similarity index 98% rename from src/main/resources/fonts/pink.csv rename to IF/src/main/resources/fonts/pink.csv index 3e04f37c..3b61414f 100644 --- a/src/main/resources/fonts/pink.csv +++ b/IF/src/main/resources/fonts/pink.csv @@ -1,118 +1,118 @@ -" ",329b337f56b9aa6077c6845eb3899496dcc3efbb1241a71e268fe1a169bd5a -!,ee6d1ca815f58431e471e18aff10bd3869ae5423af186798ad05ce8e2148a4a -"""",88643fa37027ce3996108232c2f39b9a99d6d95f8b2bf135c17117c066365d42 -#,b5a0b81b0726abdb4e504a7acde5cdbd9b6e8a12784489558bc567a2b2cf -$,dd2589babc5ede21482eed90b3b24bc7d9a86c51f8ba2c559d7aa488bc27255e -%,a0558151fb996a19fb65b9ebedfbf8dd26f1bc722c7c443e8daba98cbc7deb -&,8528aa211e30204cb21f306a1bb0e049636e2129f28226fec9dc8ee73aa35 -',c479b42cff263827c3e8c38f4534822c9d7a906eec826869918b735ea1356cbc -(,35cdba93153ebf2d5923776cb599feb792ad565a1fb8b18185943976b7b3d6 -),f271c1b26259e8dda7fc33fd3acad918ba131256f789f4e0951d73916c3d3ca4 -+,f3bfe4131a6f612c75b45d80839bcb37edd7e8717e695a3e64ce9d033beafe6 -",",43dacad738f17ffc3442821c7913b76162b930413103e746927bddb1fd31 --,c54305813828323cab2eda48f692b112556d89d4bcedda84b5c2fe3611ab8 -.,bbee2c76fb44477c69095d0a244c02f98de47b73cc850531a9c69ebb1a82 -/,b8c218c3f21bbc1c6f86a479595837e873a7707b5aa98b49e0108313e71e -0,6799351fd521fcc53732c6cf114b36f1bf9688c944b9622cc1f320dbee328f89 -1,5ba2cd9ef956eb2c32db847b9d3926a5ddc64370a7ac34e3f08cf96a88e4 -2,4f7f9df399389611a3b331419b88f153e5ec1509ba447d82f0252b566492 -3,d37b2a657719da61bc80669217daae1b4fd31416c1a4e968d3111a888ae3584 -4,53341ff75ff9f7872153796b79457c162ddc3d249ff872cdade75460491f -5,3ff87edb982d7372acde92c4524a2245571f5aa1ae940d817bffbc2a288 -6,ad617cc9bf983333bf12664143a772d52156ac6c48e168a1d916fb629916fb -7,36a3a8ee54aa8730c9229aa04e32600b32e753f2a6cc56411c3b10d45d8e2e -8,1e461fe6ebcddba14f90623486968ba9c7656d53d1aa631a574625a096917e0 -9,1aede60554a3c769189d1660761aa5ae82d84f5b66652229b66a34f4dd33c -:,d0dcfc169aa74cc9d794f2ebf7e37d1e7727851d84856891a32f2b484c1f2 -;,ad2ab0546b7212aa5bc34ade11626367b3f31b7af1c930e1191f8843e37c0 -=,71520804f9e454c2045a4b5c3e0fd710f1af396f3f42f530dad4fcfce23e68 -?,eab6eaec237d94c3699eaed566a592386fb679503a3085ca49b3a129841dcc13 -[,923d51a896caa7139f94b1e3dcca52d30f75d5a594b3b5175652677f98cf2 -\,1b944b44cc13c3b29a3ca4fae9976b7d6b52586558f5f4c335a66796d86f96a9 -],cb96749f8f5b5a9c5f27eb97e116314fa1fefe4af5ea7fdbf923fdb2e9d2f0 -_,c54fc5ea722c3edc01cf4e2c7c21aefe670ebca8f2bae156e341757a26dc -a,847f40b2a22edb1a887469a6198daf468eccc495e35de8d49eae65b48468cf8 -b,9798a89eb352457ef15a2ff181aac997d8a753ab0b73ba59d6b1b54fdb778d -c,6b878bcebd9228625cb3691cb33a48a3b95c6efe9d26c7ace7a15a2bf159861 -d,c61b32f07ce034d8607d491f802fdc6a882dcdbd5ad8b29a4abbb5fb949e8f8 -e,464969637167c9a286249a3963f188413958e5ad4912fa210ac95c73644d5a -f,b8f69649bcb6b25efc42917ea62be07ff5e64dd35c8aa1e4cdb231e3823bff3 -g,fc912a305a59437320d3fd3a9a808437344d3f26afd34c8ceae757fde3ab3d78 -h,e63f19c75c7f3b2a73538a45b262386495698acd77625c991c1e81ae4a936cb -i,f0a211c5d82aca79ab92f1f9bed59ddfb8bb152aadbff871703e3e5dbfa17389 -j,6b1d8636827384b3ebf2c51ec4ead59e6d8c2e19ef99f9c649e544798f224 -k,64935849c7058eb86afe3e9035f9c87582ec48c93f4c81817e743679264a5 -l,3e5e19e446fdae1646114a368717104f3fda235cddc92e342d164b58f64af -m,6ff9733cedb29e150746e9c2beb988f531f8f690bd386e6b2c847d401890f9 -n,68b2a78bbfacd975f4677f2b64a7e8f3d4cf971f1366a08781111c915491e6 -o,7f911d28346e5537bb972d3b82824f7b60b641c3db51c74b56772e1d09778 -p,e0d4d7d3949e1ace37201e347343cb5af5743331ebbbe1a91140b56a40562439 -q,613e84176de1aa6742f89af0313619768a0864d03bed4ffdc723fef6b3ec -r,941b7795e2b1b2a76a39ac546211d1d4dc8b90acc746874b84e87bc2ba48cb3e -s,8be431d4362d7e10e733af58bafe1827e27df921cb55b412bb2f6afbf347078 -t,d131653a473085948ecb60caa4d88de28e9a1f6164fd87381457a7cac54e3 -u,ae8173d97ebd1d7545d0726154afdb53ffdb2972c57a612578cce9d6cfd3b49 -v,8cd35d23980e898ebabb42758192642b2986dd18911d7dc691b9989f62767e9 -w,7d5ee24afb44984fa8954badb7e289768150e2b29084c81768e28a677dde89 -x,9f7455dae9698823e4087209cc8e764319ebc3348f7fabaa9a815594fc64e -y,4849207453b6879f9727fcdf39cf4f85c72a862ce5c569086f720a89fc13 -z,1ca6cd0b1846a898da1ced9b4469b60891a70bc29dc98fb677c7be929538e7 -{,f169f7d739d5fabde0ccd124c58c32d05dee9831659eb129c2aa182d814 -},7f9941f9d10ca4e30182633c7911d3995ccdc6a44e7570ccbc22cb0b445ba -\u00A1,aaa829008856129965ea48228feed39bdaa3ca4fcf47cd4820ac9c6217675ea4 -\u00BF,aeeea9bce23ad74706333798b1637a280d896c9d9cddb884e7ab1aee41e4371d -\u00E4,f819d81c3afc4f480ea57c71ced542c14abd96effbbbec4131748bfef48c -\u00EB,5ba715ff45010dc8e56b7135a5cb6aef8eda0daf110ced7e34d38ca79219486 -\u00F1,9464643b5ab6f3cb24b5a8003a03dc2213034977ab23fec398111200c01095b8 -\u00F6,ffe58091cf71347bd2fba63494dd4265c596e81d2b9164985f9abb23418968f -\u00FC,3c366138d1ad1552f8c198178bbd2015e19fafb1e03f13122f8c3caab466e615 -\u0431,4c55d83b60b73b25ef22485bd7285d3ef21b1244b4fa0bc862cae7b2782b72 -\u0433,5e53df8719b5d22b3db6e94534bd3a4c4234414b847611e75cf5afe298af0ed -\u0434,e4ab28c35cb6d8d3898fd97ba36e5e95b5ab5fa19c96f67ec2fb2237a73d9 -\u0436,47d8696a89ef958ba551354c464a643b496a9e3efc76b9dd0653c8f1cb1b9 -\u0437,eef6352017984463ebdc354bf439a8c280e0db159be178f6656b1d679825d45e -\u0438,9f8734c2151caf12a2998289b96c923cd34bfef685324edbeab820bc81d69 -\u0439,87166f8659cd81712ec3c6ab314b9e6c9e917786bfad24ddf477b1ca5f4830bd -\u043B,aa244aa5358436b31c2661493bbd8fc4915c8fbd349f212679f153e9d4d2b8e -\u043F,32e949d5895d68ac8be526b4ae1251351d798cdfeab1bd9125af54bd84772 -\u0443,c7c366b6e8895975d5514229e71ec477fc23116e6b5e1c3dd9dbc6c9a741535 -\u0444,9c475499ab6a96f82ba6795a3e8e02c7e03c2c278786e59dd4e3b2d95aaae -\u0446,5c35286c7143b121beb0635ab2cd403f90fad75c89f2f1e847eb11c8066bf -\u0447,483de975122e53d65a729be2241b54edfd7d3d29d412df5a96f03e71d13a317b -\u0448,57a0b69dc2456113fcc8767a2ffc6ecbcbef44bdf8268ab7169efec54e2d9b -\u0449,3a3c6a408b9d10131f316754761e4c37c317b26a6a6cd10957e76feedc56 -\u044A,4659621d4d50547bc278738041eb4327149572079c041f75d0e443c55f96d6 -\u044B,cc3934624afc3ef37c385373f412d9e6dbd0fead9d911d4b5380154d72e880 -\u044C,b7905451fc9fc546d6754228996bc78406b7f444e2e3d8774e69a9258ef6 -\u044D,154be8c434838a3c3b67b6abbdf4c7a090d224ea16a7d3a8a3fea91860589d -\u044E,9d5e501b26d855b34156239ac6831471ca7979d458eb42649eddedc21ca14 -\u044F,a9d5cdca7ccd86dd8e3b36ae94ac3f99a3acf6ecabb8adb21392f33e2c3d55 -\u2190,42ee597ab5bde98a7539625b414c87db386ff7f9d526ff9839e99696308b4a9e -\u2191,eec88c76e3d9a1ebd7f4a2e55ecbcc42a8d23f696784aa410f09512a3b53a -\u2192,186673dc1eaa6ac275c8add1e4c543ef94d93fae71dbf6c046f056e7f344aaaf -\u2193,f3c66c42cde1dd1f5f95143e472254f7fae8eccff4dc943b086a944b27bdfb -\u2196,608513ecf24442d3d1f2a5b4ae925c3bee23392d9d9d564872eb2b023746 -\u2197,2f24f535bb1fed7c77c258aa2d9c95b9d8a6f895a62452477a44e388d7d1 -\u2198,767a228333e1567affc9f52b90a3571b3b544164a23dd4592b27291a16df5b1 -\u2199,b89d3b9fd93ba76fa395dea9122d508bdad2bbbafe251c9fc41b977f526cc0 -\u23E9,e4e23af687bf3b37b9a9c66141cb7d1ce885240b5e9e4e8a8d40b31e79bb -\u23EA,982d741174b5a575be2891d898c71fed1a8cf97f53b750ed897b62f6d2f449c6 -\u23F4,3c2aa65538d9a6ad5b58eb0bd24afd1dd5495ce07d4df0fe67484cc4f37fc8 -\u23F5,945fd0d852e4157f978c55c57f6a6f8d565bef34e63d7196ea4cf0645be727df -\u2640,f6aac8c1c290be9d3bd495476aca42c68623b9cbefdd6ddbd6144855b9731c63 -\u2642,d5b3310e1366f19156a89e2259d464a115c0eae4e2fa6a515d5f8eb42a2dc736 -\u2648,9dbcad56c405be350042000d4ea6f09308f7d417660b5e2b4cad9c7542fc13f7 -\u2649,829eca3f2283e41441ac30cc33df168da138dea72ee6b73a4998f67e7b09dd11 -\u264A,1399ff7d05300360df2bcdab662d7018720a383f971cf6c3705cb695edf07691 -\u264B,e557159d7c40406d1175a5c01f28221b80f38abc0018d6cec74bdaab1ba4916c -\u264C,76f8e62b2486bad2b52bc87e753841f6056284464334bc748c0c49af2178764d -\u264D,322a97f0977f5dc6467a09b1ee5ac4dd77e36d32f45ec400d17353846096e7d3 -\u264E,115033a9468365078eb6c5bed579373465b9f6c466bbae678cada1c4ea27e732 -\u264F,110b0c73cb1466cc3b8dbf1d726f1272640b2be1cab4184d69e8bc1ad4223fb9 -\u2650,c2f7de23545485fc9624fc9dc7208261c06d2a962da31ad55fdb46e1aeb25168 -\u2651,e2c216b8f7505a0aaa4c8fe281436cf7fd2be9b5431de3d13ce082c89e33d813 -\u2652,6d9f03b441b5b43f9be57d54a70afaddbb05ad3126fac8f0d1a076b7c52c3e84 -\u2653,89ff624c880d5f2823381d0a7c11b7a77b177bcc33701ac5c3e41fd77b0cd81a -\u2665,c8cf6f2fa2a86a35d39c0b7886e9ea1683af8f6662c46af58dd71c3d8a39 -\u266A,9be43f770854c803e864556368cc03317820b15edc5f2093619d2dc12444548a +" ",329b337f56b9aa6077c6845eb3899496dcc3efbb1241a71e268fe1a169bd5a +!,ee6d1ca815f58431e471e18aff10bd3869ae5423af186798ad05ce8e2148a4a +"""",88643fa37027ce3996108232c2f39b9a99d6d95f8b2bf135c17117c066365d42 +#,b5a0b81b0726abdb4e504a7acde5cdbd9b6e8a12784489558bc567a2b2cf +$,dd2589babc5ede21482eed90b3b24bc7d9a86c51f8ba2c559d7aa488bc27255e +%,a0558151fb996a19fb65b9ebedfbf8dd26f1bc722c7c443e8daba98cbc7deb +&,8528aa211e30204cb21f306a1bb0e049636e2129f28226fec9dc8ee73aa35 +',c479b42cff263827c3e8c38f4534822c9d7a906eec826869918b735ea1356cbc +(,35cdba93153ebf2d5923776cb599feb792ad565a1fb8b18185943976b7b3d6 +),f271c1b26259e8dda7fc33fd3acad918ba131256f789f4e0951d73916c3d3ca4 ++,f3bfe4131a6f612c75b45d80839bcb37edd7e8717e695a3e64ce9d033beafe6 +",",43dacad738f17ffc3442821c7913b76162b930413103e746927bddb1fd31 +-,c54305813828323cab2eda48f692b112556d89d4bcedda84b5c2fe3611ab8 +.,bbee2c76fb44477c69095d0a244c02f98de47b73cc850531a9c69ebb1a82 +/,b8c218c3f21bbc1c6f86a479595837e873a7707b5aa98b49e0108313e71e +0,6799351fd521fcc53732c6cf114b36f1bf9688c944b9622cc1f320dbee328f89 +1,5ba2cd9ef956eb2c32db847b9d3926a5ddc64370a7ac34e3f08cf96a88e4 +2,4f7f9df399389611a3b331419b88f153e5ec1509ba447d82f0252b566492 +3,d37b2a657719da61bc80669217daae1b4fd31416c1a4e968d3111a888ae3584 +4,53341ff75ff9f7872153796b79457c162ddc3d249ff872cdade75460491f +5,3ff87edb982d7372acde92c4524a2245571f5aa1ae940d817bffbc2a288 +6,ad617cc9bf983333bf12664143a772d52156ac6c48e168a1d916fb629916fb +7,36a3a8ee54aa8730c9229aa04e32600b32e753f2a6cc56411c3b10d45d8e2e +8,1e461fe6ebcddba14f90623486968ba9c7656d53d1aa631a574625a096917e0 +9,1aede60554a3c769189d1660761aa5ae82d84f5b66652229b66a34f4dd33c +:,d0dcfc169aa74cc9d794f2ebf7e37d1e7727851d84856891a32f2b484c1f2 +;,ad2ab0546b7212aa5bc34ade11626367b3f31b7af1c930e1191f8843e37c0 +=,71520804f9e454c2045a4b5c3e0fd710f1af396f3f42f530dad4fcfce23e68 +?,eab6eaec237d94c3699eaed566a592386fb679503a3085ca49b3a129841dcc13 +[,923d51a896caa7139f94b1e3dcca52d30f75d5a594b3b5175652677f98cf2 +\,1b944b44cc13c3b29a3ca4fae9976b7d6b52586558f5f4c335a66796d86f96a9 +],cb96749f8f5b5a9c5f27eb97e116314fa1fefe4af5ea7fdbf923fdb2e9d2f0 +_,c54fc5ea722c3edc01cf4e2c7c21aefe670ebca8f2bae156e341757a26dc +a,847f40b2a22edb1a887469a6198daf468eccc495e35de8d49eae65b48468cf8 +b,9798a89eb352457ef15a2ff181aac997d8a753ab0b73ba59d6b1b54fdb778d +c,6b878bcebd9228625cb3691cb33a48a3b95c6efe9d26c7ace7a15a2bf159861 +d,c61b32f07ce034d8607d491f802fdc6a882dcdbd5ad8b29a4abbb5fb949e8f8 +e,464969637167c9a286249a3963f188413958e5ad4912fa210ac95c73644d5a +f,b8f69649bcb6b25efc42917ea62be07ff5e64dd35c8aa1e4cdb231e3823bff3 +g,fc912a305a59437320d3fd3a9a808437344d3f26afd34c8ceae757fde3ab3d78 +h,e63f19c75c7f3b2a73538a45b262386495698acd77625c991c1e81ae4a936cb +i,f0a211c5d82aca79ab92f1f9bed59ddfb8bb152aadbff871703e3e5dbfa17389 +j,6b1d8636827384b3ebf2c51ec4ead59e6d8c2e19ef99f9c649e544798f224 +k,64935849c7058eb86afe3e9035f9c87582ec48c93f4c81817e743679264a5 +l,3e5e19e446fdae1646114a368717104f3fda235cddc92e342d164b58f64af +m,6ff9733cedb29e150746e9c2beb988f531f8f690bd386e6b2c847d401890f9 +n,68b2a78bbfacd975f4677f2b64a7e8f3d4cf971f1366a08781111c915491e6 +o,7f911d28346e5537bb972d3b82824f7b60b641c3db51c74b56772e1d09778 +p,e0d4d7d3949e1ace37201e347343cb5af5743331ebbbe1a91140b56a40562439 +q,613e84176de1aa6742f89af0313619768a0864d03bed4ffdc723fef6b3ec +r,941b7795e2b1b2a76a39ac546211d1d4dc8b90acc746874b84e87bc2ba48cb3e +s,8be431d4362d7e10e733af58bafe1827e27df921cb55b412bb2f6afbf347078 +t,d131653a473085948ecb60caa4d88de28e9a1f6164fd87381457a7cac54e3 +u,ae8173d97ebd1d7545d0726154afdb53ffdb2972c57a612578cce9d6cfd3b49 +v,8cd35d23980e898ebabb42758192642b2986dd18911d7dc691b9989f62767e9 +w,7d5ee24afb44984fa8954badb7e289768150e2b29084c81768e28a677dde89 +x,9f7455dae9698823e4087209cc8e764319ebc3348f7fabaa9a815594fc64e +y,4849207453b6879f9727fcdf39cf4f85c72a862ce5c569086f720a89fc13 +z,1ca6cd0b1846a898da1ced9b4469b60891a70bc29dc98fb677c7be929538e7 +{,f169f7d739d5fabde0ccd124c58c32d05dee9831659eb129c2aa182d814 +},7f9941f9d10ca4e30182633c7911d3995ccdc6a44e7570ccbc22cb0b445ba +\u00A1,aaa829008856129965ea48228feed39bdaa3ca4fcf47cd4820ac9c6217675ea4 +\u00BF,aeeea9bce23ad74706333798b1637a280d896c9d9cddb884e7ab1aee41e4371d +\u00E4,f819d81c3afc4f480ea57c71ced542c14abd96effbbbec4131748bfef48c +\u00EB,5ba715ff45010dc8e56b7135a5cb6aef8eda0daf110ced7e34d38ca79219486 +\u00F1,9464643b5ab6f3cb24b5a8003a03dc2213034977ab23fec398111200c01095b8 +\u00F6,ffe58091cf71347bd2fba63494dd4265c596e81d2b9164985f9abb23418968f +\u00FC,3c366138d1ad1552f8c198178bbd2015e19fafb1e03f13122f8c3caab466e615 +\u0431,4c55d83b60b73b25ef22485bd7285d3ef21b1244b4fa0bc862cae7b2782b72 +\u0433,5e53df8719b5d22b3db6e94534bd3a4c4234414b847611e75cf5afe298af0ed +\u0434,e4ab28c35cb6d8d3898fd97ba36e5e95b5ab5fa19c96f67ec2fb2237a73d9 +\u0436,47d8696a89ef958ba551354c464a643b496a9e3efc76b9dd0653c8f1cb1b9 +\u0437,eef6352017984463ebdc354bf439a8c280e0db159be178f6656b1d679825d45e +\u0438,9f8734c2151caf12a2998289b96c923cd34bfef685324edbeab820bc81d69 +\u0439,87166f8659cd81712ec3c6ab314b9e6c9e917786bfad24ddf477b1ca5f4830bd +\u043B,aa244aa5358436b31c2661493bbd8fc4915c8fbd349f212679f153e9d4d2b8e +\u043F,32e949d5895d68ac8be526b4ae1251351d798cdfeab1bd9125af54bd84772 +\u0443,c7c366b6e8895975d5514229e71ec477fc23116e6b5e1c3dd9dbc6c9a741535 +\u0444,9c475499ab6a96f82ba6795a3e8e02c7e03c2c278786e59dd4e3b2d95aaae +\u0446,5c35286c7143b121beb0635ab2cd403f90fad75c89f2f1e847eb11c8066bf +\u0447,483de975122e53d65a729be2241b54edfd7d3d29d412df5a96f03e71d13a317b +\u0448,57a0b69dc2456113fcc8767a2ffc6ecbcbef44bdf8268ab7169efec54e2d9b +\u0449,3a3c6a408b9d10131f316754761e4c37c317b26a6a6cd10957e76feedc56 +\u044A,4659621d4d50547bc278738041eb4327149572079c041f75d0e443c55f96d6 +\u044B,cc3934624afc3ef37c385373f412d9e6dbd0fead9d911d4b5380154d72e880 +\u044C,b7905451fc9fc546d6754228996bc78406b7f444e2e3d8774e69a9258ef6 +\u044D,154be8c434838a3c3b67b6abbdf4c7a090d224ea16a7d3a8a3fea91860589d +\u044E,9d5e501b26d855b34156239ac6831471ca7979d458eb42649eddedc21ca14 +\u044F,a9d5cdca7ccd86dd8e3b36ae94ac3f99a3acf6ecabb8adb21392f33e2c3d55 +\u2190,42ee597ab5bde98a7539625b414c87db386ff7f9d526ff9839e99696308b4a9e +\u2191,eec88c76e3d9a1ebd7f4a2e55ecbcc42a8d23f696784aa410f09512a3b53a +\u2192,186673dc1eaa6ac275c8add1e4c543ef94d93fae71dbf6c046f056e7f344aaaf +\u2193,f3c66c42cde1dd1f5f95143e472254f7fae8eccff4dc943b086a944b27bdfb +\u2196,608513ecf24442d3d1f2a5b4ae925c3bee23392d9d9d564872eb2b023746 +\u2197,2f24f535bb1fed7c77c258aa2d9c95b9d8a6f895a62452477a44e388d7d1 +\u2198,767a228333e1567affc9f52b90a3571b3b544164a23dd4592b27291a16df5b1 +\u2199,b89d3b9fd93ba76fa395dea9122d508bdad2bbbafe251c9fc41b977f526cc0 +\u23E9,e4e23af687bf3b37b9a9c66141cb7d1ce885240b5e9e4e8a8d40b31e79bb +\u23EA,982d741174b5a575be2891d898c71fed1a8cf97f53b750ed897b62f6d2f449c6 +\u23F4,3c2aa65538d9a6ad5b58eb0bd24afd1dd5495ce07d4df0fe67484cc4f37fc8 +\u23F5,945fd0d852e4157f978c55c57f6a6f8d565bef34e63d7196ea4cf0645be727df +\u2640,f6aac8c1c290be9d3bd495476aca42c68623b9cbefdd6ddbd6144855b9731c63 +\u2642,d5b3310e1366f19156a89e2259d464a115c0eae4e2fa6a515d5f8eb42a2dc736 +\u2648,9dbcad56c405be350042000d4ea6f09308f7d417660b5e2b4cad9c7542fc13f7 +\u2649,829eca3f2283e41441ac30cc33df168da138dea72ee6b73a4998f67e7b09dd11 +\u264A,1399ff7d05300360df2bcdab662d7018720a383f971cf6c3705cb695edf07691 +\u264B,e557159d7c40406d1175a5c01f28221b80f38abc0018d6cec74bdaab1ba4916c +\u264C,76f8e62b2486bad2b52bc87e753841f6056284464334bc748c0c49af2178764d +\u264D,322a97f0977f5dc6467a09b1ee5ac4dd77e36d32f45ec400d17353846096e7d3 +\u264E,115033a9468365078eb6c5bed579373465b9f6c466bbae678cada1c4ea27e732 +\u264F,110b0c73cb1466cc3b8dbf1d726f1272640b2be1cab4184d69e8bc1ad4223fb9 +\u2650,c2f7de23545485fc9624fc9dc7208261c06d2a962da31ad55fdb46e1aeb25168 +\u2651,e2c216b8f7505a0aaa4c8fe281436cf7fd2be9b5431de3d13ce082c89e33d813 +\u2652,6d9f03b441b5b43f9be57d54a70afaddbb05ad3126fac8f0d1a076b7c52c3e84 +\u2653,89ff624c880d5f2823381d0a7c11b7a77b177bcc33701ac5c3e41fd77b0cd81a +\u2665,c8cf6f2fa2a86a35d39c0b7886e9ea1683af8f6662c46af58dd71c3d8a39 +\u266A,9be43f770854c803e864556368cc03317820b15edc5f2093619d2dc12444548a \u2713,28fc87aa84cc33fb5fbfaa62af69d6ee69b26498e4444c9ac94f623e4f9fcdb3 \ No newline at end of file diff --git a/src/main/resources/fonts/plush.csv b/IF/src/main/resources/fonts/plush.csv similarity index 98% rename from src/main/resources/fonts/plush.csv rename to IF/src/main/resources/fonts/plush.csv index be516efd..ebfbbcd6 100644 --- a/src/main/resources/fonts/plush.csv +++ b/IF/src/main/resources/fonts/plush.csv @@ -1,118 +1,118 @@ -" ",cce410bf66bdcaaf7d7ba4b783291d95cd0590371b875154872e30bd1b2514bd -!,ae5ac76c149a2660827a2c272189f77973fafcb882d4a7d20778e1ec6f4232f5 -"""",4f9e58c7d7a3b8fe939d9cf6dfdac1b2a8ec7e96c43357f9974c4a46907fbb -#,367edecdaf04790d5875e25bbd57deace575c62efdf95b132ef9cbe2cd6c3ad1 -$,47b69c9dfb61067c9484df7d03e63f17895c9cda3325c2c534a5c22358557631 -%,5523b4a5f66056585b85947200532150e5a59a9f3c5e691331b4b17ff6175f5c -&,e50e54b86cd5a3112d29f8cca6c1ed7aac82c5589ff1d582f12bb71f79b7d6ea -',6e4ee5dc6452aa1b24e82b3b666b84737c968591d7577218f97488da69862e90 -(,baed247f1e1e1e2185e62b54e34078780a550a8e93d97e3dd8ec3f2c862895f2 -),7e0d7d14bedd29984e038b4d79dcd4c103571218c55bb6152e62397c8a3c190d -+,32332b770a4874698862855da5b3fe47f19ab291df766b6083b5f9a0c3c6847e -",",f9941c1cd78ade5d51ac0e0f5e7d7ca5eaf62e4622dfb16a336aa820771d936d --,32cbdc9d4c590eac285a4544f2b1e068bd27fd52173ac8d7679013823cbab95a -.,a7330f68059aba9acbd5bf46a2d397ba81d1c872bfe151293b021ba1b6ce42b9 -/,fc057e5b2646719bcfc203227c1177ad92594b1ef74c2b88dfa799244a2946b3 -0,1f3d1972ce2f2b79b2df07ad5c574f9ccd0eceb204143df966d301b18e92b0b6 -1,e0a4c94dd65a7cadc4172cedf3990a8542772bb113cdf1a0f78ef652c6abe6cb -2,a47c55064f1d07625af05cdbc0fc7c84173b10541024c8855ed7132ca7767246 -3,d9cb94d8729197a18a76882c24918a8c04494d34727f4df060fb7a45a1ff8537 -4,36ad7565fa68942d2ff5f04efda80d9e9f88d33401680f182e0f37af32b8c294 -5,d0203b124acefd08c446a0492a5c9d800ee0cd8c260c3c12377731659251ad4e -6,e491017fd5267fc9a641cce0250d4683804e3b1399b2b5b58f130f5774de2821 -7,8425acc42caf8b1e95ccb16d379af0b76f95ed29ef2a494073d0b07b15dc22fd -8,b4904d5dee3782d4d6c6febe72783d96148277efbe78c1514cc20088d8ff0d09 -9,6adc65c3b896ab66df1ed7ba4250d16bb8352a6d285a54c00218ea72a4bb7149 -:,8abb6aec67d910a098beea886fce01b607ed026ebce25f502175afa4c21e40b0 -;,1006bb57b58805f57a38400b4dfb3d9cabec9c6e88b2a017b36f6302edae6127 -=,c92766fea6c05750e40dc83cd7e93ab34846d440920951da26359836ecf08f4b -?,d60888fdcbbff71c474d4cf860f88858baad1db9e5c19c650ba15bf945ef5f02 -[,9ef7da1422efa255b7d5a4ac06f42a18dd8193961df799bc53b305c2003a2023 -\,3ca193a9c5517fc7afccf16be1cd7d3af78b3e3763f61227bfc9b6a6fadfd21e -],ceacc92ec2398ec05c8e051621b66e1aef830878ce20befa77316d65b6630269 -_,a58026785ee72ab43f6d55872ca41a4e4ecb06d95e3dffeac05d7d631d2e98a2 -a,11827e965da3f9d8ada413335e4aa6a0718f38725e74987ae3036cb925d6cc63 -b,90c4a13f7e2e698d9c2ccb2be6421e91e32ad8d3e685a789d5404a2ff363c9b6 -c,767beb4d48b185b6ec57db062c6f1e3d266be8862295985455e3b8c0e77f8a34 -d,9843e3e836ad050827df31892f1fe157f513cfdce047de4c4d8e531cc580872e -e,c7232da7b35784bb076c0942b5724d8d0085940782e31a4e90ede5ca127b56ea -f,489058f62a3d0965eb45e69fb4b4fa269159014efa82c944bb08aa73ff514453 -g,43a2b69fcae48256be37706706c6748576e1860b1f5c9634b5c2207d5e1c70e9 -h,aed508e256e6f9bb549a135eaa8dbd7a284c78bf0d23f00522211d69ba592961 -i,6bf436918250b750989ce1720950e05f96cced063d52d1f5f1152b044940458b -j,3c64ca1215c0c50d00b06a4a4649346d60c15a66c1a60b8ee2e8a8cda8eaf57e -k,30dc57e5f16b3b61d617f0f5afb82ff044f2ccaf097e4da67345f2c783d5cd5a -l,d1a69766c98e78a6a3c065df51b17d5a81c5dec4105f60649f118b4b368de9f -m,c65c692d548693ebfbaf10400d2e8aa9091a90590ce43ed6b47c2c071c8dfe11 -n,67e53511da4bbace91831c58a4a01ad9aa3b6f113250c53dda966d5e9405c1a9 -o,2b88700029fc4d0ca0d347fa82e436e7a36c9614c8f734534f75861231df3b7b -p,df323ec6d848c24950fc7aa51b6caca05a22fd7068d12504dbb97213f1f20980 -q,6796daa6ba2fe80493d66d7892e1832b66273ddf4f11f098e847d52494767232 -r,826a2c7db4f098bcc1a4549289a09cc12d3acd416ce733ef9587695377829900 -s,cfbe026ca3c9f0fe9467869c0fe25783fedc2b7e0d8857ed39d5ba0dfbc8d427 -t,a2921c2645696f216b2eeb4ba6d9e0bd67ab8fe24853cb0e30ed4e94951d6e7 -u,cc8713cc52311483f9a9750d6478acc554da11319ea4d162c2cc353039f4b297 -v,2bc7f14ea855f7795783c7708ca336704ce3827df8514e512c05208a3003209 -w,15da9bb40e7cabfb3e4e80ceeb2b454e36b306e8da74f041372df6e4d582de0d -x,8df9c9a5852b45d7686dfc6368988f0694170c2467e2a82bc40c4cf97c5e674 -y,529ff42cdfd3adaac9f8c862f90cdd627d22d0aba106d71b7a44213ee6e43a99 -z,548f777107f301c240f8154fd94e72e8b22da1ee48705a61efbfcf9ee207f92d -{,228a026f098e6a8aec631413bd68681593af02795403cab93abc51a5477d7741 -},162bd9fd7e07f6e826b679dfb76b38398a2619375a68638304a9e0c86006d64b -\u00A1,df3f6b284e77a5e03234f0485c9559428502c9fd38353413c9a027a2cbf7c8c2 -\u00BF,c08116712cbe012486d9e5238568b88f4824c4ecae80578c3c9fb33bd97ac976 -\u00E4,f19bb94aec06572c20c5cc3f8e3c889997f912ae380f595df39f68abb3c6bc5 -\u00EB,40c2d733aeab9b43f45f25e924a93c3457ee9c611d4de09d360a5b0c10ef0d64 -\u00F1,4d804f85318390530df92312fb40400466304a291a9046ad2ec7cf401149c51b -\u00F6,263d221e677bc9945db2fb97506c0ddb8f029e0115769b48c7131f9258223fe0 -\u00FC,b39de43435ab50447e87bc3a488b13f7b5d08adfc9e6913b7844420dd5b752af -\u0431,d20b1412d30e98708606debf0da057eecb7ee228e1de926f7a2ed356df84af39 -\u0433,e92b7a4739aad69feed1cb6ec3fa43a8a3d005464e4113c825f57ea41e0c69e8 -\u0434,65f7e96afef18589df7387a2919bc6e0a8fbf535c3128e3201647d13686cbca4 -\u0436,27a2dedc5d9a0eadac47cf28d2e4a3b88f19779f0ceaa9295e18ec317c9338e8 -\u0437,165eb195d09b7acb26e8f9042be4b6cfe41e1791c1c7227d7f931382082a25fa -\u0438,f101fc9d21824965cdf7ca08c39bc5e7a6536a437276f6395010b41e3967bfaf -\u0439,98a61098636268faa67e257cb9c5dc9707843035a32600992329a850c2f3d98c -\u043B,2096bdd8013003a3e15e04d27b401f62697584a93bf4f9bd4e100b8d0a0fa93 -\u043F,77c07172fe664e291fe557f5a1c34ecf70ee3907b71331d72e63e8c59474cb09 -\u0443,b16de0a51e7b4c1dce45f70eb6d6a78a78fc1379faa4cccc750da4a2353738a -\u0444,f43230da9b8b9f1096941269d4d3fbba332a621e32f07b54154810c7cda83a87 -\u0446,a54f6c692616c71f364bce3afe253ab494e46fb2f72edcdf2c3bf2c0b3731657 -\u0447,c312302af8c5f306a14b6388006eb70ff11c026e7f42f13356e46ce17cb1005e -\u0448,5840bbdcd02a6de9bbd03784810a3cabb77f72e942f8cb569de65452acd34026 -\u0449,2dd3a2e26585bde4580a045ae492188624548a9e8f4ef047439c335540a48fc2 -\u044A,c9ad47599df8fae60ab12a7cf6fd43705819019af22d11b9c28dfab25de61960 -\u044B,5fa272a8bddd551504a2bc209ffdfdacafec2bb07ce9081af67c592130375bcf -\u044C,6c28fb01e68da246e23b2152689bd5f9b5f96ab145883dd5bf73f38bc8032bb3 -\u044D,645212a6ea777f6dd650769e2e615b6d367ef4a64baf69b0a102b3f9fc1e6dd1 -\u044E,b6aaa899df8993ac8a6736314f5b0e72b5729679359c2e1fc404fb8e19f6cd39 -\u044F,f7e15ca301977c85119643ea2c1e6db28b8dd23fb86817263759db0461339916 -\u2190,9293a6070503172071f35f58c82204e818cd065186901ca19f7dadbdac165e44 -\u2191,190ade10ccf4ad4a2ae6f6402e6ae07ca12262b6b1e3cd6e67155945310da176 -\u2192,1da44c767cca25861d3a52fe17c26428e660ee23dc0d793bf7bd86ea202f703d -\u2193,5eca0f55af545c4ba646c0cd9efc340900bd9dd5bbf4f52301d6d368e049123 -\u2196,7fc980410126a72eb4f084187fc68709508c23ec2bf40cb4ac35611e14b48aa7 -\u2197,fae53b7d47cec12d55666c8adc02b0978c48ef5326ab06944b017d6106fae4d1 -\u2198,3f2923a53142ecba6d67da9869b506a6613420b85fd016b132d8471c2f5e58ad -\u2199,da5401e05566783eb59e197ae3776db8386a9d0b1905294efa71b58cbf518210 -\u23E9,d3905bffc67cd4041685fbd3558a919c82675fd3f9110628f9c5331c9bbd8794 -\u23EA,59316a69c6dd655f5b89f2a8331525fe0dc92fd13d432623a8bf851ce820b034 -\u23F4,8b4b8f323a14776dd851f17003753ec4e805b9b3da31e254b4d22ccfa5eff16a -\u23F5,4feb391c76120a275dc668aef9bd54fae015c16762cfed6e35308cacd2532694 -\u2640,cc7c877d4c3fd1c9ee29aaf6695c14ceb7377852f70d90e7af3835d53e97349c -\u2642,61857c2b67d6a732740dcebb92a4f4c6f1d8a53f73c1d3292cf96276f4806da -\u2648,89e627d1278b2600f8fa5efe88173192782818556ca93433f4b5ef47570ac18e -\u2649,d13f2690540098174e31a5857bc6aa69eb20e2c89540d2a1d7c49ea3ad1514e1 -\u264A,2a4cc5321f5e17d4a39e015c56a95eab5ab478e0a04eec8a5681ff6807a6321c -\u264B,3778d66b562d25d2a39f259091c14ac9698a1535d99c549c1fdeeafb4b33d113 -\u264C,c8875808ffdcfa87e58ba0cd6c0f1d18cc367a65dd46b2975b4422b9dde7e209 -\u264D,480a305414f1b3137c92c4162a50efa147cec0a8a1ba88919c9b70ffe5173c6a -\u264E,3811af1c87674a04361d27709b38c55c90bc8ddb1cfd849d02c15dc6c4b33778 -\u264F,a88e1a1e843278d297a9e8cf99d7581cb336298b7f6fe1702793c0bad915330b -\u2650,d13bc25e432b0f5d631ff500d657a46c0c27fe9539bafa3155dd2c2cfbfdb097 -\u2651,28cda54df2e217f325fc980350ab261154b3da5b022769e2cd38f5c959480452 -\u2652,208d163f963b7298b12b7fd3c8f9ef6eeec1d8298161aa71da822e9c2d629b5c -\u2653,92ba17e760b4eaf6ce77f7c579c1fbbc942c7e43e88448626fa64535c4bd8bc9 -\u2665,f192817ba7fabbbb3b7db63771d8f854fa641e1df713cdd4c0a9942503f9f2a0 -\u266A,45117968e8a9b1736ab19391c71e84e12533d597d65a07d8c14e81727fbd9f0f +" ",cce410bf66bdcaaf7d7ba4b783291d95cd0590371b875154872e30bd1b2514bd +!,ae5ac76c149a2660827a2c272189f77973fafcb882d4a7d20778e1ec6f4232f5 +"""",4f9e58c7d7a3b8fe939d9cf6dfdac1b2a8ec7e96c43357f9974c4a46907fbb +#,367edecdaf04790d5875e25bbd57deace575c62efdf95b132ef9cbe2cd6c3ad1 +$,47b69c9dfb61067c9484df7d03e63f17895c9cda3325c2c534a5c22358557631 +%,5523b4a5f66056585b85947200532150e5a59a9f3c5e691331b4b17ff6175f5c +&,e50e54b86cd5a3112d29f8cca6c1ed7aac82c5589ff1d582f12bb71f79b7d6ea +',6e4ee5dc6452aa1b24e82b3b666b84737c968591d7577218f97488da69862e90 +(,baed247f1e1e1e2185e62b54e34078780a550a8e93d97e3dd8ec3f2c862895f2 +),7e0d7d14bedd29984e038b4d79dcd4c103571218c55bb6152e62397c8a3c190d ++,32332b770a4874698862855da5b3fe47f19ab291df766b6083b5f9a0c3c6847e +",",f9941c1cd78ade5d51ac0e0f5e7d7ca5eaf62e4622dfb16a336aa820771d936d +-,32cbdc9d4c590eac285a4544f2b1e068bd27fd52173ac8d7679013823cbab95a +.,a7330f68059aba9acbd5bf46a2d397ba81d1c872bfe151293b021ba1b6ce42b9 +/,fc057e5b2646719bcfc203227c1177ad92594b1ef74c2b88dfa799244a2946b3 +0,1f3d1972ce2f2b79b2df07ad5c574f9ccd0eceb204143df966d301b18e92b0b6 +1,e0a4c94dd65a7cadc4172cedf3990a8542772bb113cdf1a0f78ef652c6abe6cb +2,a47c55064f1d07625af05cdbc0fc7c84173b10541024c8855ed7132ca7767246 +3,d9cb94d8729197a18a76882c24918a8c04494d34727f4df060fb7a45a1ff8537 +4,36ad7565fa68942d2ff5f04efda80d9e9f88d33401680f182e0f37af32b8c294 +5,d0203b124acefd08c446a0492a5c9d800ee0cd8c260c3c12377731659251ad4e +6,e491017fd5267fc9a641cce0250d4683804e3b1399b2b5b58f130f5774de2821 +7,8425acc42caf8b1e95ccb16d379af0b76f95ed29ef2a494073d0b07b15dc22fd +8,b4904d5dee3782d4d6c6febe72783d96148277efbe78c1514cc20088d8ff0d09 +9,6adc65c3b896ab66df1ed7ba4250d16bb8352a6d285a54c00218ea72a4bb7149 +:,8abb6aec67d910a098beea886fce01b607ed026ebce25f502175afa4c21e40b0 +;,1006bb57b58805f57a38400b4dfb3d9cabec9c6e88b2a017b36f6302edae6127 +=,c92766fea6c05750e40dc83cd7e93ab34846d440920951da26359836ecf08f4b +?,d60888fdcbbff71c474d4cf860f88858baad1db9e5c19c650ba15bf945ef5f02 +[,9ef7da1422efa255b7d5a4ac06f42a18dd8193961df799bc53b305c2003a2023 +\,3ca193a9c5517fc7afccf16be1cd7d3af78b3e3763f61227bfc9b6a6fadfd21e +],ceacc92ec2398ec05c8e051621b66e1aef830878ce20befa77316d65b6630269 +_,a58026785ee72ab43f6d55872ca41a4e4ecb06d95e3dffeac05d7d631d2e98a2 +a,11827e965da3f9d8ada413335e4aa6a0718f38725e74987ae3036cb925d6cc63 +b,90c4a13f7e2e698d9c2ccb2be6421e91e32ad8d3e685a789d5404a2ff363c9b6 +c,767beb4d48b185b6ec57db062c6f1e3d266be8862295985455e3b8c0e77f8a34 +d,9843e3e836ad050827df31892f1fe157f513cfdce047de4c4d8e531cc580872e +e,c7232da7b35784bb076c0942b5724d8d0085940782e31a4e90ede5ca127b56ea +f,489058f62a3d0965eb45e69fb4b4fa269159014efa82c944bb08aa73ff514453 +g,43a2b69fcae48256be37706706c6748576e1860b1f5c9634b5c2207d5e1c70e9 +h,aed508e256e6f9bb549a135eaa8dbd7a284c78bf0d23f00522211d69ba592961 +i,6bf436918250b750989ce1720950e05f96cced063d52d1f5f1152b044940458b +j,3c64ca1215c0c50d00b06a4a4649346d60c15a66c1a60b8ee2e8a8cda8eaf57e +k,30dc57e5f16b3b61d617f0f5afb82ff044f2ccaf097e4da67345f2c783d5cd5a +l,d1a69766c98e78a6a3c065df51b17d5a81c5dec4105f60649f118b4b368de9f +m,c65c692d548693ebfbaf10400d2e8aa9091a90590ce43ed6b47c2c071c8dfe11 +n,67e53511da4bbace91831c58a4a01ad9aa3b6f113250c53dda966d5e9405c1a9 +o,2b88700029fc4d0ca0d347fa82e436e7a36c9614c8f734534f75861231df3b7b +p,df323ec6d848c24950fc7aa51b6caca05a22fd7068d12504dbb97213f1f20980 +q,6796daa6ba2fe80493d66d7892e1832b66273ddf4f11f098e847d52494767232 +r,826a2c7db4f098bcc1a4549289a09cc12d3acd416ce733ef9587695377829900 +s,cfbe026ca3c9f0fe9467869c0fe25783fedc2b7e0d8857ed39d5ba0dfbc8d427 +t,a2921c2645696f216b2eeb4ba6d9e0bd67ab8fe24853cb0e30ed4e94951d6e7 +u,cc8713cc52311483f9a9750d6478acc554da11319ea4d162c2cc353039f4b297 +v,2bc7f14ea855f7795783c7708ca336704ce3827df8514e512c05208a3003209 +w,15da9bb40e7cabfb3e4e80ceeb2b454e36b306e8da74f041372df6e4d582de0d +x,8df9c9a5852b45d7686dfc6368988f0694170c2467e2a82bc40c4cf97c5e674 +y,529ff42cdfd3adaac9f8c862f90cdd627d22d0aba106d71b7a44213ee6e43a99 +z,548f777107f301c240f8154fd94e72e8b22da1ee48705a61efbfcf9ee207f92d +{,228a026f098e6a8aec631413bd68681593af02795403cab93abc51a5477d7741 +},162bd9fd7e07f6e826b679dfb76b38398a2619375a68638304a9e0c86006d64b +\u00A1,df3f6b284e77a5e03234f0485c9559428502c9fd38353413c9a027a2cbf7c8c2 +\u00BF,c08116712cbe012486d9e5238568b88f4824c4ecae80578c3c9fb33bd97ac976 +\u00E4,f19bb94aec06572c20c5cc3f8e3c889997f912ae380f595df39f68abb3c6bc5 +\u00EB,40c2d733aeab9b43f45f25e924a93c3457ee9c611d4de09d360a5b0c10ef0d64 +\u00F1,4d804f85318390530df92312fb40400466304a291a9046ad2ec7cf401149c51b +\u00F6,263d221e677bc9945db2fb97506c0ddb8f029e0115769b48c7131f9258223fe0 +\u00FC,b39de43435ab50447e87bc3a488b13f7b5d08adfc9e6913b7844420dd5b752af +\u0431,d20b1412d30e98708606debf0da057eecb7ee228e1de926f7a2ed356df84af39 +\u0433,e92b7a4739aad69feed1cb6ec3fa43a8a3d005464e4113c825f57ea41e0c69e8 +\u0434,65f7e96afef18589df7387a2919bc6e0a8fbf535c3128e3201647d13686cbca4 +\u0436,27a2dedc5d9a0eadac47cf28d2e4a3b88f19779f0ceaa9295e18ec317c9338e8 +\u0437,165eb195d09b7acb26e8f9042be4b6cfe41e1791c1c7227d7f931382082a25fa +\u0438,f101fc9d21824965cdf7ca08c39bc5e7a6536a437276f6395010b41e3967bfaf +\u0439,98a61098636268faa67e257cb9c5dc9707843035a32600992329a850c2f3d98c +\u043B,2096bdd8013003a3e15e04d27b401f62697584a93bf4f9bd4e100b8d0a0fa93 +\u043F,77c07172fe664e291fe557f5a1c34ecf70ee3907b71331d72e63e8c59474cb09 +\u0443,b16de0a51e7b4c1dce45f70eb6d6a78a78fc1379faa4cccc750da4a2353738a +\u0444,f43230da9b8b9f1096941269d4d3fbba332a621e32f07b54154810c7cda83a87 +\u0446,a54f6c692616c71f364bce3afe253ab494e46fb2f72edcdf2c3bf2c0b3731657 +\u0447,c312302af8c5f306a14b6388006eb70ff11c026e7f42f13356e46ce17cb1005e +\u0448,5840bbdcd02a6de9bbd03784810a3cabb77f72e942f8cb569de65452acd34026 +\u0449,2dd3a2e26585bde4580a045ae492188624548a9e8f4ef047439c335540a48fc2 +\u044A,c9ad47599df8fae60ab12a7cf6fd43705819019af22d11b9c28dfab25de61960 +\u044B,5fa272a8bddd551504a2bc209ffdfdacafec2bb07ce9081af67c592130375bcf +\u044C,6c28fb01e68da246e23b2152689bd5f9b5f96ab145883dd5bf73f38bc8032bb3 +\u044D,645212a6ea777f6dd650769e2e615b6d367ef4a64baf69b0a102b3f9fc1e6dd1 +\u044E,b6aaa899df8993ac8a6736314f5b0e72b5729679359c2e1fc404fb8e19f6cd39 +\u044F,f7e15ca301977c85119643ea2c1e6db28b8dd23fb86817263759db0461339916 +\u2190,9293a6070503172071f35f58c82204e818cd065186901ca19f7dadbdac165e44 +\u2191,190ade10ccf4ad4a2ae6f6402e6ae07ca12262b6b1e3cd6e67155945310da176 +\u2192,1da44c767cca25861d3a52fe17c26428e660ee23dc0d793bf7bd86ea202f703d +\u2193,5eca0f55af545c4ba646c0cd9efc340900bd9dd5bbf4f52301d6d368e049123 +\u2196,7fc980410126a72eb4f084187fc68709508c23ec2bf40cb4ac35611e14b48aa7 +\u2197,fae53b7d47cec12d55666c8adc02b0978c48ef5326ab06944b017d6106fae4d1 +\u2198,3f2923a53142ecba6d67da9869b506a6613420b85fd016b132d8471c2f5e58ad +\u2199,da5401e05566783eb59e197ae3776db8386a9d0b1905294efa71b58cbf518210 +\u23E9,d3905bffc67cd4041685fbd3558a919c82675fd3f9110628f9c5331c9bbd8794 +\u23EA,59316a69c6dd655f5b89f2a8331525fe0dc92fd13d432623a8bf851ce820b034 +\u23F4,8b4b8f323a14776dd851f17003753ec4e805b9b3da31e254b4d22ccfa5eff16a +\u23F5,4feb391c76120a275dc668aef9bd54fae015c16762cfed6e35308cacd2532694 +\u2640,cc7c877d4c3fd1c9ee29aaf6695c14ceb7377852f70d90e7af3835d53e97349c +\u2642,61857c2b67d6a732740dcebb92a4f4c6f1d8a53f73c1d3292cf96276f4806da +\u2648,89e627d1278b2600f8fa5efe88173192782818556ca93433f4b5ef47570ac18e +\u2649,d13f2690540098174e31a5857bc6aa69eb20e2c89540d2a1d7c49ea3ad1514e1 +\u264A,2a4cc5321f5e17d4a39e015c56a95eab5ab478e0a04eec8a5681ff6807a6321c +\u264B,3778d66b562d25d2a39f259091c14ac9698a1535d99c549c1fdeeafb4b33d113 +\u264C,c8875808ffdcfa87e58ba0cd6c0f1d18cc367a65dd46b2975b4422b9dde7e209 +\u264D,480a305414f1b3137c92c4162a50efa147cec0a8a1ba88919c9b70ffe5173c6a +\u264E,3811af1c87674a04361d27709b38c55c90bc8ddb1cfd849d02c15dc6c4b33778 +\u264F,a88e1a1e843278d297a9e8cf99d7581cb336298b7f6fe1702793c0bad915330b +\u2650,d13bc25e432b0f5d631ff500d657a46c0c27fe9539bafa3155dd2c2cfbfdb097 +\u2651,28cda54df2e217f325fc980350ab261154b3da5b022769e2cd38f5c959480452 +\u2652,208d163f963b7298b12b7fd3c8f9ef6eeec1d8298161aa71da822e9c2d629b5c +\u2653,92ba17e760b4eaf6ce77f7c579c1fbbc942c7e43e88448626fa64535c4bd8bc9 +\u2665,f192817ba7fabbbb3b7db63771d8f854fa641e1df713cdd4c0a9942503f9f2a0 +\u266A,45117968e8a9b1736ab19391c71e84e12533d597d65a07d8c14e81727fbd9f0f \u2713,7481cedc15cc170f2e30d4157f4476cd5c1fcb46722d2fd32514e53936a61e41 \ No newline at end of file diff --git a/src/main/resources/fonts/pumpkin.csv b/IF/src/main/resources/fonts/pumpkin.csv similarity index 98% rename from src/main/resources/fonts/pumpkin.csv rename to IF/src/main/resources/fonts/pumpkin.csv index a71a8799..4d5290da 100644 --- a/src/main/resources/fonts/pumpkin.csv +++ b/IF/src/main/resources/fonts/pumpkin.csv @@ -1,117 +1,117 @@ -!,74fb58c1b8c8f327aebb4defebc7d53b4459c4a7d3b461eb2aec02291605c -"""",b74e7941a96cebddf1850fb75f754c55e11337562dda2254ff6db5cd8c016 -#,9938ea2fc1954933d6c3b9124b473afab561f9dbd525df2bceb66f76ba8b9654 -$,8bc27d63306771bd53934c310519c40edbcd9174738717e01eabd51da0c0d73f -%,b0b34ea30147e694e8b06857a1721ee1cee5297d675dce3324573f3f4ba395 -&,3de1d767dd1e18ba946bc361d5584d449ca5df2a09cf58efdaee6b8b9fcd -',7bc23a59fd3f43c5df5f12acdd8f1b5d79adfbba5adf24b728e329aa8 -(,5336e840ae96e584141aef84157ee13b5dd34ba148e8ecb71bd554b8ac2f257 -),beb4f1c651b5e49d911743de8462bae2f37e6f4d63deabeb02a3d8c159998 -+,bd69a70a735ca6b4b48652e3e23a5d19d10b87276a5a25ef73da3f568b21d2c -",",3dc1efaf9c8c71d647c25f7d99fe94dbbfb725bad9b0415d45ff01865fbdb --,f579e6d5f4d9e2ada692108de03a5e714611b520849e191255615d7890f758 -.,295d8e32c9329d5841b3a4c9736b5566cee41282f4ea966e1d522cba4a55a9 -/,2cf6463ce2fdfdc285a8f4eeae5b86fb8a95462f0802a80c7b6108386ee3 -0,5b22b79b72acef85910db9e9ae8a7bae8ebce8342c18e34725273e77c1aa4 -1,30c4873e4a219145eb4e3f66c09e2ce8b27de2fd81deb48e3c7e04e974e5eaa -2,a35f8f56e1a233fcd9777285e4b5ab13faa0c6d82fa635425c1745d411e8571d -3,144635d6bb8f9aa46db60875bb5db3940ab0c4f0eb684c6b888647bb33927e -4,29a9f3d79a2d8db8d66b59752542ad6e1349853258fad984878927736bd5b91 -5,f9e8d228e53079d00b2dfc57993d52ff78e6a7ea2742bbdfb3c4f4e93cd19b6 -6,2c5f577fb5c4b488d980ef733b5ed5d545a8e0701ab2841d817e83883a561f -7,74bbb7ebd5d9debf72a42cabf30d25574324cedac8f7f8a5501cd81e716f9 -8,48efb6cd1f8e591ee53c192f6476e83e25b95bbd27eec1c644c11525f07622 -9,c02f6023b5b90f6e2b0b2e3a72297634719d574bd9ff64767f54d19bed3fa -:,be6df45a4cae5f62032ce7c2c96942cceb8377e9f7db7a9b9a15516d1376 -;,a1c244b6a881e39b866493fb768512e1ca1239ee5e0a95ab88913138969434 -=,3291ac6c3d5b609f77875eea8706237776ea01434861a6ad6e434beb71326b -?,a8b4b3351aa8a260761e50445c877f75289789674e25468867d8813c33984 -[,d81025fb8b60a7f17fa6a5a084be93e6959fc22945a4808f8a6647709eecf9cf -\,8e72b994e074e18d69dcbc8abc4357f2f7c846bc9548db62c47f2bad0851ba4 -],5040b7ce38ac47359b5a95127622486b6157ded719ea88d9550f8937e55d420 -_,6c0a3d93e43b323d27732309c11b3de92a6e05c16d72aa951aa116ee0a5cfda -a,b62ae02dd68823d110993cb0380733ce6b3c646f24c27dd7f9015314d46874c -b,d8417e7ad9399a6a333120a776b28f7bf7bdca41aec6d095e3af6378b1132e42 -c,ff7f4ec613f834d316b5bc4fffe245e1eca55c42eedc5ae9719ffbd891a6b -d,6ebb92af9327b4ce8d9a31c27fbaefd95e4ed93f384f2adb953d8647b6d5a17 -e,5635ac69ed2bb9a354e5189a55b8bb3a2b53438731c73b920e09342f592f21 -f,12c9381e1663dd84a5e59a58c7856628805eeca33cc92e6772d7b33e3db9fa -g,9c2f4db0824740b96e6b2d36647269417529dc9d99cd733f07c598c86859 -h,bdeadb9cc3eba749293b79a14536bb8e751c4962afc7b0753e969dbc92ab59b -i,bc91865fb0367844b2972e9c726eacfc79a4e3835e5acffd4f16db7a3747c6 -j,ff3baa64cab06544079457392e8b4126efc73879babab1b6ade0cf8d6a1d9 -k,b415f040493efb36f0c69284e9751c5b31fe39a13a8ed2a5dce62dc341373e -l,bf5a6db93b4f381ce9f7af9fde05cef4478562ce82f6078c91a3bac151c3517 -m,df1ca2545fdc10bcd6802f0bb23be3a82b35d2afb1ec13367b74cd0f964971b -n,c9f6f9d2b3be50a941cc2d1bd69ae6a6a2e6d74870a01fda9cd361ce9eb69 -o,e912842e9d342952c9715deac40c3affa6f41e48e7cc6e9b25597582385489 -p,d670b4148b229e57388ea02eb93dcc17a9a89c38da126ec574969e43b3753f1a -q,3f880863ad82750ec9eafd8361c1e5232b38550e2f7779fd5c1beb77439e -r,cae63f0f4a01ca52f31347b48da865cb5c73f97e10af1c4532eeff390dd -s,c2f0341ab1c1fdf02efbe53333d7c39e43cf84859337bf2bc2ff1fb4c1a1ed8 -t,e897cb58a7615f278425775851165bb96ff0283c24f21c9d990dfcfc4eaf4 -u,f8d1ad3710bb7b7af61afdb6b18b3a3c26a57e8a54fc5ec2cbde2a87414a892f -v,d4abb84074aebcc6c689f58413933929291b618932799cccc9d8e2e172d1f9 -w,9b90cfd56fb1d765854c3e1a9d285df91f09b231fbaf0b050ca7aa8794ad6a3 -x,16f91d56acacddfe7b64566ad3d3ba1d18ff9fb941b4ddd83cb5672621089 -y,8dacffdfd3f28c2c6eb86242e935491768f4a316336d4da617b31b1f337214d -z,fc6bd7f25ac1328c3f65b1ee023fa6ae2311884b553177f9f24e21464ed3ff2 -{,a3799c8154cb3841fe5df33b2f728b243841fa1e1b75a32ae7db6a3bb2f77 -},3d256a273c63924f18e967be59a1121d36b199d24c570338dc347f69b55609d -\u00A1,b048f3eeef954845e9939c0818bbfd683c6495f2835d841ab5ed8fd0a2503f4d -\u00BF,cc15fe60fb439bc5f7f7733f45acc00c9cb0a942f493aee7483890883b1837fd -\u00E4,d99077dcd1cd54873926458a09ab3fe7f107d31d79d306363aaeb2f30f16bd4 -\u00EB,36d0abdad844126c5557ef5a29405c53903376b26f5197f9ddea7192bd1e4 -\u00F1,9250ce41aa5437510cad18ff2eeccc530a434f59b09a6d180f4ce9b7534013d7 -\u00F6,7ca644bbb5c2a0e7e18f7cde03b67b87db7146caf92dc7a25def10af461fb6 -\u00FC,c2e2ab155225c2abf8434a133be1fa9689219680f038fa834e5442214931 -\u0431,c228c65c436757f431c15d935fae9ed952f595c0b433b10bf2e867ed6fb -\u0433,f48f6b36ab545a72e473b334a487fac775321f391d2eaf46cd1aebcab267c -\u0434,739ad9a063ab90b7ac72a5d4c17acb4fb03d8a8c582fbe2854245332bd3db9a7 -\u0436,dcfdf2b76722b460d6f0d794ac11e1c89ab67fe4db8b2a67334465f1ec59f5d5 -\u0437,6e8e71bb9efcf5b95cbc94207d5e3fef9762ad52579115871618bb6b8d84da -\u0438,4538b9a6ce7730e55859412055bd31373a7a757156b7a488146bb5644414aa1e -\u0439,f068cd1c61219d73eeb641da116806efd8af2af8735e592adb1623e9371b -\u043B,3fc3aac220da9fdc6085b6cf7c89316ae1ae74e45a46163f8af8dbe17d7ee08 -\u043F,74ff98955722036589b394b9adb5e78e6a9c681682b74bc4c8233a1aa93d3c3 -\u0443,3a549c6def8ea1de5f24582d42e9d495895becb9f178339b863362b2ff56d -\u0444,ba515702d6f9798b45233f9a3277ac63ca397ed92f2f8787d7a237a3e514b5 -\u0446,9b4046d1dee52f846f62140195a70ab71e09248ec69f0e340de56c551a0536e -\u0447,17d261e2c774fa40eea5d97b5380a652a8be5681717258241e8678c4663369ec -\u0448,e6ae74a47f1656f1c73593c75522b50bd57918ea83c57b91fe5726ec2e2d3 -\u0449,a96c672429b95d01ad06125a1f5de183b5faa27d27e39e1c97165f7d751d8f2 -\u044A,6cb5c516da956645656908861b84e1b4ef1f6d7398ba195e73858ccf18959c5 -\u044B,c41927873af71092d3147d4ec3ec81712cbb94862719f9ad851e27ce26fde6b -\u044C,f6bbfee4e24f9d74e6bda41fbc57ef9598b139702f16471f8322d8a838fe628c -\u044D,be84472a8a1aa351afd4872a7eb54c8be5a905e8474dfc6fe3d45de66a8e6 -\u044E,1fdd7ad0c69a95b90b4da2aa9571161b843e1c1a792aea18fd587d10cb2377 -\u044F,3873b44217b2cb10a2f6b235797cc0565868d2fe4e7bef7ab08f2eddf8a84739 -\u2190,28a86bb4fcac3862aad3d51393faa7a1cf3553e4934103ed45ac2a9a888eb9a -\u2191,45adb6ffa2c5c0e350c28499138a5566441d7bc573de1989fde212fcb1966826 -\u2192,c9895d58a04626d5cce18769d54198d0355fd770683bdfb7176d08c7547de -\u2193,a72220f543a692a3f2f949eb2a5343495610264e916b19b773c7e4d21b85d4c7 -\u2196,b6ce91a43999b6aaad32a4cb6f8d84631937f1ce64ec75aec6534499fc1f4d44 -\u2197,77ae4ccc85eadc6cfdfeb3bc15d653a6f978e5259cc537d7e23fd1dea2232a -\u2198,ca23d489e9432f0865214bce1c0e69312a1bda265d6900dad4907525e16d3e -\u2199,8d5efb7c638d8024fa82fe4232de39997682143d62b747555a917fa37437fc -\u23E9,c4d771be9a42262c7382543bc16b6b39e7aee046441d35b7d8357d86ab4550 -\u23EA,7eabf6df65818438ea0c5f886decb393393f15abf2787a5ec4e83682192ba -\u23F4,71597a3696b19f5cfba9f8be757908481c86be5bb3e76a893b42fe56172ec -\u23F5,13c4b90e0348baf9b8c61fe17ea14bb3ca2ad9ad51b33a98751f4cd6345fd -\u2640,3e8f557fbd55ddad6aea7e90f434913e7c039f679a133e53de543726e0c46894 -\u2642,6a9b41f581372c00e63425d4d2ac8d85d057c46e0a8fa16dd9bc552a48b6ca28 -\u2648,35265a6ebe7295ecbeb2a3f45d12ed5d2a519b4da7b69ec80eacb08430108955 -\u2649,56bbbe5a23355cb230765b1d1e0d8c2e795fbd2148b4b65703885c58b2e76e7f -\u264A,4fc2ea33f39f8a47c0ff981020b08ffdf423e0c921d63e7b0c43e87e538d4601 -\u264B,fbd2fd9717458ce1c1ad31bcd648359c763badd78d98750201e1a1c50b8b6462 -\u264C,b8c272627240fff188290a352cdabb6cdf441a0cf31ce4eb71edce123aedbd2e -\u264D,c753aba70492656c09c0909e99598c680a0d93460cf1d7af6b10090ecb762dcb -\u264E,4285f00b3d094015048f2e25ff688be0e482a3ee6e8ca3e7ec06bdb3855eba69 -\u264F,ac5756aad722587f8a8f77a218357e0e200542824c04dec1e84b622c70215d4c -\u2650,a0ec08641e54fcff259dca916ee569d40767534ca6075cbc4430e3639be45177 -\u2651,29cd07e09e4ba9720bd6a6668ce70cc19e4916ffce80553ed26fd4ddc70b603a -\u2652,b4f0a513121bc650906a478faaf41116b7acf01a2ef3f44b2f2379943a4fc0e -\u2653,780d746edf839e5889003ec5b4cb38cfeaacbc9e4b1b03b96d56c97205b4b073 -\u2665,18a76ffa2a2f2c0cd669d4f892594604dcd9dad4c85aeb2e5aabf2572d6cb1 -\u266A,e7ee421160045b95f7899568ca99b2009b4137ae1df32a76957297cac407bb83 +!,74fb58c1b8c8f327aebb4defebc7d53b4459c4a7d3b461eb2aec02291605c +"""",b74e7941a96cebddf1850fb75f754c55e11337562dda2254ff6db5cd8c016 +#,9938ea2fc1954933d6c3b9124b473afab561f9dbd525df2bceb66f76ba8b9654 +$,8bc27d63306771bd53934c310519c40edbcd9174738717e01eabd51da0c0d73f +%,b0b34ea30147e694e8b06857a1721ee1cee5297d675dce3324573f3f4ba395 +&,3de1d767dd1e18ba946bc361d5584d449ca5df2a09cf58efdaee6b8b9fcd +',7bc23a59fd3f43c5df5f12acdd8f1b5d79adfbba5adf24b728e329aa8 +(,5336e840ae96e584141aef84157ee13b5dd34ba148e8ecb71bd554b8ac2f257 +),beb4f1c651b5e49d911743de8462bae2f37e6f4d63deabeb02a3d8c159998 ++,bd69a70a735ca6b4b48652e3e23a5d19d10b87276a5a25ef73da3f568b21d2c +",",3dc1efaf9c8c71d647c25f7d99fe94dbbfb725bad9b0415d45ff01865fbdb +-,f579e6d5f4d9e2ada692108de03a5e714611b520849e191255615d7890f758 +.,295d8e32c9329d5841b3a4c9736b5566cee41282f4ea966e1d522cba4a55a9 +/,2cf6463ce2fdfdc285a8f4eeae5b86fb8a95462f0802a80c7b6108386ee3 +0,5b22b79b72acef85910db9e9ae8a7bae8ebce8342c18e34725273e77c1aa4 +1,30c4873e4a219145eb4e3f66c09e2ce8b27de2fd81deb48e3c7e04e974e5eaa +2,a35f8f56e1a233fcd9777285e4b5ab13faa0c6d82fa635425c1745d411e8571d +3,144635d6bb8f9aa46db60875bb5db3940ab0c4f0eb684c6b888647bb33927e +4,29a9f3d79a2d8db8d66b59752542ad6e1349853258fad984878927736bd5b91 +5,f9e8d228e53079d00b2dfc57993d52ff78e6a7ea2742bbdfb3c4f4e93cd19b6 +6,2c5f577fb5c4b488d980ef733b5ed5d545a8e0701ab2841d817e83883a561f +7,74bbb7ebd5d9debf72a42cabf30d25574324cedac8f7f8a5501cd81e716f9 +8,48efb6cd1f8e591ee53c192f6476e83e25b95bbd27eec1c644c11525f07622 +9,c02f6023b5b90f6e2b0b2e3a72297634719d574bd9ff64767f54d19bed3fa +:,be6df45a4cae5f62032ce7c2c96942cceb8377e9f7db7a9b9a15516d1376 +;,a1c244b6a881e39b866493fb768512e1ca1239ee5e0a95ab88913138969434 +=,3291ac6c3d5b609f77875eea8706237776ea01434861a6ad6e434beb71326b +?,a8b4b3351aa8a260761e50445c877f75289789674e25468867d8813c33984 +[,d81025fb8b60a7f17fa6a5a084be93e6959fc22945a4808f8a6647709eecf9cf +\,8e72b994e074e18d69dcbc8abc4357f2f7c846bc9548db62c47f2bad0851ba4 +],5040b7ce38ac47359b5a95127622486b6157ded719ea88d9550f8937e55d420 +_,6c0a3d93e43b323d27732309c11b3de92a6e05c16d72aa951aa116ee0a5cfda +a,b62ae02dd68823d110993cb0380733ce6b3c646f24c27dd7f9015314d46874c +b,d8417e7ad9399a6a333120a776b28f7bf7bdca41aec6d095e3af6378b1132e42 +c,ff7f4ec613f834d316b5bc4fffe245e1eca55c42eedc5ae9719ffbd891a6b +d,6ebb92af9327b4ce8d9a31c27fbaefd95e4ed93f384f2adb953d8647b6d5a17 +e,5635ac69ed2bb9a354e5189a55b8bb3a2b53438731c73b920e09342f592f21 +f,12c9381e1663dd84a5e59a58c7856628805eeca33cc92e6772d7b33e3db9fa +g,9c2f4db0824740b96e6b2d36647269417529dc9d99cd733f07c598c86859 +h,bdeadb9cc3eba749293b79a14536bb8e751c4962afc7b0753e969dbc92ab59b +i,bc91865fb0367844b2972e9c726eacfc79a4e3835e5acffd4f16db7a3747c6 +j,ff3baa64cab06544079457392e8b4126efc73879babab1b6ade0cf8d6a1d9 +k,b415f040493efb36f0c69284e9751c5b31fe39a13a8ed2a5dce62dc341373e +l,bf5a6db93b4f381ce9f7af9fde05cef4478562ce82f6078c91a3bac151c3517 +m,df1ca2545fdc10bcd6802f0bb23be3a82b35d2afb1ec13367b74cd0f964971b +n,c9f6f9d2b3be50a941cc2d1bd69ae6a6a2e6d74870a01fda9cd361ce9eb69 +o,e912842e9d342952c9715deac40c3affa6f41e48e7cc6e9b25597582385489 +p,d670b4148b229e57388ea02eb93dcc17a9a89c38da126ec574969e43b3753f1a +q,3f880863ad82750ec9eafd8361c1e5232b38550e2f7779fd5c1beb77439e +r,cae63f0f4a01ca52f31347b48da865cb5c73f97e10af1c4532eeff390dd +s,c2f0341ab1c1fdf02efbe53333d7c39e43cf84859337bf2bc2ff1fb4c1a1ed8 +t,e897cb58a7615f278425775851165bb96ff0283c24f21c9d990dfcfc4eaf4 +u,f8d1ad3710bb7b7af61afdb6b18b3a3c26a57e8a54fc5ec2cbde2a87414a892f +v,d4abb84074aebcc6c689f58413933929291b618932799cccc9d8e2e172d1f9 +w,9b90cfd56fb1d765854c3e1a9d285df91f09b231fbaf0b050ca7aa8794ad6a3 +x,16f91d56acacddfe7b64566ad3d3ba1d18ff9fb941b4ddd83cb5672621089 +y,8dacffdfd3f28c2c6eb86242e935491768f4a316336d4da617b31b1f337214d +z,fc6bd7f25ac1328c3f65b1ee023fa6ae2311884b553177f9f24e21464ed3ff2 +{,a3799c8154cb3841fe5df33b2f728b243841fa1e1b75a32ae7db6a3bb2f77 +},3d256a273c63924f18e967be59a1121d36b199d24c570338dc347f69b55609d +\u00A1,b048f3eeef954845e9939c0818bbfd683c6495f2835d841ab5ed8fd0a2503f4d +\u00BF,cc15fe60fb439bc5f7f7733f45acc00c9cb0a942f493aee7483890883b1837fd +\u00E4,d99077dcd1cd54873926458a09ab3fe7f107d31d79d306363aaeb2f30f16bd4 +\u00EB,36d0abdad844126c5557ef5a29405c53903376b26f5197f9ddea7192bd1e4 +\u00F1,9250ce41aa5437510cad18ff2eeccc530a434f59b09a6d180f4ce9b7534013d7 +\u00F6,7ca644bbb5c2a0e7e18f7cde03b67b87db7146caf92dc7a25def10af461fb6 +\u00FC,c2e2ab155225c2abf8434a133be1fa9689219680f038fa834e5442214931 +\u0431,c228c65c436757f431c15d935fae9ed952f595c0b433b10bf2e867ed6fb +\u0433,f48f6b36ab545a72e473b334a487fac775321f391d2eaf46cd1aebcab267c +\u0434,739ad9a063ab90b7ac72a5d4c17acb4fb03d8a8c582fbe2854245332bd3db9a7 +\u0436,dcfdf2b76722b460d6f0d794ac11e1c89ab67fe4db8b2a67334465f1ec59f5d5 +\u0437,6e8e71bb9efcf5b95cbc94207d5e3fef9762ad52579115871618bb6b8d84da +\u0438,4538b9a6ce7730e55859412055bd31373a7a757156b7a488146bb5644414aa1e +\u0439,f068cd1c61219d73eeb641da116806efd8af2af8735e592adb1623e9371b +\u043B,3fc3aac220da9fdc6085b6cf7c89316ae1ae74e45a46163f8af8dbe17d7ee08 +\u043F,74ff98955722036589b394b9adb5e78e6a9c681682b74bc4c8233a1aa93d3c3 +\u0443,3a549c6def8ea1de5f24582d42e9d495895becb9f178339b863362b2ff56d +\u0444,ba515702d6f9798b45233f9a3277ac63ca397ed92f2f8787d7a237a3e514b5 +\u0446,9b4046d1dee52f846f62140195a70ab71e09248ec69f0e340de56c551a0536e +\u0447,17d261e2c774fa40eea5d97b5380a652a8be5681717258241e8678c4663369ec +\u0448,e6ae74a47f1656f1c73593c75522b50bd57918ea83c57b91fe5726ec2e2d3 +\u0449,a96c672429b95d01ad06125a1f5de183b5faa27d27e39e1c97165f7d751d8f2 +\u044A,6cb5c516da956645656908861b84e1b4ef1f6d7398ba195e73858ccf18959c5 +\u044B,c41927873af71092d3147d4ec3ec81712cbb94862719f9ad851e27ce26fde6b +\u044C,f6bbfee4e24f9d74e6bda41fbc57ef9598b139702f16471f8322d8a838fe628c +\u044D,be84472a8a1aa351afd4872a7eb54c8be5a905e8474dfc6fe3d45de66a8e6 +\u044E,1fdd7ad0c69a95b90b4da2aa9571161b843e1c1a792aea18fd587d10cb2377 +\u044F,3873b44217b2cb10a2f6b235797cc0565868d2fe4e7bef7ab08f2eddf8a84739 +\u2190,28a86bb4fcac3862aad3d51393faa7a1cf3553e4934103ed45ac2a9a888eb9a +\u2191,45adb6ffa2c5c0e350c28499138a5566441d7bc573de1989fde212fcb1966826 +\u2192,c9895d58a04626d5cce18769d54198d0355fd770683bdfb7176d08c7547de +\u2193,a72220f543a692a3f2f949eb2a5343495610264e916b19b773c7e4d21b85d4c7 +\u2196,b6ce91a43999b6aaad32a4cb6f8d84631937f1ce64ec75aec6534499fc1f4d44 +\u2197,77ae4ccc85eadc6cfdfeb3bc15d653a6f978e5259cc537d7e23fd1dea2232a +\u2198,ca23d489e9432f0865214bce1c0e69312a1bda265d6900dad4907525e16d3e +\u2199,8d5efb7c638d8024fa82fe4232de39997682143d62b747555a917fa37437fc +\u23E9,c4d771be9a42262c7382543bc16b6b39e7aee046441d35b7d8357d86ab4550 +\u23EA,7eabf6df65818438ea0c5f886decb393393f15abf2787a5ec4e83682192ba +\u23F4,71597a3696b19f5cfba9f8be757908481c86be5bb3e76a893b42fe56172ec +\u23F5,13c4b90e0348baf9b8c61fe17ea14bb3ca2ad9ad51b33a98751f4cd6345fd +\u2640,3e8f557fbd55ddad6aea7e90f434913e7c039f679a133e53de543726e0c46894 +\u2642,6a9b41f581372c00e63425d4d2ac8d85d057c46e0a8fa16dd9bc552a48b6ca28 +\u2648,35265a6ebe7295ecbeb2a3f45d12ed5d2a519b4da7b69ec80eacb08430108955 +\u2649,56bbbe5a23355cb230765b1d1e0d8c2e795fbd2148b4b65703885c58b2e76e7f +\u264A,4fc2ea33f39f8a47c0ff981020b08ffdf423e0c921d63e7b0c43e87e538d4601 +\u264B,fbd2fd9717458ce1c1ad31bcd648359c763badd78d98750201e1a1c50b8b6462 +\u264C,b8c272627240fff188290a352cdabb6cdf441a0cf31ce4eb71edce123aedbd2e +\u264D,c753aba70492656c09c0909e99598c680a0d93460cf1d7af6b10090ecb762dcb +\u264E,4285f00b3d094015048f2e25ff688be0e482a3ee6e8ca3e7ec06bdb3855eba69 +\u264F,ac5756aad722587f8a8f77a218357e0e200542824c04dec1e84b622c70215d4c +\u2650,a0ec08641e54fcff259dca916ee569d40767534ca6075cbc4430e3639be45177 +\u2651,29cd07e09e4ba9720bd6a6668ce70cc19e4916ffce80553ed26fd4ddc70b603a +\u2652,b4f0a513121bc650906a478faaf41116b7acf01a2ef3f44b2f2379943a4fc0e +\u2653,780d746edf839e5889003ec5b4cb38cfeaacbc9e4b1b03b96d56c97205b4b073 +\u2665,18a76ffa2a2f2c0cd669d4f892594604dcd9dad4c85aeb2e5aabf2572d6cb1 +\u266A,e7ee421160045b95f7899568ca99b2009b4137ae1df32a76957297cac407bb83 \u2713,b89f158adb4316b13652f43daf375be83b45ad4c9f26bea5aadb8ebb779fdee1 \ No newline at end of file diff --git a/src/main/resources/fonts/purple.csv b/IF/src/main/resources/fonts/purple.csv similarity index 98% rename from src/main/resources/fonts/purple.csv rename to IF/src/main/resources/fonts/purple.csv index 03e623d6..0f2f867d 100644 --- a/src/main/resources/fonts/purple.csv +++ b/IF/src/main/resources/fonts/purple.csv @@ -1,118 +1,118 @@ -" ",6f67891591a88b9d3995047bf9403df24d609cd696bbf97cd31f787eb4b -!,e3179dbf5dbb4365cc9e610fcb4b9b92ba1b44884394e1f61e8aec31a1ef94b -"""",bbe0b5112b73cd09c5049936c8d944845c64236aa6d1d22f76681c8521798 -#,8c9227b36ab3403e85324a57e8d9b0e8c7ba342f5bda4fcef831d4da8d3ebdce -$,b4038a4eec3a97922ee348f0d3093409f9216553330fb1b19fc8538a4461d27d -%,5846bba368ffc379d63a322b692e675e627b5c8d78abd4cad9a89718d32ed -&,36d5def172c291bcdd3d49052cda4b915fa7aa040e6dc1572a2c11cd65ade28 -',7f1d8a6d41bcbab35a73edd3a1292ccfc2ace856d6922f1dde1566180e09 -(,7394486d273eb59a647b26e9766e2a52e77ba9e9b22ac480761330fbc84fb -),ada411181c5ef31adb8d33ea1732131a622b51118b59e19451f3896d9cd9c -+,7fce66789b77b261e669b239fcd4a6296965585ad01933f830de7a93de4374ce -",",3eb97b6a492fdda3028bb5eaee28dc0ac6f84363b113ee22982158a461320 --,f9710ceae69b72a177e5abbb86c8ada432981ce7fc2d3ed1c651560f7a11e -.,ab4226d9b2f1b4fc13c0ef166c4b7c97f6339c308b1d9391cc8b109fbee8cf94 -/,c6cf21531d5d19e82c498dbcb959bdd076901b35651b639d6857b63dfbd18a -0,dcdf22e25ab547b376f083cbf8462c4268cef5555a9689b0e7d2dffe8672b2 -1,78a42df06fc916de110f61bd76eddbf58ed4249fce5ee51c219ec75a37b414 -2,1ef134f0efa88351b837f7c087afe1b3fb36435ab7d746fa37c0ef155e4f29 -3,1965e9c57c14c95c84e622e5306e1cf23bc5f1e47ac791f3d357b5ae8cded24 -4,6e31837d89c264c3b54f8214ae24f89a368a92bc46df9225333ad7cd449f856 -5,49357cb4664426a9ae0f9c7725ea4351dc69f15a8062c03591e26ac11bbc5a -6,b8d550717d26ae8dda55e9a0a9edc92f04a774b501a36e24c8c4e682e32c59 -7,89141952aabca4987bddf208c5e15ca6a5bfce239af39584aeb5ee876d87 -8,a112a392ef19ee393a14505bbdad9c1e9293a04ec3ab337e374880222e708244 -9,b7277b841ef2f06e6b7631d9cfac275498f889fad94687668b251fc339a51f0 -:,cdf81d2f30b5ed7273c622ea149066b5a28e113153e058bfd4f4adbe87ef0c4 -;,be38324cb83cbde363eb537d5468ac5ba3c2ceb9d12e9dd379a656fc8ad79b -=,4fe01a678d5ddf7d92a2d4b3326cc3fd1e3027a47835fb4035fdda8b7a782 -?,fe5653187521d752a91b163a62d587d2bce65c869ca996825271f6b4539cf2f -[,53d58645b288381fa1c573f762063b5bcaaa57eb3138405db3aa46dc29f4b -\,fc7c441aa72e885a706b38b8f81852c2fabbd698983ee84b4fe3a52975d91 -],43db6f3f8ccb39ae1a2dfb61cbff648ee7c322c5fb3919e7e1b9e480c445de -_,ad36e26080c0d64f68763f6f41fb4996cb1db91175d92b8f74cd2cce33e78a -a,910e92e0258d70ec132b69664f5f7f292bfec7e0f727685a1d7970d12249 -b,4593f9b9bfc1b2110411c7ad7de362cbbf349682c2449bb54452ad8c5f55c42 -c,7b224444b447cb52ea61767fa5b854874c496ce13e39912513b388d679485d0 -d,486c71ad9652946b7ebf2d5a262f8b73e44458a8dc743a782dca578ad954e14 -e,95372c5f441c36d96a33a0c3cba514568049d811742b7a90c01ea1c1bc39 -f,c113c20be886c387fe5554fefb4e6bc5dd6cc5a3899dcc26cbe3447481ce6 -g,cbfbe416f501c4096cfc9eb3814d517c4e45f559688bdb1bf52c26229492 -h,f92dbcb04a6d3158138c9d62f2282ae2858417cbfefbf64476965a7d767d38 -i,bceee22d731914f67096b74e5ead4dd84c5e8eb92b54398e61e8b27bfb37 -j,d5d3ac095cfce7dbe86103ac897c74f8d3ff164d8aa29322185966f38a -k,23d63cdd33c7a2d1ff3bd5577a85ac7441ea2c5307d8070ac055cacfdd19fa -l,b4d806433df7690975f2a51652524be5a5a42c32dc73845124c7f13de45 -m,819b26d993b1931c931ed2d57e8bab8a278429c2402b56d564c24db422eef885 -n,fd45f5c2cefde4367b758fd3b19d746b9c4a8caf14f9cf77c540c223e5d9a1 -o,bb84db6a63aa8681ce9e4e2e8ebbdfe1481307ed39a2fb24635ebb79f83d64 -p,2f3c4bd6fd4e15dffac34680a766b8a2b5d523451cbd3f9834294cc8f2c92bf -q,a839e8a1e5341ffc5416e8e6630897b91e71e35dd545e2b2689965556ae47 -r,c69beb676da143bbc4f4d8f5246aaeaf3b39a4caa3a908b3dab4050b082a355 -s,98f7914e98d98e94a7e3cf972cb66c53a66cfa24305d34b333cae82dfd4be455 -t,c451897d7f747a901c183bfee2ed174f35655c966f9adf6e2c7630a03a8155bd -u,a4691deabf92f5474d57f6accb096aaa22393faf5d327dfc13c7fd4516d8e3 -v,9d2f5a83e7e5bfc4c19920f675b1d62cd2b2117cb45b195330145996fed6569d -w,fc428bdba8f516665e5bd2fa9294145b4d1ec12a4be24ba5ece2d235189125d -x,4b48ca8f92c15ff5ef3801cde3dde8f4efead877a60a28b72ae17241896d -y,a15a3426119bb7040425281dfe7165171a919c10804f498a45de361b656589 -z,cbfed415bac65b5d136b2a07f540956d143d9ab1af2facd511ac8956b11437 -{,423a44615ea1fdda7c576b328510813efcbc15ece2c371eebe6afeefd0dc2318 -},35507210cbb3c517853949d63068c338db2b7984ba1a4958a115acd35e12165 -\u00A1,306d6bce194a7d05b599ccbe39a0e21c6feb560de00cfa6387a319f9a3388b37 -\u00BF,fa98ae6f3384288d2856e3a5fbecc0d72e4840485c7408abe357832a4d414b69 -\u00E4,9518cf8f5c97ca3778be622fdecd076390083e7268f8190165e1d7212170 -\u00EB,99a310def1ab3c704a26892e45166beb18913d33a0488fdb3d18331a95c83c47 -\u00F1,eba36c1f1d2cd582967aa4e3df7d168c0e22a391de050d7f2495e8cf4c48739f -\u00F6,b7588d0e2a6462436a2c412b55650cd4f6f83c1fd63fe1ba2707186a3bf84b9 -\u00FC,1324439206ad61b212e6255b2a0e75d6b43896075f36aa3124682cd33a773a9 -\u0431,923fcba1f880bab74c364b118a118ac9e47b1a1f4fe9474bc0da75626ab16 -\u0433,8f50eef4471547d6352379aee41cc4de1527b4719f685c4fcba08b2f94ca32 -\u0434,894dab994819e6647a6b6396424d5365eb4194e55b47fbc3ff92baf3fc7d703a -\u0436,b78b68c3b92b415dab6a8ce4be5843da3bacef94fd9c6ff8f83cf0c1a5ccd1 -\u0437,e8a198bdceca5a3ae59d68d0182d387b78864944323ec69c95c70151d02e17 -\u0438,d3cdfea626b8a9f8152905232156313a2d6a37af75cf43162aaa1206146 -\u0439,be20fb2f7fd790ff70667a6aa61471cefef3a4c9dda313677eae6c99dde52375 -\u043B,9adf3c905a8138989f61549cf9df9a6b09a6612ac96c561607db9bdfeddfc69 -\u043F,a19de72c89ee4ee543838c4d84bb7aa33beb954154be471758c6b6902d23e2 -\u0443,db38a5fefe3f8be3d1d4ba49395a373b01217225e83f7e5184552f25919208b -\u0444,691c24c9298d3dbd4dacf4f1fe72225d1f672071772f2b9be27521148576d8 -\u0446,295bc21eb731deb93aa26b39bbc646712af5c2b6f9538963b5c46d72f3fe50 -\u0447,9d5cb5b5ffd965ddb53b5c2beab7535a0b6d6baf8ab56160a7e6e47184f5ad -\u0448,2e314ad5c9146f8411f16a97db327e17d2287cd5057b7aa907ee9f22cc4743 -\u0449,afd4b94f6e3c4211fbe3357765472dbb34ebb4ecd4bc79b144a13647ff08f6f -\u044A,fec948b4477b98d5c11fd69e1daefb42e7dec927cf89a2d1d385e79afde2c1 -\u044B,1f97754266c23175262c4ce0a149d2f217c8a73d6b96dfcf0d8f67b5bd238 -\u044C,e6cb9d93bce5f243924ed1840f7dfcfc151c0aaca9cf3e806857b72e8e664 -\u044D,7aa19c463cfb1f76c477a96d9c9d1270193ba82753f8e163321cfc2f56c5cb78 -\u044E,15b625cf9dad702197e2f9aca4f867efe78f39847c51ef9f9f3cf6da4e9113 -\u044F,fbbcfb5dc6c9652727fe928ad42c67e691ab502a34b2ca6554815e9a648bfd7 -\u2190,2eff7559102aa8ff9712976b62292ee45e0793c46f668916868207f399effab -\u2191,94a04b32d2b7598f9dd8e23fb4015c69c3cd942a37a9ea84d06869f459f1 -\u2192,f726d288a74e8ac924c58c93f5b35cacd6946a6ccfdbda85fe8acb9e3eecebdb -\u2193,1e573e99b8a5af8a7d745b776564dc727defdef070257630aa36cdb49b7cf8b -\u2196,658afcb2be19f511646ba8ade018e29e6c89886e0d6f099dc14589c5e6ac1 -\u2197,ac79f3d1dddeee531c23b9b26ea76db92a78ac1594e9dc8f62324db132a9b -\u2198,fe6c8a93fd876bcc22fe4d6f57653b6171942241db4ac8b45bf6dbbd6eea44 -\u2199,ec8de5f42dbc19eadf1e713d81d54899b379cf653ab3dc41303fbfdbf76398 -\u23E9,9deef67084a582ddf7d2f3c48bdbc590ce43ef38afeb1cdc106d3bcb30d7af -\u23EA,f15698e81924e3a28891dc6e17e65bffacf78729db3a899312dde1d9c83c61 -\u23F4,aec49f4d5951e4326bf3812296eea8f20fb2754b0a0fbac17ab5b5a6466ba -\u23F5,41ff9f2e6523db75b91b861ca4e190f53aad7496e424cac8ad936536b054a7d3 -\u2640,8a4cbb7d68bd2795cda9753aa46cdf9ebef50c8d4bb1b137176c4467e196d1fa -\u2642,20a3c4f3bbc52f073d55b6aa667b02c279bc54361fa56c047e4c1a41322770e5 -\u2648,8c2c5120ed84ca5afb81bd4c96797b86654b3e769e7fe4a01aa08d2b172d7767 -\u2649,819ff4a988d8c7071f36175e86674e9ba8fb393ce47a52ba6e44f7966dd19546 -\u264A,d7687395041d2e87da1044ca5a763cfdae03cd301c2c4e176c65cd359f48276b -\u264B,e34d173b0f006aa350e0a3b5abfd9ae9cad979970193b61e2aa9434e2f8628fd -\u264C,a4719a552417d8fa1d850fdce881846fc9a62d2697d9a3cf7b50f0678f2bdc46 -\u264D,23da4ff1f494c001cfdc343d75583b7208ad01ee24b856dc96376191b65a234c -\u264E,fd32bdc54e13c1bdca844d08649019c1451bb2d9694305e97ee5afd937056402 -\u264F,1a9e394949b25ccb417d604cc7c0e1b423b44d3bfc2d41e15fe5a87bf61120d -\u2650,48fe0cb0f9854ae02fd535d992a860b816d73328d6b6dafee3b2c9c02838dbd8 -\u2651,5d1201f2f9a7867260a7f774470691b7ce62f35e8d393f9054803d873c41f776 -\u2652,e540047276dc1cf58ce6796d1a9e66309a218a938a370a9b1ff34472a92e2c08 -\u2653,d4572c335b47fc58d5c5c3fedec0fbb01376e6152e85ee116feca59463bcc831 -\u2665,8e5aa91f11a27b5cf62aa06dc1d3a47a748bf1870dceda8b6674a301a284 -\u266A,27b995f5945cbf4de29f78a0cd2acd44cc288733f4de512fe72ca4cb1983c424 +" ",6f67891591a88b9d3995047bf9403df24d609cd696bbf97cd31f787eb4b +!,e3179dbf5dbb4365cc9e610fcb4b9b92ba1b44884394e1f61e8aec31a1ef94b +"""",bbe0b5112b73cd09c5049936c8d944845c64236aa6d1d22f76681c8521798 +#,8c9227b36ab3403e85324a57e8d9b0e8c7ba342f5bda4fcef831d4da8d3ebdce +$,b4038a4eec3a97922ee348f0d3093409f9216553330fb1b19fc8538a4461d27d +%,5846bba368ffc379d63a322b692e675e627b5c8d78abd4cad9a89718d32ed +&,36d5def172c291bcdd3d49052cda4b915fa7aa040e6dc1572a2c11cd65ade28 +',7f1d8a6d41bcbab35a73edd3a1292ccfc2ace856d6922f1dde1566180e09 +(,7394486d273eb59a647b26e9766e2a52e77ba9e9b22ac480761330fbc84fb +),ada411181c5ef31adb8d33ea1732131a622b51118b59e19451f3896d9cd9c ++,7fce66789b77b261e669b239fcd4a6296965585ad01933f830de7a93de4374ce +",",3eb97b6a492fdda3028bb5eaee28dc0ac6f84363b113ee22982158a461320 +-,f9710ceae69b72a177e5abbb86c8ada432981ce7fc2d3ed1c651560f7a11e +.,ab4226d9b2f1b4fc13c0ef166c4b7c97f6339c308b1d9391cc8b109fbee8cf94 +/,c6cf21531d5d19e82c498dbcb959bdd076901b35651b639d6857b63dfbd18a +0,dcdf22e25ab547b376f083cbf8462c4268cef5555a9689b0e7d2dffe8672b2 +1,78a42df06fc916de110f61bd76eddbf58ed4249fce5ee51c219ec75a37b414 +2,1ef134f0efa88351b837f7c087afe1b3fb36435ab7d746fa37c0ef155e4f29 +3,1965e9c57c14c95c84e622e5306e1cf23bc5f1e47ac791f3d357b5ae8cded24 +4,6e31837d89c264c3b54f8214ae24f89a368a92bc46df9225333ad7cd449f856 +5,49357cb4664426a9ae0f9c7725ea4351dc69f15a8062c03591e26ac11bbc5a +6,b8d550717d26ae8dda55e9a0a9edc92f04a774b501a36e24c8c4e682e32c59 +7,89141952aabca4987bddf208c5e15ca6a5bfce239af39584aeb5ee876d87 +8,a112a392ef19ee393a14505bbdad9c1e9293a04ec3ab337e374880222e708244 +9,b7277b841ef2f06e6b7631d9cfac275498f889fad94687668b251fc339a51f0 +:,cdf81d2f30b5ed7273c622ea149066b5a28e113153e058bfd4f4adbe87ef0c4 +;,be38324cb83cbde363eb537d5468ac5ba3c2ceb9d12e9dd379a656fc8ad79b +=,4fe01a678d5ddf7d92a2d4b3326cc3fd1e3027a47835fb4035fdda8b7a782 +?,fe5653187521d752a91b163a62d587d2bce65c869ca996825271f6b4539cf2f +[,53d58645b288381fa1c573f762063b5bcaaa57eb3138405db3aa46dc29f4b +\,fc7c441aa72e885a706b38b8f81852c2fabbd698983ee84b4fe3a52975d91 +],43db6f3f8ccb39ae1a2dfb61cbff648ee7c322c5fb3919e7e1b9e480c445de +_,ad36e26080c0d64f68763f6f41fb4996cb1db91175d92b8f74cd2cce33e78a +a,910e92e0258d70ec132b69664f5f7f292bfec7e0f727685a1d7970d12249 +b,4593f9b9bfc1b2110411c7ad7de362cbbf349682c2449bb54452ad8c5f55c42 +c,7b224444b447cb52ea61767fa5b854874c496ce13e39912513b388d679485d0 +d,486c71ad9652946b7ebf2d5a262f8b73e44458a8dc743a782dca578ad954e14 +e,95372c5f441c36d96a33a0c3cba514568049d811742b7a90c01ea1c1bc39 +f,c113c20be886c387fe5554fefb4e6bc5dd6cc5a3899dcc26cbe3447481ce6 +g,cbfbe416f501c4096cfc9eb3814d517c4e45f559688bdb1bf52c26229492 +h,f92dbcb04a6d3158138c9d62f2282ae2858417cbfefbf64476965a7d767d38 +i,bceee22d731914f67096b74e5ead4dd84c5e8eb92b54398e61e8b27bfb37 +j,d5d3ac095cfce7dbe86103ac897c74f8d3ff164d8aa29322185966f38a +k,23d63cdd33c7a2d1ff3bd5577a85ac7441ea2c5307d8070ac055cacfdd19fa +l,b4d806433df7690975f2a51652524be5a5a42c32dc73845124c7f13de45 +m,819b26d993b1931c931ed2d57e8bab8a278429c2402b56d564c24db422eef885 +n,fd45f5c2cefde4367b758fd3b19d746b9c4a8caf14f9cf77c540c223e5d9a1 +o,bb84db6a63aa8681ce9e4e2e8ebbdfe1481307ed39a2fb24635ebb79f83d64 +p,2f3c4bd6fd4e15dffac34680a766b8a2b5d523451cbd3f9834294cc8f2c92bf +q,a839e8a1e5341ffc5416e8e6630897b91e71e35dd545e2b2689965556ae47 +r,c69beb676da143bbc4f4d8f5246aaeaf3b39a4caa3a908b3dab4050b082a355 +s,98f7914e98d98e94a7e3cf972cb66c53a66cfa24305d34b333cae82dfd4be455 +t,c451897d7f747a901c183bfee2ed174f35655c966f9adf6e2c7630a03a8155bd +u,a4691deabf92f5474d57f6accb096aaa22393faf5d327dfc13c7fd4516d8e3 +v,9d2f5a83e7e5bfc4c19920f675b1d62cd2b2117cb45b195330145996fed6569d +w,fc428bdba8f516665e5bd2fa9294145b4d1ec12a4be24ba5ece2d235189125d +x,4b48ca8f92c15ff5ef3801cde3dde8f4efead877a60a28b72ae17241896d +y,a15a3426119bb7040425281dfe7165171a919c10804f498a45de361b656589 +z,cbfed415bac65b5d136b2a07f540956d143d9ab1af2facd511ac8956b11437 +{,423a44615ea1fdda7c576b328510813efcbc15ece2c371eebe6afeefd0dc2318 +},35507210cbb3c517853949d63068c338db2b7984ba1a4958a115acd35e12165 +\u00A1,306d6bce194a7d05b599ccbe39a0e21c6feb560de00cfa6387a319f9a3388b37 +\u00BF,fa98ae6f3384288d2856e3a5fbecc0d72e4840485c7408abe357832a4d414b69 +\u00E4,9518cf8f5c97ca3778be622fdecd076390083e7268f8190165e1d7212170 +\u00EB,99a310def1ab3c704a26892e45166beb18913d33a0488fdb3d18331a95c83c47 +\u00F1,eba36c1f1d2cd582967aa4e3df7d168c0e22a391de050d7f2495e8cf4c48739f +\u00F6,b7588d0e2a6462436a2c412b55650cd4f6f83c1fd63fe1ba2707186a3bf84b9 +\u00FC,1324439206ad61b212e6255b2a0e75d6b43896075f36aa3124682cd33a773a9 +\u0431,923fcba1f880bab74c364b118a118ac9e47b1a1f4fe9474bc0da75626ab16 +\u0433,8f50eef4471547d6352379aee41cc4de1527b4719f685c4fcba08b2f94ca32 +\u0434,894dab994819e6647a6b6396424d5365eb4194e55b47fbc3ff92baf3fc7d703a +\u0436,b78b68c3b92b415dab6a8ce4be5843da3bacef94fd9c6ff8f83cf0c1a5ccd1 +\u0437,e8a198bdceca5a3ae59d68d0182d387b78864944323ec69c95c70151d02e17 +\u0438,d3cdfea626b8a9f8152905232156313a2d6a37af75cf43162aaa1206146 +\u0439,be20fb2f7fd790ff70667a6aa61471cefef3a4c9dda313677eae6c99dde52375 +\u043B,9adf3c905a8138989f61549cf9df9a6b09a6612ac96c561607db9bdfeddfc69 +\u043F,a19de72c89ee4ee543838c4d84bb7aa33beb954154be471758c6b6902d23e2 +\u0443,db38a5fefe3f8be3d1d4ba49395a373b01217225e83f7e5184552f25919208b +\u0444,691c24c9298d3dbd4dacf4f1fe72225d1f672071772f2b9be27521148576d8 +\u0446,295bc21eb731deb93aa26b39bbc646712af5c2b6f9538963b5c46d72f3fe50 +\u0447,9d5cb5b5ffd965ddb53b5c2beab7535a0b6d6baf8ab56160a7e6e47184f5ad +\u0448,2e314ad5c9146f8411f16a97db327e17d2287cd5057b7aa907ee9f22cc4743 +\u0449,afd4b94f6e3c4211fbe3357765472dbb34ebb4ecd4bc79b144a13647ff08f6f +\u044A,fec948b4477b98d5c11fd69e1daefb42e7dec927cf89a2d1d385e79afde2c1 +\u044B,1f97754266c23175262c4ce0a149d2f217c8a73d6b96dfcf0d8f67b5bd238 +\u044C,e6cb9d93bce5f243924ed1840f7dfcfc151c0aaca9cf3e806857b72e8e664 +\u044D,7aa19c463cfb1f76c477a96d9c9d1270193ba82753f8e163321cfc2f56c5cb78 +\u044E,15b625cf9dad702197e2f9aca4f867efe78f39847c51ef9f9f3cf6da4e9113 +\u044F,fbbcfb5dc6c9652727fe928ad42c67e691ab502a34b2ca6554815e9a648bfd7 +\u2190,2eff7559102aa8ff9712976b62292ee45e0793c46f668916868207f399effab +\u2191,94a04b32d2b7598f9dd8e23fb4015c69c3cd942a37a9ea84d06869f459f1 +\u2192,f726d288a74e8ac924c58c93f5b35cacd6946a6ccfdbda85fe8acb9e3eecebdb +\u2193,1e573e99b8a5af8a7d745b776564dc727defdef070257630aa36cdb49b7cf8b +\u2196,658afcb2be19f511646ba8ade018e29e6c89886e0d6f099dc14589c5e6ac1 +\u2197,ac79f3d1dddeee531c23b9b26ea76db92a78ac1594e9dc8f62324db132a9b +\u2198,fe6c8a93fd876bcc22fe4d6f57653b6171942241db4ac8b45bf6dbbd6eea44 +\u2199,ec8de5f42dbc19eadf1e713d81d54899b379cf653ab3dc41303fbfdbf76398 +\u23E9,9deef67084a582ddf7d2f3c48bdbc590ce43ef38afeb1cdc106d3bcb30d7af +\u23EA,f15698e81924e3a28891dc6e17e65bffacf78729db3a899312dde1d9c83c61 +\u23F4,aec49f4d5951e4326bf3812296eea8f20fb2754b0a0fbac17ab5b5a6466ba +\u23F5,41ff9f2e6523db75b91b861ca4e190f53aad7496e424cac8ad936536b054a7d3 +\u2640,8a4cbb7d68bd2795cda9753aa46cdf9ebef50c8d4bb1b137176c4467e196d1fa +\u2642,20a3c4f3bbc52f073d55b6aa667b02c279bc54361fa56c047e4c1a41322770e5 +\u2648,8c2c5120ed84ca5afb81bd4c96797b86654b3e769e7fe4a01aa08d2b172d7767 +\u2649,819ff4a988d8c7071f36175e86674e9ba8fb393ce47a52ba6e44f7966dd19546 +\u264A,d7687395041d2e87da1044ca5a763cfdae03cd301c2c4e176c65cd359f48276b +\u264B,e34d173b0f006aa350e0a3b5abfd9ae9cad979970193b61e2aa9434e2f8628fd +\u264C,a4719a552417d8fa1d850fdce881846fc9a62d2697d9a3cf7b50f0678f2bdc46 +\u264D,23da4ff1f494c001cfdc343d75583b7208ad01ee24b856dc96376191b65a234c +\u264E,fd32bdc54e13c1bdca844d08649019c1451bb2d9694305e97ee5afd937056402 +\u264F,1a9e394949b25ccb417d604cc7c0e1b423b44d3bfc2d41e15fe5a87bf61120d +\u2650,48fe0cb0f9854ae02fd535d992a860b816d73328d6b6dafee3b2c9c02838dbd8 +\u2651,5d1201f2f9a7867260a7f774470691b7ce62f35e8d393f9054803d873c41f776 +\u2652,e540047276dc1cf58ce6796d1a9e66309a218a938a370a9b1ff34472a92e2c08 +\u2653,d4572c335b47fc58d5c5c3fedec0fbb01376e6152e85ee116feca59463bcc831 +\u2665,8e5aa91f11a27b5cf62aa06dc1d3a47a748bf1870dceda8b6674a301a284 +\u266A,27b995f5945cbf4de29f78a0cd2acd44cc288733f4de512fe72ca4cb1983c424 \u2713,d5d4c645eb42bee415658e1661889e62268b5cb3f1e1da33ac6cc1e00a7090ff \ No newline at end of file diff --git a/src/main/resources/fonts/quartz.csv b/IF/src/main/resources/fonts/quartz.csv similarity index 98% rename from src/main/resources/fonts/quartz.csv rename to IF/src/main/resources/fonts/quartz.csv index 3454aee7..49f950e6 100644 --- a/src/main/resources/fonts/quartz.csv +++ b/IF/src/main/resources/fonts/quartz.csv @@ -1,118 +1,118 @@ -" ",c723704a9d5910b9cd505dc99c779bf50379cb84745cc719e9f784dd8c -!,7b87d2252cac1aa15df325998b8ec82ef9109b6c567610afac0ecda513f61 -"""",d584cf7d79f1aeb2554c1bfd46e6b78ca6ae3aa2a2132346a410f15e426f31 -#,b7dc3e29a0923e52ecee6b4c9d533a79e74bb6bed541b495a13abd359627653 -$,6f38d61203e4e6a2c9248030609efb577b4fe9ef786ca40db943f53f480ae688 -%,1fe1972f2cfa4d30dc2f34e8d215358c0c57432a55f6c37ad91e0dd44191a -&,e2b8b315f8716a31f32d543874a37f94cff5dafd2a58656ff3a9e8280ec49c7 -',46e3e9ef4a23a173651951bdad73f44bcfa1c8bf6b766c1057c3415aefb883 -(,f59875a9919ff68e88b31424826ecf8e29e16b5c2f3b21b3bdcd73588aed1e -),39a9a09f60d599d5126eab60c4f4fe311eb50237dae0f256f77bad8e22ea21 -+,47a0fc6dcf739c11fece43cdd184dea791cf757bf7bd91536fdbc96fa47acfb -",",dccb70aa464958bac751645dbac7b4ff3ead6b9740bcb1f71ae2cc80b3ae --,9d6b1293db729d010f534ce1361bbc55ae5a8c8f83a1947afe7a86732efc2 -.,671e57f1ecd46ed8b8d937ee231767889da94f86770a8f2281cfcf53411f5cc -/,cdf07aafe1a1fbe7804834e8d617cbdfc66493a941c11d87fb7141e57897f83 -0,1f886d9c40ef7f50c238824792c41fbfb54f665f159bf1bcb0b27b3ead373b -1,a0a19e23d21f2db063cc55e99ae874dc8b23be779be34e52e7c7b9a25 -2,cc596a41daea51be2e9fec7de2d89068e2fa61c9d57a8bdde44b55937b6037 -3,b85d4fda56bfeb85124460ff72b251dca8d1deb6578070d612b2d3adbf5a8 -4,3852a25fe69ca86fb982fb3cc7ac9793f7356b50b92cb0e193d6b4632a9bd629 -5,74ee7d954eb14a5ccd346266231bf9a6716527b59bbcd7956cef04a9d9b -6,2682a3ae948374e037e3d7dd687d59d185dd2cc8fc09dfeb42f98f8d259e5c3 -7,4ea30c24c60b3bc1af658ef661b771c48d5b9c9e28188cf9de9f832422e510 -8,66abafd023f230e4485aaf26e19368f5980d4f14a59fcc6d11a4466994892 -9,8d7910e10334f890a625483ac0c824b5e4a1a4b15a956327a3e3ae458d9ea4 -:,b71b5ca3a61bef29165eb1266b405ac2591572c16a4b39cb36edaf46c86c088 -;,a19a11febff973044629b90aa25fbfe8665d22807f26e83e3e968edf0ac1 -=,303082f033f9724cb22fe27d0de4975090335641eee5d8d927adf5a8b67f -?,fc271052719ef64079ee8c1498951238a74dac4c27b95640db6fbddc2d6b5b6e -[,cb823732cf64a87bb65350cd79345cb4b392432f4cf0897c86c6452c2d69f1 -\,c568c9b953ec3e3217c4d2b1cbdd27f354ee0be8da884ee75a82fc4b04d5f39 -],d2892217ce8fa84128abe264b5e71d7ee7e6a9d58238258ef7d2efdc347 -_,a242302ebd655f6d429c1e4aede21b7f5c4db68a4045ebaec17633a050a1a1 -a,42cd5a1b5288caaa21a6acd4c98ceafd4c1588c8b2026c88b70d3c154d39bab -b,bd5031e87139a81768e14fd3f0a47a67213f062546fa17a8a86222be1978a3f -c,2d3b2e3e9954f822b43fe5f915099e0a6caaa81f791222b5803d4145a85170 -d,da6a7d1b7629193942f8e146c6d1d2db191d27f811d21e29a2e4cfbabda088 -e,bf3cf8dd82f3819831bda6716540eddc2d7153c85bcc78e4325956504f675f -f,76ef83e6cab19cd23807ef206d1ca66e41baa3a0fa5bdc9ea44bbe96d186b -g,c68dfbc95adb4f648c36164a15d68ef5f9c7697d86f87213c7d7a645577aa66 -h,a8d0c67baa725a1e41bab30805777e732bb2ae6e934f8735cc407875d64ccb -i,9769e2c134ee5fc6daefe412e4af3d57df9dbb3caacd8e36e599979ec1ac4 -j,9c342719a038268e36953aaaeb73eda82de681b23a47891a3ffe7fbe540a312 -k,8812ec3e3bffb3e58e9315966a55a7441488de73d983c582b2aa3668f84b683 -l,6adcf96106613a33d3d2a464adb1b1a5c5e0cb11dce72926b599943e363df -m,7f8334151c234f41647113be3eadf287d1817115bac9445ffbbbe9cb2b284b0 -n,bc4d75b99faec5e12ad2f92da61ac492626e505b6a84f6d69bbf2499e7b84427 -o,7bff8211e3d9d16b4ca2c20cd2a6f99cce8fe4d98ef5ca5516f51f25cf1c31 -p,13f5f9fdf0b3d5b84783db79d21c8c34208eaa2865d58ac733f4228f156393 -q,efb1e147db9811cc8da47d9996c2c3d294c82ed9461267d5b3861eecc517f68 -r,339886a914819364859837024c4bcfa853d86bd82be5417d68c057b8433 -s,f38d2759569d515d2454d4a7891a94cc63ddfe72d03bfdf76f1d4277d590 -t,ca6e53bfb7c13fedbdfe89676f81fc2ca7974634a684141ad1f5164f0edf4a2 -u,3326846935a96261f44f448580891db99dfb8119591ce5b61d3046a3a380d3 -v,23ac34185bcee626dd9bc966be6498438fbfa7541c862ac716ffef9fd185 -w,695a23ef2542f9dd1d11cfdae618e1af1dd82a9b3f7a267ab288be3295492ac -x,391d6eda83ed2c24dcdccb1e33df3694eee397a57012255bfc56a3c244bcc474 -y,89ff8c744950729f58cb4e66dc68eaf62d0106f8a531529133bed1d55e3 -z,705f18d416f68e9bd19d55df9fa742edfbf1a525c8e29f659ae833af217d535 -{,c8671198382de93e1d3c7834de86704a6ecc791419f0ddb49a41a9608ad472 -},8133a423606694da6c91a84ea66d49efc3a23f73fa8af8cc1fe2983fe8bb5d3 -\u00A1,e6d554ad5e0dc601efbb925d13424ccea532c831a90b9ca73d5e93ab6dbc5daf -\u00BF,f882ccd75e6b8e5ef360055c252123cb26e687c35c0acaf79efde869e53f070a -\u00E4,aa4d2dffc6af9612b424bad7d8cbf7c8939e0852138676d8e251c214e7224f2 -\u00EB,b72b1826aae4f1eec5af696aa54a5485482ba952d5a168d45cea0f9cbf4ef3a -\u00F1,a086a3c406347f8b099c05a5acbf9b395b7d075a4478ccec43e77ed0a5bd31f2 -\u00F6,4b17935bb94492f89b5e26389eff8fee4ea9b8885d556c0429ae33de3bf8b74 -\u00FC,3acb5a1c70b8e313425a2fe7e9f22d74a94455c4bab9f4f61f21ed1cf437830 -\u0431,a8d311478f436e3a3a3d8ed28061668edbbc942ec676394542522f80496c8c -\u0433,f3ac51477a8d42714c256925f436f2c4d58a9529ce8c16a1e37f265e5c489a -\u0434,5d68bd8dc3b2a83f74080caf2fbd38722ad3746408b6d11a6bb77571d46fc67 -\u0436,c1c3d543a85250859f957933588f44b12c5d1e0f0643359ebb80ab2bb9377d -\u0437,7f474384572c785f77c9c7206eadf2dab0b7a28cac3ab5084e47c655e1f936 -\u0438,6840ae4e44bcc992e8350961c3765e1b1b22f4a4f54c87b73341d1239b3c6 -\u0439,f7eca1d5e131b62294ac2c4b5e54d5efebf9f8e94bd6698ee841ed6471ea67fa -\u043B,6bfc1778cd72823f4d91b66c9ec59abb564eac96cef8e110d4879d8f6152289c -\u043F,1c725a7d077231468057d0a3fd6bb9567f84b65523da93f93b31e96a0275e -\u0443,e0b62a3ab191e62db41111e3f3404818561d95fc18968bc6b4a5d0551cc740e8 -\u0444,cc3366cc7abe89387e2fe6a8161a19ba212588428c89cebc9951979a81164ed -\u0446,eafdad7546273d3551d6edb9e9f9375296310d3e26b823df1f0d6e46fc3faa2 -\u0447,e8ed0786c948dce859142fc234c11bfadabb6363d24b71dd5dd4198adc1b8 -\u0448,6d7eed89e3d03fc3cc86aaf7342a7dbb279bc38e21df81d7786c5e21b7397ae -\u0449,b257d6e241f7a77b4f14edd17472b8c0ecf8cb5613271bfc77374b978c7f5 -\u044A,2fe8196034e9996a2f260368769c5f049b020ecfc96c4586a396705caf68b -\u044B,f8fc2d43a86545a33a374276df6212a4be2f4f57ac5bac0f1ae8849b660d7 -\u044C,fd8533d13cde1c2184912b07b859875295bcd30eb45427e92f3c6446be6f853 -\u044D,756bb140265c67ab431c6ad16aabfdf7e5b468f52d1102a6f4fc13c6af4f5 -\u044E,d4bb80343a4a24e0ae421f3ca4df2bb40c367244ad331984024e013e16dc457 -\u044F,dd22892c789928f45ebb4d56f37848927cbf8c15ed5b8e6850c192604af3c46c -\u2190,5f133e91919db0acefdc272d67fd87b4be88dc44a958958824474e21e06d53e6 -\u2191,a99aaf2456a6122de8f6b62683f2bc2eed9abb81fd5bea1b4c23a58156b669 -\u2192,e3fc52264d8ad9e654f415bef01a23947edbccccf649373289bea4d149541f70 -\u2193,3912d45b1c78cc22452723ee66ba2d15777cc288568d6c1b62a545b29c7187 -\u2196,f2eeefd986ad106434c64fac669f70ef88dc6bb6c82cbd7fa8d66436973db1ad -\u2197,aacacb836c5e428b49b5d224cab22828efe2f6c704f759364d71c656e301420 -\u2198,3667d141c41b05b74bb146eec22b21c5fea3367efdb6c7b5bfb5ef8a9e34aa2 -\u2199,a7dd76ab3f9c645196e2458564d8556ad59fd32725ed4888c01e307a37aeb -\u23E9,b54fabb1664b8b4d8db2889476c6feddbb4505eba42878c653a5d793f719b16 -\u23EA,4c301a17c955807d89f9c72a19207d1393b8c58c4e6e420f714f696a87fdd -\u23F4,48348aa77f9fb2b91eef662b5c81b5ca335ddee1b905f3a8b92095d0a1f141 -\u23F5,17b03b71d3f86220ef122f9831a726eb2b283319c7b62e7dcd2d64d9682 -\u2640,63c3b885c18b79c1f4cb096a5729d58bf83b2a3b2b5fb6b94503974875ca69da -\u2642,6102d2f24cbce43302646498d23dc4f88de2a11d89683088994d29dfdcf175b9 -\u2648,7871ea1ea676307c65825ed31c10122e06cfd0caab524f9dceb7a6f51e6b6ef7 -\u2649,acd0763650636b36e8fc86cb836f8b0eb0e721bc8ef52d02195d10cc862cc38 -\u264A,ddecfda367081529b506a933a26d9a72116524208ac271ef58dd683320aaed2d -\u264B,a011e7516daac5f2320f67b97ad5304f9066f86407b58a530f80f8fc97b3e86e -\u264C,e0500f5e2502ac0433b211eb350b2dff93338360a4825a765d7e55b56c58c8ee -\u264D,8729659d4d03da56dd991852f6c6b2c99f4f659ecca9a68bc8c849b18a01e556 -\u264E,6d8612211baa7526674ef810af341c48fe1a9033abb8572639da2157842e3e42 -\u264F,716fdb74f4ead342eb4cd891e9f1ce967d76cfb6d0ac990561ca92584657807 -\u2650,40e75be2fef183e90009c0d2e2dfd829b25030fca419951e395ca9562e647e63 -\u2651,1b334c50269b9b9e36611c1b3e64647e77caccbd2a938289e354866d744b6c57 -\u2652,280247bf10576b4d12f69072990aacc67d2dc9e791c4dc07d377aee9bf2540ec -\u2653,50ff20a5b13a8ed5d4d64d225eca7fefd10733b722fc0ef7e79c639474f9f2be -\u2665,09a52cb50992d83c5599fd6e41a6ce99cf7f1e6203611963dc2c2fda0b55583 -\u266A,3919fbd1df48c322c1305bb1f8eab9674c21844a0493a5535d94caba1eca3c1d +" ",c723704a9d5910b9cd505dc99c779bf50379cb84745cc719e9f784dd8c +!,7b87d2252cac1aa15df325998b8ec82ef9109b6c567610afac0ecda513f61 +"""",d584cf7d79f1aeb2554c1bfd46e6b78ca6ae3aa2a2132346a410f15e426f31 +#,b7dc3e29a0923e52ecee6b4c9d533a79e74bb6bed541b495a13abd359627653 +$,6f38d61203e4e6a2c9248030609efb577b4fe9ef786ca40db943f53f480ae688 +%,1fe1972f2cfa4d30dc2f34e8d215358c0c57432a55f6c37ad91e0dd44191a +&,e2b8b315f8716a31f32d543874a37f94cff5dafd2a58656ff3a9e8280ec49c7 +',46e3e9ef4a23a173651951bdad73f44bcfa1c8bf6b766c1057c3415aefb883 +(,f59875a9919ff68e88b31424826ecf8e29e16b5c2f3b21b3bdcd73588aed1e +),39a9a09f60d599d5126eab60c4f4fe311eb50237dae0f256f77bad8e22ea21 ++,47a0fc6dcf739c11fece43cdd184dea791cf757bf7bd91536fdbc96fa47acfb +",",dccb70aa464958bac751645dbac7b4ff3ead6b9740bcb1f71ae2cc80b3ae +-,9d6b1293db729d010f534ce1361bbc55ae5a8c8f83a1947afe7a86732efc2 +.,671e57f1ecd46ed8b8d937ee231767889da94f86770a8f2281cfcf53411f5cc +/,cdf07aafe1a1fbe7804834e8d617cbdfc66493a941c11d87fb7141e57897f83 +0,1f886d9c40ef7f50c238824792c41fbfb54f665f159bf1bcb0b27b3ead373b +1,a0a19e23d21f2db063cc55e99ae874dc8b23be779be34e52e7c7b9a25 +2,cc596a41daea51be2e9fec7de2d89068e2fa61c9d57a8bdde44b55937b6037 +3,b85d4fda56bfeb85124460ff72b251dca8d1deb6578070d612b2d3adbf5a8 +4,3852a25fe69ca86fb982fb3cc7ac9793f7356b50b92cb0e193d6b4632a9bd629 +5,74ee7d954eb14a5ccd346266231bf9a6716527b59bbcd7956cef04a9d9b +6,2682a3ae948374e037e3d7dd687d59d185dd2cc8fc09dfeb42f98f8d259e5c3 +7,4ea30c24c60b3bc1af658ef661b771c48d5b9c9e28188cf9de9f832422e510 +8,66abafd023f230e4485aaf26e19368f5980d4f14a59fcc6d11a4466994892 +9,8d7910e10334f890a625483ac0c824b5e4a1a4b15a956327a3e3ae458d9ea4 +:,b71b5ca3a61bef29165eb1266b405ac2591572c16a4b39cb36edaf46c86c088 +;,a19a11febff973044629b90aa25fbfe8665d22807f26e83e3e968edf0ac1 +=,303082f033f9724cb22fe27d0de4975090335641eee5d8d927adf5a8b67f +?,fc271052719ef64079ee8c1498951238a74dac4c27b95640db6fbddc2d6b5b6e +[,cb823732cf64a87bb65350cd79345cb4b392432f4cf0897c86c6452c2d69f1 +\,c568c9b953ec3e3217c4d2b1cbdd27f354ee0be8da884ee75a82fc4b04d5f39 +],d2892217ce8fa84128abe264b5e71d7ee7e6a9d58238258ef7d2efdc347 +_,a242302ebd655f6d429c1e4aede21b7f5c4db68a4045ebaec17633a050a1a1 +a,42cd5a1b5288caaa21a6acd4c98ceafd4c1588c8b2026c88b70d3c154d39bab +b,bd5031e87139a81768e14fd3f0a47a67213f062546fa17a8a86222be1978a3f +c,2d3b2e3e9954f822b43fe5f915099e0a6caaa81f791222b5803d4145a85170 +d,da6a7d1b7629193942f8e146c6d1d2db191d27f811d21e29a2e4cfbabda088 +e,bf3cf8dd82f3819831bda6716540eddc2d7153c85bcc78e4325956504f675f +f,76ef83e6cab19cd23807ef206d1ca66e41baa3a0fa5bdc9ea44bbe96d186b +g,c68dfbc95adb4f648c36164a15d68ef5f9c7697d86f87213c7d7a645577aa66 +h,a8d0c67baa725a1e41bab30805777e732bb2ae6e934f8735cc407875d64ccb +i,9769e2c134ee5fc6daefe412e4af3d57df9dbb3caacd8e36e599979ec1ac4 +j,9c342719a038268e36953aaaeb73eda82de681b23a47891a3ffe7fbe540a312 +k,8812ec3e3bffb3e58e9315966a55a7441488de73d983c582b2aa3668f84b683 +l,6adcf96106613a33d3d2a464adb1b1a5c5e0cb11dce72926b599943e363df +m,7f8334151c234f41647113be3eadf287d1817115bac9445ffbbbe9cb2b284b0 +n,bc4d75b99faec5e12ad2f92da61ac492626e505b6a84f6d69bbf2499e7b84427 +o,7bff8211e3d9d16b4ca2c20cd2a6f99cce8fe4d98ef5ca5516f51f25cf1c31 +p,13f5f9fdf0b3d5b84783db79d21c8c34208eaa2865d58ac733f4228f156393 +q,efb1e147db9811cc8da47d9996c2c3d294c82ed9461267d5b3861eecc517f68 +r,339886a914819364859837024c4bcfa853d86bd82be5417d68c057b8433 +s,f38d2759569d515d2454d4a7891a94cc63ddfe72d03bfdf76f1d4277d590 +t,ca6e53bfb7c13fedbdfe89676f81fc2ca7974634a684141ad1f5164f0edf4a2 +u,3326846935a96261f44f448580891db99dfb8119591ce5b61d3046a3a380d3 +v,23ac34185bcee626dd9bc966be6498438fbfa7541c862ac716ffef9fd185 +w,695a23ef2542f9dd1d11cfdae618e1af1dd82a9b3f7a267ab288be3295492ac +x,391d6eda83ed2c24dcdccb1e33df3694eee397a57012255bfc56a3c244bcc474 +y,89ff8c744950729f58cb4e66dc68eaf62d0106f8a531529133bed1d55e3 +z,705f18d416f68e9bd19d55df9fa742edfbf1a525c8e29f659ae833af217d535 +{,c8671198382de93e1d3c7834de86704a6ecc791419f0ddb49a41a9608ad472 +},8133a423606694da6c91a84ea66d49efc3a23f73fa8af8cc1fe2983fe8bb5d3 +\u00A1,e6d554ad5e0dc601efbb925d13424ccea532c831a90b9ca73d5e93ab6dbc5daf +\u00BF,f882ccd75e6b8e5ef360055c252123cb26e687c35c0acaf79efde869e53f070a +\u00E4,aa4d2dffc6af9612b424bad7d8cbf7c8939e0852138676d8e251c214e7224f2 +\u00EB,b72b1826aae4f1eec5af696aa54a5485482ba952d5a168d45cea0f9cbf4ef3a +\u00F1,a086a3c406347f8b099c05a5acbf9b395b7d075a4478ccec43e77ed0a5bd31f2 +\u00F6,4b17935bb94492f89b5e26389eff8fee4ea9b8885d556c0429ae33de3bf8b74 +\u00FC,3acb5a1c70b8e313425a2fe7e9f22d74a94455c4bab9f4f61f21ed1cf437830 +\u0431,a8d311478f436e3a3a3d8ed28061668edbbc942ec676394542522f80496c8c +\u0433,f3ac51477a8d42714c256925f436f2c4d58a9529ce8c16a1e37f265e5c489a +\u0434,5d68bd8dc3b2a83f74080caf2fbd38722ad3746408b6d11a6bb77571d46fc67 +\u0436,c1c3d543a85250859f957933588f44b12c5d1e0f0643359ebb80ab2bb9377d +\u0437,7f474384572c785f77c9c7206eadf2dab0b7a28cac3ab5084e47c655e1f936 +\u0438,6840ae4e44bcc992e8350961c3765e1b1b22f4a4f54c87b73341d1239b3c6 +\u0439,f7eca1d5e131b62294ac2c4b5e54d5efebf9f8e94bd6698ee841ed6471ea67fa +\u043B,6bfc1778cd72823f4d91b66c9ec59abb564eac96cef8e110d4879d8f6152289c +\u043F,1c725a7d077231468057d0a3fd6bb9567f84b65523da93f93b31e96a0275e +\u0443,e0b62a3ab191e62db41111e3f3404818561d95fc18968bc6b4a5d0551cc740e8 +\u0444,cc3366cc7abe89387e2fe6a8161a19ba212588428c89cebc9951979a81164ed +\u0446,eafdad7546273d3551d6edb9e9f9375296310d3e26b823df1f0d6e46fc3faa2 +\u0447,e8ed0786c948dce859142fc234c11bfadabb6363d24b71dd5dd4198adc1b8 +\u0448,6d7eed89e3d03fc3cc86aaf7342a7dbb279bc38e21df81d7786c5e21b7397ae +\u0449,b257d6e241f7a77b4f14edd17472b8c0ecf8cb5613271bfc77374b978c7f5 +\u044A,2fe8196034e9996a2f260368769c5f049b020ecfc96c4586a396705caf68b +\u044B,f8fc2d43a86545a33a374276df6212a4be2f4f57ac5bac0f1ae8849b660d7 +\u044C,fd8533d13cde1c2184912b07b859875295bcd30eb45427e92f3c6446be6f853 +\u044D,756bb140265c67ab431c6ad16aabfdf7e5b468f52d1102a6f4fc13c6af4f5 +\u044E,d4bb80343a4a24e0ae421f3ca4df2bb40c367244ad331984024e013e16dc457 +\u044F,dd22892c789928f45ebb4d56f37848927cbf8c15ed5b8e6850c192604af3c46c +\u2190,5f133e91919db0acefdc272d67fd87b4be88dc44a958958824474e21e06d53e6 +\u2191,a99aaf2456a6122de8f6b62683f2bc2eed9abb81fd5bea1b4c23a58156b669 +\u2192,e3fc52264d8ad9e654f415bef01a23947edbccccf649373289bea4d149541f70 +\u2193,3912d45b1c78cc22452723ee66ba2d15777cc288568d6c1b62a545b29c7187 +\u2196,f2eeefd986ad106434c64fac669f70ef88dc6bb6c82cbd7fa8d66436973db1ad +\u2197,aacacb836c5e428b49b5d224cab22828efe2f6c704f759364d71c656e301420 +\u2198,3667d141c41b05b74bb146eec22b21c5fea3367efdb6c7b5bfb5ef8a9e34aa2 +\u2199,a7dd76ab3f9c645196e2458564d8556ad59fd32725ed4888c01e307a37aeb +\u23E9,b54fabb1664b8b4d8db2889476c6feddbb4505eba42878c653a5d793f719b16 +\u23EA,4c301a17c955807d89f9c72a19207d1393b8c58c4e6e420f714f696a87fdd +\u23F4,48348aa77f9fb2b91eef662b5c81b5ca335ddee1b905f3a8b92095d0a1f141 +\u23F5,17b03b71d3f86220ef122f9831a726eb2b283319c7b62e7dcd2d64d9682 +\u2640,63c3b885c18b79c1f4cb096a5729d58bf83b2a3b2b5fb6b94503974875ca69da +\u2642,6102d2f24cbce43302646498d23dc4f88de2a11d89683088994d29dfdcf175b9 +\u2648,7871ea1ea676307c65825ed31c10122e06cfd0caab524f9dceb7a6f51e6b6ef7 +\u2649,acd0763650636b36e8fc86cb836f8b0eb0e721bc8ef52d02195d10cc862cc38 +\u264A,ddecfda367081529b506a933a26d9a72116524208ac271ef58dd683320aaed2d +\u264B,a011e7516daac5f2320f67b97ad5304f9066f86407b58a530f80f8fc97b3e86e +\u264C,e0500f5e2502ac0433b211eb350b2dff93338360a4825a765d7e55b56c58c8ee +\u264D,8729659d4d03da56dd991852f6c6b2c99f4f659ecca9a68bc8c849b18a01e556 +\u264E,6d8612211baa7526674ef810af341c48fe1a9033abb8572639da2157842e3e42 +\u264F,716fdb74f4ead342eb4cd891e9f1ce967d76cfb6d0ac990561ca92584657807 +\u2650,40e75be2fef183e90009c0d2e2dfd829b25030fca419951e395ca9562e647e63 +\u2651,1b334c50269b9b9e36611c1b3e64647e77caccbd2a938289e354866d744b6c57 +\u2652,280247bf10576b4d12f69072990aacc67d2dc9e791c4dc07d377aee9bf2540ec +\u2653,50ff20a5b13a8ed5d4d64d225eca7fefd10733b722fc0ef7e79c639474f9f2be +\u2665,09a52cb50992d83c5599fd6e41a6ce99cf7f1e6203611963dc2c2fda0b55583 +\u266A,3919fbd1df48c322c1305bb1f8eab9674c21844a0493a5535d94caba1eca3c1d \u2713,37b62d275d87c09ce10acbccf34c4ba0b5f135d643dc537da1f1df355a225e82 \ No newline at end of file diff --git a/src/main/resources/fonts/rainbow.csv b/IF/src/main/resources/fonts/rainbow.csv similarity index 98% rename from src/main/resources/fonts/rainbow.csv rename to IF/src/main/resources/fonts/rainbow.csv index ca583059..2defe859 100644 --- a/src/main/resources/fonts/rainbow.csv +++ b/IF/src/main/resources/fonts/rainbow.csv @@ -1,118 +1,118 @@ -" ",72b6732199faf1b2447725e56829090fbceb6c2b514953862ff03c16b53f3599 -!,ac3aaf1137e5783ce271402d015ac83529e2c3f53d91f69ab629f6a9565fee78 -"""",3c8f6a113c2459d3c5af63520d068e834c6d140277a3ca7565aa31111b07168d -#,b41564bfec3bd3af03558823c60e0e19e89a0bc77c64f5b7b25f5c435a5b1f9c -$,b116b68d62a35c0ce0c8c557ac634f7677048c6fed296a0dd1ed1a9c476b26e6 -%,67d6be1dca5352a5693e29ea35d806b2a27c4a97b64eebbf632c998d5948f1c4 -&,e914d2d634180e712ad9bc252b4255ac70bb9b8d44966cfaff973fea1adcc9f0 -',2dc091801da9df0c36835f704f3b9a4bbcd07456137a7d451aca00704db4445 -(,1820a0ef19ff135db10b75e2828027c265a7d83a1f94eb8d0ca67cbd205f16df -),17002361617dad8e1ba32e8a2b86903ccc4581d424cf128bd424c7a89f566b9d -+,5d8604b9e195367f85a23d03d9dd503638fcfb05b0032535bc43734422483bde -",",6b18516df85e3a143b09ce83e001d9d4016a2d7a46dca92c4e39679268680638 --,482c23992a02725d9ed1bcd90fd0307c8262d87e80ce6fac8078387de18d0851 -.,c655ef6ca5b3f87de3109bc4b12fec924f6d273d8a0ed5047ff07cd6caa94000 -/,53ad52e1749ebd056f0aa33e11486e6dc312c2db7854a04ef718475a0987c5a1 -0,3b468f5598af7c66f1c1d73465ec31dcd67a88d90051b897dad84bb360b33799 -1,d9b30303f94e7c785a31e5727a9381535daf4753449ea41db746e1234e9dd2b5 -2,e3ca7d7c1534dc6b9ed1647f9025ddf244e0107dc8dd4f4f0852c82081d6350e -3,195e1e2fb2de7e6299a0f61ddf7d9a6d101f8d664f1959d3b67dce8b049a8ae1 -4,3839eaf9ee07670607d3da4d6c1d30fe59db56458fad5f55b5412d56b3deb559 -5,e8140ec4845631a89ffe8344ae98d1049b82c2159393290bd38a8a008465b3d9 -6,8ebf9b6a6c4eb0cbfd0a3d37c34c45860681f13f7270f1337fd136a7011898f0 -7,64c2d6cbdff00b97af7f8cfe8767fd87cd65639abdf83ec1039a46415e69e398 -8,bd2791752f67a6450b975d357412356b0a99e3555e67ebdad2d40326129bdda4 -9,517077c0c68c49691aa7044394aab908386394c3d47aafc57b06b8e32d1656f5 -:,49a7903fe13abd07ac546c8f67f259a2b0f14c87376db5dafcfcb79f15d4da87 -;,7522def2f8422174788e444a714a9535abbf7ee1b8630b01d5830c8f8b07624f -=,573a9de145d018086932bee88cdf79c1b62a5ca5f159dba10098b6dd883e9aad -?,1035c528036b384c53c9c8a1a125685e16bfb369c197cc9f03dfa3b835b1aa55 -[,51708f977a8e057711f5312a119a421ddbe5f7f87da914c7b8e3fa3d1a69e6f3 -\,f1e1ad26fc3d5f13ccd9e01bbbdb157c27188e7d05e6f3885b18c59f12416f7d -],2f08c306595e702cdd74d453ffe09869d04a88155b2f4081884b78d21987b258 -_,62335e19ad3f3f066652ffdf827e507f3068ca7518322383c41cd7c21317100e -a,a517b4829b83192bd72711277a8efc4196711e4180c22b3e2b8166bea1a9de19 -b,e1131aca5fcfe6e58f616ff8befd027416fe6b98eb5ec642e035ed8339607bf0 -c,b2e594ea15486eb19261f2111e95837ad6e9a6b1d549c70ecfe7f83e41362b57 -d,6b31b79e380df31d5a4d649b1ae9fc02067d7e99487122d04d6d6ab7f7de6181 -e,b77165c9db763a9acd13c06220e92d3c970dfa36dac56e5957d02d36f5a9f0b8 -f,8442b066e0e5e09a6e6bb9989cc27451f2bd78fb0dc72108aa940fc9db1c24e1 -g,5c1a8fc8ea45d744307916eb50ddca5e40065a3461a8e469490439f9e24f4f24 -h,dca24ac8c13d21720ff5acbf2eee7270c5b3662383208db93721d0549b45b9e5 -i,84bcc9531ade2e0639a6ae03c78bc07a1a9be60fc6f3e3fe39370fb56c6b5976 -j,eb060bbe4d6d601469b49e105253ebae05293098a974b6f2d5684f941ca5a5fc -k,b37e51ce0d4c8eadf675941a45e10b928e43d22eab539ac886edbf40bb87ec0f -l,206bc417e3c06b22735d539f9c6c8fd7c1efd19236e2c381534051d9d6bee804 -m,1d716256d727ba1df18f826f119051c33a394209a95be837ccf6fae9ee6b871b -n,e713d2601e35242d35018cece3b34c61bf5001f5dbd7463a4c5587ac365b3d1f -o,35385b05e7af54635b10f02cdb0045672c91c724cf164e5193a4f7be7292ff30 -p,b553141aabe89a8a5804a172133b43d5d0ee0549cc19db0385684043cfa946a5 -q,a4d746e7e3534e729956f1a04757832fa3bf9e2d14ef6d0db8dcfc4e21532338 -r,55827f45aae65681bb27e3e0465af6228ed6292bb63b0a7764596224727f8d81 -s,dcd7d14c6db841e5864511d16ba7670b3d2038142466981feb05afc6e5edc6cb -t,b94ac36d9a6fbff1c558941381e4dcf595df825913f6c383ffaa71b756a875d3 -u,e8060faec45097eefa68088a5c07657743426e0453f8b66cf26b839c04864c00 -v,fa3fa916b5e5915e026b91b264544398ff02d1eede7630bc8158f3a663ca02ad -w,23324d1fa070cf698f2be539d69ff438aaa6b1f494c5e013c7ee9d9c33eb83c0 -x,55d5c75f6675edc292ea37846077970d226fbd524e7fd6808f3a4781a549b08c -y,1ad30e9e25705c51b846e74e7779623b69c0744645da0004d4db0fe46336ff8e -z,9a24b0f6c184ff173686c7d128df536d10b7280f8008636a5546f1c777234354 -{,a99a8bed6ffe662cc70f12f92d86efdde1a0d7933aa9a8ecb5f2952c104b4764 -},71a7c3a4aef1449435740631f02f272dce0be7add6bcf00bea17f8d48aa35413 -\u00A1,3dbaf203ce9d49b72cade405b861acfe4b653dc8c8a43e80b670fa97e560efeb -\u00BF,8064777a09c00a4a92eee74aba7c672bfea7f0384b256894ea261d5a915af8ee -\u00E4,c31403da08e7e3ae66e617682bb2e4ec183c93791a91a41fb4121de5a340942f -\u00EB,52a20d66e193b58d8d341cf9300d404d89c8f11158988e927ceb79d3bf18b749 -\u00F1,45f676f6209e844905963da139f6bbfd3cbb315d088ee134637b82ec7dc3a46e -\u00F6,1082813030d52019d11ec3847d26a46277627f468f7309d5f7d6e71a2c6a44aa -\u00FC,c3c50336e4da6426a5a7eb94881f8db14b5dc556a088d55da4d59325ba053195 -\u0431,52a20d66e193b58d8d341cf9300d404d89c8f11158988e927ceb79d3bf18b749 -\u0433,3cbf0813f9edb2de7939e5c03f5fef0820f98b3be69d52a777960015b47e7c4b -\u0434,583763532ff4a56dedb25bde59f548da443716c236112656b0ba7daaaf0a37d4 -\u0436,9be72039a40f1002fba6ab1bb5f7f00d70f53b4b48c2e9bf0f1bea70830081ac -\u0437,4fb7b208bdb44a5dce8c571f806834fc316aecb5e65e17733dd32769cb8cbcb9 -\u0438,9216b7312261523e06005fb94dbee65576f00028bcaf87db1046d380a17c8f78 -\u0439,a23c758634862e23c82463c61267f3a24ced2002819a6eb81f207918eac47c86 -\u043B,5716be5b00b3b72fc47a648a8a99948a75a51c405fc302c32d746a3026e34197 -\u043F,ecf4954cbd8681c9c0d9205b054cd2730aa0e687567be1d6001ed571c2a16a25 -\u0443,bceef846bd627442dd6fd431fe7bdac1d7fc0e895b86fd00547f94c5fde13d37 -\u0444,dc1b112d40bd8cec295f52822a3bb77fd1156752531f06aee8edd2867527b9ee -\u0446,f752477015a47f120210ca432bde6344a76bf8d4bcfa2b49ef4eeffe051b955a -\u0447,b7da8992d8adaf1eb8c01b94784be49bd718f79c0e132672e2a6b966d0b42aa8 -\u0448,5b7a10e57dc9ac43a44b41492a41d8c72b7a9bdcb0033480f84c9b376dae8f22 -\u0449,d6f54e012e262fb01f37ee607a73058963f1aa45b8ce67bf4b6837a79d946093 -\u044A,1b1760f955e47839bbd6f7fe65fb0a308e04f4239ef8dbbb7077b51e4dbdc6 -\u044B,6385969a2c52601ac56f8dab121e42f2c3f4cc79567e09eb1e3cefd45b1db261 -\u044C,758610590a4bb6c57fa31bfe8dc305678f9e4aa0968995a3bd426128efedf871 -\u044D,de3f8db3c690cbeb1d6d50de8b54c8462da33c20a4e0f69da0df912886d368b1 -\u044E,3115e99e8f795ce5a3fb389508fe933cb6345b38566505806278999f3adc52dd -\u044F,b13a4eaab76b9d212594a447d8713f36d1739e559140fd7ad08774ec1d4298f2 -\u2190,81c96a5c3d13c3199183e1bc7f086f54ca2a6527126303ac8e25d63e16b64ccf -\u2191,9cdb8f43656c06c4e8683e2e6341b4479f157f48082fea4aff09b37ca3c6995b -\u2192,333ae8de7ed079e38d2c82dd42b74cfcbd94b3480348dbb5ecd93da8b81015e3 -\u2193,61e1e730c77279c8e2e15d8b271a117e5e2ca93d25c8be3a00cc92a00cc0bb85 -\u2196,425d9d5398bd757f2fdec2a62fd0325fa8641e7f788c7f676ec8c6f4b3c529b5 -\u2197,9ef664d506e975349391985c1cd071cea7d4631763e5a2f914fa470cc2bda20a -\u2198,2cfbc163535eb54bfa5830b4f8fa32edba26881da107d61cd7e7bda853280e1c -\u2199,656abb4c74d11bb3ecca9ed4270cdbddeea9705822fd33b94e05c47c3ee56f90 -\u23E9,c920f0d4b2e010e80153a68b45501d054c43bb248f44bb8373640e3235679ac3 -\u23EA,d44af2e8d3980ab8d507257c5b2da1389b7579a6fb4b8dcd8db50d2facd680d6 -\u23F4,fc99aa6fc2ecce35665d948a01325153fe53fc1771fb2784f57967f10e2ddcf8 -\u23F5,a8ae11a9c940c5ac62b905837d21537dbe2f3e5011f0bbbfdc11224b8603dbbd -\u2640,f570ee67722f5a80d1eef4fe3dd018a9fbcadeee51eeb4a92cb558623e728ad6 -\u2642,15df33171dcfdd45ab6a6bdba86c2d0fefc04a6e461af4591f2b58b8267ede68 -\u2648,c75493546982496ea18e4316bd80c759e7089f7cf03e4c905f3e1f462add6e2f -\u2649,75ade7cf0c9b7f68cf8320452aa1f1f79785159f99b78631c9491c13604932ac -\u264A,4e585f6434dba73132c4b3849bb377f4ab5c01330763a8eb9417b6e2d04f9c32 -\u264B,317d2222ce8b5caa261e8b094cd515f6b5e814e98382281041a69eb7d6b49bc3 -\u264C,1a9e06c973ad7ab386c7ad02f2d8590749d2e27500b9d5f1dd1a92a5ce95772d -\u264D,d44af2e8d3980ab8d507257c5b2da1389b7579a6fb4b8dcd8db50d2facd680d6 -\u264E,60a3af187bb8b83e5af566fb6afdcff33e36476fb34b19096f2b57d3312fe292 -\u264F,9f0a53e6a79a4cd8a63585601c6d68da3c3bb9a7e15df16352ae5608cdbc3110 -\u2650,13b20a1acda7e566064eec9acb61428386ec9f5940018338c6d8fed4ddcd6b59 -\u2651,12f08a99474aebcf55402ef6473472cd7acbdcc9ba2f143b8369a0c58c3e0be3 -\u2652,a4c780569b3a4f62a899036dab8bb96fb02b2ab71c5332eaa4b7211765492062 -\u2653,ebf011891fb520da8e419954e007d42367e1c669f5d53b121605e3439da8f1ed -\u2665,caae1743c4cf0c75c916df6102a396bba61a6c40da5eebc6b92d7ad2bc5ef5bf -\u266A,f22e40b4bfbcc0433044d86d67685f0567025904271d0a74996afbe3f9be2c0f +" ",72b6732199faf1b2447725e56829090fbceb6c2b514953862ff03c16b53f3599 +!,ac3aaf1137e5783ce271402d015ac83529e2c3f53d91f69ab629f6a9565fee78 +"""",3c8f6a113c2459d3c5af63520d068e834c6d140277a3ca7565aa31111b07168d +#,b41564bfec3bd3af03558823c60e0e19e89a0bc77c64f5b7b25f5c435a5b1f9c +$,b116b68d62a35c0ce0c8c557ac634f7677048c6fed296a0dd1ed1a9c476b26e6 +%,67d6be1dca5352a5693e29ea35d806b2a27c4a97b64eebbf632c998d5948f1c4 +&,e914d2d634180e712ad9bc252b4255ac70bb9b8d44966cfaff973fea1adcc9f0 +',2dc091801da9df0c36835f704f3b9a4bbcd07456137a7d451aca00704db4445 +(,1820a0ef19ff135db10b75e2828027c265a7d83a1f94eb8d0ca67cbd205f16df +),17002361617dad8e1ba32e8a2b86903ccc4581d424cf128bd424c7a89f566b9d ++,5d8604b9e195367f85a23d03d9dd503638fcfb05b0032535bc43734422483bde +",",6b18516df85e3a143b09ce83e001d9d4016a2d7a46dca92c4e39679268680638 +-,482c23992a02725d9ed1bcd90fd0307c8262d87e80ce6fac8078387de18d0851 +.,c655ef6ca5b3f87de3109bc4b12fec924f6d273d8a0ed5047ff07cd6caa94000 +/,53ad52e1749ebd056f0aa33e11486e6dc312c2db7854a04ef718475a0987c5a1 +0,3b468f5598af7c66f1c1d73465ec31dcd67a88d90051b897dad84bb360b33799 +1,d9b30303f94e7c785a31e5727a9381535daf4753449ea41db746e1234e9dd2b5 +2,e3ca7d7c1534dc6b9ed1647f9025ddf244e0107dc8dd4f4f0852c82081d6350e +3,195e1e2fb2de7e6299a0f61ddf7d9a6d101f8d664f1959d3b67dce8b049a8ae1 +4,3839eaf9ee07670607d3da4d6c1d30fe59db56458fad5f55b5412d56b3deb559 +5,e8140ec4845631a89ffe8344ae98d1049b82c2159393290bd38a8a008465b3d9 +6,8ebf9b6a6c4eb0cbfd0a3d37c34c45860681f13f7270f1337fd136a7011898f0 +7,64c2d6cbdff00b97af7f8cfe8767fd87cd65639abdf83ec1039a46415e69e398 +8,bd2791752f67a6450b975d357412356b0a99e3555e67ebdad2d40326129bdda4 +9,517077c0c68c49691aa7044394aab908386394c3d47aafc57b06b8e32d1656f5 +:,49a7903fe13abd07ac546c8f67f259a2b0f14c87376db5dafcfcb79f15d4da87 +;,7522def2f8422174788e444a714a9535abbf7ee1b8630b01d5830c8f8b07624f +=,573a9de145d018086932bee88cdf79c1b62a5ca5f159dba10098b6dd883e9aad +?,1035c528036b384c53c9c8a1a125685e16bfb369c197cc9f03dfa3b835b1aa55 +[,51708f977a8e057711f5312a119a421ddbe5f7f87da914c7b8e3fa3d1a69e6f3 +\,f1e1ad26fc3d5f13ccd9e01bbbdb157c27188e7d05e6f3885b18c59f12416f7d +],2f08c306595e702cdd74d453ffe09869d04a88155b2f4081884b78d21987b258 +_,62335e19ad3f3f066652ffdf827e507f3068ca7518322383c41cd7c21317100e +a,a517b4829b83192bd72711277a8efc4196711e4180c22b3e2b8166bea1a9de19 +b,e1131aca5fcfe6e58f616ff8befd027416fe6b98eb5ec642e035ed8339607bf0 +c,b2e594ea15486eb19261f2111e95837ad6e9a6b1d549c70ecfe7f83e41362b57 +d,6b31b79e380df31d5a4d649b1ae9fc02067d7e99487122d04d6d6ab7f7de6181 +e,b77165c9db763a9acd13c06220e92d3c970dfa36dac56e5957d02d36f5a9f0b8 +f,8442b066e0e5e09a6e6bb9989cc27451f2bd78fb0dc72108aa940fc9db1c24e1 +g,5c1a8fc8ea45d744307916eb50ddca5e40065a3461a8e469490439f9e24f4f24 +h,dca24ac8c13d21720ff5acbf2eee7270c5b3662383208db93721d0549b45b9e5 +i,84bcc9531ade2e0639a6ae03c78bc07a1a9be60fc6f3e3fe39370fb56c6b5976 +j,eb060bbe4d6d601469b49e105253ebae05293098a974b6f2d5684f941ca5a5fc +k,b37e51ce0d4c8eadf675941a45e10b928e43d22eab539ac886edbf40bb87ec0f +l,206bc417e3c06b22735d539f9c6c8fd7c1efd19236e2c381534051d9d6bee804 +m,1d716256d727ba1df18f826f119051c33a394209a95be837ccf6fae9ee6b871b +n,e713d2601e35242d35018cece3b34c61bf5001f5dbd7463a4c5587ac365b3d1f +o,35385b05e7af54635b10f02cdb0045672c91c724cf164e5193a4f7be7292ff30 +p,b553141aabe89a8a5804a172133b43d5d0ee0549cc19db0385684043cfa946a5 +q,a4d746e7e3534e729956f1a04757832fa3bf9e2d14ef6d0db8dcfc4e21532338 +r,55827f45aae65681bb27e3e0465af6228ed6292bb63b0a7764596224727f8d81 +s,dcd7d14c6db841e5864511d16ba7670b3d2038142466981feb05afc6e5edc6cb +t,b94ac36d9a6fbff1c558941381e4dcf595df825913f6c383ffaa71b756a875d3 +u,e8060faec45097eefa68088a5c07657743426e0453f8b66cf26b839c04864c00 +v,fa3fa916b5e5915e026b91b264544398ff02d1eede7630bc8158f3a663ca02ad +w,23324d1fa070cf698f2be539d69ff438aaa6b1f494c5e013c7ee9d9c33eb83c0 +x,55d5c75f6675edc292ea37846077970d226fbd524e7fd6808f3a4781a549b08c +y,1ad30e9e25705c51b846e74e7779623b69c0744645da0004d4db0fe46336ff8e +z,9a24b0f6c184ff173686c7d128df536d10b7280f8008636a5546f1c777234354 +{,a99a8bed6ffe662cc70f12f92d86efdde1a0d7933aa9a8ecb5f2952c104b4764 +},71a7c3a4aef1449435740631f02f272dce0be7add6bcf00bea17f8d48aa35413 +\u00A1,3dbaf203ce9d49b72cade405b861acfe4b653dc8c8a43e80b670fa97e560efeb +\u00BF,8064777a09c00a4a92eee74aba7c672bfea7f0384b256894ea261d5a915af8ee +\u00E4,c31403da08e7e3ae66e617682bb2e4ec183c93791a91a41fb4121de5a340942f +\u00EB,52a20d66e193b58d8d341cf9300d404d89c8f11158988e927ceb79d3bf18b749 +\u00F1,45f676f6209e844905963da139f6bbfd3cbb315d088ee134637b82ec7dc3a46e +\u00F6,1082813030d52019d11ec3847d26a46277627f468f7309d5f7d6e71a2c6a44aa +\u00FC,c3c50336e4da6426a5a7eb94881f8db14b5dc556a088d55da4d59325ba053195 +\u0431,52a20d66e193b58d8d341cf9300d404d89c8f11158988e927ceb79d3bf18b749 +\u0433,3cbf0813f9edb2de7939e5c03f5fef0820f98b3be69d52a777960015b47e7c4b +\u0434,583763532ff4a56dedb25bde59f548da443716c236112656b0ba7daaaf0a37d4 +\u0436,9be72039a40f1002fba6ab1bb5f7f00d70f53b4b48c2e9bf0f1bea70830081ac +\u0437,4fb7b208bdb44a5dce8c571f806834fc316aecb5e65e17733dd32769cb8cbcb9 +\u0438,9216b7312261523e06005fb94dbee65576f00028bcaf87db1046d380a17c8f78 +\u0439,a23c758634862e23c82463c61267f3a24ced2002819a6eb81f207918eac47c86 +\u043B,5716be5b00b3b72fc47a648a8a99948a75a51c405fc302c32d746a3026e34197 +\u043F,ecf4954cbd8681c9c0d9205b054cd2730aa0e687567be1d6001ed571c2a16a25 +\u0443,bceef846bd627442dd6fd431fe7bdac1d7fc0e895b86fd00547f94c5fde13d37 +\u0444,dc1b112d40bd8cec295f52822a3bb77fd1156752531f06aee8edd2867527b9ee +\u0446,f752477015a47f120210ca432bde6344a76bf8d4bcfa2b49ef4eeffe051b955a +\u0447,b7da8992d8adaf1eb8c01b94784be49bd718f79c0e132672e2a6b966d0b42aa8 +\u0448,5b7a10e57dc9ac43a44b41492a41d8c72b7a9bdcb0033480f84c9b376dae8f22 +\u0449,d6f54e012e262fb01f37ee607a73058963f1aa45b8ce67bf4b6837a79d946093 +\u044A,1b1760f955e47839bbd6f7fe65fb0a308e04f4239ef8dbbb7077b51e4dbdc6 +\u044B,6385969a2c52601ac56f8dab121e42f2c3f4cc79567e09eb1e3cefd45b1db261 +\u044C,758610590a4bb6c57fa31bfe8dc305678f9e4aa0968995a3bd426128efedf871 +\u044D,de3f8db3c690cbeb1d6d50de8b54c8462da33c20a4e0f69da0df912886d368b1 +\u044E,3115e99e8f795ce5a3fb389508fe933cb6345b38566505806278999f3adc52dd +\u044F,b13a4eaab76b9d212594a447d8713f36d1739e559140fd7ad08774ec1d4298f2 +\u2190,81c96a5c3d13c3199183e1bc7f086f54ca2a6527126303ac8e25d63e16b64ccf +\u2191,9cdb8f43656c06c4e8683e2e6341b4479f157f48082fea4aff09b37ca3c6995b +\u2192,333ae8de7ed079e38d2c82dd42b74cfcbd94b3480348dbb5ecd93da8b81015e3 +\u2193,61e1e730c77279c8e2e15d8b271a117e5e2ca93d25c8be3a00cc92a00cc0bb85 +\u2196,425d9d5398bd757f2fdec2a62fd0325fa8641e7f788c7f676ec8c6f4b3c529b5 +\u2197,9ef664d506e975349391985c1cd071cea7d4631763e5a2f914fa470cc2bda20a +\u2198,2cfbc163535eb54bfa5830b4f8fa32edba26881da107d61cd7e7bda853280e1c +\u2199,656abb4c74d11bb3ecca9ed4270cdbddeea9705822fd33b94e05c47c3ee56f90 +\u23E9,c920f0d4b2e010e80153a68b45501d054c43bb248f44bb8373640e3235679ac3 +\u23EA,d44af2e8d3980ab8d507257c5b2da1389b7579a6fb4b8dcd8db50d2facd680d6 +\u23F4,fc99aa6fc2ecce35665d948a01325153fe53fc1771fb2784f57967f10e2ddcf8 +\u23F5,a8ae11a9c940c5ac62b905837d21537dbe2f3e5011f0bbbfdc11224b8603dbbd +\u2640,f570ee67722f5a80d1eef4fe3dd018a9fbcadeee51eeb4a92cb558623e728ad6 +\u2642,15df33171dcfdd45ab6a6bdba86c2d0fefc04a6e461af4591f2b58b8267ede68 +\u2648,c75493546982496ea18e4316bd80c759e7089f7cf03e4c905f3e1f462add6e2f +\u2649,75ade7cf0c9b7f68cf8320452aa1f1f79785159f99b78631c9491c13604932ac +\u264A,4e585f6434dba73132c4b3849bb377f4ab5c01330763a8eb9417b6e2d04f9c32 +\u264B,317d2222ce8b5caa261e8b094cd515f6b5e814e98382281041a69eb7d6b49bc3 +\u264C,1a9e06c973ad7ab386c7ad02f2d8590749d2e27500b9d5f1dd1a92a5ce95772d +\u264D,d44af2e8d3980ab8d507257c5b2da1389b7579a6fb4b8dcd8db50d2facd680d6 +\u264E,60a3af187bb8b83e5af566fb6afdcff33e36476fb34b19096f2b57d3312fe292 +\u264F,9f0a53e6a79a4cd8a63585601c6d68da3c3bb9a7e15df16352ae5608cdbc3110 +\u2650,13b20a1acda7e566064eec9acb61428386ec9f5940018338c6d8fed4ddcd6b59 +\u2651,12f08a99474aebcf55402ef6473472cd7acbdcc9ba2f143b8369a0c58c3e0be3 +\u2652,a4c780569b3a4f62a899036dab8bb96fb02b2ab71c5332eaa4b7211765492062 +\u2653,ebf011891fb520da8e419954e007d42367e1c669f5d53b121605e3439da8f1ed +\u2665,caae1743c4cf0c75c916df6102a396bba61a6c40da5eebc6b92d7ad2bc5ef5bf +\u266A,f22e40b4bfbcc0433044d86d67685f0567025904271d0a74996afbe3f9be2c0f \u2713,d2c2260b7027c354865e83c129f2d332ffebdbb85f66469bbf9fd20f3c3c6077 \ No newline at end of file diff --git a/src/main/resources/fonts/red.csv b/IF/src/main/resources/fonts/red.csv similarity index 98% rename from src/main/resources/fonts/red.csv rename to IF/src/main/resources/fonts/red.csv index f95e6f9a..18761f10 100644 --- a/src/main/resources/fonts/red.csv +++ b/IF/src/main/resources/fonts/red.csv @@ -1,118 +1,118 @@ -" ",3cc470ae2631efdfaf967b369413bc2451cd7a39465da7836a6c7a14e877 -!,e7f9c6fef2ad96b3a5465642ba954671be1c4543e2e25e56aef0a47d5f1f -"""",89b5931c12c3f2d387bc429af22e8396921fe2f643a3774374f38ad34b2d -#,34dfd9663c3ee4d341d97faac5fa70d213eafb14813af20d4a425342242142f -$,b856ccab6f72b6f37332840a2779bb42758bbb2c015f54ce53740cb0f1cb4ca1 -%,e1adc213c1b9ac9bc3b17019b3f9537be72eba8a256815a45d43d561429c84f6 -&,f8ae3cc274f5b63718f5fc3d4f865384f3ada6f7016ddc1c146ebc1845d53 -',379ed0b5ecd4c1d808a9eac3b7387d2b9dd87b5d14e1d01a549fc43e33191 -(,82d78b42703adf165f844f7ec9fe4e9c7fa168857cafabd1d8262d3112d3ad -),864393e6489ef1af7899d444ec7cdab2e755d8454dd177683f849bdaabc725 -+,ac731c3c723f67d2cfb1a1192b947086fba32aea472d347a5ed5d7642f73b -",",a6102ae382edd8b2ccbeb83494307c103dace3b3f0f49db7d48e30ab31c5e326 --,4e4b8b8d2362c864e062301487d94d3272a6b570afbf80c2c5b148c954579d46 -.,c554843286108f464a1d6da4c5a4d1b472d660ef37f96c3d579e23e92062537d -/,45afffe7a94e1266a188c8353a19a95be1525527b43f9713cf1347f41555fcd -0,85bd1e613ff32b523ccf9e574cc311b798c2b3a6828f0f71a254c995e6db8e5 -1,8d2454e4c67b323d5be953b5b3d54174aa271460374ee28410c5aeae2c11f5 -2,b13b778c6e5128024214f859b4fadc7738c7be367ee4b9b8dbad7954cff3a -3,031f66be0950588598feeea7e6c6779355e57cc6de8b91a44391b2e9fd72 -4,95bc42c69846c3da9531ac7dba2b55363f8f9472576e17d423b7a9b81c9151 -5,df3f565a88928ee5a9d6843d982d78eae6b41d9077f2a1e526af867d78fb -6,c5da1cb6c4c23710224b4f4e8d6ffcf8b4b55f7fe891c1204af7485cf252a1d8 -7,af4e7a5cf5b5a4d2ff4fb0433b1a68751aa12e9a021d3918e92e219a953b -8,1683440c6447c195aaf764e27a1259219e91c6d8ab6bd89a11ca8d2cc799fa8 -9,f8977adedfa6c81a67f825ea37c4d5aa90dfe3c2a72dd98791f4521e1da36 -:,42d22207011ab35e5d559944967f37c9afb5bdce1e881bae0bc3b62618f6a -;,aa159889a6718456dec6953f762d87130222f2595a7c9714b8d2f67bcca1ac -=,d345e5fce2fcfff78cdac65ed881918c79c38e855ebbc192c97c5784c32d378 -?,4fd5bde994e0a647af1823681a613c2bfc3d9736f889dbf8c3bbba5a13f8ed -[,fee9e656749675e563da71357c1f84967244c420504697293ce878cdb8a36 -\,98c34a2ad2cfe86ca95480a289978760e272f7925beb380c513e9454426e6b -],a888dc3650da47b09c97fe9b77a7c557ad836416e6150bfc7167f369e837 -_,688ff9ae437118dee608031a73420188a13211e528160ebcc3d5d3c544c97 -a,51d383401f77beffcb998c2cf79b7afee23f18c41d8a56affed79bb56e2267a3 -b,d4c4a254bec46e274757c07979f0ddae36c7b365487c8f35ffead4cb2e311b9 -c,78514b21ae9cdf5a33b88298ec5a77f820b869e97cd248ee9791e4d315607e -d,ed68ae3150d81e4c0a9d172bd84c4ff73cdc0b87fee8ec661213468d544483 -e,2f4f251752c7317bb2fb628e4c37c82c60719d909985146b261832152a30ada2 -f,88bbc35213c65109fbd8e90771e4c6db785a9be8e403d29ed8ed2e3dcfb128 -g,185361377215e214a35c96cbaf9db672105afafc9494bbf4ae72aa673c5fe7c -h,4d9e33d743ee342243312291ccdcffd7fcca5bdc8a6a8459ee8e62ce57add7 -i,135c1e44fa6a4ba45c2a34f519aca241d895c5d7883dde07df44fb987748 -j,c7f83144c4ce32e9ea3a448ccc85fd9c9be43c2bf5688ec2dd533a1995661066 -k,e883b5beb4e601c3cbf50505c8bd552e81b996076312cffe27b3cc1a29e3 -l,2d16e9582a48a430e827ef09b715789a72d9fa5b1224a3261c4bbe5cbbc2c -m,116afb385724783947a6052ca2758f9c937cb8130c0eac1a3f068dc55495393 -n,3a1d1f6fec429e7cbabc6965b03285ec5ac918ee6e5c3511aef81f52a848e71 -o,faecedf5b8b0ac3f56192fccb0ade48dc5a043e7e0eea2bcc5f54ad0281f67c9 -p,565f23ddc6e83ab7d0c4aa9c5744af7b96bc739bc83a96cb1f2b18d671f -q,ffa3c3313ea3e2e418e57c9f5cc30b0bcc835b8dffb83beae1c1a6026a6ea -r,35f45c875eff538fcec98f6acc1df2aecae28f4860aecd24e2dbdf13924b327 -s,fdd2cce04674c2c3d5a3a94ff219787a2b459de790a0c01ff29b96729072cd -t,a2c3b2e622712b1495fb95dfcb05eb143b2f2697e6f3c4e4a3d685cf31d4 -u,d2ddeb19b4c1221784e79f5b615e94fbbe742b5b972b3cc8e7f672d42424682c -v,7ca6eabed620fd1c3579dbe6568f7427b32a09f731dc8b745504058c9853449 -w,9b518e0ab30fe82ffc6e5adc43fd2287ccd8fa4715cbc29d89b59b2348b34b -x,beb588b21a6f98ad1ff4e085c552dcb050efc9cab427f46048f18fc803475f7 -y,d88f6ee26fb74c7b2e2ba3e3c4a587216a1fd6cbcc6dff9cd350cb269af93b7 -z,c83ce0872548a9d1eec72e5b195aa99c3b02f665892b9872722acbce21e93 -{,634f9b1d6825c8ecf8979c452dc7604cdc31cbaf9958b0c3b74f1d328be015 -},679d32d134dead923f8dedfbdcf1ad5fcd16b36501afbecc9924af97b3e8 -\u00A1,fbeb2546564af4df7f7f589423f68102dea69cd4466b0583c474e5ac693b2b99 -\u00BF,5e9054704623b1e3dac1839b208b2aaae468092e5e001f7104bc8ac618b71d72 -\u00E4,71e8cb38d0d9b24b1361ad1661a28f0c236d3a4eab3f6a1b13bf764932eca8 -\u00EB,861a7714824fb024a4ac1d379ba8b61b67b517aa9fcede2d81fced59f191d29 -\u00F1,935d6a29dd20d090239fdd4d7f66ed086b95031a6261308425ed660399ba4c38 -\u00F6,b237c6fc0bf78d2e971fd43bd12fe7622fa3c3386116ab93c862ed34e09524 -\u00FC,3ee1201d1da8f13f25a46936f1a98625f17c5509861165556f5ba7c3b2a4d61 -\u0431,a11792c8b907d1438842b928f8e3cdcb38f52802df483fc6d5e247afab74 -\u0433,5561a8f44fc83f87d16f8962d6cea51640b29df6f5282473aa74acf997a1331 -\u0434,f57ff72185a2c12b0e56564f8318f34f460ce97d3d43248472cbbb514907d -\u0436,15488711b226dff8b4b7b9ebc7b5262d3b7a8a9c77c50a857f5bc13b45ee4 -\u0437,9ba72f114b1d2a8b2a7286768af9b2fe23689f332f2ff512b8fed14560dd4f2 -\u0438,3dd72e7056da7abfc6b980553fbd1b42f9ef3acb929b4fc2e1bda161e3d1719 -\u0439,d7f0846aec775dd23aca88d624c7b530f6a6f1e2e58f80e6e4aeecb9acafd1 -\u043B,9f311ad9b528a7667e5d41f34ef1b64257533685084ade234e1af10e982db14 -\u043F,77b5e7c0952d86c494f11ad930cc132fe43d58db7966d24018a55b29f1cb9528 -\u0443,4e6c9a852a75fcc6670a1dcc2117a5e9a5b7272612c9dcef792b8c8b701035 -\u0444,4789e786681579dd1d9f4d11cd81015ac3ac99cf25c8f8ace9946b956222f5 -\u0446,914a4a54f875cf5fd4eeabc4bdbbeca3a9ebf2e30f662e74daa67414682e3c -\u0447,5a1df1a3af605957151eba9ed0ff28e4b3c91e7c773e3453d07943a3cfe2d79 -\u0448,1c6c7a95623ccba5e1e9a267fe7e0d196a7ba6f39ba751aa4d78273646 -\u0449,b62dd83a563b723372e3e9dcdbcc6d99b2ca0d053446ea5539c217e5594e9 -\u044A,3518162b0ab4853d8872159b316a745b1d8d1e723c7a90d67ede112d3eca -\u044B,ed137793ea1185a43a25bc11f8bab8f23c21cc4ab27d31153ab80a28edf6aa -\u044C,d0ace0b09e48d90bdd8184568d5acdfd8cdadbae99be27c5d6717cecb7960 -\u044D,e65b744c30a9b66eba8624b668e9dd538098e3862675141922693be6b4eecf -\u044E,2ca6c6f99538229d868339af69756ebc86c9cca191c624eb9e38065856ab44a -\u044F,fa928c727e3b9213f4b252d275fb766446a8947078c58af3f4b35a11bafc1459 -\u2190,f84f597131bbe25dc058af888cb29831f79599bc67c95c802925ce4afba332fc -\u2191,2d9287616343d833e9e7317159caa2cb3e59745113962c1379052ce478884fa -\u2192,fcfe8845a8d5e635fb87728ccc93895d42b4fc2e6a53f1ba78c845225822 -\u2193,a3852bf616f31ed67c37de4b0baa2c5f8d8fca82e72dbcafcba66956a81c4 -\u2196,314616ad4881c72543a22d8ca67d679ece7b3f84250736d962bd7c0306964 -\u2197,574e65e2f1625b0b2102d6bf3df8264ac43d9d679437a3a42e262d24c4fc -\u2198,b94326b538ed9898710d58e5524726f31303734483d1e5237ee325a8bbe5217 -\u2199,a9dbed522e8de1a681dddd37854ee4267efc48b59917f9a9acb420d6fdb9 -\u23E9,da44945494259bb1e047825c437ea9f848427e07dc2a3abc4669f111cb3b -\u23EA,c49d271c5df84f8a3c8aa5d15427f62839341dab52c619a5987d38fbe18e464 -\u23F4,edf5c2f893bd3f89ca40703ded3e42dd0fbdba6f6768c8789afdff1fa78bf6 -\u23F5,abae89e92ac362635ba3e9fb7c12b7ddd9b38adb11df8aa1aff3e51ac428a4 -\u2640,61e9c97ae807a415758f4a043cdff978fa4e11c0f7885e629373d0c122fea3de -\u2642,5606293bfe74f878b07d7b6cec53bd115a7c4c73e3204f5623d5da9e26f7508f -\u2648,a2d91b4a0527f2fbcfaa34b599ac69c2cda1ef2ce9c7f8bcf9f74b2b193f1ac7 -\u2649,bb13fb9771339f4ebe17ce46fa82280562ea6adf60249a79a1d306d854514148 -\u264A,ff0c9f96a52042cb7599a7545f35ef8592432e3bcd489b81c6e57ab7a36f339c -\u264B,e873f73c098ceb1c1243312f10dd1653f581ed873e508ec882d736d0e03ce0cf -\u264C,bb170afae063d8a4a703c7585a935b2e499fac7a20a03cae3a0fedf1cdd48c67 -\u264D,8e6f062f91e99f68a75268e12494f65356f1840e13050840e8585f7573931a1f -\u264E,39a74600d258ab53c2e6ea246ecc9487789c42f8dae786b032cec18ee66ee3f1 -\u264F,21533d721e31233795c1d8169cf9dd34df14442127d649a2998b99c04ced9eda -\u2650,9996eb2dbc70ab7674fddc862f0a4d41b721bc44b65775ce55f9781b963be7b2 -\u2651,ff2d0a4c13053258dd49cd4f17f111a3a704e031238f4766d49a4bbdb9ed5cd0 -\u2652,8ee129978dadebd8896393e1a13d74f2f4e0882c8ddfb16830e592a4f300e2d3 -\u2653,27b6c9ac6f0e96b646e9cb9c91e6a2311ec4d9e891ebbd5f6ebe430ce48e12e4 -\u2665,b837f3db13a40d4979de77179e18af6e0bc3cc39ea6aba518bb080a6f01a40 -\u266A,36aa41e84f062fa8386e1d7c1a620a39b99a11258290ab3ef15a255d87be040f +" ",3cc470ae2631efdfaf967b369413bc2451cd7a39465da7836a6c7a14e877 +!,e7f9c6fef2ad96b3a5465642ba954671be1c4543e2e25e56aef0a47d5f1f +"""",89b5931c12c3f2d387bc429af22e8396921fe2f643a3774374f38ad34b2d +#,34dfd9663c3ee4d341d97faac5fa70d213eafb14813af20d4a425342242142f +$,b856ccab6f72b6f37332840a2779bb42758bbb2c015f54ce53740cb0f1cb4ca1 +%,e1adc213c1b9ac9bc3b17019b3f9537be72eba8a256815a45d43d561429c84f6 +&,f8ae3cc274f5b63718f5fc3d4f865384f3ada6f7016ddc1c146ebc1845d53 +',379ed0b5ecd4c1d808a9eac3b7387d2b9dd87b5d14e1d01a549fc43e33191 +(,82d78b42703adf165f844f7ec9fe4e9c7fa168857cafabd1d8262d3112d3ad +),864393e6489ef1af7899d444ec7cdab2e755d8454dd177683f849bdaabc725 ++,ac731c3c723f67d2cfb1a1192b947086fba32aea472d347a5ed5d7642f73b +",",a6102ae382edd8b2ccbeb83494307c103dace3b3f0f49db7d48e30ab31c5e326 +-,4e4b8b8d2362c864e062301487d94d3272a6b570afbf80c2c5b148c954579d46 +.,c554843286108f464a1d6da4c5a4d1b472d660ef37f96c3d579e23e92062537d +/,45afffe7a94e1266a188c8353a19a95be1525527b43f9713cf1347f41555fcd +0,85bd1e613ff32b523ccf9e574cc311b798c2b3a6828f0f71a254c995e6db8e5 +1,8d2454e4c67b323d5be953b5b3d54174aa271460374ee28410c5aeae2c11f5 +2,b13b778c6e5128024214f859b4fadc7738c7be367ee4b9b8dbad7954cff3a +3,031f66be0950588598feeea7e6c6779355e57cc6de8b91a44391b2e9fd72 +4,95bc42c69846c3da9531ac7dba2b55363f8f9472576e17d423b7a9b81c9151 +5,df3f565a88928ee5a9d6843d982d78eae6b41d9077f2a1e526af867d78fb +6,c5da1cb6c4c23710224b4f4e8d6ffcf8b4b55f7fe891c1204af7485cf252a1d8 +7,af4e7a5cf5b5a4d2ff4fb0433b1a68751aa12e9a021d3918e92e219a953b +8,1683440c6447c195aaf764e27a1259219e91c6d8ab6bd89a11ca8d2cc799fa8 +9,f8977adedfa6c81a67f825ea37c4d5aa90dfe3c2a72dd98791f4521e1da36 +:,42d22207011ab35e5d559944967f37c9afb5bdce1e881bae0bc3b62618f6a +;,aa159889a6718456dec6953f762d87130222f2595a7c9714b8d2f67bcca1ac +=,d345e5fce2fcfff78cdac65ed881918c79c38e855ebbc192c97c5784c32d378 +?,4fd5bde994e0a647af1823681a613c2bfc3d9736f889dbf8c3bbba5a13f8ed +[,fee9e656749675e563da71357c1f84967244c420504697293ce878cdb8a36 +\,98c34a2ad2cfe86ca95480a289978760e272f7925beb380c513e9454426e6b +],a888dc3650da47b09c97fe9b77a7c557ad836416e6150bfc7167f369e837 +_,688ff9ae437118dee608031a73420188a13211e528160ebcc3d5d3c544c97 +a,51d383401f77beffcb998c2cf79b7afee23f18c41d8a56affed79bb56e2267a3 +b,d4c4a254bec46e274757c07979f0ddae36c7b365487c8f35ffead4cb2e311b9 +c,78514b21ae9cdf5a33b88298ec5a77f820b869e97cd248ee9791e4d315607e +d,ed68ae3150d81e4c0a9d172bd84c4ff73cdc0b87fee8ec661213468d544483 +e,2f4f251752c7317bb2fb628e4c37c82c60719d909985146b261832152a30ada2 +f,88bbc35213c65109fbd8e90771e4c6db785a9be8e403d29ed8ed2e3dcfb128 +g,185361377215e214a35c96cbaf9db672105afafc9494bbf4ae72aa673c5fe7c +h,4d9e33d743ee342243312291ccdcffd7fcca5bdc8a6a8459ee8e62ce57add7 +i,135c1e44fa6a4ba45c2a34f519aca241d895c5d7883dde07df44fb987748 +j,c7f83144c4ce32e9ea3a448ccc85fd9c9be43c2bf5688ec2dd533a1995661066 +k,e883b5beb4e601c3cbf50505c8bd552e81b996076312cffe27b3cc1a29e3 +l,2d16e9582a48a430e827ef09b715789a72d9fa5b1224a3261c4bbe5cbbc2c +m,116afb385724783947a6052ca2758f9c937cb8130c0eac1a3f068dc55495393 +n,3a1d1f6fec429e7cbabc6965b03285ec5ac918ee6e5c3511aef81f52a848e71 +o,faecedf5b8b0ac3f56192fccb0ade48dc5a043e7e0eea2bcc5f54ad0281f67c9 +p,565f23ddc6e83ab7d0c4aa9c5744af7b96bc739bc83a96cb1f2b18d671f +q,ffa3c3313ea3e2e418e57c9f5cc30b0bcc835b8dffb83beae1c1a6026a6ea +r,35f45c875eff538fcec98f6acc1df2aecae28f4860aecd24e2dbdf13924b327 +s,fdd2cce04674c2c3d5a3a94ff219787a2b459de790a0c01ff29b96729072cd +t,a2c3b2e622712b1495fb95dfcb05eb143b2f2697e6f3c4e4a3d685cf31d4 +u,d2ddeb19b4c1221784e79f5b615e94fbbe742b5b972b3cc8e7f672d42424682c +v,7ca6eabed620fd1c3579dbe6568f7427b32a09f731dc8b745504058c9853449 +w,9b518e0ab30fe82ffc6e5adc43fd2287ccd8fa4715cbc29d89b59b2348b34b +x,beb588b21a6f98ad1ff4e085c552dcb050efc9cab427f46048f18fc803475f7 +y,d88f6ee26fb74c7b2e2ba3e3c4a587216a1fd6cbcc6dff9cd350cb269af93b7 +z,c83ce0872548a9d1eec72e5b195aa99c3b02f665892b9872722acbce21e93 +{,634f9b1d6825c8ecf8979c452dc7604cdc31cbaf9958b0c3b74f1d328be015 +},679d32d134dead923f8dedfbdcf1ad5fcd16b36501afbecc9924af97b3e8 +\u00A1,fbeb2546564af4df7f7f589423f68102dea69cd4466b0583c474e5ac693b2b99 +\u00BF,5e9054704623b1e3dac1839b208b2aaae468092e5e001f7104bc8ac618b71d72 +\u00E4,71e8cb38d0d9b24b1361ad1661a28f0c236d3a4eab3f6a1b13bf764932eca8 +\u00EB,861a7714824fb024a4ac1d379ba8b61b67b517aa9fcede2d81fced59f191d29 +\u00F1,935d6a29dd20d090239fdd4d7f66ed086b95031a6261308425ed660399ba4c38 +\u00F6,b237c6fc0bf78d2e971fd43bd12fe7622fa3c3386116ab93c862ed34e09524 +\u00FC,3ee1201d1da8f13f25a46936f1a98625f17c5509861165556f5ba7c3b2a4d61 +\u0431,a11792c8b907d1438842b928f8e3cdcb38f52802df483fc6d5e247afab74 +\u0433,5561a8f44fc83f87d16f8962d6cea51640b29df6f5282473aa74acf997a1331 +\u0434,f57ff72185a2c12b0e56564f8318f34f460ce97d3d43248472cbbb514907d +\u0436,15488711b226dff8b4b7b9ebc7b5262d3b7a8a9c77c50a857f5bc13b45ee4 +\u0437,9ba72f114b1d2a8b2a7286768af9b2fe23689f332f2ff512b8fed14560dd4f2 +\u0438,3dd72e7056da7abfc6b980553fbd1b42f9ef3acb929b4fc2e1bda161e3d1719 +\u0439,d7f0846aec775dd23aca88d624c7b530f6a6f1e2e58f80e6e4aeecb9acafd1 +\u043B,9f311ad9b528a7667e5d41f34ef1b64257533685084ade234e1af10e982db14 +\u043F,77b5e7c0952d86c494f11ad930cc132fe43d58db7966d24018a55b29f1cb9528 +\u0443,4e6c9a852a75fcc6670a1dcc2117a5e9a5b7272612c9dcef792b8c8b701035 +\u0444,4789e786681579dd1d9f4d11cd81015ac3ac99cf25c8f8ace9946b956222f5 +\u0446,914a4a54f875cf5fd4eeabc4bdbbeca3a9ebf2e30f662e74daa67414682e3c +\u0447,5a1df1a3af605957151eba9ed0ff28e4b3c91e7c773e3453d07943a3cfe2d79 +\u0448,1c6c7a95623ccba5e1e9a267fe7e0d196a7ba6f39ba751aa4d78273646 +\u0449,b62dd83a563b723372e3e9dcdbcc6d99b2ca0d053446ea5539c217e5594e9 +\u044A,3518162b0ab4853d8872159b316a745b1d8d1e723c7a90d67ede112d3eca +\u044B,ed137793ea1185a43a25bc11f8bab8f23c21cc4ab27d31153ab80a28edf6aa +\u044C,d0ace0b09e48d90bdd8184568d5acdfd8cdadbae99be27c5d6717cecb7960 +\u044D,e65b744c30a9b66eba8624b668e9dd538098e3862675141922693be6b4eecf +\u044E,2ca6c6f99538229d868339af69756ebc86c9cca191c624eb9e38065856ab44a +\u044F,fa928c727e3b9213f4b252d275fb766446a8947078c58af3f4b35a11bafc1459 +\u2190,f84f597131bbe25dc058af888cb29831f79599bc67c95c802925ce4afba332fc +\u2191,2d9287616343d833e9e7317159caa2cb3e59745113962c1379052ce478884fa +\u2192,fcfe8845a8d5e635fb87728ccc93895d42b4fc2e6a53f1ba78c845225822 +\u2193,a3852bf616f31ed67c37de4b0baa2c5f8d8fca82e72dbcafcba66956a81c4 +\u2196,314616ad4881c72543a22d8ca67d679ece7b3f84250736d962bd7c0306964 +\u2197,574e65e2f1625b0b2102d6bf3df8264ac43d9d679437a3a42e262d24c4fc +\u2198,b94326b538ed9898710d58e5524726f31303734483d1e5237ee325a8bbe5217 +\u2199,a9dbed522e8de1a681dddd37854ee4267efc48b59917f9a9acb420d6fdb9 +\u23E9,da44945494259bb1e047825c437ea9f848427e07dc2a3abc4669f111cb3b +\u23EA,c49d271c5df84f8a3c8aa5d15427f62839341dab52c619a5987d38fbe18e464 +\u23F4,edf5c2f893bd3f89ca40703ded3e42dd0fbdba6f6768c8789afdff1fa78bf6 +\u23F5,abae89e92ac362635ba3e9fb7c12b7ddd9b38adb11df8aa1aff3e51ac428a4 +\u2640,61e9c97ae807a415758f4a043cdff978fa4e11c0f7885e629373d0c122fea3de +\u2642,5606293bfe74f878b07d7b6cec53bd115a7c4c73e3204f5623d5da9e26f7508f +\u2648,a2d91b4a0527f2fbcfaa34b599ac69c2cda1ef2ce9c7f8bcf9f74b2b193f1ac7 +\u2649,bb13fb9771339f4ebe17ce46fa82280562ea6adf60249a79a1d306d854514148 +\u264A,ff0c9f96a52042cb7599a7545f35ef8592432e3bcd489b81c6e57ab7a36f339c +\u264B,e873f73c098ceb1c1243312f10dd1653f581ed873e508ec882d736d0e03ce0cf +\u264C,bb170afae063d8a4a703c7585a935b2e499fac7a20a03cae3a0fedf1cdd48c67 +\u264D,8e6f062f91e99f68a75268e12494f65356f1840e13050840e8585f7573931a1f +\u264E,39a74600d258ab53c2e6ea246ecc9487789c42f8dae786b032cec18ee66ee3f1 +\u264F,21533d721e31233795c1d8169cf9dd34df14442127d649a2998b99c04ced9eda +\u2650,9996eb2dbc70ab7674fddc862f0a4d41b721bc44b65775ce55f9781b963be7b2 +\u2651,ff2d0a4c13053258dd49cd4f17f111a3a704e031238f4766d49a4bbdb9ed5cd0 +\u2652,8ee129978dadebd8896393e1a13d74f2f4e0882c8ddfb16830e592a4f300e2d3 +\u2653,27b6c9ac6f0e96b646e9cb9c91e6a2311ec4d9e891ebbd5f6ebe430ce48e12e4 +\u2665,b837f3db13a40d4979de77179e18af6e0bc3cc39ea6aba518bb080a6f01a40 +\u266A,36aa41e84f062fa8386e1d7c1a620a39b99a11258290ab3ef15a255d87be040f \u2713,ff9d9de62ecae9b798555fd23e8ca35e2605291939c1862fe79066698c9508a7 \ No newline at end of file diff --git a/src/main/resources/fonts/spruce-planks.csv b/IF/src/main/resources/fonts/spruce-planks.csv similarity index 98% rename from src/main/resources/fonts/spruce-planks.csv rename to IF/src/main/resources/fonts/spruce-planks.csv index 66c5bc3b..c8dd72ee 100644 --- a/src/main/resources/fonts/spruce-planks.csv +++ b/IF/src/main/resources/fonts/spruce-planks.csv @@ -1,118 +1,118 @@ -" ",f61474ca5d461e0f19da2c5a8cea3f18442590b939d1d995785573c84aa16 -!,b319fce475cd84e2e589d72d4196c03342a421998d4dddd7459c614f4ad6 -"""",55a370f99fec9f7a2b2e8635da6ff650cea7853b1ad5183b66d7a335446b2c -#,372e9e2642bdc7d5caad8994a871beda5bc3fda07c8aad6966dcf27fa8257980 -$,13b0255fac1bfbc99d4faef5f8b5aa14577fd003b2a34c7e50feefeec89d8e50 -%,7b4d29157686a3ece4b140b98f1484deac96719a3e3bc1fac56e0fd5c6515d -&,7695ba1a42fcf9304f303dfc67717f6c7b68bace70f3b794872454ec563766c6 -',41979eaf3c77b3ead6ab31d8e2d222bbe42a7542a9555a855dfc882e6311b847 -(,1aeea7a78980858067edce3b0651b6b9a7a2f43903182d2745fa0e8fdfc5e -),6a9bc31ac9f4abb8c91786d245b38737d0295a577128e72d606665482a3e30d3 -+,2f4812e91da610c0d17a19de8d6c7deefb104d4f439e6ac178db4e4fc23fb7cb -",",aecc4ed04a64bb65395f6e8963746ba50658e52cfcc3ec65be05fe053614d --,e88ae765a5f4c190ff2c65bce43f52accdee90e2ed5e15bd37688975a5641 -.,eddd976a37a30b6651ef6ca3cdea28349d6f539e4907cd97e625a254bcff4 -/,d3a3153a47c99e5935cdf298e13dc9d82042de46b56d345d5a583a6174b47 -0,1ebfa2f9692975ae4ad3a3fe98859f4acf9993a2397171ead34a8530746030 -1,5506ee0e382a2891eb1a3322a1c886c9d97c3485fbc127b33689fc1283e71c -2,c3cf2c1523f5e91c3bdab076b395a1b381121ca1c0b42ae6783fb7ce518a -3,42cd2bff21f6918ea7da41833d99a0bdb019aca2a67e5dc20f1a17a61b3d62a -4,dacc5994884573dbc6cd7b503cc55b733b18b85a1aea5f401c065326cc3c3f -5,6415a5b9f471be6e261f6bb5a080d6661acc34d493afa37d7815f6607819402e -6,496e2a3fe1ed64436e8d60b9f999ff38701ac13b14510dacbf0704060fb2a -7,86a51b9374e6dbceaa17337d3bd833f7dba611fc36965d98c1dd2b587cacec -8,76c76f62cb6b557497f322ff95372e4518ca7d9879b76d46da9ee01a3cabe94f -9,ce9af5566da02ac460a8349f9a558ba160478183f1cf5cfa9be639bb60582 -:,e98aa5c5e1c41681ffa6742b5c7d8d916e52722f68fd7279e3ebb62d23537354 -;,40d5de81c778c04d59621650ea31dc9a8b93f3a824272553c5176b4224931f -=,833033ebf781ca375a749557530f4a9b299a382d6999c34bc3ebc55f088151 -?,dbaddad9caceb05f34bdcf32937b95d2c44dd7444a15f76a9385c328fcab -[,ca4b229ac84eb891a1388df32acea887ddbc552b6303619eced7c2fe1f2db -\,d4e926edb65e9a908bad541060dc32195ff697b8793227c1d3b354d89a1fd9b5 -],37e9b46b61df2516d67bc5546dec21766acae5d22cb0f28f29a49a42a845c -_,688749ce6e7fcd1930bc4c50ea7ccdb3309dc9384585db8bb42aec1f59a6d2 -a,ed844802203334898599fb82b8bf924aaa6958a3dd3041d7acfc979953969 -b,ec7b8c93c5aff33c3d86da16128c9d92d6c0d627ba9df8075a411f5a05263b9 -c,98b760d571c5c76f2b421126fe5f3b76323863fcf5f106c8fad359c411caf8b -d,d9ae68a8d21cf9e465354431b85a2bec07f5134c26040541cac747498a58a -e,dced3ee8ac7241e046e133a7426cee1a1f645ad645178243f1a92995183120dd -f,4b277e5f92a444ba386450bfcf425f8c29d29e3c5076482278e276e41a8164c1 -g,44df70d6a60d8eff8c41f604eb5462ed66dcba7fa2a473e9dd9939d8fd44ddd -h,f15478aee2ac3fdc43b6b6d275ecef7913782d513f944b40cd6252983b539c -i,6bd2313353dccc08daea24b1a94a89f1bb19c692ac1cafee1bb698fc5f0 -j,fee48f2524b02cc8f58caf9485480fc704c698568cfd870fa2d9eb275c12a85 -k,ca95a74179cfb938762faf41812fd8d8c60c8cce5bab1987aace5faefeebb2 -l,f05e46e06e5a63987594ac5d6617c18da531f638ed3e60c25289e6918276 -m,b94dd9cc906d77c5534779b69483b650b683db67257b9f3e4eef56f488aed54 -n,b9acb8a6457f8183b153f6b3c52454b95f664eda13c6572a09b4778591a631f -o,feef3d1cbdd569d462378590af95269dc7835358fb41fa07e66a687dabf82f -p,efea725d2c84a3cd52f06a26e1b6e467412da9cb7b9ba238f51de81d9a0c8a0 -q,b33522ff7f44c27388ced09233203ab45512244c16f53e41d485e5bd8cf0f3cb -r,e8dbab9bf5ee532a7cc22323303548d5fa344a0bcd02a2da6451fb99c8174 -s,eb1ada587d5d8b4035edd031fd5dbaf44e2efd462cd9c7f7e58f0b1d817bc -t,8ac74c17ac4e538428e2abb8e1d238d02331a956ca4bb5827ed6d4bc3d19149a -u,c269feccc2b28a7f3e0f990e92ef35b72933d21893c13e7c9a77f2a78423e -v,7236a963d9bd60a2a24a5625ffbe309ab6ebce6930c3227da042e43ff7d3cc -w,a71d93cc35eacbc74378a9a193fffa7a5820b87aaf28f79d392143708ff5cc -x,5b30507783c37db3a3092cad043e57951aa8b4c6ea9acc47d604b7eb5aea028 -y,a0b8a78dcb85ca359e2dd26dd8504a58df5a47a9bea12338ecf6a03120a0 -z,5ddae1142a117e5c128f5f46f03e65f0ff34f2bb43d7fa5659360426f5ab5a2 -{,c3f84f42cfee67557834e4261574db4f215143672e26e709a80132a2dffdc -},9c4827f138ecd6b596fe4065d68527954df6ec65f55e6189b1b2e151d6f9d58b -\u00A1,82b6d19bd04a13147a2343032f9670b4f375ee0a2c70f7581c02ecbc84267311 -\u00BF,13a67a8821c8a9bf7ff54b08f9ea6e988e5f7e7b77a0f36f0bde3d147b7d0505 -\u00E4,5b8a54715962d264e5358c699989b50ff298cb54c06ebb14e5b2b6e23aeb1e -\u00EB,8a11e1d4799365a169d81d1b992082ab9169b28a6732f3566a6f9d476789868 -\u00F1,5ebca5108b66837f575526028d9f84febe63f6dbf8b750e768ad61be41a1a1a0 -\u00F6,1360243bd2bd996cbb316a85f99b98dbc8f2ccd9c1a8e53b4b42c630ee96e3d4 -\u00FC,1e69addc2d868e66338e62c9812aab9f977ba51d7d1fac21ff582bf37e7 -\u0431,30eb76837359a65b9f423ad817d652e7a298d5287c9bb4e6b4988a60bdf3d0 -\u0433,8eddebc33235de639b2fa4fef76bc532e1ee941c593c7e3c1a8014806eef11 -\u0434,9d3029e993c170b340531a5e628a92ccf5191257c369c3f5a6ea4cbdbb30a3 -\u0436,225c2167f74b28f2b9c652db021d49acd925c3b9b3d444acd6d53485feb45c -\u0437,e74acd6a38eda58d0990b0a88953a3dc8dc797d1183d641d10b15384cbb6c5 -\u0438,d24f792f1ce230d38017ede03e5308f1575ad3a537db19d952d42aaa3fbac -\u0439,23d319f7950c684e43525fbf957566c4619f597675672744f4e5f34d89719 -\u043B,1874c2231f9a27e67dcee2be4254458ec84afb985b54715ec4a44be1c21e9 -\u043F,a7a691292cacf5e453146c95d56ab49adeecc2f82938171a24c3752b79ff4e -\u0443,a44966cef5afbf64be74c463be42532ec71d0d2e786e92e9394f60fc7879e -\u0444,64cb8d5f90fc823a2d748af926c6e07d384a2dbe9b862977a0b535a55dbc2eb6 -\u0446,5d556c562d4793d7ccd87ba158a5033861f7992cee8bca727f9941e8209577 -\u0447,5a22dc1ec0fad586edb8ff53d414ba4c3f130142d11444efc6de025af21c0 -\u0448,531b7e54c843c3e8d71ea2db604e7fd5ff6d5e8f38551f9fba268986dcd146 -\u0449,69df5afe60bacb85a5b7d4cb7bc853999181a33612d1f8518bea87b2481a91 -\u044A,659d51af4f2755b650a0980643accfe4758b4f4ba128fe9bab23c68c295289 -\u044B,c67479a1fbfbfa6d32eee5dee2a89d9214927137e11c46ed1f58c6645a923b -\u044C,a0ea331c2527859b8326331b5487443140cb426080d13cc9151a64aa5619e -\u044D,f1e83b19407c969b2b19454d2653fda519301d8c8b7caa67aa77c254ed6748a -\u044E,16c79bff21b9ecf62632092c33c6073c8472b76daa764824637d761fc3f5 -\u044F,9e9fa38ebdbe3d4b8eeb4fc82334c982426f138e858f728b0b0698ab785d0c4 -\u2190,d59be1557201c7ff1a0b3696d19eab4104880d6a9cdb4d5fa21b6daa9db2d1 -\u2191,365fc0426230a2e88df29d2d8ec4512e6dbdbc0777b4b83cdda2ede81864d6 -\u2192,42b0c07fa0e89237d679e13116b5aa75aebb34e9c968c6badb251e127bdd5b1 -\u2193,4e8ba7863b15a5e40fa7da9629bb866aa22699553e931df1f693cbb1c9f3b6 -\u2196,b6e14f2b7d1f5cb6f56ab3e6881fc8490eda6ff2d1d48a3241d147223cb3 -\u2197,370a90a159d79854cdeca5cd4b1b633984a0bc1c9f187d8397f584f614a -\u2198,d8bbf1ecacfac5fa8ed74129b8edf1f4e88fc9a86f82a028aa94aeb9f17937 -\u2199,bc192bdaa1a9a452857732ad3f0d12f548c02bee8e4bdcf33be884cf50f9f6 -\u23E9,b79264185ece225c4073596b667f6da3326a3881a09399e79f5c9962378e64 -\u23EA,f0b2425913d2c4bafbbbfdb556c65fff6238c95486a41432e9fd5a27dfbfa67c -\u23F4,b3295a9f11478e6b789bf6eb06296e016c127d0a627f354fec26c27f46d417 -\u23F5,6bb0c63d5afc325856625b855ff2461f1560b3d1a74a1e4619e624069c5b962 -\u2640,84b7cd56ced6a9be67cc863c53a8172101c4190a90f8dd6bf40180f77f1b2377 -\u2642,4b13d31b82197aeaf829bf45506b7175a9aa9af291e7b7b35ac7bc75b4a249c1 -\u2648,ae9f3de67c0fdd867736de23b26bb7912ce5fa5c4b891b79fbe998f048ec52fa -\u2649,99a4c731c3d65217bce3d36b21f8d4e65f9262526716ff159693cc10bc71313a -\u264A,164cb551e7afae4dc14c2e83e3dfa5aedde2dd4faa262d24a62b526158ecc319 -\u264B,c83cb3aa3d6b1e9fe244852e89449ddd46432d13ceae2c6c0a77cb9846806612 -\u264C,d57526b703b1265c5b7884de8ee0e099aac2cd95857c11740f7b0995c2ea42a9 -\u264D,db4fcb653140a2dce76f43d7bdc45c9b910762badf09603b92e49b0d3340a8bf -\u264E,e5664c7805fbdf0cab78039d80920b9c58f0d81f1824491f23e07bc697652aef -\u264F,7c6f607970f0395885d4eea7b504a9903063c331121ad4d8605abb800922afdd -\u2650,c3dcccb6ba736a3ebf71ca00e057267efba748c6b9bcef2a6c9e5bdb5db76ee8 -\u2651,1c2fb7f86acfdc562bb50a532a82bae256ecb5bdb1f3cbfba548aea1f6c87ca5 -\u2652,2953fc3655de28bee1cd3bc13fe13d606325590b11b4ae0ac84612b225464128 -\u2653,353237e6eaa2bc0b729dca18084076c03a81bf199b0758f76e6806442701543d -\u2665,8ea6848c5931d3967f58c3eda2555c72c716df9a1da3d2dd6bc63c16cd17b5eb -\u266A,4606922e907d4a4fde41a6e994941d41d41c42784ee6244c3e45761fa2516ed7 +" ",f61474ca5d461e0f19da2c5a8cea3f18442590b939d1d995785573c84aa16 +!,b319fce475cd84e2e589d72d4196c03342a421998d4dddd7459c614f4ad6 +"""",55a370f99fec9f7a2b2e8635da6ff650cea7853b1ad5183b66d7a335446b2c +#,372e9e2642bdc7d5caad8994a871beda5bc3fda07c8aad6966dcf27fa8257980 +$,13b0255fac1bfbc99d4faef5f8b5aa14577fd003b2a34c7e50feefeec89d8e50 +%,7b4d29157686a3ece4b140b98f1484deac96719a3e3bc1fac56e0fd5c6515d +&,7695ba1a42fcf9304f303dfc67717f6c7b68bace70f3b794872454ec563766c6 +',41979eaf3c77b3ead6ab31d8e2d222bbe42a7542a9555a855dfc882e6311b847 +(,1aeea7a78980858067edce3b0651b6b9a7a2f43903182d2745fa0e8fdfc5e +),6a9bc31ac9f4abb8c91786d245b38737d0295a577128e72d606665482a3e30d3 ++,2f4812e91da610c0d17a19de8d6c7deefb104d4f439e6ac178db4e4fc23fb7cb +",",aecc4ed04a64bb65395f6e8963746ba50658e52cfcc3ec65be05fe053614d +-,e88ae765a5f4c190ff2c65bce43f52accdee90e2ed5e15bd37688975a5641 +.,eddd976a37a30b6651ef6ca3cdea28349d6f539e4907cd97e625a254bcff4 +/,d3a3153a47c99e5935cdf298e13dc9d82042de46b56d345d5a583a6174b47 +0,1ebfa2f9692975ae4ad3a3fe98859f4acf9993a2397171ead34a8530746030 +1,5506ee0e382a2891eb1a3322a1c886c9d97c3485fbc127b33689fc1283e71c +2,c3cf2c1523f5e91c3bdab076b395a1b381121ca1c0b42ae6783fb7ce518a +3,42cd2bff21f6918ea7da41833d99a0bdb019aca2a67e5dc20f1a17a61b3d62a +4,dacc5994884573dbc6cd7b503cc55b733b18b85a1aea5f401c065326cc3c3f +5,6415a5b9f471be6e261f6bb5a080d6661acc34d493afa37d7815f6607819402e +6,496e2a3fe1ed64436e8d60b9f999ff38701ac13b14510dacbf0704060fb2a +7,86a51b9374e6dbceaa17337d3bd833f7dba611fc36965d98c1dd2b587cacec +8,76c76f62cb6b557497f322ff95372e4518ca7d9879b76d46da9ee01a3cabe94f +9,ce9af5566da02ac460a8349f9a558ba160478183f1cf5cfa9be639bb60582 +:,e98aa5c5e1c41681ffa6742b5c7d8d916e52722f68fd7279e3ebb62d23537354 +;,40d5de81c778c04d59621650ea31dc9a8b93f3a824272553c5176b4224931f +=,833033ebf781ca375a749557530f4a9b299a382d6999c34bc3ebc55f088151 +?,dbaddad9caceb05f34bdcf32937b95d2c44dd7444a15f76a9385c328fcab +[,ca4b229ac84eb891a1388df32acea887ddbc552b6303619eced7c2fe1f2db +\,d4e926edb65e9a908bad541060dc32195ff697b8793227c1d3b354d89a1fd9b5 +],37e9b46b61df2516d67bc5546dec21766acae5d22cb0f28f29a49a42a845c +_,688749ce6e7fcd1930bc4c50ea7ccdb3309dc9384585db8bb42aec1f59a6d2 +a,ed844802203334898599fb82b8bf924aaa6958a3dd3041d7acfc979953969 +b,ec7b8c93c5aff33c3d86da16128c9d92d6c0d627ba9df8075a411f5a05263b9 +c,98b760d571c5c76f2b421126fe5f3b76323863fcf5f106c8fad359c411caf8b +d,d9ae68a8d21cf9e465354431b85a2bec07f5134c26040541cac747498a58a +e,dced3ee8ac7241e046e133a7426cee1a1f645ad645178243f1a92995183120dd +f,4b277e5f92a444ba386450bfcf425f8c29d29e3c5076482278e276e41a8164c1 +g,44df70d6a60d8eff8c41f604eb5462ed66dcba7fa2a473e9dd9939d8fd44ddd +h,f15478aee2ac3fdc43b6b6d275ecef7913782d513f944b40cd6252983b539c +i,6bd2313353dccc08daea24b1a94a89f1bb19c692ac1cafee1bb698fc5f0 +j,fee48f2524b02cc8f58caf9485480fc704c698568cfd870fa2d9eb275c12a85 +k,ca95a74179cfb938762faf41812fd8d8c60c8cce5bab1987aace5faefeebb2 +l,f05e46e06e5a63987594ac5d6617c18da531f638ed3e60c25289e6918276 +m,b94dd9cc906d77c5534779b69483b650b683db67257b9f3e4eef56f488aed54 +n,b9acb8a6457f8183b153f6b3c52454b95f664eda13c6572a09b4778591a631f +o,feef3d1cbdd569d462378590af95269dc7835358fb41fa07e66a687dabf82f +p,efea725d2c84a3cd52f06a26e1b6e467412da9cb7b9ba238f51de81d9a0c8a0 +q,b33522ff7f44c27388ced09233203ab45512244c16f53e41d485e5bd8cf0f3cb +r,e8dbab9bf5ee532a7cc22323303548d5fa344a0bcd02a2da6451fb99c8174 +s,eb1ada587d5d8b4035edd031fd5dbaf44e2efd462cd9c7f7e58f0b1d817bc +t,8ac74c17ac4e538428e2abb8e1d238d02331a956ca4bb5827ed6d4bc3d19149a +u,c269feccc2b28a7f3e0f990e92ef35b72933d21893c13e7c9a77f2a78423e +v,7236a963d9bd60a2a24a5625ffbe309ab6ebce6930c3227da042e43ff7d3cc +w,a71d93cc35eacbc74378a9a193fffa7a5820b87aaf28f79d392143708ff5cc +x,5b30507783c37db3a3092cad043e57951aa8b4c6ea9acc47d604b7eb5aea028 +y,a0b8a78dcb85ca359e2dd26dd8504a58df5a47a9bea12338ecf6a03120a0 +z,5ddae1142a117e5c128f5f46f03e65f0ff34f2bb43d7fa5659360426f5ab5a2 +{,c3f84f42cfee67557834e4261574db4f215143672e26e709a80132a2dffdc +},9c4827f138ecd6b596fe4065d68527954df6ec65f55e6189b1b2e151d6f9d58b +\u00A1,82b6d19bd04a13147a2343032f9670b4f375ee0a2c70f7581c02ecbc84267311 +\u00BF,13a67a8821c8a9bf7ff54b08f9ea6e988e5f7e7b77a0f36f0bde3d147b7d0505 +\u00E4,5b8a54715962d264e5358c699989b50ff298cb54c06ebb14e5b2b6e23aeb1e +\u00EB,8a11e1d4799365a169d81d1b992082ab9169b28a6732f3566a6f9d476789868 +\u00F1,5ebca5108b66837f575526028d9f84febe63f6dbf8b750e768ad61be41a1a1a0 +\u00F6,1360243bd2bd996cbb316a85f99b98dbc8f2ccd9c1a8e53b4b42c630ee96e3d4 +\u00FC,1e69addc2d868e66338e62c9812aab9f977ba51d7d1fac21ff582bf37e7 +\u0431,30eb76837359a65b9f423ad817d652e7a298d5287c9bb4e6b4988a60bdf3d0 +\u0433,8eddebc33235de639b2fa4fef76bc532e1ee941c593c7e3c1a8014806eef11 +\u0434,9d3029e993c170b340531a5e628a92ccf5191257c369c3f5a6ea4cbdbb30a3 +\u0436,225c2167f74b28f2b9c652db021d49acd925c3b9b3d444acd6d53485feb45c +\u0437,e74acd6a38eda58d0990b0a88953a3dc8dc797d1183d641d10b15384cbb6c5 +\u0438,d24f792f1ce230d38017ede03e5308f1575ad3a537db19d952d42aaa3fbac +\u0439,23d319f7950c684e43525fbf957566c4619f597675672744f4e5f34d89719 +\u043B,1874c2231f9a27e67dcee2be4254458ec84afb985b54715ec4a44be1c21e9 +\u043F,a7a691292cacf5e453146c95d56ab49adeecc2f82938171a24c3752b79ff4e +\u0443,a44966cef5afbf64be74c463be42532ec71d0d2e786e92e9394f60fc7879e +\u0444,64cb8d5f90fc823a2d748af926c6e07d384a2dbe9b862977a0b535a55dbc2eb6 +\u0446,5d556c562d4793d7ccd87ba158a5033861f7992cee8bca727f9941e8209577 +\u0447,5a22dc1ec0fad586edb8ff53d414ba4c3f130142d11444efc6de025af21c0 +\u0448,531b7e54c843c3e8d71ea2db604e7fd5ff6d5e8f38551f9fba268986dcd146 +\u0449,69df5afe60bacb85a5b7d4cb7bc853999181a33612d1f8518bea87b2481a91 +\u044A,659d51af4f2755b650a0980643accfe4758b4f4ba128fe9bab23c68c295289 +\u044B,c67479a1fbfbfa6d32eee5dee2a89d9214927137e11c46ed1f58c6645a923b +\u044C,a0ea331c2527859b8326331b5487443140cb426080d13cc9151a64aa5619e +\u044D,f1e83b19407c969b2b19454d2653fda519301d8c8b7caa67aa77c254ed6748a +\u044E,16c79bff21b9ecf62632092c33c6073c8472b76daa764824637d761fc3f5 +\u044F,9e9fa38ebdbe3d4b8eeb4fc82334c982426f138e858f728b0b0698ab785d0c4 +\u2190,d59be1557201c7ff1a0b3696d19eab4104880d6a9cdb4d5fa21b6daa9db2d1 +\u2191,365fc0426230a2e88df29d2d8ec4512e6dbdbc0777b4b83cdda2ede81864d6 +\u2192,42b0c07fa0e89237d679e13116b5aa75aebb34e9c968c6badb251e127bdd5b1 +\u2193,4e8ba7863b15a5e40fa7da9629bb866aa22699553e931df1f693cbb1c9f3b6 +\u2196,b6e14f2b7d1f5cb6f56ab3e6881fc8490eda6ff2d1d48a3241d147223cb3 +\u2197,370a90a159d79854cdeca5cd4b1b633984a0bc1c9f187d8397f584f614a +\u2198,d8bbf1ecacfac5fa8ed74129b8edf1f4e88fc9a86f82a028aa94aeb9f17937 +\u2199,bc192bdaa1a9a452857732ad3f0d12f548c02bee8e4bdcf33be884cf50f9f6 +\u23E9,b79264185ece225c4073596b667f6da3326a3881a09399e79f5c9962378e64 +\u23EA,f0b2425913d2c4bafbbbfdb556c65fff6238c95486a41432e9fd5a27dfbfa67c +\u23F4,b3295a9f11478e6b789bf6eb06296e016c127d0a627f354fec26c27f46d417 +\u23F5,6bb0c63d5afc325856625b855ff2461f1560b3d1a74a1e4619e624069c5b962 +\u2640,84b7cd56ced6a9be67cc863c53a8172101c4190a90f8dd6bf40180f77f1b2377 +\u2642,4b13d31b82197aeaf829bf45506b7175a9aa9af291e7b7b35ac7bc75b4a249c1 +\u2648,ae9f3de67c0fdd867736de23b26bb7912ce5fa5c4b891b79fbe998f048ec52fa +\u2649,99a4c731c3d65217bce3d36b21f8d4e65f9262526716ff159693cc10bc71313a +\u264A,164cb551e7afae4dc14c2e83e3dfa5aedde2dd4faa262d24a62b526158ecc319 +\u264B,c83cb3aa3d6b1e9fe244852e89449ddd46432d13ceae2c6c0a77cb9846806612 +\u264C,d57526b703b1265c5b7884de8ee0e099aac2cd95857c11740f7b0995c2ea42a9 +\u264D,db4fcb653140a2dce76f43d7bdc45c9b910762badf09603b92e49b0d3340a8bf +\u264E,e5664c7805fbdf0cab78039d80920b9c58f0d81f1824491f23e07bc697652aef +\u264F,7c6f607970f0395885d4eea7b504a9903063c331121ad4d8605abb800922afdd +\u2650,c3dcccb6ba736a3ebf71ca00e057267efba748c6b9bcef2a6c9e5bdb5db76ee8 +\u2651,1c2fb7f86acfdc562bb50a532a82bae256ecb5bdb1f3cbfba548aea1f6c87ca5 +\u2652,2953fc3655de28bee1cd3bc13fe13d606325590b11b4ae0ac84612b225464128 +\u2653,353237e6eaa2bc0b729dca18084076c03a81bf199b0758f76e6806442701543d +\u2665,8ea6848c5931d3967f58c3eda2555c72c716df9a1da3d2dd6bc63c16cd17b5eb +\u266A,4606922e907d4a4fde41a6e994941d41d41c42784ee6244c3e45761fa2516ed7 \u2713,a94965d84f21c02a0b62dc949141af4307aae0b58bad53231c3db7e51c947011 \ No newline at end of file diff --git a/src/main/resources/fonts/stone.csv b/IF/src/main/resources/fonts/stone.csv similarity index 98% rename from src/main/resources/fonts/stone.csv rename to IF/src/main/resources/fonts/stone.csv index 0abda39c..71d7b7d4 100644 --- a/src/main/resources/fonts/stone.csv +++ b/IF/src/main/resources/fonts/stone.csv @@ -1,118 +1,118 @@ -" ",8e646d878591c58c39f2d7a1daf01e1144544d465977eba5c3fe743b9fcf140 -!,87d19aabfcfd99ffaba4214caef299516ce52e6d13bf2dda125985e481b72f9 -"""",152b40d3e786c4ebe36d9c41dcf5412b0ddb198db67bed1aa6f4797fff23e5 -#,944c4df7e17db3c7e996cc67b17e8f8a97d62c81fe32f852e1a4779a9fc588b8 -$,1f5e36aba86644b7399188a4bc69f8a49ece1de1fb2c0b17b8211b49f224108c -%,685be76de28ddcb39d283e3d71f6ed63de854f839623ec18a5380c84f1c25f9 -&,bba18d5132777969cf61653c31d2ace8524b10484dcb6706595f8f16b72e -',8ab7e099af20b431894d46d3145e549a8bcf1e21f7559b20cf2239136d55c1 -(,86e067947cf2c9a366504838b768c41663b7bfc1f34c2b5b2c6ac1ce561a9bb -),66b1fed8e8101a749b7d4db0f3f75b980b759e545eb65e336c90c5d1fa17 -+,0a21eb4c57750729a48b88e9bbdb987eb6250a5bc2157b59316f5f1887db5 -",",e85b4618c19e3f91e9b14b4fb9b08ce160ebd5b5a712f4056ef8b3dec9c62 --,a8c67fed7a2472b7e9afd8d772c13db7b82c32ceeff8db977474c11e4611 -.,6ff99ff279a2cf25deb4bd5b66c3576b824cc96c36781027af727ed3a4c1308e -/,2d593f0945cbb85a8e0be7d9a526010ee774810f2bc428cd4a23e4d232eff8 -0,55a224807693978ed834355f9e5145f9c56ef68cf6f2c9e1734a46e246aae1 -1,31a9463fd3c433d5e1d9fec6d5d4b09a83a970b0b74dd546ce67a73348caab -2,acb419d984d8796373c9646233c7a02664bd2ce3a1d3476dd9b1c5463b14ebe -3,f8ebab57b7614bb22a117be43e848bcd14daecb50e8f5d0926e4864dff470 -4,62bfcfb489da867dce96e3c3c17a3db7c79cae8ac1f9a5a8c8ac95e4ba3 -5,ef4ecf110b0acee4af1da343fb136f1f2c216857dfda6961defdbee7b9528 -6,f331a6a6fcd6995b62088d353bfb68d9b89ae258325caf3f2886464f54a7329 -7,d4ba6ac07d422377a855793f36dea2ed240223f52fd1648181612ecd1a0cfd5 -8,c61a8a641437be9aea207253dd3f25440d954ea2b5866c552f386b29ac4d049 -9,a1928e1bfd86a9b79397c4cb4b65ef99af49b7d5f7957ad62c0c699a622cfbe -:,bd898c40e47c5d2d76924065360768065d624ee5b9ee0be9e12b98fb77c76 -;,c565949039f159651dd6ddbe1598ca3282acecd23ed80bab26efada4ce9c13 -=,4fd1fc30fa578163ca65c59e2ffdecaceb846c0f219c12bc3e1012b8a9c3bf -?,d23eaefbd581159384274cdbbd576ced82eb72423f2ea887124f9ed33a6872c -[,5f3ae18d9afd7c3f60f5ba5e5c40f9ac1129eb5889581ccb71bba32e517a -\,39b9e4afcff695c27f3491584a99673b6a4766870dea6b22bee9d5e2bee3710 -],1f301c8ec7e50cb8464b55ac53ef8e132eb7f59b244bdd6cba30719b517187 -_,4f2fae2e35447de1835322f61ef7c790707971e6aafbba5f6b92681f7a2f58d6 -a,2ac58b1a3b53b9481e317a1ea4fc5eed6bafca7a25e741a32e4e3c2841278c -b,d4c711571e7e214ee78dfe4ee0e1263b92516e418de8fc8f3257ae0901431 -c,fff5aabead6feafaaecf4422cdd7837cbb36b03c9841dd1b1d2d3edb7825e851 -d,893e622b581975792f7c119ec6f40a4f16e552bb98776b0c7ae2bdfd4154fe7 -e,a157d65b19921c760ff4910b3404455b9c2ee36afc202d8538baefec676953 -f,c54cf261b2cd6ab54b0c624f8f6ff565a7b63e28e3b50c6dbfb52b5f0d7cf9f -g,d3c9f8a74ca01ba8c54de1edc82e1fc07a83923e66574b6ffe606919240c6 -h,f8c58c509034617bf81ee0db9be0ba3e85ca15568163914c87669edb2fd7 -i,4246323c9fb319326ee2bf3f5b63ec3d99df76a12439bf0b4c3ab32d13fd9 -j,c58456cd9bb8a7e978591ae0cb26af1aadad4fa7a16725b295145e09bed8064 -k,af49fb708369e7bc2944ad706963fb6ac6ce6d4c67081ddadecfe5da51 -l,8c84f75416e853a74f6c70fc7e1093d53961879955b433bd8c7c6d5a6df -m,31fde91b19b9309913724fea9e85311271c67bcb78578d461bf65d9613074 -n,1c7c972e6785d6b0aceb779abdd7702d98341c24c2a71e702930eca58055 -o,8073bb44f9345f9bb31a679027e7939e461842a8c27486d7a6b842c39eb38c4e -p,64b231a8d55870cfb5a9f4e65db06dd7f8e34282f1416f95878b19acc34ac95 -q,ffedd6f9efdb156b86935699b2b4834df0f5d214513c01d38af3bd031cbcc92 -r,c03a1cd583cbbffde08f943e56ac3e3afafecaede834221a81e6db6c64667f7d -s,b6572e655725d78375a9817eb9ee8b37829ca1fea93b6095cc7aa19e5eac -t,708c9ef3a3751e254e2af1ad8b5d668ccf5c6ec3ea2641877cba575807d39 -u,55a6e3ae5ae625923524838fac9fef5b42527f5027c9ca149e6c207792eb -v,975121f7d9c68da0e5b6a96ac615298b12b2ee5bd19989436ee647879da5b -w,67e165c3edc5541d4654c4728871e6908f613fc0ec46e823c96eac82ac62e62 -x,1919d1594bf809db7b44b3782bf90a69f449a87ce5d18cb40eb653fdec2722 -y,e35424bb86305d7747604b13e924d74f1efe38906e4e458dd18dcc67b6ca48 -z,4e91200df1cae51acc071f85c7f7f5b8449d39bb32f363b0aa51dbc85d133e -{,d0b6a416a2d73d3df496eaf787267bceda28bf4fb5b46f98e1915ff1f4e5f13 -},d2a05a5cdff0ba9de4bd02085b3149d1532b127ff8c47a9c9481731190ff1e -\u00A1,ec3157225df342404a983f5fe739c9eab8d1fee7bf1575a7419415d6caac1f9e -\u00BF,fc219d5f0bb2159457a985c4b077e9da779f720e08b853ae845d95cf953af984 -\u00E4,4c9c2bbd7b7f7204dceb5729a6fba7fd45d6f193f3760ec59a6807533e63b -\u00EB,d22cef4b4931528ccbb3a22ac901d59b475de8c1e7cb019a0c38357b1262 -\u00F1,2d2004a418d3da3163b964a826cb6ce42fc80445f0601b864e36829eb2cfa2c6 -\u00F6,c83d42bcb9b8e66c16166ccf261e2f9f78c68ee7886da225e43895cdbcaf5f -\u00FC,caec53e4a6d221afd7297b65e55be87913cf9cb7f4f4547f7186120701d8d -\u0431,65187adfe3a1ce83866ebd7fb3779165aab9e1356cf0f9ce85479b43be45ce -\u0433,dd7e5768adeb132e372d66b5cf3e75fa6c0e93052cca9af7087f278ff17b4bb -\u0434,15339579b3c441789951638d8ccca6db09550927c3950ffb4d0218b40f382 -\u0436,cf891f5ee059399d79fe5969b4bdbbdb778ebd3ea36b364e5debca582def17 -\u0437,ff21241881b7b28d60fcb78a510ba8904d4aac8afc2b40abd5ea4e8be46c -\u0438,cc391c922575dfacb931bc3a490fb4dafc5ed60ef6f4bd7d85cfa5cc7441257 -\u0439,eda6316f0ba2e6aaf23a6c90d87e9dd91a84854f91d2e3632a485124f652a -\u043B,ad61c220894b6863d8604b7ca74d72f3ff40dea1a2be7396a8cde8837188eac6 -\u043F,c2dd9623518a37983d6ac6ceacdc595ea30d82b3840eaa2dfce188cdc7b518 -\u0443,fe60b01054c453c57c1a3786d490fa612b11f96bc2ecf7391c84e0a0f33a1946 -\u0444,28d4f5f5fd5817c5731cc77fda1578c0fb96ce9052e3ac581b382bfba16977a3 -\u0446,b1a821bf5688a0f4d24825b033eed0896b8aff81bc81d54229f43185da95643 -\u0447,ad9452f2ffe6320798da8866bd11de9bcf0d5d7f29caa65bf6805b72d1dc -\u0448,514cbd4f732903d96e61a499d509664f6fd58e79d0a1d5c86263af577c63 -\u0449,51f87863a95ae435843a51f0dae0288da54ebbdb28e480d4bdf33843499ea952 -\u044A,b01ae24311bf47a4e43acc3c1c6d695631c49ac46eeeaebdd1817682c9d7c -\u044B,955683d03c5c46834b7a2db02b30461ce7653ad54d970801ccd1e2f93536a6 -\u044C,7b69d8d5258224cfa1bc352455a6f216422d9197341299bdefd2c412ab63d -\u044D,9e22d38efab90272678691f14457716e53aac546ae0e0e3328d51e8fdb03 -\u044E,64a9f9da6fb432f7eab98e7e48d44ea5836282bdf2f46bb9bd942ec8643a8b -\u044F,6634eb183b134045e5f7d56a49113d4cc6a205a5846847fd7e618039f20b4 -\u2190,bb0f6e8af46ac6faf88914191ab66f261d6726a7999c637cf2e4159fe1fc477 -\u2191,58fe251a40e4167d35d081c27869ac151af96b6bd16dd2834d5dc7235f47791d -\u2192,f2f3a2dfce0c3dab7ee10db385e5229f1a39534a8ba2646178e37c4fa93b -\u2193,9b7ce683d0868aa4378aeb60caa5ea80596bcffdab6b5af2d12595837a84853 -\u2196,473e1fe0ffcd546c21b63eaa910ab5c93132a64e644179fccaa21dc8bc660 -\u2197,577ec44fb7503de6afe3bdd7e583c7b93979f59f6d634b6b6a5af7f3a1c58515 -\u2198,8e1ce9c0d33236f9921d22c4ec4bf509237aef676b5d1d2bacc93f5a819480 -\u2199,52651ecd3780cf6e451ecaccdee69715c08cae7cd4509084462cdcd963a6b322 -\u23E9,127e89165945c4943c6e6372fc8c2ee0dd916e84685872b27a9e3d2b7761df -\u23EA,b23d7e7711fb79d96c5bbffab174466a6cfc2b7db023288301ea44b1ea013e7 -\u23F4,ee3d8225f8f5b98597df15fd92bf6959aefd4c5bec9914dd63caa0c329c7a06b -\u23F5,a3ea6512713b7bb8fee377a98732378757f26df8434d0faf897adb7564 -\u2640,10c1050de19c68ceb1ce4a03cccbccda5189905251d992920d5a11b1ffa05838 -\u2642,f57fffa3543fe169bbbe61fdd885e829dd521d9a2f5ce0b89316fb48b966ac20 -\u2648,6c505323d78f9e5f2710b91846c3fa12f47a847a1b13f7505fda69a3f42ec5f7 -\u2649,eb13836b7847416926738c948922f4feffa13e6d8a9131745e56a76574d1acca -\u264A,c79735dc91715194fd0c3d24b8d6c0cb6ddc50f9d6566fbb0f48a51a644dcfb7 -\u264B,c87456fa484d8613456d83662f4c731bd9ba35e9bfd3e70a1a9e00679bc59aba -\u264C,f477647700469cc44a72d10edee1c2f7599ddbf2a19b2acddfecaddf84413b85 -\u264D,66a825275ecdc451b3520f66ba1df4f39c626a24e05dad0cae782eddab887683 -\u264E,86cf403e40da4184b94d0f38b17164f4b2cf80628fee34835da8382e91c767e2 -\u264F,c21c9897d2562a62a8c340f47afc9d4e23e2a420f008e9cb5f80a496449b70ca -\u2650,c4a7bdd0936da5621062b63a14b787d560742edf4f772d7cfc7b04c0a2540b99 -\u2651,f99894bd9eea43f17696fa45bd6305f3246a54768fe91eb391896ae64ee73a6c -\u2652,58f982fdb8413c06b50e77d66f693369e847be7781b3717b8df99c58c7867409 -\u2653,dbc2185e85aac11b559724965c6c6825b7c250a2646b4dc457b4f914e17d9483 -\u2665,cbf4b52cbdc86de7d9dd7b3b8be33e8301c5cf398904af69bc28decfc81278d -\u266A,dc8dbe6b3190106b874261e34107223ee985e03016371647cf10ef4404c28d72 +" ",8e646d878591c58c39f2d7a1daf01e1144544d465977eba5c3fe743b9fcf140 +!,87d19aabfcfd99ffaba4214caef299516ce52e6d13bf2dda125985e481b72f9 +"""",152b40d3e786c4ebe36d9c41dcf5412b0ddb198db67bed1aa6f4797fff23e5 +#,944c4df7e17db3c7e996cc67b17e8f8a97d62c81fe32f852e1a4779a9fc588b8 +$,1f5e36aba86644b7399188a4bc69f8a49ece1de1fb2c0b17b8211b49f224108c +%,685be76de28ddcb39d283e3d71f6ed63de854f839623ec18a5380c84f1c25f9 +&,bba18d5132777969cf61653c31d2ace8524b10484dcb6706595f8f16b72e +',8ab7e099af20b431894d46d3145e549a8bcf1e21f7559b20cf2239136d55c1 +(,86e067947cf2c9a366504838b768c41663b7bfc1f34c2b5b2c6ac1ce561a9bb +),66b1fed8e8101a749b7d4db0f3f75b980b759e545eb65e336c90c5d1fa17 ++,0a21eb4c57750729a48b88e9bbdb987eb6250a5bc2157b59316f5f1887db5 +",",e85b4618c19e3f91e9b14b4fb9b08ce160ebd5b5a712f4056ef8b3dec9c62 +-,a8c67fed7a2472b7e9afd8d772c13db7b82c32ceeff8db977474c11e4611 +.,6ff99ff279a2cf25deb4bd5b66c3576b824cc96c36781027af727ed3a4c1308e +/,2d593f0945cbb85a8e0be7d9a526010ee774810f2bc428cd4a23e4d232eff8 +0,55a224807693978ed834355f9e5145f9c56ef68cf6f2c9e1734a46e246aae1 +1,31a9463fd3c433d5e1d9fec6d5d4b09a83a970b0b74dd546ce67a73348caab +2,acb419d984d8796373c9646233c7a02664bd2ce3a1d3476dd9b1c5463b14ebe +3,f8ebab57b7614bb22a117be43e848bcd14daecb50e8f5d0926e4864dff470 +4,62bfcfb489da867dce96e3c3c17a3db7c79cae8ac1f9a5a8c8ac95e4ba3 +5,ef4ecf110b0acee4af1da343fb136f1f2c216857dfda6961defdbee7b9528 +6,f331a6a6fcd6995b62088d353bfb68d9b89ae258325caf3f2886464f54a7329 +7,d4ba6ac07d422377a855793f36dea2ed240223f52fd1648181612ecd1a0cfd5 +8,c61a8a641437be9aea207253dd3f25440d954ea2b5866c552f386b29ac4d049 +9,a1928e1bfd86a9b79397c4cb4b65ef99af49b7d5f7957ad62c0c699a622cfbe +:,bd898c40e47c5d2d76924065360768065d624ee5b9ee0be9e12b98fb77c76 +;,c565949039f159651dd6ddbe1598ca3282acecd23ed80bab26efada4ce9c13 +=,4fd1fc30fa578163ca65c59e2ffdecaceb846c0f219c12bc3e1012b8a9c3bf +?,d23eaefbd581159384274cdbbd576ced82eb72423f2ea887124f9ed33a6872c +[,5f3ae18d9afd7c3f60f5ba5e5c40f9ac1129eb5889581ccb71bba32e517a +\,39b9e4afcff695c27f3491584a99673b6a4766870dea6b22bee9d5e2bee3710 +],1f301c8ec7e50cb8464b55ac53ef8e132eb7f59b244bdd6cba30719b517187 +_,4f2fae2e35447de1835322f61ef7c790707971e6aafbba5f6b92681f7a2f58d6 +a,2ac58b1a3b53b9481e317a1ea4fc5eed6bafca7a25e741a32e4e3c2841278c +b,d4c711571e7e214ee78dfe4ee0e1263b92516e418de8fc8f3257ae0901431 +c,fff5aabead6feafaaecf4422cdd7837cbb36b03c9841dd1b1d2d3edb7825e851 +d,893e622b581975792f7c119ec6f40a4f16e552bb98776b0c7ae2bdfd4154fe7 +e,a157d65b19921c760ff4910b3404455b9c2ee36afc202d8538baefec676953 +f,c54cf261b2cd6ab54b0c624f8f6ff565a7b63e28e3b50c6dbfb52b5f0d7cf9f +g,d3c9f8a74ca01ba8c54de1edc82e1fc07a83923e66574b6ffe606919240c6 +h,f8c58c509034617bf81ee0db9be0ba3e85ca15568163914c87669edb2fd7 +i,4246323c9fb319326ee2bf3f5b63ec3d99df76a12439bf0b4c3ab32d13fd9 +j,c58456cd9bb8a7e978591ae0cb26af1aadad4fa7a16725b295145e09bed8064 +k,af49fb708369e7bc2944ad706963fb6ac6ce6d4c67081ddadecfe5da51 +l,8c84f75416e853a74f6c70fc7e1093d53961879955b433bd8c7c6d5a6df +m,31fde91b19b9309913724fea9e85311271c67bcb78578d461bf65d9613074 +n,1c7c972e6785d6b0aceb779abdd7702d98341c24c2a71e702930eca58055 +o,8073bb44f9345f9bb31a679027e7939e461842a8c27486d7a6b842c39eb38c4e +p,64b231a8d55870cfb5a9f4e65db06dd7f8e34282f1416f95878b19acc34ac95 +q,ffedd6f9efdb156b86935699b2b4834df0f5d214513c01d38af3bd031cbcc92 +r,c03a1cd583cbbffde08f943e56ac3e3afafecaede834221a81e6db6c64667f7d +s,b6572e655725d78375a9817eb9ee8b37829ca1fea93b6095cc7aa19e5eac +t,708c9ef3a3751e254e2af1ad8b5d668ccf5c6ec3ea2641877cba575807d39 +u,55a6e3ae5ae625923524838fac9fef5b42527f5027c9ca149e6c207792eb +v,975121f7d9c68da0e5b6a96ac615298b12b2ee5bd19989436ee647879da5b +w,67e165c3edc5541d4654c4728871e6908f613fc0ec46e823c96eac82ac62e62 +x,1919d1594bf809db7b44b3782bf90a69f449a87ce5d18cb40eb653fdec2722 +y,e35424bb86305d7747604b13e924d74f1efe38906e4e458dd18dcc67b6ca48 +z,4e91200df1cae51acc071f85c7f7f5b8449d39bb32f363b0aa51dbc85d133e +{,d0b6a416a2d73d3df496eaf787267bceda28bf4fb5b46f98e1915ff1f4e5f13 +},d2a05a5cdff0ba9de4bd02085b3149d1532b127ff8c47a9c9481731190ff1e +\u00A1,ec3157225df342404a983f5fe739c9eab8d1fee7bf1575a7419415d6caac1f9e +\u00BF,fc219d5f0bb2159457a985c4b077e9da779f720e08b853ae845d95cf953af984 +\u00E4,4c9c2bbd7b7f7204dceb5729a6fba7fd45d6f193f3760ec59a6807533e63b +\u00EB,d22cef4b4931528ccbb3a22ac901d59b475de8c1e7cb019a0c38357b1262 +\u00F1,2d2004a418d3da3163b964a826cb6ce42fc80445f0601b864e36829eb2cfa2c6 +\u00F6,c83d42bcb9b8e66c16166ccf261e2f9f78c68ee7886da225e43895cdbcaf5f +\u00FC,caec53e4a6d221afd7297b65e55be87913cf9cb7f4f4547f7186120701d8d +\u0431,65187adfe3a1ce83866ebd7fb3779165aab9e1356cf0f9ce85479b43be45ce +\u0433,dd7e5768adeb132e372d66b5cf3e75fa6c0e93052cca9af7087f278ff17b4bb +\u0434,15339579b3c441789951638d8ccca6db09550927c3950ffb4d0218b40f382 +\u0436,cf891f5ee059399d79fe5969b4bdbbdb778ebd3ea36b364e5debca582def17 +\u0437,ff21241881b7b28d60fcb78a510ba8904d4aac8afc2b40abd5ea4e8be46c +\u0438,cc391c922575dfacb931bc3a490fb4dafc5ed60ef6f4bd7d85cfa5cc7441257 +\u0439,eda6316f0ba2e6aaf23a6c90d87e9dd91a84854f91d2e3632a485124f652a +\u043B,ad61c220894b6863d8604b7ca74d72f3ff40dea1a2be7396a8cde8837188eac6 +\u043F,c2dd9623518a37983d6ac6ceacdc595ea30d82b3840eaa2dfce188cdc7b518 +\u0443,fe60b01054c453c57c1a3786d490fa612b11f96bc2ecf7391c84e0a0f33a1946 +\u0444,28d4f5f5fd5817c5731cc77fda1578c0fb96ce9052e3ac581b382bfba16977a3 +\u0446,b1a821bf5688a0f4d24825b033eed0896b8aff81bc81d54229f43185da95643 +\u0447,ad9452f2ffe6320798da8866bd11de9bcf0d5d7f29caa65bf6805b72d1dc +\u0448,514cbd4f732903d96e61a499d509664f6fd58e79d0a1d5c86263af577c63 +\u0449,51f87863a95ae435843a51f0dae0288da54ebbdb28e480d4bdf33843499ea952 +\u044A,b01ae24311bf47a4e43acc3c1c6d695631c49ac46eeeaebdd1817682c9d7c +\u044B,955683d03c5c46834b7a2db02b30461ce7653ad54d970801ccd1e2f93536a6 +\u044C,7b69d8d5258224cfa1bc352455a6f216422d9197341299bdefd2c412ab63d +\u044D,9e22d38efab90272678691f14457716e53aac546ae0e0e3328d51e8fdb03 +\u044E,64a9f9da6fb432f7eab98e7e48d44ea5836282bdf2f46bb9bd942ec8643a8b +\u044F,6634eb183b134045e5f7d56a49113d4cc6a205a5846847fd7e618039f20b4 +\u2190,bb0f6e8af46ac6faf88914191ab66f261d6726a7999c637cf2e4159fe1fc477 +\u2191,58fe251a40e4167d35d081c27869ac151af96b6bd16dd2834d5dc7235f47791d +\u2192,f2f3a2dfce0c3dab7ee10db385e5229f1a39534a8ba2646178e37c4fa93b +\u2193,9b7ce683d0868aa4378aeb60caa5ea80596bcffdab6b5af2d12595837a84853 +\u2196,473e1fe0ffcd546c21b63eaa910ab5c93132a64e644179fccaa21dc8bc660 +\u2197,577ec44fb7503de6afe3bdd7e583c7b93979f59f6d634b6b6a5af7f3a1c58515 +\u2198,8e1ce9c0d33236f9921d22c4ec4bf509237aef676b5d1d2bacc93f5a819480 +\u2199,52651ecd3780cf6e451ecaccdee69715c08cae7cd4509084462cdcd963a6b322 +\u23E9,127e89165945c4943c6e6372fc8c2ee0dd916e84685872b27a9e3d2b7761df +\u23EA,b23d7e7711fb79d96c5bbffab174466a6cfc2b7db023288301ea44b1ea013e7 +\u23F4,ee3d8225f8f5b98597df15fd92bf6959aefd4c5bec9914dd63caa0c329c7a06b +\u23F5,a3ea6512713b7bb8fee377a98732378757f26df8434d0faf897adb7564 +\u2640,10c1050de19c68ceb1ce4a03cccbccda5189905251d992920d5a11b1ffa05838 +\u2642,f57fffa3543fe169bbbe61fdd885e829dd521d9a2f5ce0b89316fb48b966ac20 +\u2648,6c505323d78f9e5f2710b91846c3fa12f47a847a1b13f7505fda69a3f42ec5f7 +\u2649,eb13836b7847416926738c948922f4feffa13e6d8a9131745e56a76574d1acca +\u264A,c79735dc91715194fd0c3d24b8d6c0cb6ddc50f9d6566fbb0f48a51a644dcfb7 +\u264B,c87456fa484d8613456d83662f4c731bd9ba35e9bfd3e70a1a9e00679bc59aba +\u264C,f477647700469cc44a72d10edee1c2f7599ddbf2a19b2acddfecaddf84413b85 +\u264D,66a825275ecdc451b3520f66ba1df4f39c626a24e05dad0cae782eddab887683 +\u264E,86cf403e40da4184b94d0f38b17164f4b2cf80628fee34835da8382e91c767e2 +\u264F,c21c9897d2562a62a8c340f47afc9d4e23e2a420f008e9cb5f80a496449b70ca +\u2650,c4a7bdd0936da5621062b63a14b787d560742edf4f772d7cfc7b04c0a2540b99 +\u2651,f99894bd9eea43f17696fa45bd6305f3246a54768fe91eb391896ae64ee73a6c +\u2652,58f982fdb8413c06b50e77d66f693369e847be7781b3717b8df99c58c7867409 +\u2653,dbc2185e85aac11b559724965c6c6825b7c250a2646b4dc457b4f914e17d9483 +\u2665,cbf4b52cbdc86de7d9dd7b3b8be33e8301c5cf398904af69bc28decfc81278d +\u266A,dc8dbe6b3190106b874261e34107223ee985e03016371647cf10ef4404c28d72 \u2713,c6e45d7cf4ff21732172d71b2a340626c708397626319b6d57d76c9ac48c675f \ No newline at end of file diff --git a/src/main/resources/fonts/watermelon.csv b/IF/src/main/resources/fonts/watermelon.csv similarity index 98% rename from src/main/resources/fonts/watermelon.csv rename to IF/src/main/resources/fonts/watermelon.csv index faddf35a..a24ded1c 100644 --- a/src/main/resources/fonts/watermelon.csv +++ b/IF/src/main/resources/fonts/watermelon.csv @@ -1,118 +1,118 @@ -" ",74114e2c17ed202309863b5f64e3d18b86ccf9ca3dbbea2b934ad6a5aaaf9d83 -!,3c9b69a46b2233fa339a2a8f8c0e15936371ac981a0b27875782e1219b5273e0 -"""",e27d1b23cf1f0608739e3d4aa49f832bd4f13f913046e28bb785d4b3035a55ac -#,cab3d30e2dc40f7de5293eabc69a2cf025651eaaad282bf7561afd86d2e51132 -$,44e27d3a3520623e0782703a83b881408e56c5fa67f1a74605ae22a04faf56f1 -%,bcd43e0f0aafd060d4c429a4ae0e7214ff2a5cb17657f5bfc8b0d92faa41b887 -&,ab186378bab2c10cc4a2c36962e6f3f12e33c8b1f503f86895df36003d467384 -',587e350499a7103567c0f0dc3121d751c339112889a90a7e8a67348a807e74fb -(,9e413d7db559acb2b3ae1d3b79681bfc1a1893a1d7e69fd13db5ab7cf18105d9 -),486193eb917d42b84cdaea535d9be0813b387e70cd9301ca498f2d31d8089ff5 -+,edbf1a096cf2dd6167be9aeb0f1eeb88700dffc0bc28be329ccc5cb61877918c -",",2cdb157168af756faab96cb474adc987346d3afa3040e687801070bca560a9d5 --,4a13fe355de5c74dc900ec80850134cf65669591b7bd1ae551e51289d10c0002 -.,10d37954899a74be71f6d6458b30b44ebf7f0bf8790385e4471ebe9d5aa9054f -/,3d7dfb54c8bd8f580a6572ebe0e0e6302f6dfedc0dd65addd1ba73331de9e10d -0,5d2410f8b8a9bff35e0b9fdcdece552c6e618190c7b2e62b765750d164e61585 -1,15f83647f41462f43c008a18729b951a6a30fa7dc7f2f203ce1277a88a32fbf6 -2,e3e16a437b5925fd379c3b39f5d58c0117e5d18839275805807531173ab7ab7b -3,9034fd10dcf4fe1a7b7ba3c5f8e9416056ca2dcf96ded0e23c04efb63d42f0ed -4,35682ea3333f6e786329cd8b1536b1496f8b8c1afa1a1f410c42d71b58baa399 -5,4a3f1736eea1f83766e3b917e1781e4d596b7f347cffb97774ea60124d4bee03 -6,da2fce6610c3fddc61c3ba054a8853ff38194e775475c4f8d3911ca036a0a196 -7,d5a9af0d51f6b7835ad84a4b5b35780e18c25e840595d2305ed8a571d1f04380 -8,8a79a8874eba3ce3340029afc620d537cc56418a64ee94c06ae8aef09695c181 -9,7f9809a21b4c40ac4eeb42686fe36e90891e40c82ba523b54a861e48e794885d -:,8faf5f3c9e93c339e6e730390ba3c79b93e0f8360503c431245e72e84870e7ee -;,ae93d713250a24e1f98a00d3a235ce1f51521b6472f43a517d3ece50cf39a9b0 -=,787db9658e3bdcf49c706d84700971c5b01a2ebc3bee345f92b27dadc513d49a -?,1b3b844684dab37b2e9a6e7f69b7903128c679bec03ee9d26e804ad9c79c52b5 -[,205f44837f761ea8c90e5b4085ce4bdcae6940b0a87c4d2c0b8788ab5bac0dbb -\,7af8c66b8c6095dc5f0206f9075e8915b912a3ea53e9b9e5580047ebc9d56376 -],15dc2c621aefc69d013a30526d0ccc6d23ab1c4fb58d13a871f70ee1171d3c2a -_,b22cf6fd09a62f70598e42e5c88d18aaf7a860ebb881d3c3b0814e8a97c9ee1e -a,d66e31e4a1cfaf61b0d2c3c7959f9d4a9f2b6be3adae9428d766d26077a79397 -b,3740cd8c99c4734d399259f7a34acd06b9077ffeba2a3a3d67fc029ac1202f39 -c,4eb6520483679acb0c99e18bc07570384f270b790b51f1cea084ac059bb421da -d,b4eff0cd1e0183874053279d4c03be749e3d65509567270645366b104d9b9f34 -e,efc9329221c36f6d387181e2662a884e711b629ed4ee7aadff24167221e9610f -f,36fd688f06f62aaa51b7a7204fb9bf2f420953b1dab0247108992eb5f2df0183 -g,d792ff1b63ff64545d967c8ffbbc0a670ee51219f0c9f8960e7d053ebbc1168d -h,8a262a52fa3f9b6b7ba610e577947dcc5abba937c21f850338660c2e4ca0abf4 -i,391f6ec8c0f3a03b2c95717d06f32c84151fdbe2dbad819d5774e148d0a326d0 -j,91db81ecd85d741f28bf119de6305b1d92715bea0845ac377e2b1a2d9d4d9b79 -k,1a783f2d065478e5f4bd3bb967c85bd579eacb845d17ea392cfad451214e8278 -l,c6dff51d0298adcf30d2241c44fc9cdb2c3b83fd48b3a1a65fb92d75341d0d76 -m,a50fc14abf0b891eaaccbe18661f711ef7cabc691fd603330db589a74f862723 -n,ce5638c06bc67a485c538ebb3dc234bb812745e1c6a27f492a275a338d75133c -o,11044a7a108a221a82af56201ec08da72df3213bad12b6d3b51c23064163160 -p,499964f084db8743846b860abb25aff167d773c09eeaf2aa7608994cbe5d28a5 -q,e34372a7e0b124a843e74566b0aa64f660599c0e7b964e4e9af0fc7b6b239d2f -r,2dedc7491efd87cec2e9482b3ba1bf5f14386fdbeda9ade60e2e8204817d20e -s,c0849ec5b7f8e6a5369d5ea716c110dc292e99528ef5aa4e4f8ed27528fbe276 -t,eece4cb3480e74e035d2c4baaef0eeca54b40d689de326aa4d8ac1d2f4f4372 -u,cb7f58e8a76f07439e1b1b30e1d21bcda003dab505e4a2f94d7cc8432be706e9 -v,5f3262bf28e67b60110d92bbb62621e336ac830e829cd98b1123edc5d153ec2a -w,21e92d72b17fe6b65383dcabdd87c369bd645e19287c4a97cd90cbc37667be14 -x,5ea066abbc14102ceca350fcb31dea5a758725e8fa8bc8a238849cb119173e5a -y,7a7bbc8bf2394d0ef23a83689b2e66a92b96bc6226cc1540bbf6affb9281f515 -z,75acf92db0f34fafc4e8a80ff2e130f0378cdf56631b58148b2f1377cd867519 -{,51e85b8b47f647ae775c0b3a6fd877a05e164051885444824338b176a6eb9ce7 -},5f1c4bb893e559252d7e46f23881a512d56a93cf70d7ab2fdb97163932ce0312 -\u00A1,99e65d820a67708a49c4b913407a2b4eaded47d777f051013713bdac8815d125 -\u00BF,d89a0e614a8ce3f15446cd07b7230a5eb09743a4fa2d5d4a9e00b42eb17a7295 -\u00E4,a46d4857a1eab770eb8545657871e5dc9b6cb38f4fd8b9d2665a1c478024113d -\u00EB,eab56def763f6ff23ec617043a9769d36ba601f220a4df31327378b97e6a37d6 -\u00F1,6ca2f9f0d3689cd5172645990aba9482338d37bc70afa002235e8f378c45d5d9 -\u00F6,46dabff50ae5737781ee829126254c9f14f7493d663d8c9370fdedba5edb6436 -\u00FC,299a2172d88db9e54e6f486878ab28b906c72271207a643fe04be55144f05a3d -\u0431,5bb49e417e69ddc2db715b04f2c4cc1f00f1de95461925ba2bac7e0235d62ac9 -\u0433,eff912331d56c5878346a293ce5205bfa1b5b642f95ca522056386d03e71aae3 -\u0434,372cb8f37f763cf1889d5b11299ed938cf6d835abaf333a5ad22c2024f9499d4 -\u0436,38ee71cb87400d5ea7339eae2ec146b6087c9014cfbbd58ebfc58011e018e1ec -\u0437,f9984d024eebb135dc8c9948a2f67d2b86c2c0d089c8f3d6ed0362840a412e65 -\u0438,ccbc55096ce96ff3860582d801387883cc5bc48bd9365b61c8c7730aa7e9e164 -\u0439,5dbb87bd721ce45b8574fdf119d11947afa6d838e9793e265f1f01aa29010e53 -\u043B,e242990482b4294d5f2874abb5db996a122c37fb36fb4f2975a2c94aeac005d3 -\u043F,ed4f587896af34d5dad947725c975efee22b9d8202df905c66498611526f70d7 -\u0443,fd6583ee852b2212d679b73c22d09e4483fa755b17f3c873171e22c9ae2ca9ef -\u0444,6c2dcbc56c9eb70930bf24deaf15a92835f68b678844b689424e22500201550d -\u0446,8764b82e4a481862459f6140bf185956572e3360507de16445d4fdce8e720bf0 -\u0447,c6811219f0b14f4fd3c72a259ec0c3cf3fc2725fb85975b6764f8066e174e72 -\u0448,42b9b19e9528f62407f1b5bd71f79a2c354ba50237c08c5b2ed8c2d3226d1887 -\u0449,ef7e4e4972da917b805b890f3dc750aa7e73057c7c2d5cc09fa1df1fdf87cf40 -\u044A,8ffb44852161b609126e66024620b8f0e06c4c163198d27492d8b6d35dff9017 -\u044B,b04de49db1f172d55a7ca1f40cb1a4c275931ce82fd272f1890eab2780e0a873 -\u044C,52f5460b6f8e91eb30ffe7f465efb76d158818e7797fbddc02399e70af289a28 -\u044D,a398b6c0f0dd1aac44ff2a1f873894d95a966da7557167be683b7d0f50b844b8 -\u044E,35237c8fbf359bd93a748f5488b495fe1ee4836296732789a59bf5f6319e8af4 -\u044F,8f469718b8a65a1d5b70d4a1b4396817aa23ab53e6f2b505d5326dccc35049b3 -\u2190,3bd169f41860a305558cb5b7072c733f5a42576b48007ad09aa5715ad7e76d99 -\u2191,1560cde883c652708664bd49f902827b29eee37727a7fd01a806e04854eb8383 -\u2192,68da84cb1bf63d50688df55f5159d8683361fd93b14e1e90463adaf0d8559529 -\u2193,8860a18a33d8e3aa640f62a647043d52342385daa6f62a9c78d394b58a6e0674 -\u2196,d8d77c66bccce574ce70689b669887556b5c0ae6c322d9e2dda584b9eb7e6ea4 -\u2197,305d60988913b868b1a8f1e64cfe81665da116eac75540195e94df8aad86122 -\u2198,139f76b5998c9791b66cd11c50bae1eecffbc76bd0ac2e728977c8e716d24fb -\u2199,6e40a96c99e7bcbcc66ce83238553327c745dbf6874bf3b812d69a9bd693974c -\u23E9,753847bcfcf7c4f0fe5a6110d93c8e9932935d521d72d45a8d894a0952878c -\u23EA,503e8c6e62f9f0ac9bb383f86908e690334f544c3bf6251d902e17ce294f95ad -\u23F4,e94a86ad1962e2c86cd6009c839ab150b7f6dd4f5dabebe82e9060c658011cc0 -\u23F5,9c8e3b07e357ac6003eba3ab1634204779b0bee4d756777f89538f4b16d3d093 -\u2640,f5a08c7fb339a64affc4c96d4c1d1fc1161f2806c4f3d03a9ddccddd2ba4d816 -\u2642,fd0287ed468a2cf59856dec3a258bf092a6c1721c134cddbdfda033df9392b70 -\u2648,c382c124c4aadb3cb18a8c2eaab6c3ca1180422ff7179e509acecb20221192e5 -\u2649,803abfcebe2f48b6d4b0ff650fe4093224d8830d035ab10fabb133110e7b0676 -\u264A,d9015d6987c842362516638d5d1fcacb087f80c936ec9ba4577a31583bbecb9e -\u264B,7ddaaa1cb6d40091f1b39939b9c615ae79ced7c94518c8214ab4dad7e9aa1d66 -\u264C,272aa740f0aae49b322c2b0d1ceb3d9120a1306ceb59013bcbc64eb0bb2e3768 -\u264D,b515b0d1a4a9a230549651e6245b2b58539eeece49b686ebe075f392f996c0d3 -\u264E,37d2268186ee85f0e6fd98b9cafe82e83e8917750069b60e370d6fa372bcb8ef -\u264F,80d3b59440f6705c31c495c1aa3f92c6e71395ea06d052f4cc0eaec96c8c7d -\u2650,a41b75a59f612643ddf62de932a4e4bd5b087b992d051ea5936e9c8cbcf8d5d2 -\u2651,ab945868bf9c789de1f9a6cb4d21de11d2ce705944cf73f4e383560b5bfffb7c -\u2652,bce3753f5da820cdadf9f96e4f05cd8fce3ffe7a7a69df3f70005cd956886e32 -\u2653,8715c70b9db5f820d1e440fff2aa3fef022c27e3c2d60da74bfe2e4f97187cc0 -\u2665,c24af840ce406f905cf07d371284291c15886b6568bcdaa742345a45577d9739 -\u266A,d41dfb301c0470187f907814f5943ebdb8b6a1278333369aa35299ce39409277 +" ",74114e2c17ed202309863b5f64e3d18b86ccf9ca3dbbea2b934ad6a5aaaf9d83 +!,3c9b69a46b2233fa339a2a8f8c0e15936371ac981a0b27875782e1219b5273e0 +"""",e27d1b23cf1f0608739e3d4aa49f832bd4f13f913046e28bb785d4b3035a55ac +#,cab3d30e2dc40f7de5293eabc69a2cf025651eaaad282bf7561afd86d2e51132 +$,44e27d3a3520623e0782703a83b881408e56c5fa67f1a74605ae22a04faf56f1 +%,bcd43e0f0aafd060d4c429a4ae0e7214ff2a5cb17657f5bfc8b0d92faa41b887 +&,ab186378bab2c10cc4a2c36962e6f3f12e33c8b1f503f86895df36003d467384 +',587e350499a7103567c0f0dc3121d751c339112889a90a7e8a67348a807e74fb +(,9e413d7db559acb2b3ae1d3b79681bfc1a1893a1d7e69fd13db5ab7cf18105d9 +),486193eb917d42b84cdaea535d9be0813b387e70cd9301ca498f2d31d8089ff5 ++,edbf1a096cf2dd6167be9aeb0f1eeb88700dffc0bc28be329ccc5cb61877918c +",",2cdb157168af756faab96cb474adc987346d3afa3040e687801070bca560a9d5 +-,4a13fe355de5c74dc900ec80850134cf65669591b7bd1ae551e51289d10c0002 +.,10d37954899a74be71f6d6458b30b44ebf7f0bf8790385e4471ebe9d5aa9054f +/,3d7dfb54c8bd8f580a6572ebe0e0e6302f6dfedc0dd65addd1ba73331de9e10d +0,5d2410f8b8a9bff35e0b9fdcdece552c6e618190c7b2e62b765750d164e61585 +1,15f83647f41462f43c008a18729b951a6a30fa7dc7f2f203ce1277a88a32fbf6 +2,e3e16a437b5925fd379c3b39f5d58c0117e5d18839275805807531173ab7ab7b +3,9034fd10dcf4fe1a7b7ba3c5f8e9416056ca2dcf96ded0e23c04efb63d42f0ed +4,35682ea3333f6e786329cd8b1536b1496f8b8c1afa1a1f410c42d71b58baa399 +5,4a3f1736eea1f83766e3b917e1781e4d596b7f347cffb97774ea60124d4bee03 +6,da2fce6610c3fddc61c3ba054a8853ff38194e775475c4f8d3911ca036a0a196 +7,d5a9af0d51f6b7835ad84a4b5b35780e18c25e840595d2305ed8a571d1f04380 +8,8a79a8874eba3ce3340029afc620d537cc56418a64ee94c06ae8aef09695c181 +9,7f9809a21b4c40ac4eeb42686fe36e90891e40c82ba523b54a861e48e794885d +:,8faf5f3c9e93c339e6e730390ba3c79b93e0f8360503c431245e72e84870e7ee +;,ae93d713250a24e1f98a00d3a235ce1f51521b6472f43a517d3ece50cf39a9b0 +=,787db9658e3bdcf49c706d84700971c5b01a2ebc3bee345f92b27dadc513d49a +?,1b3b844684dab37b2e9a6e7f69b7903128c679bec03ee9d26e804ad9c79c52b5 +[,205f44837f761ea8c90e5b4085ce4bdcae6940b0a87c4d2c0b8788ab5bac0dbb +\,7af8c66b8c6095dc5f0206f9075e8915b912a3ea53e9b9e5580047ebc9d56376 +],15dc2c621aefc69d013a30526d0ccc6d23ab1c4fb58d13a871f70ee1171d3c2a +_,b22cf6fd09a62f70598e42e5c88d18aaf7a860ebb881d3c3b0814e8a97c9ee1e +a,d66e31e4a1cfaf61b0d2c3c7959f9d4a9f2b6be3adae9428d766d26077a79397 +b,3740cd8c99c4734d399259f7a34acd06b9077ffeba2a3a3d67fc029ac1202f39 +c,4eb6520483679acb0c99e18bc07570384f270b790b51f1cea084ac059bb421da +d,b4eff0cd1e0183874053279d4c03be749e3d65509567270645366b104d9b9f34 +e,efc9329221c36f6d387181e2662a884e711b629ed4ee7aadff24167221e9610f +f,36fd688f06f62aaa51b7a7204fb9bf2f420953b1dab0247108992eb5f2df0183 +g,d792ff1b63ff64545d967c8ffbbc0a670ee51219f0c9f8960e7d053ebbc1168d +h,8a262a52fa3f9b6b7ba610e577947dcc5abba937c21f850338660c2e4ca0abf4 +i,391f6ec8c0f3a03b2c95717d06f32c84151fdbe2dbad819d5774e148d0a326d0 +j,91db81ecd85d741f28bf119de6305b1d92715bea0845ac377e2b1a2d9d4d9b79 +k,1a783f2d065478e5f4bd3bb967c85bd579eacb845d17ea392cfad451214e8278 +l,c6dff51d0298adcf30d2241c44fc9cdb2c3b83fd48b3a1a65fb92d75341d0d76 +m,a50fc14abf0b891eaaccbe18661f711ef7cabc691fd603330db589a74f862723 +n,ce5638c06bc67a485c538ebb3dc234bb812745e1c6a27f492a275a338d75133c +o,11044a7a108a221a82af56201ec08da72df3213bad12b6d3b51c23064163160 +p,499964f084db8743846b860abb25aff167d773c09eeaf2aa7608994cbe5d28a5 +q,e34372a7e0b124a843e74566b0aa64f660599c0e7b964e4e9af0fc7b6b239d2f +r,2dedc7491efd87cec2e9482b3ba1bf5f14386fdbeda9ade60e2e8204817d20e +s,c0849ec5b7f8e6a5369d5ea716c110dc292e99528ef5aa4e4f8ed27528fbe276 +t,eece4cb3480e74e035d2c4baaef0eeca54b40d689de326aa4d8ac1d2f4f4372 +u,cb7f58e8a76f07439e1b1b30e1d21bcda003dab505e4a2f94d7cc8432be706e9 +v,5f3262bf28e67b60110d92bbb62621e336ac830e829cd98b1123edc5d153ec2a +w,21e92d72b17fe6b65383dcabdd87c369bd645e19287c4a97cd90cbc37667be14 +x,5ea066abbc14102ceca350fcb31dea5a758725e8fa8bc8a238849cb119173e5a +y,7a7bbc8bf2394d0ef23a83689b2e66a92b96bc6226cc1540bbf6affb9281f515 +z,75acf92db0f34fafc4e8a80ff2e130f0378cdf56631b58148b2f1377cd867519 +{,51e85b8b47f647ae775c0b3a6fd877a05e164051885444824338b176a6eb9ce7 +},5f1c4bb893e559252d7e46f23881a512d56a93cf70d7ab2fdb97163932ce0312 +\u00A1,99e65d820a67708a49c4b913407a2b4eaded47d777f051013713bdac8815d125 +\u00BF,d89a0e614a8ce3f15446cd07b7230a5eb09743a4fa2d5d4a9e00b42eb17a7295 +\u00E4,a46d4857a1eab770eb8545657871e5dc9b6cb38f4fd8b9d2665a1c478024113d +\u00EB,eab56def763f6ff23ec617043a9769d36ba601f220a4df31327378b97e6a37d6 +\u00F1,6ca2f9f0d3689cd5172645990aba9482338d37bc70afa002235e8f378c45d5d9 +\u00F6,46dabff50ae5737781ee829126254c9f14f7493d663d8c9370fdedba5edb6436 +\u00FC,299a2172d88db9e54e6f486878ab28b906c72271207a643fe04be55144f05a3d +\u0431,5bb49e417e69ddc2db715b04f2c4cc1f00f1de95461925ba2bac7e0235d62ac9 +\u0433,eff912331d56c5878346a293ce5205bfa1b5b642f95ca522056386d03e71aae3 +\u0434,372cb8f37f763cf1889d5b11299ed938cf6d835abaf333a5ad22c2024f9499d4 +\u0436,38ee71cb87400d5ea7339eae2ec146b6087c9014cfbbd58ebfc58011e018e1ec +\u0437,f9984d024eebb135dc8c9948a2f67d2b86c2c0d089c8f3d6ed0362840a412e65 +\u0438,ccbc55096ce96ff3860582d801387883cc5bc48bd9365b61c8c7730aa7e9e164 +\u0439,5dbb87bd721ce45b8574fdf119d11947afa6d838e9793e265f1f01aa29010e53 +\u043B,e242990482b4294d5f2874abb5db996a122c37fb36fb4f2975a2c94aeac005d3 +\u043F,ed4f587896af34d5dad947725c975efee22b9d8202df905c66498611526f70d7 +\u0443,fd6583ee852b2212d679b73c22d09e4483fa755b17f3c873171e22c9ae2ca9ef +\u0444,6c2dcbc56c9eb70930bf24deaf15a92835f68b678844b689424e22500201550d +\u0446,8764b82e4a481862459f6140bf185956572e3360507de16445d4fdce8e720bf0 +\u0447,c6811219f0b14f4fd3c72a259ec0c3cf3fc2725fb85975b6764f8066e174e72 +\u0448,42b9b19e9528f62407f1b5bd71f79a2c354ba50237c08c5b2ed8c2d3226d1887 +\u0449,ef7e4e4972da917b805b890f3dc750aa7e73057c7c2d5cc09fa1df1fdf87cf40 +\u044A,8ffb44852161b609126e66024620b8f0e06c4c163198d27492d8b6d35dff9017 +\u044B,b04de49db1f172d55a7ca1f40cb1a4c275931ce82fd272f1890eab2780e0a873 +\u044C,52f5460b6f8e91eb30ffe7f465efb76d158818e7797fbddc02399e70af289a28 +\u044D,a398b6c0f0dd1aac44ff2a1f873894d95a966da7557167be683b7d0f50b844b8 +\u044E,35237c8fbf359bd93a748f5488b495fe1ee4836296732789a59bf5f6319e8af4 +\u044F,8f469718b8a65a1d5b70d4a1b4396817aa23ab53e6f2b505d5326dccc35049b3 +\u2190,3bd169f41860a305558cb5b7072c733f5a42576b48007ad09aa5715ad7e76d99 +\u2191,1560cde883c652708664bd49f902827b29eee37727a7fd01a806e04854eb8383 +\u2192,68da84cb1bf63d50688df55f5159d8683361fd93b14e1e90463adaf0d8559529 +\u2193,8860a18a33d8e3aa640f62a647043d52342385daa6f62a9c78d394b58a6e0674 +\u2196,d8d77c66bccce574ce70689b669887556b5c0ae6c322d9e2dda584b9eb7e6ea4 +\u2197,305d60988913b868b1a8f1e64cfe81665da116eac75540195e94df8aad86122 +\u2198,139f76b5998c9791b66cd11c50bae1eecffbc76bd0ac2e728977c8e716d24fb +\u2199,6e40a96c99e7bcbcc66ce83238553327c745dbf6874bf3b812d69a9bd693974c +\u23E9,753847bcfcf7c4f0fe5a6110d93c8e9932935d521d72d45a8d894a0952878c +\u23EA,503e8c6e62f9f0ac9bb383f86908e690334f544c3bf6251d902e17ce294f95ad +\u23F4,e94a86ad1962e2c86cd6009c839ab150b7f6dd4f5dabebe82e9060c658011cc0 +\u23F5,9c8e3b07e357ac6003eba3ab1634204779b0bee4d756777f89538f4b16d3d093 +\u2640,f5a08c7fb339a64affc4c96d4c1d1fc1161f2806c4f3d03a9ddccddd2ba4d816 +\u2642,fd0287ed468a2cf59856dec3a258bf092a6c1721c134cddbdfda033df9392b70 +\u2648,c382c124c4aadb3cb18a8c2eaab6c3ca1180422ff7179e509acecb20221192e5 +\u2649,803abfcebe2f48b6d4b0ff650fe4093224d8830d035ab10fabb133110e7b0676 +\u264A,d9015d6987c842362516638d5d1fcacb087f80c936ec9ba4577a31583bbecb9e +\u264B,7ddaaa1cb6d40091f1b39939b9c615ae79ced7c94518c8214ab4dad7e9aa1d66 +\u264C,272aa740f0aae49b322c2b0d1ceb3d9120a1306ceb59013bcbc64eb0bb2e3768 +\u264D,b515b0d1a4a9a230549651e6245b2b58539eeece49b686ebe075f392f996c0d3 +\u264E,37d2268186ee85f0e6fd98b9cafe82e83e8917750069b60e370d6fa372bcb8ef +\u264F,80d3b59440f6705c31c495c1aa3f92c6e71395ea06d052f4cc0eaec96c8c7d +\u2650,a41b75a59f612643ddf62de932a4e4bd5b087b992d051ea5936e9c8cbcf8d5d2 +\u2651,ab945868bf9c789de1f9a6cb4d21de11d2ce705944cf73f4e383560b5bfffb7c +\u2652,bce3753f5da820cdadf9f96e4f05cd8fce3ffe7a7a69df3f70005cd956886e32 +\u2653,8715c70b9db5f820d1e440fff2aa3fef022c27e3c2d60da74bfe2e4f97187cc0 +\u2665,c24af840ce406f905cf07d371284291c15886b6568bcdaa742345a45577d9739 +\u266A,d41dfb301c0470187f907814f5943ebdb8b6a1278333369aa35299ce39409277 \u2713,57cc940147aed0576bc4d3fa591a8cb5fef09c57d00da5d8c2cdd840022fedc4 \ No newline at end of file diff --git a/src/main/resources/fonts/white.csv b/IF/src/main/resources/fonts/white.csv similarity index 98% rename from src/main/resources/fonts/white.csv rename to IF/src/main/resources/fonts/white.csv index 4692ab8b..33806e90 100644 --- a/src/main/resources/fonts/white.csv +++ b/IF/src/main/resources/fonts/white.csv @@ -1,118 +1,118 @@ -" ",97c2144fdcb55c3fc1bf1de51cabdf52c3883bcb578923226beb0d85cb2d980 -!,b8ea57c7551c6ab33b8fed354b43df523f1e357c4b4f551143c34ddeac5b6c8d -"""",8c4114b6d3d8c34818b425c9fb9541f510f37caa4aee587066cbd9e83541aa13 -#,99b2bd29b9f36e265417d8d18745149259aad4c8fb5556bd53dc23d63a735a2 -$,8ba7d49233eac0c4f664967adb27fde1d2dc67937cf7d4ecf854a96ba18f5b0c -%,a9f27d54ec5552c2ed8f8e1917e8a21cb98814cbb4bc3643c2f561f9e1e69f -&,772aba4adac466ae19e432a915e547bdce17401fa5d1859ec84ecd463b31b -',a0c411995a290f390471e22e17b1b316ca977f50dcacbb93e94d84564756 -(,674153bb6a3fa8979a889f99aa0fc84ba9f427ff0d8e487f76fa6c8831d18e9 -),9c60e240cda0d9bb315b385119e5a9482e885827baf018e1c03b6a6d612d3f -+,60b55f74681c68283a1c1ce51f1c83b52e2971c91ee34efcb598df3990a7e7 -",",c3885a63453782c915ed6d894cf1d94318740f6a156d6ea9d39524ba5d05f65 --,c3e4b533e4ba2dff7c0fa90f67e8bef36428b6cb06c45262631b0b25db85b -.,323e619dcb7511cdc252a5dca8565b19d952ac9f82d467e66c52242f9cd88fa -/,57b1791bdc46d8a5c51729e8982fd439bb40513f64b5babee93294efc1c7 -0,3f09018f46f349e553446946a38649fcfcf9fdfd62916aec33ebca96bb21b5 -1,ca516fbae16058f251aef9a68d3078549f48f6d5b683f19cf5a1745217d72cc -2,4698add39cf9e4ea92d42fadefdec3be8a7dafa11fb359de752e9f54aecedc9a -3,fd9e4cd5e1b9f3c8d6ca5a1bf45d86edd1d51e535dbf855fe9d2f5d4cffcd2 -4,f2a3d53898141c58d5acbcfc87469a87d48c5c1fc82fb4e72f7015a3648058 -5,d1fe36c4104247c87ebfd358ae6ca7809b61affd6245fa984069275d1cba763 -6,3ab4da2358b7b0e8980d03bdb64399efb4418763aaf89afb0434535637f0a1 -7,297712ba32496c9e82b20cc7d16e168b035b6f89f3df014324e4d7c365db3fb -8,abc0fda9fa1d9847a3b146454ad6737ad1be48bdaa94324426eca0918512d -9,d6abc61dcaefbd52d9689c0697c24c7ec4bc1afb56b8b3755e6154b24a5d8ba -:,2ffcc318c212dc749b599755e7697d492382993c07de3f8e54fe8fc7ddd1e -;,3690f391822451f064c9ec2aa66e60249dc8566fcdcd5acea72b8168274f -=,d773155306c9d2d58b149673951cbc6666aef87b8f873538fc85745f01b51 -?,bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40 -[,9326db518441ff329be356d651952c3362ea232ae6435c9993f8fdf62f3ca5f -\,40543b6ca17d2e4d132e43e77c92766cfbc61f89b72d8fb853f902ae1dd7b0 -],8745b1f41e7522327150555dcb97e17068ee63fb3fd0943fb3adb320ab401deb -_,461c8febcac21b9f63d87f9fd933589fe6468e93aa81cfcf5e52a4322e16e6 -a,4e41748121626f22ae16a4c664c7301a9f8ea591bf4d29888957682a9fdaf -b,42b9e16e26206a709bf07c2493ca4c5d24f5675654fc130d1d5ec5e8c5be5 -c,62a5876113322f39aa2bbef4bd6b79ec6b52a97bb6fab674bddbd7b6eab3ba -d,fa661419de49ff4a2c97b27f868014fbdaeb8dd7f4392777830b2714caafd1f -e,1aeef88e2c928b466c6ed5deaa4e1975a9436c2b1b498f9f7cbf92a9b599a6 -f,cd9d6e96b5b92ffcaf47dd1caf61d3f6e842913fc88849f3de548beed71fa8 -g,220c3b2bbfa1ed3ac8c35b3dd38247456563c92acefd5926b125ccc67d7d5fd -h,7ba9c33a95fa1e519f85a41ca56799384db41fe7e1d7a791751ece9bbae5d27f -i,5c99dfb2704e1bd6e7facfb43b3e6fbabaf16ebc7e1fab07417a6c464e1d -j,781efaa9bc3b60747a750a648b198787f186eb93859aea52031d5a8c881075 -k,35dc6d513cf1633372f41caa0261396e6cc6720e059308c679d44b47ed6 -l,d4affa455b7f58217de8acbbd9201c9ea87c134aa35625494f5d3f65ce946 -m,c8dec4666b4c67d8759714c85714be6ea4e39ff9628849f98b514edf1c3e4680 -n,da221e4f96bee6261752396a3265ffa4dedf8ff4839abd14f49edee1e53092 -o,cbb1d17cebc5f0ecc987b80efc03e32ecb1cb40dbc5bce2faf3e60542a40 -p,d02c10adc31b1c21cc98ecf809225f87e25e72378cf417db4be3f67e91bb1 -q,4524d28c82f3711a97501411ecc3cb466877483b122a2656c8eeadfb8d21 -r,78a81efdae47bcb480a25ed91ff6de9772b07ae87c3c4e277705abbbd3419 -s,d710138416528889815548b4623d28d86bbbae5619d69cd9dbc5ad6b43744 -t,a3fb50fe7559bc99f13c47356cce97fda3aa923557fb5bfb17c825abf4b1d19 -u,d6991dcba25eae243eb5ceb8325f4ab78f9f14127c382f6cd42c4c78042d4b5 -v,e8d68018994f2f2f59d9e5f2e3ba3d46d8b0b9ea0e684bfbb8ecc7b86eb924c -w,80c9483f51d1267432e0f2f3baa8cd93e65b5eac7482b27dbccebafb721748b -x,1d1a3c96562348527d5798f291609281f72e16d611f1a76c0fa7abe043665 -y,3da8b6473052ada22e6ca30c49f6dce9b99916e423ac4fc6b301ad733697f -z,70d44fee0303f6d37faca7e9c315309556fa3df379bdd582317aa368aa843e -{,4abcd9b4ee249d7b15f7e16edd3935cd50511a9358722c9a73db98a443327 -},6b3a8c6aef332bc2a4dedd20f65e6a6fb0aa32e2276f781f2dc24c8250d2 -\u00A1,f0be205d6089e498225e511dbc3c1d3bfd0739039da4d2e231aea2bb1f76f31a -\u00BF,e52701c6871bae03c1c37705d4349fe088ca9709bfde07ca0f2730469cb4e4 -\u00E4,5f76f247b9e737dd45820672b482e43b86011bbe1309beca561b39ca77c3e74 -\u00EB,c42471bd5ae565e8c331b8bc15ac60fea48db3726cb0b5a6da3b9f6c3b597c -\u00F1,e195f6da34ff1b0ceb4ae221111466f84e03e25a20435004d3e67848078c6867 -\u00F6,68d9e13d7b211a5f0f855631ec0f86c1990f467cb321b9a5837ccb917dada0 -\u00FC,70615c383fc1e415444b964e88e999a3c7fa895263be1abff14cafe4dd6881 -\u0431,ac82266158e57316477be6c1e0d83c53433687e02a6cdf293955064564d6 -\u0433,2c9f516557d2843c86ebc90c8897a39816559a7022e8b10925a95d579e77 -\u0434,2cc03e44c394b24de3b7f07d7ffe788a5fa6cfdd1564ef959fa7ac9fd95ed88 -\u0436,ebc0c360b1233021e43ad164d4ee895e3324122322e7db597a8a0b785af99 -\u0437,a8ba42fcf1e478c07612ae9b39affb756337c1c3fcd3b9eb318814b82ba37a -\u0438,c52011905bc220d06840ebf59fe0f475177ac535834e22147b37c3ff39542297 -\u0439,e47edef1a0742f3aa3ee4cb2b52e256347d2f2455eb16db7ae9a186d0afdc2b -\u043B,76f2f4b92473888f3a769083ff333dfa3847b2f8cd85e47b5a91e55bee6a8c -\u043F,5f238c868ed6e198d785f71e1a228cea4e32afa4c74fab47765c572d4e2c865 -\u0443,af0ad559daff1e61cbfbf28ca6b4328463608b5c22b40dcc693fb80a5c3ed -\u0444,51f4ceb54d64b5c8edea32c11aac107838eff23ace75b9b4bc27a0786b8f -\u0446,2c50395f333094dbcb47962a96eff74496622b1ea3cbd8e0baf18fcf31c8e8 -\u0447,f325c0a6dc79b58787f1cba3fadc39d8597af33d8ed01444f01f1967777a6 -\u0448,e5f29dd0645c8774b51a75c05db7f3f1b4c0a739665d6dca59f6c227ace5c11 -\u0449,4ee71e986db7b688425b3438823d51dda88279d51a0de4583ddc72b24ba886d -\u044A,8b4eeb9a4734ecca8ed19f851af7dc1c46fd5a317b09f1aa651ad9851ac28d7 -\u044B,3019ed4e1e2faa63ce5437d8daa570ced43bf1e8d22b1826afa3351f31637c72 -\u044C,1485d20e8308d9d7dc4db53fd89902ce1e47cd9e6b1ea5091ab2aeb3726c8c4 -\u044D,8fa45482596851154966c26f3e5614c3e172494fa45c6c63df6c3ee567c6 -\u044E,c5e961587cf06cde64c04d7876ea26ee5c8e1c90e2df5f2dd94d9d21396e792 -\u044F,e5c1796a96fcdfcba54ccd617a51b59006d7a9c9b426c1f16f1fe4e0d9e -\u2190,cdc9e4dcfa4221a1fadc1b5b2b11d8beeb57879af1c42362142bae1edd5 -\u2191,1ad6c81f899a785ecf26be1dc48eae2bcfe777a862390f5785e95bd83bd14d -\u2192,956a3618459e43b287b22b7e235ec699594546c6fcd6dc84bfca4cf30ab9311 -\u2193,882faf9a584c4d676d730b23f8942bb997fa3dad46d4f65e288c39eb471ce7 -\u2196,468f5037a5e54b71cc0fe814c5896a45adc2556e3c9abe3f7847dc5afec014 -\u2197,cd4e6c392e14f34b6a31e3635a8bf18d973eef6dc9b1a3519451497197d4c -\u2198,34b2863b662921cba6cd16394ef2325f931e8fa46bc743b4cfb94317ca5787 -\u2199,ddf29faa67ae5b613dc654da4331b98733da9734a762c8ee91ba146b6341 -\u23E9,98f293f294980d732f523321c34a4cdcc3e6f9e36c9320e150f1cce31aa5 -\u23EA,c4e490e1658bfde4d4ef1ea7cd646c5353377905a1369b86ee966746ae25ca7 -\u23F4,ad73cf66d31b83cd8b8644c15958c1b73c8d97323b801170c1d8864bb6a846d -\u23F5,c86185b1d519ade585f184c34f3f3e20bb641deb879e81378e4eaf209287 -\u2640,bfda596dcc81798bf0f2fe81ce83f62c92b9cb60b4f61d4cd6bb3359bf3e9a7f -\u2642,6c9d9fd578348b3ad01a7781e0920856b8e361e45617ce38af04811513f68197 -\u2648,94747de792b4bef9dada802d6d0c9574476633bb71db24d42e6ac177779ec997 -\u2649,ae714aa30fbb6fb75cf97ef0dcf0e66dc6197be0c814fedeb5f66861da21742e -\u264A,87de21f5a82870d2450009cb5cd5b339507dd9fb6c54ba3a9cf53ca398df48f4 -\u264B,908b8c8aeacd90e0e6ff4428acc22b7171cedcd3e3a974af5467316084f462c9 -\u264C,4b804d06fe1c3912d562c86a7da20634d4e7f8c6490bf30bb173c62ebea69c99 -\u264D,328cedc9931fe82a6d96e0dac28d9035b2bf4f17a1d66bde138e50438286a915 -\u264E,88d4514bff7c7fda76be78008f573aeabbe55c4739cf1a16cd25c601b49304cc -\u264F,abb8e6410abf98c13cc8bde8791c45dbcd2db3c6c821557d3fd2a97fab82321b -\u2650,72b7f9253c0a7659e5f96550ebbf3a870b28e1735698663bd2e8810977eae2aa -\u2651,2deb9d24b138d3376bace7df34c7b6be149113970c85e5202299dac1a87f51b4 -\u2652,eaf2b0d503aca1b9ff881560b38d994c687e701de5f3f144feeff5ccc4d61918 -\u2653,5ab2d50d71f83325c98cc2e8cf544023744ab05c0c609de17acfa19740471648 -\u2665,5463d366534d4176f4ec159385d63491d82f29f9f07323b877627bea3dc75d -\u266A,edc9d1b7fc9125b96333fe2d1acd1ca83d8f7f9f397bf7049ef2b6b8b76f7ff1 +" ",97c2144fdcb55c3fc1bf1de51cabdf52c3883bcb578923226beb0d85cb2d980 +!,b8ea57c7551c6ab33b8fed354b43df523f1e357c4b4f551143c34ddeac5b6c8d +"""",8c4114b6d3d8c34818b425c9fb9541f510f37caa4aee587066cbd9e83541aa13 +#,99b2bd29b9f36e265417d8d18745149259aad4c8fb5556bd53dc23d63a735a2 +$,8ba7d49233eac0c4f664967adb27fde1d2dc67937cf7d4ecf854a96ba18f5b0c +%,a9f27d54ec5552c2ed8f8e1917e8a21cb98814cbb4bc3643c2f561f9e1e69f +&,772aba4adac466ae19e432a915e547bdce17401fa5d1859ec84ecd463b31b +',a0c411995a290f390471e22e17b1b316ca977f50dcacbb93e94d84564756 +(,674153bb6a3fa8979a889f99aa0fc84ba9f427ff0d8e487f76fa6c8831d18e9 +),9c60e240cda0d9bb315b385119e5a9482e885827baf018e1c03b6a6d612d3f ++,60b55f74681c68283a1c1ce51f1c83b52e2971c91ee34efcb598df3990a7e7 +",",c3885a63453782c915ed6d894cf1d94318740f6a156d6ea9d39524ba5d05f65 +-,c3e4b533e4ba2dff7c0fa90f67e8bef36428b6cb06c45262631b0b25db85b +.,323e619dcb7511cdc252a5dca8565b19d952ac9f82d467e66c52242f9cd88fa +/,57b1791bdc46d8a5c51729e8982fd439bb40513f64b5babee93294efc1c7 +0,3f09018f46f349e553446946a38649fcfcf9fdfd62916aec33ebca96bb21b5 +1,ca516fbae16058f251aef9a68d3078549f48f6d5b683f19cf5a1745217d72cc +2,4698add39cf9e4ea92d42fadefdec3be8a7dafa11fb359de752e9f54aecedc9a +3,fd9e4cd5e1b9f3c8d6ca5a1bf45d86edd1d51e535dbf855fe9d2f5d4cffcd2 +4,f2a3d53898141c58d5acbcfc87469a87d48c5c1fc82fb4e72f7015a3648058 +5,d1fe36c4104247c87ebfd358ae6ca7809b61affd6245fa984069275d1cba763 +6,3ab4da2358b7b0e8980d03bdb64399efb4418763aaf89afb0434535637f0a1 +7,297712ba32496c9e82b20cc7d16e168b035b6f89f3df014324e4d7c365db3fb +8,abc0fda9fa1d9847a3b146454ad6737ad1be48bdaa94324426eca0918512d +9,d6abc61dcaefbd52d9689c0697c24c7ec4bc1afb56b8b3755e6154b24a5d8ba +:,2ffcc318c212dc749b599755e7697d492382993c07de3f8e54fe8fc7ddd1e +;,3690f391822451f064c9ec2aa66e60249dc8566fcdcd5acea72b8168274f +=,d773155306c9d2d58b149673951cbc6666aef87b8f873538fc85745f01b51 +?,bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40 +[,9326db518441ff329be356d651952c3362ea232ae6435c9993f8fdf62f3ca5f +\,40543b6ca17d2e4d132e43e77c92766cfbc61f89b72d8fb853f902ae1dd7b0 +],8745b1f41e7522327150555dcb97e17068ee63fb3fd0943fb3adb320ab401deb +_,461c8febcac21b9f63d87f9fd933589fe6468e93aa81cfcf5e52a4322e16e6 +a,4e41748121626f22ae16a4c664c7301a9f8ea591bf4d29888957682a9fdaf +b,42b9e16e26206a709bf07c2493ca4c5d24f5675654fc130d1d5ec5e8c5be5 +c,62a5876113322f39aa2bbef4bd6b79ec6b52a97bb6fab674bddbd7b6eab3ba +d,fa661419de49ff4a2c97b27f868014fbdaeb8dd7f4392777830b2714caafd1f +e,1aeef88e2c928b466c6ed5deaa4e1975a9436c2b1b498f9f7cbf92a9b599a6 +f,cd9d6e96b5b92ffcaf47dd1caf61d3f6e842913fc88849f3de548beed71fa8 +g,220c3b2bbfa1ed3ac8c35b3dd38247456563c92acefd5926b125ccc67d7d5fd +h,7ba9c33a95fa1e519f85a41ca56799384db41fe7e1d7a791751ece9bbae5d27f +i,5c99dfb2704e1bd6e7facfb43b3e6fbabaf16ebc7e1fab07417a6c464e1d +j,781efaa9bc3b60747a750a648b198787f186eb93859aea52031d5a8c881075 +k,35dc6d513cf1633372f41caa0261396e6cc6720e059308c679d44b47ed6 +l,d4affa455b7f58217de8acbbd9201c9ea87c134aa35625494f5d3f65ce946 +m,c8dec4666b4c67d8759714c85714be6ea4e39ff9628849f98b514edf1c3e4680 +n,da221e4f96bee6261752396a3265ffa4dedf8ff4839abd14f49edee1e53092 +o,cbb1d17cebc5f0ecc987b80efc03e32ecb1cb40dbc5bce2faf3e60542a40 +p,d02c10adc31b1c21cc98ecf809225f87e25e72378cf417db4be3f67e91bb1 +q,4524d28c82f3711a97501411ecc3cb466877483b122a2656c8eeadfb8d21 +r,78a81efdae47bcb480a25ed91ff6de9772b07ae87c3c4e277705abbbd3419 +s,d710138416528889815548b4623d28d86bbbae5619d69cd9dbc5ad6b43744 +t,a3fb50fe7559bc99f13c47356cce97fda3aa923557fb5bfb17c825abf4b1d19 +u,d6991dcba25eae243eb5ceb8325f4ab78f9f14127c382f6cd42c4c78042d4b5 +v,e8d68018994f2f2f59d9e5f2e3ba3d46d8b0b9ea0e684bfbb8ecc7b86eb924c +w,80c9483f51d1267432e0f2f3baa8cd93e65b5eac7482b27dbccebafb721748b +x,1d1a3c96562348527d5798f291609281f72e16d611f1a76c0fa7abe043665 +y,3da8b6473052ada22e6ca30c49f6dce9b99916e423ac4fc6b301ad733697f +z,70d44fee0303f6d37faca7e9c315309556fa3df379bdd582317aa368aa843e +{,4abcd9b4ee249d7b15f7e16edd3935cd50511a9358722c9a73db98a443327 +},6b3a8c6aef332bc2a4dedd20f65e6a6fb0aa32e2276f781f2dc24c8250d2 +\u00A1,f0be205d6089e498225e511dbc3c1d3bfd0739039da4d2e231aea2bb1f76f31a +\u00BF,e52701c6871bae03c1c37705d4349fe088ca9709bfde07ca0f2730469cb4e4 +\u00E4,5f76f247b9e737dd45820672b482e43b86011bbe1309beca561b39ca77c3e74 +\u00EB,c42471bd5ae565e8c331b8bc15ac60fea48db3726cb0b5a6da3b9f6c3b597c +\u00F1,e195f6da34ff1b0ceb4ae221111466f84e03e25a20435004d3e67848078c6867 +\u00F6,68d9e13d7b211a5f0f855631ec0f86c1990f467cb321b9a5837ccb917dada0 +\u00FC,70615c383fc1e415444b964e88e999a3c7fa895263be1abff14cafe4dd6881 +\u0431,ac82266158e57316477be6c1e0d83c53433687e02a6cdf293955064564d6 +\u0433,2c9f516557d2843c86ebc90c8897a39816559a7022e8b10925a95d579e77 +\u0434,2cc03e44c394b24de3b7f07d7ffe788a5fa6cfdd1564ef959fa7ac9fd95ed88 +\u0436,ebc0c360b1233021e43ad164d4ee895e3324122322e7db597a8a0b785af99 +\u0437,a8ba42fcf1e478c07612ae9b39affb756337c1c3fcd3b9eb318814b82ba37a +\u0438,c52011905bc220d06840ebf59fe0f475177ac535834e22147b37c3ff39542297 +\u0439,e47edef1a0742f3aa3ee4cb2b52e256347d2f2455eb16db7ae9a186d0afdc2b +\u043B,76f2f4b92473888f3a769083ff333dfa3847b2f8cd85e47b5a91e55bee6a8c +\u043F,5f238c868ed6e198d785f71e1a228cea4e32afa4c74fab47765c572d4e2c865 +\u0443,af0ad559daff1e61cbfbf28ca6b4328463608b5c22b40dcc693fb80a5c3ed +\u0444,51f4ceb54d64b5c8edea32c11aac107838eff23ace75b9b4bc27a0786b8f +\u0446,2c50395f333094dbcb47962a96eff74496622b1ea3cbd8e0baf18fcf31c8e8 +\u0447,f325c0a6dc79b58787f1cba3fadc39d8597af33d8ed01444f01f1967777a6 +\u0448,e5f29dd0645c8774b51a75c05db7f3f1b4c0a739665d6dca59f6c227ace5c11 +\u0449,4ee71e986db7b688425b3438823d51dda88279d51a0de4583ddc72b24ba886d +\u044A,8b4eeb9a4734ecca8ed19f851af7dc1c46fd5a317b09f1aa651ad9851ac28d7 +\u044B,3019ed4e1e2faa63ce5437d8daa570ced43bf1e8d22b1826afa3351f31637c72 +\u044C,1485d20e8308d9d7dc4db53fd89902ce1e47cd9e6b1ea5091ab2aeb3726c8c4 +\u044D,8fa45482596851154966c26f3e5614c3e172494fa45c6c63df6c3ee567c6 +\u044E,c5e961587cf06cde64c04d7876ea26ee5c8e1c90e2df5f2dd94d9d21396e792 +\u044F,e5c1796a96fcdfcba54ccd617a51b59006d7a9c9b426c1f16f1fe4e0d9e +\u2190,cdc9e4dcfa4221a1fadc1b5b2b11d8beeb57879af1c42362142bae1edd5 +\u2191,1ad6c81f899a785ecf26be1dc48eae2bcfe777a862390f5785e95bd83bd14d +\u2192,956a3618459e43b287b22b7e235ec699594546c6fcd6dc84bfca4cf30ab9311 +\u2193,882faf9a584c4d676d730b23f8942bb997fa3dad46d4f65e288c39eb471ce7 +\u2196,468f5037a5e54b71cc0fe814c5896a45adc2556e3c9abe3f7847dc5afec014 +\u2197,cd4e6c392e14f34b6a31e3635a8bf18d973eef6dc9b1a3519451497197d4c +\u2198,34b2863b662921cba6cd16394ef2325f931e8fa46bc743b4cfb94317ca5787 +\u2199,ddf29faa67ae5b613dc654da4331b98733da9734a762c8ee91ba146b6341 +\u23E9,98f293f294980d732f523321c34a4cdcc3e6f9e36c9320e150f1cce31aa5 +\u23EA,c4e490e1658bfde4d4ef1ea7cd646c5353377905a1369b86ee966746ae25ca7 +\u23F4,ad73cf66d31b83cd8b8644c15958c1b73c8d97323b801170c1d8864bb6a846d +\u23F5,c86185b1d519ade585f184c34f3f3e20bb641deb879e81378e4eaf209287 +\u2640,bfda596dcc81798bf0f2fe81ce83f62c92b9cb60b4f61d4cd6bb3359bf3e9a7f +\u2642,6c9d9fd578348b3ad01a7781e0920856b8e361e45617ce38af04811513f68197 +\u2648,94747de792b4bef9dada802d6d0c9574476633bb71db24d42e6ac177779ec997 +\u2649,ae714aa30fbb6fb75cf97ef0dcf0e66dc6197be0c814fedeb5f66861da21742e +\u264A,87de21f5a82870d2450009cb5cd5b339507dd9fb6c54ba3a9cf53ca398df48f4 +\u264B,908b8c8aeacd90e0e6ff4428acc22b7171cedcd3e3a974af5467316084f462c9 +\u264C,4b804d06fe1c3912d562c86a7da20634d4e7f8c6490bf30bb173c62ebea69c99 +\u264D,328cedc9931fe82a6d96e0dac28d9035b2bf4f17a1d66bde138e50438286a915 +\u264E,88d4514bff7c7fda76be78008f573aeabbe55c4739cf1a16cd25c601b49304cc +\u264F,abb8e6410abf98c13cc8bde8791c45dbcd2db3c6c821557d3fd2a97fab82321b +\u2650,72b7f9253c0a7659e5f96550ebbf3a870b28e1735698663bd2e8810977eae2aa +\u2651,2deb9d24b138d3376bace7df34c7b6be149113970c85e5202299dac1a87f51b4 +\u2652,eaf2b0d503aca1b9ff881560b38d994c687e701de5f3f144feeff5ccc4d61918 +\u2653,5ab2d50d71f83325c98cc2e8cf544023744ab05c0c609de17acfa19740471648 +\u2665,5463d366534d4176f4ec159385d63491d82f29f9f07323b877627bea3dc75d +\u266A,edc9d1b7fc9125b96333fe2d1acd1ca83d8f7f9f397bf7049ef2b6b8b76f7ff1 \u2713,ee28bea9d39373d36ee8fa40ec83f9c3fcdd93175227743f9dd1f7e7886b7ee5 \ No newline at end of file diff --git a/src/main/resources/fonts/yellow.csv b/IF/src/main/resources/fonts/yellow.csv similarity index 98% rename from src/main/resources/fonts/yellow.csv rename to IF/src/main/resources/fonts/yellow.csv index bfd45014..8f716640 100644 --- a/src/main/resources/fonts/yellow.csv +++ b/IF/src/main/resources/fonts/yellow.csv @@ -1,118 +1,118 @@ -" ",ab2cdf481747f11993647937e9c489d8bebcaf5f2d886fd98c2032844d1 -!,9b934ab94b56c348ada42e2126f4f9743291c2b6ef449dc4e38315dc7b1ac -"""",6f5948a1d388a928ad1c671549fc4236b1976dfb7f8ed31d89d56f11248d4 -#,fe98c9a59b6e5c8876b4bca2acfc7b6f4eaaec684494de4767c1d4e7b8ad55 -$,d9e9068d15b4d8a4b64fbb0674410db349a6c6aad79fe8a5ab71e94da240fff6 -%,dbee97fdc5c1985b9aed306176d8c432847f3aed8f1e296f12f723aeec44d -&,81c43a22c098ba79a95fcd355b946e533c3fefb9cf77919a9dadcbb44ffba78 -',7039f6e6f4fcaa597b3ab2f368d5345f8a1e7497780386717ac5351d0af2e -(,26bafb6c82d13fa846cb405e8cb6e461feffcd874a350f097e5235bb5cfa6c5 -),561de541355af84416a23afca7884f7fcc8dbe26ddf885b671f8d6f8ae8dd8 -+,edfff1b3c5d85fe3cdd5656869baa0eade5e53aca9d561427648cc72f5e25a9 -",",8e57b1a264a079e76a473633353a995e617f9361246324fcffdb63a3c516fb --,ed24dfaf1ee17d73eeec2422158ca33ad187ee727abb796f2132dedfd01fc49e -.,6a16b5ca1014e18463a8e75c610d63ec774cde33a9936692b9e3774375 -/,96cf881cfa165e7464ccd9e5c94f926c36fa6fa1343b5d68ee6d48ddf33765 -0,15b2484ad3693c69110ca45e28201771605bbeb49f277382ef2d9921455 -1,b949df36a1a3f7cb4c67065a9d5350258a3c51b02a1a377b84a82876d77b -2,58cca1e0fb5d9bf77f527356e8bf4e53cb4a4c56f11e779abadae541bbedc6 -3,fe907672a470938525058c0ea319d8be5ba28d972c52f2bd55dbf4182b8 -4,af2d2601f9c1aceffcc823657e2259d358bb52bd46312bf1c76ee23d3b17 -5,b7973537bd2162a78a586397a1eda8599f4c90dc11a1e7d655288483429251bd -6,df4960f57dcc1852f974a4288778b45477678b3c3671e2cfa8205022443b6923 -7,e4fd8cfc44658f6c78c376b2752df3c63610a5aed194f2eca3e6736d47ce72 -8,7acc81bd5a59a1862a2c01be7412231e15ce057d458fbc18435b9385593f5 -9,85bdbddbb81ae7a894b6df0a5f8e21c22fbd065dc8211b41737e0a1d0c2cfc6 -:,89186c3e64c1c36755350c1c11e5ab9d65a1b6acabeb2e84a5b8e16fca77 -;,711856c48743a6bcda8d1b56baabd2e71ab1a46c2d9ce2ff651c7440f4b830 -=,36633ae5eb7121f8bde5acdf87a09f67800d7cedf4190f129e78efee9e63 -?,718079d5847416abf44e8c2fec2ccd44f08d736ca8e51f95a436d85f643fbc -[,7a8d985a10532fc8f2a4d1572b3bd83afab936b7b48f2d3d6548ad78 -\,387ed6b0d2abc893b04f55b517422299a538e29ce35b8d77197561f861c9fe1 -],71173924421a41f58bf2c71e8a473d9b8656a4ef8d2b2ce6d5d26c6bbf4795cc -_,11667bf289231b6ad8e8d43a498290f1b44f3ae7525ef17ffb9b616ab71477 -a,17ef28de8e2accdcb23b0942f5624f4149a5aa490ec19f7dc4991a850b65f40 -b,12694ede96b218511602153f665398be7c9669caf672c4bc8f35bcd517e28c3 -c,13cf53c847e2c485d421ca3b2f5bbba439da190642a188c228b279b3fac52d -d,493ff94569cc2fd4113e5cbf55a47c67a070919fb3d64adde2c5ada3d29572a1 -e,71a8b843d88d639a62bb30a77df34f819b42347e1d6fe5372edcbeae53fa4a8 -f,e237d0992c63f3a49fd236a5d68680bda5d17c38bdd8cad417cc91d51068d2 -g,4a39df898cbdf0ca741ac5b57542152419c8f60703d5c349b8fd0e86117b2e1 -h,5fce5d85b4895662f336429c5bf5ca2ca33f6195bf24762224123841096758 -i,57c89cd652b121c5bed4315e9ef04c6a13f6ddf762881bfac8f5e5c6fd90 -j,7ae65b7d6912a311e2644ea14b5d302ab238dfa4bf02a0ea51d831489a4fd8 -k,c99862b0f8874a67478e973219e6c8186dd6bdc4396baa2f4f5ee9fc86f884 -l,1a837d84eb363ffbb933496e39d9206496ff7576982219ea25cf5d515bc5c -m,bc917f2f64aacd895395dc4e2877be7ccb3dc1e9d2c4c1c7fac7634ac8ad -n,40407391cf059ff8e403f32e96f22c0631fff4c7c37bde114cef66c3eae5d4 -o,7ca93c7bc8e38dddfa44cd68cb6e44b755c5e8acae2b9c63f832454b2ae3bb6 -p,65ed6035a512c63ff5312573f9511b3143ce7d7aaba22345dff439736d51c1c -q,d8d295cc3415fffa22b58010d39ca84e1ba69f4a85c16674776e14d986dfe7 -r,6ac6f775e8acfdf6e1deac80a8da1f37b3b4ba5caa4a35249f9eb145ccf43da5 -s,9d3841a1b85bf22bacdbe8a28e076ddc88fa869d469ac3b49b16fcb4f492b -t,43d4a3d59b49a19bb890e1a43fb1f87e2f20c4d61c34744512ea165a8ec58 -u,2c21b56bfba659911a5c75c48fe1aa29ab1b5760ec21532ee7a1db17cebfdf2d -v,34cb8048817c20b8c1399948f0f977d95b9a8c531897a686a64f39fbc17b7e1 -w,4e97da85a91474beb58f99a9f8dd17754e5da0c16c41c4183431d3b48a234e -x,6360dcf8235f823f6cbb2a996457daa7b92b5ef1554ab58e0f34839118d54 -y,f64f62146c759fb411692cca9d12acd2e5f16470948d42de907fd6c3f0e83c -z,dbd61ec2858aef9060bacbc91ae728b5de50ecb759a34140337e743d741 -{,22d9c6232b8332effc634551f38d4e9a9b4a96d98ffcbe63fafab6461db0 -},4f8dc2723b91d753183cdc60b0ba74f3ad4e5ba544b67a2f211bc9118ad -\u00A1,a8f7f16235df227a6a198dc9a0149ffc66e9cff0e07fac23817c0b9e8126ccb9 -\u00BF,762b3497158007f7d8c3d799578c91c9935bb0b36f5a9bfcc1d4953e0c511226 -\u00E4,9a4b12c5ce67ab4e9ffdcbb0a94e2851ff1a33793b1af4a59bcd7da84f6e -\u00EB,7d8f606a104508d999770e7237a2136de4bd20ec911137c5648377838dac9 -\u00F1,f96cc6d73051f548159f06d1e9a9415f631d302748e771a2cee339fd0da9438f -\u00F6,d45e51726ce418299a925a6a8e53a80d3991fe215c73b1b2214b278576e033 -\u00FC,2ac8a4a577eee06b6b88d457124c243f5f2aca9eb2b2c828c81f8b9e5e27c -\u0431,c582a049e7a997f0aa1b991c532c3b9832c6792ab4eb237750ef75d4664d787c -\u0433,ac9f484e48d5c7043c9a7ce9e1f420036e6f695f31626428a26440d66254 -\u0434,b77dcc454e839d98a952312bc33aa18719eef134752a4cf588ab8723a9af3f -\u0436,f08a2a9ead6129f9f7676ddd1c826d727417dc0865e6dc9dea0ba15b346b7c -\u0437,c671f36cd152df6613429c8cbda4c7934e42a64949eaf32a3ec2e2be6683f -\u0438,57d74f3e3753f99bdc36bfb540a16ac03eb27eba46ce2c81adb2e04a4ce89c -\u0439,9d97f6bce1121566687d87815a9e35736d24ce2394d88bf597eccff2fe2a2d -\u043B,4dacd0dd559ae514baf2d1363a33673e6f9ee89ee29dfcce28de85969ea8f -\u043F,c82944d4cf718c669aca86f4f718c6595316c79167d938218cb1d17bc341b7a -\u0443,33dbb2dfb3ba5b1d2f498801eb2d4f826585cf335ec87bd0339418dbb8996e -\u0444,b41ca8e6b6c2c6c78f172ac27ad49bdd46ba8b776995ec8327e98ccc6ea372 -\u0446,0daaeebc362e46aab6556238834ac558f147d099b346408e9a61df38e2fbe -\u0447,c62225f3d22dc83a5297d59c9ef2f2585370afd695b12eebb6ce8df21e9b29a8 -\u0448,89b2a5fb4c80d44e5ec1cce5ff210213b3333e1ecb97b9e31641ba993efbe8 -\u0449,53fef34f462da0211776cd0133ef115866bddc75bf98c8976567e679d88515 -\u044A,1d7447a27b9d533b3e82228821f28fc2219b5a78f1daaa1a4c295f5ac79e5 -\u044B,277b5c565f12f4536f536bb73e2f767bacab4bf53d01d4f1ae6ecf97ea3ac6a -\u044C,e19ce653e139454ca9776ecad6c9caa1aed5e875a384b68906879565e485 -\u044D,48b3305bb2665f355d6249a695499942c0df24fef0d4d5375ea08fe59bef2642 -\u044E,c91d5be76f55a3b83bf7f13769ce213a2f63b7a2a89172b5b66fe9f43944ec -\u044F,178d31e33b62c9913b2349cda8eec43e19fb30229c1bbbe898b339692bd261 -\u2190,49b2bee39b6ef47e182d6f1dca9dea842fcd68bda9bacc6a6d66a8dcdf3ec -\u2191,3e4f2f9698c3f186fe44cc63d2f3c4f9a241223acf0581775d9cecd7075 -\u2192,141ff6bc67a481232d2e669e43c4f087f9d2306665b4f829fb86892d13b70ca -\u2193,6b29eceef3ddb14f906dbd4fa41d63f3d7d4537871cee4315c59e76ebc5f85 -\u2196,10279495de2e372c4192246786c911317eb41af5fd1cfb318e30cfd5c7c76c -\u2197,50a18aeee357a22d94211c349962d1ce521039b05be542945c441f9193a119e -\u2198,3ae8bda3e58452c87bcd5f2feccabd282bc22310a951fd1bdb1b15687fbdf -\u2199,953bda2ed46efae26d6b6f3282e28394ee39f3313cf39af8d9e39709b87643b -\u23E9,738816b8eafb5a0e49cbaa096cd924d7a1463a4e84d203d92e3157758797b -\u23EA,b1241fabf6bf75861e1022e57f9a839f3818da1144341cb0502847d94ce7c5 -\u23F4,ab6e2191f14ce9932c3e24c5f8c8479c740cf4dfafa258153ee807362af4812 -\u23F5,e4f9f1589ceb2df743a8e32b919a6c75a207f74681923cd9edffa03e494d5c -\u2640,1ab0aff8514d2a8af5ce83a4aa3aa5837567d91c746e119b99f4d0e79986fca1 -\u2642,45bf45332ffba08a4b23fcaf312c3ac13561b6feb75e4a7e06b87722bf86c507 -\u2648,4ff6d21d6d1e05625faccfdf4a5175e99684d9ed9cc7f96e587eb95b673e560e -\u2649,bc02f117a26e00eeb5d4518e1f5d2063e329b78c626c48541132cfa1c44577c1 -\u264A,aed3e99e954c570c147c7d7e923903a4086b9f4b87bd93376ad7642b35f75563 -\u264B,2de86b8a310a0164faa806a3b74fad9112fc514b9def08740aabcdc403a16496 -\u264C,247fa61ca12fe4410dfd2061ac4c3260d7500675509c5942c479ffc16ccab2b5 -\u264D,77f857d5067ebcc7586125174b17d26d1df25bf60f9b6f0a49bcea991082208 -\u264E,c567dffc07807527856e091e3aa6864311325c4a4302aba058f85109321784cb -\u264F,1afc823f6c625f4ed49eb954fdc7c96bb633a45bf3b5c6b7978046355f3b9c69 -\u2650,93f6e44e88ed582049e9238516830e6dd465f56e7f79f62c76191feca45a2ee0 -\u2651,ec45378f21ed015068c0495fe7ac7b1537c5c4caf2cc67eb964ff52278c6596c -\u2652,9c0a76a8a5c4f4339d13d5de7188a958aa5ef50e0e699f7a23f5d109141ebb0 -\u2653,5da1426abe4b0ab46cab13c27b9e206304a76fff74342f23e0f68c02935e2eb1 -\u2665,103da2ed6f1b9cde85218e2780a1f9223dc638c8810fbaad1ae77d6feae7ad7 -\u266A,929a4365576defce19a2ebc643bc59e1487ee8c250a9e9fa288f8723e4025507 +" ",ab2cdf481747f11993647937e9c489d8bebcaf5f2d886fd98c2032844d1 +!,9b934ab94b56c348ada42e2126f4f9743291c2b6ef449dc4e38315dc7b1ac +"""",6f5948a1d388a928ad1c671549fc4236b1976dfb7f8ed31d89d56f11248d4 +#,fe98c9a59b6e5c8876b4bca2acfc7b6f4eaaec684494de4767c1d4e7b8ad55 +$,d9e9068d15b4d8a4b64fbb0674410db349a6c6aad79fe8a5ab71e94da240fff6 +%,dbee97fdc5c1985b9aed306176d8c432847f3aed8f1e296f12f723aeec44d +&,81c43a22c098ba79a95fcd355b946e533c3fefb9cf77919a9dadcbb44ffba78 +',7039f6e6f4fcaa597b3ab2f368d5345f8a1e7497780386717ac5351d0af2e +(,26bafb6c82d13fa846cb405e8cb6e461feffcd874a350f097e5235bb5cfa6c5 +),561de541355af84416a23afca7884f7fcc8dbe26ddf885b671f8d6f8ae8dd8 ++,edfff1b3c5d85fe3cdd5656869baa0eade5e53aca9d561427648cc72f5e25a9 +",",8e57b1a264a079e76a473633353a995e617f9361246324fcffdb63a3c516fb +-,ed24dfaf1ee17d73eeec2422158ca33ad187ee727abb796f2132dedfd01fc49e +.,6a16b5ca1014e18463a8e75c610d63ec774cde33a9936692b9e3774375 +/,96cf881cfa165e7464ccd9e5c94f926c36fa6fa1343b5d68ee6d48ddf33765 +0,15b2484ad3693c69110ca45e28201771605bbeb49f277382ef2d9921455 +1,b949df36a1a3f7cb4c67065a9d5350258a3c51b02a1a377b84a82876d77b +2,58cca1e0fb5d9bf77f527356e8bf4e53cb4a4c56f11e779abadae541bbedc6 +3,fe907672a470938525058c0ea319d8be5ba28d972c52f2bd55dbf4182b8 +4,af2d2601f9c1aceffcc823657e2259d358bb52bd46312bf1c76ee23d3b17 +5,b7973537bd2162a78a586397a1eda8599f4c90dc11a1e7d655288483429251bd +6,df4960f57dcc1852f974a4288778b45477678b3c3671e2cfa8205022443b6923 +7,e4fd8cfc44658f6c78c376b2752df3c63610a5aed194f2eca3e6736d47ce72 +8,7acc81bd5a59a1862a2c01be7412231e15ce057d458fbc18435b9385593f5 +9,85bdbddbb81ae7a894b6df0a5f8e21c22fbd065dc8211b41737e0a1d0c2cfc6 +:,89186c3e64c1c36755350c1c11e5ab9d65a1b6acabeb2e84a5b8e16fca77 +;,711856c48743a6bcda8d1b56baabd2e71ab1a46c2d9ce2ff651c7440f4b830 +=,36633ae5eb7121f8bde5acdf87a09f67800d7cedf4190f129e78efee9e63 +?,718079d5847416abf44e8c2fec2ccd44f08d736ca8e51f95a436d85f643fbc +[,7a8d985a10532fc8f2a4d1572b3bd83afab936b7b48f2d3d6548ad78 +\,387ed6b0d2abc893b04f55b517422299a538e29ce35b8d77197561f861c9fe1 +],71173924421a41f58bf2c71e8a473d9b8656a4ef8d2b2ce6d5d26c6bbf4795cc +_,11667bf289231b6ad8e8d43a498290f1b44f3ae7525ef17ffb9b616ab71477 +a,17ef28de8e2accdcb23b0942f5624f4149a5aa490ec19f7dc4991a850b65f40 +b,12694ede96b218511602153f665398be7c9669caf672c4bc8f35bcd517e28c3 +c,13cf53c847e2c485d421ca3b2f5bbba439da190642a188c228b279b3fac52d +d,493ff94569cc2fd4113e5cbf55a47c67a070919fb3d64adde2c5ada3d29572a1 +e,71a8b843d88d639a62bb30a77df34f819b42347e1d6fe5372edcbeae53fa4a8 +f,e237d0992c63f3a49fd236a5d68680bda5d17c38bdd8cad417cc91d51068d2 +g,4a39df898cbdf0ca741ac5b57542152419c8f60703d5c349b8fd0e86117b2e1 +h,5fce5d85b4895662f336429c5bf5ca2ca33f6195bf24762224123841096758 +i,57c89cd652b121c5bed4315e9ef04c6a13f6ddf762881bfac8f5e5c6fd90 +j,7ae65b7d6912a311e2644ea14b5d302ab238dfa4bf02a0ea51d831489a4fd8 +k,c99862b0f8874a67478e973219e6c8186dd6bdc4396baa2f4f5ee9fc86f884 +l,1a837d84eb363ffbb933496e39d9206496ff7576982219ea25cf5d515bc5c +m,bc917f2f64aacd895395dc4e2877be7ccb3dc1e9d2c4c1c7fac7634ac8ad +n,40407391cf059ff8e403f32e96f22c0631fff4c7c37bde114cef66c3eae5d4 +o,7ca93c7bc8e38dddfa44cd68cb6e44b755c5e8acae2b9c63f832454b2ae3bb6 +p,65ed6035a512c63ff5312573f9511b3143ce7d7aaba22345dff439736d51c1c +q,d8d295cc3415fffa22b58010d39ca84e1ba69f4a85c16674776e14d986dfe7 +r,6ac6f775e8acfdf6e1deac80a8da1f37b3b4ba5caa4a35249f9eb145ccf43da5 +s,9d3841a1b85bf22bacdbe8a28e076ddc88fa869d469ac3b49b16fcb4f492b +t,43d4a3d59b49a19bb890e1a43fb1f87e2f20c4d61c34744512ea165a8ec58 +u,2c21b56bfba659911a5c75c48fe1aa29ab1b5760ec21532ee7a1db17cebfdf2d +v,34cb8048817c20b8c1399948f0f977d95b9a8c531897a686a64f39fbc17b7e1 +w,4e97da85a91474beb58f99a9f8dd17754e5da0c16c41c4183431d3b48a234e +x,6360dcf8235f823f6cbb2a996457daa7b92b5ef1554ab58e0f34839118d54 +y,f64f62146c759fb411692cca9d12acd2e5f16470948d42de907fd6c3f0e83c +z,dbd61ec2858aef9060bacbc91ae728b5de50ecb759a34140337e743d741 +{,22d9c6232b8332effc634551f38d4e9a9b4a96d98ffcbe63fafab6461db0 +},4f8dc2723b91d753183cdc60b0ba74f3ad4e5ba544b67a2f211bc9118ad +\u00A1,a8f7f16235df227a6a198dc9a0149ffc66e9cff0e07fac23817c0b9e8126ccb9 +\u00BF,762b3497158007f7d8c3d799578c91c9935bb0b36f5a9bfcc1d4953e0c511226 +\u00E4,9a4b12c5ce67ab4e9ffdcbb0a94e2851ff1a33793b1af4a59bcd7da84f6e +\u00EB,7d8f606a104508d999770e7237a2136de4bd20ec911137c5648377838dac9 +\u00F1,f96cc6d73051f548159f06d1e9a9415f631d302748e771a2cee339fd0da9438f +\u00F6,d45e51726ce418299a925a6a8e53a80d3991fe215c73b1b2214b278576e033 +\u00FC,2ac8a4a577eee06b6b88d457124c243f5f2aca9eb2b2c828c81f8b9e5e27c +\u0431,c582a049e7a997f0aa1b991c532c3b9832c6792ab4eb237750ef75d4664d787c +\u0433,ac9f484e48d5c7043c9a7ce9e1f420036e6f695f31626428a26440d66254 +\u0434,b77dcc454e839d98a952312bc33aa18719eef134752a4cf588ab8723a9af3f +\u0436,f08a2a9ead6129f9f7676ddd1c826d727417dc0865e6dc9dea0ba15b346b7c +\u0437,c671f36cd152df6613429c8cbda4c7934e42a64949eaf32a3ec2e2be6683f +\u0438,57d74f3e3753f99bdc36bfb540a16ac03eb27eba46ce2c81adb2e04a4ce89c +\u0439,9d97f6bce1121566687d87815a9e35736d24ce2394d88bf597eccff2fe2a2d +\u043B,4dacd0dd559ae514baf2d1363a33673e6f9ee89ee29dfcce28de85969ea8f +\u043F,c82944d4cf718c669aca86f4f718c6595316c79167d938218cb1d17bc341b7a +\u0443,33dbb2dfb3ba5b1d2f498801eb2d4f826585cf335ec87bd0339418dbb8996e +\u0444,b41ca8e6b6c2c6c78f172ac27ad49bdd46ba8b776995ec8327e98ccc6ea372 +\u0446,0daaeebc362e46aab6556238834ac558f147d099b346408e9a61df38e2fbe +\u0447,c62225f3d22dc83a5297d59c9ef2f2585370afd695b12eebb6ce8df21e9b29a8 +\u0448,89b2a5fb4c80d44e5ec1cce5ff210213b3333e1ecb97b9e31641ba993efbe8 +\u0449,53fef34f462da0211776cd0133ef115866bddc75bf98c8976567e679d88515 +\u044A,1d7447a27b9d533b3e82228821f28fc2219b5a78f1daaa1a4c295f5ac79e5 +\u044B,277b5c565f12f4536f536bb73e2f767bacab4bf53d01d4f1ae6ecf97ea3ac6a +\u044C,e19ce653e139454ca9776ecad6c9caa1aed5e875a384b68906879565e485 +\u044D,48b3305bb2665f355d6249a695499942c0df24fef0d4d5375ea08fe59bef2642 +\u044E,c91d5be76f55a3b83bf7f13769ce213a2f63b7a2a89172b5b66fe9f43944ec +\u044F,178d31e33b62c9913b2349cda8eec43e19fb30229c1bbbe898b339692bd261 +\u2190,49b2bee39b6ef47e182d6f1dca9dea842fcd68bda9bacc6a6d66a8dcdf3ec +\u2191,3e4f2f9698c3f186fe44cc63d2f3c4f9a241223acf0581775d9cecd7075 +\u2192,141ff6bc67a481232d2e669e43c4f087f9d2306665b4f829fb86892d13b70ca +\u2193,6b29eceef3ddb14f906dbd4fa41d63f3d7d4537871cee4315c59e76ebc5f85 +\u2196,10279495de2e372c4192246786c911317eb41af5fd1cfb318e30cfd5c7c76c +\u2197,50a18aeee357a22d94211c349962d1ce521039b05be542945c441f9193a119e +\u2198,3ae8bda3e58452c87bcd5f2feccabd282bc22310a951fd1bdb1b15687fbdf +\u2199,953bda2ed46efae26d6b6f3282e28394ee39f3313cf39af8d9e39709b87643b +\u23E9,738816b8eafb5a0e49cbaa096cd924d7a1463a4e84d203d92e3157758797b +\u23EA,b1241fabf6bf75861e1022e57f9a839f3818da1144341cb0502847d94ce7c5 +\u23F4,ab6e2191f14ce9932c3e24c5f8c8479c740cf4dfafa258153ee807362af4812 +\u23F5,e4f9f1589ceb2df743a8e32b919a6c75a207f74681923cd9edffa03e494d5c +\u2640,1ab0aff8514d2a8af5ce83a4aa3aa5837567d91c746e119b99f4d0e79986fca1 +\u2642,45bf45332ffba08a4b23fcaf312c3ac13561b6feb75e4a7e06b87722bf86c507 +\u2648,4ff6d21d6d1e05625faccfdf4a5175e99684d9ed9cc7f96e587eb95b673e560e +\u2649,bc02f117a26e00eeb5d4518e1f5d2063e329b78c626c48541132cfa1c44577c1 +\u264A,aed3e99e954c570c147c7d7e923903a4086b9f4b87bd93376ad7642b35f75563 +\u264B,2de86b8a310a0164faa806a3b74fad9112fc514b9def08740aabcdc403a16496 +\u264C,247fa61ca12fe4410dfd2061ac4c3260d7500675509c5942c479ffc16ccab2b5 +\u264D,77f857d5067ebcc7586125174b17d26d1df25bf60f9b6f0a49bcea991082208 +\u264E,c567dffc07807527856e091e3aa6864311325c4a4302aba058f85109321784cb +\u264F,1afc823f6c625f4ed49eb954fdc7c96bb633a45bf3b5c6b7978046355f3b9c69 +\u2650,93f6e44e88ed582049e9238516830e6dd465f56e7f79f62c76191feca45a2ee0 +\u2651,ec45378f21ed015068c0495fe7ac7b1537c5c4caf2cc67eb964ff52278c6596c +\u2652,9c0a76a8a5c4f4339d13d5de7188a958aa5ef50e0e699f7a23f5d109141ebb0 +\u2653,5da1426abe4b0ab46cab13c27b9e206304a76fff74342f23e0f68c02935e2eb1 +\u2665,103da2ed6f1b9cde85218e2780a1f9223dc638c8810fbaad1ae77d6feae7ad7 +\u266A,929a4365576defce19a2ebc643bc59e1487ee8c250a9e9fa288f8723e4025507 \u2713,eef425b4db7d62b200e89c013e421a9e110bfb27f2d8b9f5884d10104d00f4f4 \ No newline at end of file diff --git a/IF/src/test/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponentTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponentTest.java new file mode 100644 index 00000000..c5d04ed4 --- /dev/null +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/gui/InventoryComponentTest.java @@ -0,0 +1,99 @@ +package com.github.stefvanschie.inventoryframework.gui; + +import com.github.stefvanschie.inventoryframework.pane.*; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class InventoryComponentTest { + + @Test + void testConstructor() { + assertThrows(IllegalArgumentException.class, () -> new InventoryComponent(-1, 1)); + assertThrows(IllegalArgumentException.class, () -> new InventoryComponent(1, -1)); + assertThrows(IllegalArgumentException.class, () -> new InventoryComponent(-1, -1)); + assertDoesNotThrow(() -> new InventoryComponent(0, 0)); + } + + @Test + void testAddPane() { + InventoryComponent inventoryComponent = new InventoryComponent(0, 0); + + inventoryComponent.addPane(new StaticPane(0, 0)); + + List panes = inventoryComponent.getPanes(); + + assertEquals(1, panes.size()); + assertTrue(panes.get(0) instanceof StaticPane); + } + + @Test + void testCopy() { + InventoryComponent original = new InventoryComponent(0, 0); + + original.addPane(new StaticPane(0, 0)); + original.addPane(new OutlinePane(0, 0)); + + InventoryComponent copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPanes().size(), copy.getPanes().size()); + } + + @Test + void testExcludeRowsValid() { + InventoryComponent original = new InventoryComponent(0, 6); + + original.addPane(new StaticPane(0, 0)); + original.addPane(new OutlinePane(0, 0)); + original.addPane(new PaginatedPane(0, 0)); + original.addPane(new MasonryPane(0, 0)); + + InventoryComponent shrunk = original.excludeRows(4, 4); + + assertEquals(5, shrunk.getHeight()); + assertEquals(original.getPanes().size(), shrunk.getPanes().size()); + + for (Pane pane : original.getPanes()) { + assertTrue(shrunk.getPanes().contains(pane)); + } + } + + @Test + void testExcludeRowsInvalid() { + InventoryComponent inventoryComponent = new InventoryComponent(0, 5); + + //noinspection ResultOfMethodCallIgnored + assertThrows(IllegalArgumentException.class, () -> inventoryComponent.excludeRows(8, 8)); + } + + @Test + void testGetPanesEmptyWhenNone() { + assertEquals(0, new InventoryComponent(0, 0).getPanes().size()); + } + + @Test + void testGetPanesSorted() { + InventoryComponent inventoryComponent = new InventoryComponent(0, 0); + + inventoryComponent.addPane(new StaticPane(0, 0, 0, 0, Pane.Priority.HIGHEST)); + inventoryComponent.addPane(new OutlinePane(0, 0, 0, 0, Pane.Priority.LOW)); + inventoryComponent.addPane(new PaginatedPane(0, 0, 0, 0, Pane.Priority.MONITOR)); + + List panes = inventoryComponent.getPanes(); + + assertEquals(Pane.Priority.LOW, panes.get(0).getPriority()); + assertEquals(Pane.Priority.HIGHEST, panes.get(1).getPriority()); + assertEquals(Pane.Priority.MONITOR, panes.get(2).getPriority()); + } + + @Test + void testGetSize() { + assertEquals(30, new InventoryComponent(3, 10).getSize()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java similarity index 94% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java index 665639da..e1f4a9ab 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/MasonryPaneTest.java @@ -1,37 +1,36 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.pane.component.CycleButton; -import com.github.stefvanschie.inventoryframework.pane.component.ToggleButton; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class MasonryPaneTest { - - @Test - void testCopy() { - MasonryPane original = new MasonryPane(7, 5, 1, 1, Pane.Priority.LOW); - original.setVisible(false); - original.setOrientation(Orientable.Orientation.VERTICAL); - - original.addPane(new CycleButton(1, 1)); - original.addPane(new StaticPane(1, 1)); - original.addPane(new PaginatedPane(1, 1)); - original.addPane(new MasonryPane(1, 1)); - original.addPane(new OutlinePane(1, 1)); - - MasonryPane copy = original.copy(); - - assertNotSame(original, copy); - - assertEquals(original.getX(), copy.getX()); - assertEquals(original.getY(), copy.getY()); - assertEquals(original.getLength(), copy.getLength()); - assertEquals(original.getHeight(), copy.getHeight()); - assertEquals(original.getPriority(), copy.getPriority()); - assertEquals(original.isVisible(), copy.isVisible()); - assertEquals(original.getOrientation(), copy.getOrientation()); - assertEquals(original.getPanes().size(), copy.getPanes().size()); - assertEquals(original.getUUID(), copy.getUUID()); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.pane.component.CycleButton; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class MasonryPaneTest { + + @Test + void testCopy() { + MasonryPane original = new MasonryPane(7, 5, 1, 1, Pane.Priority.LOW); + original.setVisible(false); + original.setOrientation(Orientable.Orientation.VERTICAL); + + original.addPane(new CycleButton(1, 1)); + original.addPane(new StaticPane(1, 1)); + original.addPane(new PaginatedPane(1, 1)); + original.addPane(new MasonryPane(1, 1)); + original.addPane(new OutlinePane(1, 1)); + + MasonryPane copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getX(), copy.getX()); + assertEquals(original.getY(), copy.getY()); + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPriority(), copy.getPriority()); + assertEquals(original.isVisible(), copy.isVisible()); + assertEquals(original.getOrientation(), copy.getOrientation()); + assertEquals(original.getPanes().size(), copy.getPanes().size()); + assertEquals(original.getUUID(), copy.getUUID()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java index 27924fd7..3522c118 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/OutlinePaneTest.java @@ -1,47 +1,47 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.pane.util.Mask; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class OutlinePaneTest { - - @Test - void testApplyMaskInvalidDimensions() { - assertThrows(IllegalArgumentException.class, () -> - new OutlinePane(3, 7).applyMask(new Mask("0", "1"))); - } - - @Test - void testCopy() { - OutlinePane original = new OutlinePane(8, 5, 1, 1, Pane.Priority.HIGHEST); - original.setVisible(false); - original.setOrientation(Orientable.Orientation.VERTICAL); - original.setRotation(180); - original.setGap(0); - original.setRepeat(false); - original.flipHorizontally(true); - original.flipVertically(true); - original.applyMask(new Mask("0")); - - OutlinePane copy = original.copy(); - - assertNotSame(original, copy); - - assertEquals(original.getX(), copy.getX()); - assertEquals(original.getY(), copy.getY()); - assertEquals(original.getLength(), copy.getLength()); - assertEquals(original.getHeight(), copy.getHeight()); - assertEquals(original.getPriority(), copy.getPriority()); - assertEquals(original.isVisible(), copy.isVisible()); - assertEquals(original.getOrientation(), copy.getOrientation()); - assertEquals(original.getRotation(), copy.getRotation()); - assertEquals(original.getGap(), copy.getGap()); - assertEquals(original.doesRepeat(), copy.doesRepeat()); - assertEquals(original.isFlippedHorizontally(), copy.isFlippedHorizontally()); - assertEquals(original.isFlippedVertically(), copy.isFlippedVertically()); - assertEquals(original.getMask(), copy.getMask()); - assertEquals(original.getUUID(), copy.getUUID()); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.pane.util.Mask; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class OutlinePaneTest { + + @Test + void testApplyMaskInvalidDimensions() { + assertThrows(IllegalArgumentException.class, () -> + new OutlinePane(3, 7).applyMask(new Mask("0", "1"))); + } + + @Test + void testCopy() { + OutlinePane original = new OutlinePane(8, 5, 1, 1, Pane.Priority.HIGHEST); + original.setVisible(false); + original.setOrientation(Orientable.Orientation.VERTICAL); + original.setRotation(180); + original.setGap(0); + original.setRepeat(false); + original.flipHorizontally(true); + original.flipVertically(true); + original.applyMask(new Mask("0")); + + OutlinePane copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getX(), copy.getX()); + assertEquals(original.getY(), copy.getY()); + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPriority(), copy.getPriority()); + assertEquals(original.isVisible(), copy.isVisible()); + assertEquals(original.getOrientation(), copy.getOrientation()); + assertEquals(original.getRotation(), copy.getRotation()); + assertEquals(original.getGap(), copy.getGap()); + assertEquals(original.doesRepeat(), copy.doesRepeat()); + assertEquals(original.isFlippedHorizontally(), copy.isFlippedHorizontally()); + assertEquals(original.isFlippedVertically(), copy.isFlippedVertically()); + assertEquals(original.getMask(), copy.getMask()); + assertEquals(original.getUUID(), copy.getUUID()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java index 2805502b..6be43125 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaginatedPaneTest.java @@ -1,40 +1,40 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import com.github.stefvanschie.inventoryframework.font.util.Font; -import com.github.stefvanschie.inventoryframework.pane.component.Label; -import com.github.stefvanschie.inventoryframework.pane.component.PercentageBar; -import com.github.stefvanschie.inventoryframework.pane.component.ToggleButton; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class PaginatedPaneTest { - - @Test - void testCopy() { - PaginatedPane original = new PaginatedPane(5, 5, 4, 1, Pane.Priority.NORMAL); - original.setVisible(false); - - original.addPane(0, new OutlinePane(1, 1)); - original.addPane(1, new OutlinePane(1, 1)); - original.addPane(2, new PaginatedPane(1, 1)); - original.addPane(3, new PaginatedPane(1, 1)); - original.addPane(4, new OutlinePane(1, 1)); - - original.setPage(4); - - PaginatedPane copy = original.copy(); - - assertNotSame(original, copy); - - assertEquals(original.getX(), copy.getX()); - assertEquals(original.getY(), copy.getY()); - assertEquals(original.getLength(), copy.getLength()); - assertEquals(original.getHeight(), copy.getHeight()); - assertEquals(original.getPriority(), copy.getPriority()); - assertEquals(original.isVisible(), copy.isVisible()); - assertEquals(original.getPage(), copy.getPage()); - assertEquals(original.getPages(), copy.getPages()); - assertEquals(original.getUUID(), copy.getUUID()); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import com.github.stefvanschie.inventoryframework.font.util.Font; +import com.github.stefvanschie.inventoryframework.pane.component.Label; +import com.github.stefvanschie.inventoryframework.pane.component.PercentageBar; +import com.github.stefvanschie.inventoryframework.pane.component.ToggleButton; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class PaginatedPaneTest { + + @Test + void testCopy() { + PaginatedPane original = new PaginatedPane(5, 5, 4, 1, Pane.Priority.NORMAL); + original.setVisible(false); + + original.addPane(0, new OutlinePane(1, 1)); + original.addPane(1, new OutlinePane(1, 1)); + original.addPane(2, new PaginatedPane(1, 1)); + original.addPane(3, new PaginatedPane(1, 1)); + original.addPane(4, new OutlinePane(1, 1)); + + original.setPage(4); + + PaginatedPane copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getX(), copy.getX()); + assertEquals(original.getY(), copy.getY()); + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPriority(), copy.getPriority()); + assertEquals(original.isVisible(), copy.isVisible()); + assertEquals(original.getPage(), copy.getPage()); + assertEquals(original.getPages(), copy.getPages()); + assertEquals(original.getUUID(), copy.getUUID()); + } +} diff --git a/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaneTest.java new file mode 100644 index 00000000..d0d4b17d --- /dev/null +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/PaneTest.java @@ -0,0 +1,20 @@ +package com.github.stefvanschie.inventoryframework.pane; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class PaneTest { + + @Test + void testPriorityIsGreaterThan() { + assertTrue(Pane.Priority.MONITOR.isGreaterThan(Pane.Priority.HIGH)); + assertFalse(Pane.Priority.NORMAL.isGreaterThan(Pane.Priority.MONITOR)); + } + + @Test + void testPriorityIsLessThan() { + assertTrue(Pane.Priority.HIGHEST.isLessThan(Pane.Priority.MONITOR)); + assertFalse(Pane.Priority.NORMAL.isLessThan(Pane.Priority.LOWEST)); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java index cc27cc5d..38dfec05 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/StaticPaneTest.java @@ -1,32 +1,32 @@ -package com.github.stefvanschie.inventoryframework.pane; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class StaticPaneTest { - - @Test - void testCopy() { - StaticPane original = new StaticPane(5, 1, 1, 1, Pane.Priority.MONITOR); - original.setVisible(false); - original.setRotation(90); - original.flipHorizontally(false); - original.flipVertically(true); - - StaticPane copy = original.copy(); - - assertNotSame(original, copy); - - assertEquals(original.getX(), copy.getX()); - assertEquals(original.getY(), copy.getY()); - assertEquals(original.getLength(), copy.getLength()); - assertEquals(original.getHeight(), copy.getHeight()); - assertEquals(original.getPriority(), copy.getPriority()); - assertEquals(original.isVisible(), copy.isVisible()); - assertEquals(original.getRotation(), copy.getRotation()); - assertEquals(original.isFlippedHorizontally(), copy.isFlippedHorizontally()); - assertEquals(original.isFlippedVertically(), copy.isFlippedVertically()); - assertEquals(original.getUUID(), copy.getUUID()); - } -} +package com.github.stefvanschie.inventoryframework.pane; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class StaticPaneTest { + + @Test + void testCopy() { + StaticPane original = new StaticPane(5, 1, 1, 1, Pane.Priority.MONITOR); + original.setVisible(false); + original.setRotation(90); + original.flipHorizontally(false); + original.flipVertically(true); + + StaticPane copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getX(), copy.getX()); + assertEquals(original.getY(), copy.getY()); + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPriority(), copy.getPriority()); + assertEquals(original.isVisible(), copy.isVisible()); + assertEquals(original.getRotation(), copy.getRotation()); + assertEquals(original.isFlippedHorizontally(), copy.isFlippedHorizontally()); + assertEquals(original.isFlippedVertically(), copy.isFlippedVertically()); + assertEquals(original.getUUID(), copy.getUUID()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java index 20639214..ee0f8978 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/component/CycleButtonTest.java @@ -1,30 +1,30 @@ -package com.github.stefvanschie.inventoryframework.pane.component; - -import com.github.stefvanschie.inventoryframework.pane.Pane; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class CycleButtonTest { - - @Test - void testCopy() { - CycleButton original = new CycleButton(6, 2, 2, 3, Pane.Priority.HIGH); - original.setVisible(true); - - original.addPane(new CycleButton(1, 1)); - - CycleButton copy = original.copy(); - - assertNotSame(original, copy); - - assertEquals(original.getX(), copy.getX()); - assertEquals(original.getY(), copy.getY()); - assertEquals(original.getLength(), copy.getLength()); - assertEquals(original.getHeight(), copy.getHeight()); - assertEquals(original.getPriority(), copy.getPriority()); - assertEquals(original.isVisible(), copy.isVisible()); - assertEquals(original.getPanes().size(), copy.getPanes().size()); - assertEquals(original.getUUID(), copy.getUUID()); - } -} +package com.github.stefvanschie.inventoryframework.pane.component; + +import com.github.stefvanschie.inventoryframework.pane.Pane; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class CycleButtonTest { + + @Test + void testCopy() { + CycleButton original = new CycleButton(6, 2, 2, 3, Pane.Priority.HIGH); + original.setVisible(true); + + original.addPane(new CycleButton(1, 1)); + + CycleButton copy = original.copy(); + + assertNotSame(original, copy); + + assertEquals(original.getX(), copy.getX()); + assertEquals(original.getY(), copy.getY()); + assertEquals(original.getLength(), copy.getLength()); + assertEquals(original.getHeight(), copy.getHeight()); + assertEquals(original.getPriority(), copy.getPriority()); + assertEquals(original.isVisible(), copy.isVisible()); + assertEquals(original.getPanes().size(), copy.getPanes().size()); + assertEquals(original.getUUID(), copy.getUUID()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java similarity index 85% rename from src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java index 61b80425..b0006195 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/pane/util/MaskTest.java @@ -1,71 +1,77 @@ -package com.github.stefvanschie.inventoryframework.pane.util; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class MaskTest { - - @Test - void testConstructorIncorrectCharacters() { - assertThrows(IllegalArgumentException.class, () -> new Mask("missingno.")); - } - - @Test - void testConstructorInvalidLengths() { - assertThrows(IllegalArgumentException.class, () -> new Mask( - "0", - "0000000000" - )); - } - - @Test - void testAmountOfEnabledSlots() { - assertEquals(4, new Mask( - "1001", - "1001" - ).amountOfEnabledSlots()); - } - - @Test - void testGetColumn() { - assertArrayEquals(new boolean[] {true, false}, new Mask( - "10", - "00" - ).getColumn(0)); - } - - @Test - void testGetRow() { - assertArrayEquals(new boolean[] {true, false}, new Mask( - "10", - "00" - ).getRow(0)); - } - - @Test - void testIsEnabled() { - assertTrue(new Mask( - "10", - "00" - ).isEnabled(0, 0)); - } - - @Test - void testGetLength() { - assertEquals(2, new Mask( - "10", - "00", - "01" - ).getLength()); - } - - @Test - void testGetHeight() { - assertEquals(3, new Mask( - "10", - "00", - "01" - ).getHeight()); - } -} +package com.github.stefvanschie.inventoryframework.pane.util; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.ThrowingSupplier; + +import static org.junit.jupiter.api.Assertions.*; + +public class MaskTest { + + @Test + void testConstructorIncorrectCharacters() { + assertThrows(IllegalArgumentException.class, () -> new Mask("missingno.")); + } + + @Test + void testConstructorInvalidLengths() { + assertThrows(IllegalArgumentException.class, () -> new Mask( + "0", + "0000000000" + )); + } + + @Test + void testConstructorAcceptEmpty() { + assertDoesNotThrow((ThrowingSupplier) Mask::new); + } + + @Test + void testAmountOfEnabledSlots() { + assertEquals(4, new Mask( + "1001", + "1001" + ).amountOfEnabledSlots()); + } + + @Test + void testGetColumn() { + assertArrayEquals(new boolean[] {true, false}, new Mask( + "10", + "00" + ).getColumn(0)); + } + + @Test + void testGetRow() { + assertArrayEquals(new boolean[] {true, false}, new Mask( + "10", + "00" + ).getRow(0)); + } + + @Test + void testIsEnabled() { + assertTrue(new Mask( + "10", + "00" + ).isEnabled(0, 0)); + } + + @Test + void testGetLength() { + assertEquals(2, new Mask( + "10", + "00", + "01" + ).getLength()); + } + + @Test + void testGetHeight() { + assertEquals(3, new Mask( + "10", + "00", + "01" + ).getHeight()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java index 481a35b7..cb2187c7 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/CSVUtilTest.java @@ -1,30 +1,30 @@ -package com.github.stefvanschie.inventoryframework.util; - -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -public class CSVUtilTest { - - @Test - void testCsvReading() throws IOException { - try (InputStream inputStream = getClass().getResourceAsStream("/test-csv-file.csv")) { - List strings = CSVUtil.readAll(inputStream); - - assertEquals("a", strings.get(0)[0]); - assertEquals("b", strings.get(0)[1]); - assertEquals("c", strings.get(1)[0]); - assertEquals("d", strings.get(1)[1]); - assertEquals("\"", strings.get(2)[0]); - assertEquals("e", strings.get(2)[1]); - assertEquals("f", strings.get(3)[0]); - assertEquals("g", strings.get(3)[1]); - assertEquals(",", strings.get(4)[0]); - assertEquals(",", strings.get(4)[1]); - } - } -} +package com.github.stefvanschie.inventoryframework.util; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class CSVUtilTest { + + @Test + void testCsvReading() throws IOException { + try (InputStream inputStream = getClass().getResourceAsStream("/test-csv-file.csv")) { + List strings = CSVUtil.readAll(inputStream); + + assertEquals("a", strings.get(0)[0]); + assertEquals("b", strings.get(0)[1]); + assertEquals("c", strings.get(1)[0]); + assertEquals("d", strings.get(1)[1]); + assertEquals("\"", strings.get(2)[0]); + assertEquals("e", strings.get(2)[1]); + assertEquals("f", strings.get(3)[0]); + assertEquals("g", strings.get(3)[1]); + assertEquals(",", strings.get(4)[0]); + assertEquals(",", strings.get(4)[1]); + } + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java similarity index 97% rename from src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java index 60f2e4c2..25f96761 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/GeometryUtilTest.java @@ -1,32 +1,32 @@ -package com.github.stefvanschie.inventoryframework.util; - -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; - -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -public class GeometryUtilTest { - - @Test - void testClockwiseRotations() { - testRotation(3, 2, GeometryUtil.processClockwiseRotation(3, 2, 5, 5, 0)); - testRotation(4, 1, GeometryUtil.processClockwiseRotation(1, 1, 6, 6, 90)); - testRotation(3, 5, GeometryUtil.processClockwiseRotation(2, 0, 6, 6, 180)); - testRotation(0, 1, GeometryUtil.processClockwiseRotation(0, 0, 2, 2, 270)); - } - - @Test - void testCounterClockwiseRotations() { - testRotation(0, 0, GeometryUtil.processCounterClockwiseRotation(0, 0, 6, 6, 0)); - testRotation(2, 2, GeometryUtil.processCounterClockwiseRotation(0, 2, 3, 3, 90)); - testRotation(1, 0, GeometryUtil.processCounterClockwiseRotation(2, 3, 4, 4, 180)); - testRotation(3, 1, GeometryUtil.processCounterClockwiseRotation(1, 0, 4, 4, 270)); - } - - void testRotation(int expectedX, int expectedY, @NotNull Map.Entry coordinates) { - assertEquals(expectedX, (int) coordinates.getKey()); - assertEquals(expectedY, (int) coordinates.getValue()); - } -} +package com.github.stefvanschie.inventoryframework.util; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +public class GeometryUtilTest { + + @Test + void testClockwiseRotations() { + testRotation(3, 2, GeometryUtil.processClockwiseRotation(3, 2, 5, 5, 0)); + testRotation(4, 1, GeometryUtil.processClockwiseRotation(1, 1, 6, 6, 90)); + testRotation(3, 5, GeometryUtil.processClockwiseRotation(2, 0, 6, 6, 180)); + testRotation(0, 1, GeometryUtil.processClockwiseRotation(0, 0, 2, 2, 270)); + } + + @Test + void testCounterClockwiseRotations() { + testRotation(0, 0, GeometryUtil.processCounterClockwiseRotation(0, 0, 6, 6, 0)); + testRotation(2, 2, GeometryUtil.processCounterClockwiseRotation(0, 2, 3, 3, 90)); + testRotation(1, 0, GeometryUtil.processCounterClockwiseRotation(2, 3, 4, 4, 180)); + testRotation(3, 1, GeometryUtil.processCounterClockwiseRotation(1, 0, 4, 4, 270)); + } + + void testRotation(int expectedX, int expectedY, @NotNull Map.Entry coordinates) { + assertEquals(expectedX, (int) coordinates.getKey()); + assertEquals(expectedY, (int) coordinates.getValue()); + } +} diff --git a/src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java similarity index 96% rename from src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java rename to IF/src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java index d343b55c..f7141724 100644 --- a/src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java +++ b/IF/src/test/java/com/github/stefvanschie/inventoryframework/util/PaginatedPaneTest.java @@ -1,54 +1,54 @@ -package com.github.stefvanschie.inventoryframework.util; - -import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; -import com.github.stefvanschie.inventoryframework.pane.Pane; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; -import org.junit.jupiter.api.Test; - -import java.util.Collection; - -import static org.junit.jupiter.api.Assertions.*; - -public class PaginatedPaneTest { - - @Test - void testGetPanesNonExistentPage() { - PaginatedPane pane = new PaginatedPane(0, 0); - - //noinspection ResultOfMethodCallIgnored - assertThrows(IllegalArgumentException.class, () -> pane.getPanes(0)); - } - - @Test - void testGetPanesCollectionContents() { - PaginatedPane paginatedPane = new PaginatedPane(0, 0); - - StaticPane pane0 = new StaticPane(0, 0); - StaticPane pane1 = new StaticPane(0, 0); - StaticPane pane2 = new StaticPane(0, 0); - - paginatedPane.addPane(0, pane0); - paginatedPane.addPane(0, pane1); - paginatedPane.addPane(0, pane2); - - Collection panes = paginatedPane.getPanes(0); - assertTrue(panes.contains(pane0)); - assertTrue(panes.contains(pane1)); - assertTrue(panes.contains(pane2)); - } - - @Test - void testGetPanesCollectionSize() { - PaginatedPane paginatedPane = new PaginatedPane(0, 0); - - StaticPane pane0 = new StaticPane(0, 0); - StaticPane pane1 = new StaticPane(0, 0); - StaticPane pane2 = new StaticPane(0, 0); - - paginatedPane.addPane(0, pane0); - paginatedPane.addPane(0, pane1); - paginatedPane.addPane(0, pane2); - - assertEquals(3, paginatedPane.getPanes(0).size()); - } -} +package com.github.stefvanschie.inventoryframework.util; + +import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; +import com.github.stefvanschie.inventoryframework.pane.Pane; +import com.github.stefvanschie.inventoryframework.pane.StaticPane; +import org.junit.jupiter.api.Test; + +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.*; + +public class PaginatedPaneTest { + + @Test + void testGetPanesNonExistentPage() { + PaginatedPane pane = new PaginatedPane(0, 0); + + //noinspection ResultOfMethodCallIgnored + assertThrows(IllegalArgumentException.class, () -> pane.getPanes(0)); + } + + @Test + void testGetPanesCollectionContents() { + PaginatedPane paginatedPane = new PaginatedPane(0, 0); + + StaticPane pane0 = new StaticPane(0, 0); + StaticPane pane1 = new StaticPane(0, 0); + StaticPane pane2 = new StaticPane(0, 0); + + paginatedPane.addPane(0, pane0); + paginatedPane.addPane(0, pane1); + paginatedPane.addPane(0, pane2); + + Collection panes = paginatedPane.getPanes(0); + assertTrue(panes.contains(pane0)); + assertTrue(panes.contains(pane1)); + assertTrue(panes.contains(pane2)); + } + + @Test + void testGetPanesCollectionSize() { + PaginatedPane paginatedPane = new PaginatedPane(0, 0); + + StaticPane pane0 = new StaticPane(0, 0); + StaticPane pane1 = new StaticPane(0, 0); + StaticPane pane2 = new StaticPane(0, 0); + + paginatedPane.addPane(0, pane0); + paginatedPane.addPane(0, pane1); + paginatedPane.addPane(0, pane2); + + assertEquals(3, paginatedPane.getPanes(0).size()); + } +} diff --git a/src/test/resources/test-csv-file.csv b/IF/src/test/resources/test-csv-file.csv similarity index 89% rename from src/test/resources/test-csv-file.csv rename to IF/src/test/resources/test-csv-file.csv index d86fb8c4..13c213b2 100644 --- a/src/test/resources/test-csv-file.csv +++ b/IF/src/test/resources/test-csv-file.csv @@ -1,5 +1,5 @@ -a, b -"c", d -"""", e -\u0066, \u0067 -",","," +a, b +"c", d +"""", e +\u0066, \u0067 +",","," diff --git a/nms/1_14_R1/pom.xml b/nms/1_14_R1/pom.xml new file mode 100644 index 00000000..b7a37c32 --- /dev/null +++ b/nms/1_14_R1/pom.xml @@ -0,0 +1,29 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + 1_14_R1 + + + + org.spigotmc + spigot + 1.14.4-R0.1-SNAPSHOT + provided + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + \ No newline at end of file diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/AnvilInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/AnvilInventoryImpl.java new file mode 100644 index 00000000..a17945e3 --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/AnvilInventoryImpl.java @@ -0,0 +1,304 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal anvil inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerAnvil; + + int id = containerAnvil.windowId; + ChatMessage message = new ChatMessage(title); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.a); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.8.0 + */ + private class ContainerAnvilImpl extends ContainerAnvil { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the repair inventory field + */ + @NotNull + private final Field repairInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + /** + * Field for accessing the container access field + */ + @NotNull + private final Field containerAccessField; + + /** + * Creates a new custom anvil container for the specified player + * + * @param entityPlayer the player for who this anvil container is + * @since 0.8.0 + */ + public ContainerAnvilImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + try { + repairInventoryField = ContainerAnvil.class.getDeclaredField("repairInventory"); + repairInventoryField.setAccessible(true); + + resultInventoryField = ContainerAnvil.class.getDeclaredField("resultInventory"); + resultInventoryField.setAccessible(true); + + containerAccessField = ContainerAnvil.class.getDeclaredField("containerAccess"); + containerAccessField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getRepairInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getRepairInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = getContainerAccess().getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, getRepairInventory(), getResultInventory(), + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void a(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, getResultInventory().getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getRepairInventory() { + try { + return (IInventory) repairInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Contract(pure = true) + private ContainerAccess getContainerAccess() { + try { + return (ContainerAccess) containerAccessField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/BeaconInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/BeaconInventoryImpl.java new file mode 100644 index 00000000..e6fb366d --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/BeaconInventoryImpl.java @@ -0,0 +1,181 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(entityPlayer, item); + + entityPlayer.activeContainer = containerBeacon; + + int id = containerBeacon.windowId; + ChatMessage message = new ChatMessage("Beacon"); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.BEACON, message)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.a( + ItemStack.a, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), items)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.8.0 + */ + private class ContainerBeaconImpl extends ContainerBeacon { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull EntityPlayer entityPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.beaconField = ContainerBeacon.class.getDeclaredField("beacon"); + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((IInventory) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((IInventory) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/CartographyTableInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..75766664 --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/CartographyTableInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + entityPlayer, items + ); + + entityPlayer.activeContainer = containerCartographyTable; + + int id = containerCartographyTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.CARTOGRAPHY, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.8.0 + */ + private class ContainerCartographyTableImpl extends ContainerCartography { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerCartographyTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerCartography.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/EnchantingTableInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..0acb7390 --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/EnchantingTableInventoryImpl.java @@ -0,0 +1,194 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.ENCHANTMENT, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerEnchantingTableImpl extends ContainerEnchantTable { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.enchantSlotsField = ContainerEnchantTable.class.getDeclaredField("enchantSlots"); + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + IInventory input = (IInventory) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((IInventory) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/GrindstoneInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..c93769a7 --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/GrindstoneInventoryImpl.java @@ -0,0 +1,227 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerGrindstone; + + int id = containerGrindstone.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.GRINDSTONE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.8.0 + */ + private class ContainerGrindstoneImpl extends ContainerGrindstone { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field craftInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerGrindstoneImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.craftInventoryField = ContainerGrindstone.class.getDeclaredField("craftInventory"); + this.craftInventoryField.setAccessible(true); + + this.resultInventoryField = ContainerGrindstone.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getCraftInventory() { + try { + return (IInventory) craftInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/StonecutterInventoryImpl.java b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/StonecutterInventoryImpl.java new file mode 100644 index 00000000..a193a995 --- /dev/null +++ b/nms/1_14_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_14_R1/StonecutterInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_14_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import net.minecraft.server.v1_14_R1.*; +import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.14 R1 + * + * @since 0.8.0 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.STONECUTTER, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerStonecutterImpl extends ContainerStonecutter { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerStonecutterImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerStonecutter.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_15_R1/pom.xml b/nms/1_15_R1/pom.xml new file mode 100644 index 00000000..cee27afa --- /dev/null +++ b/nms/1_15_R1/pom.xml @@ -0,0 +1,29 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + 1_15_R1 + + + + org.spigotmc + spigot + 1.15.2-R0.1-SNAPSHOT + provided + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + \ No newline at end of file diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/AnvilInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/AnvilInventoryImpl.java new file mode 100644 index 00000000..2cbfc8c5 --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/AnvilInventoryImpl.java @@ -0,0 +1,304 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal anvil inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerAnvil; + + int id = containerAnvil.windowId; + ChatMessage message = new ChatMessage(title); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.a); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.8.0 + */ + private class ContainerAnvilImpl extends ContainerAnvil { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the repair inventory field + */ + @NotNull + private final Field repairInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + /** + * Field for accessing the container access field + */ + @NotNull + private final Field containerAccessField; + + /** + * Creates a new custom anvil container for the specified player + * + * @param entityPlayer the player for who this anvil container is + * @since 0.8.0 + */ + public ContainerAnvilImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + try { + repairInventoryField = ContainerAnvil.class.getDeclaredField("repairInventory"); + repairInventoryField.setAccessible(true); + + resultInventoryField = ContainerAnvil.class.getDeclaredField("resultInventory"); + resultInventoryField.setAccessible(true); + + containerAccessField = ContainerAnvil.class.getDeclaredField("containerAccess"); + containerAccessField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getRepairInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getRepairInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = getContainerAccess().getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, getRepairInventory(), getResultInventory(), + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void a(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, getResultInventory().getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getRepairInventory() { + try { + return (IInventory) repairInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Contract(pure = true) + private ContainerAccess getContainerAccess() { + try { + return (ContainerAccess) containerAccessField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/BeaconInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/BeaconInventoryImpl.java new file mode 100644 index 00000000..38d7d21d --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/BeaconInventoryImpl.java @@ -0,0 +1,181 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(entityPlayer, item); + + entityPlayer.activeContainer = containerBeacon; + + int id = containerBeacon.windowId; + ChatMessage message = new ChatMessage("Beacon"); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.BEACON, message)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.a( + ItemStack.a, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), items)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.8.0 + */ + private class ContainerBeaconImpl extends ContainerBeacon { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull EntityPlayer entityPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.beaconField = ContainerBeacon.class.getDeclaredField("beacon"); + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((IInventory) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((IInventory) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/CartographyTableInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..9748a472 --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/CartographyTableInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + entityPlayer, items + ); + + entityPlayer.activeContainer = containerCartographyTable; + + int id = containerCartographyTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.CARTOGRAPHY_TABLE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.8.0 + */ + private class ContainerCartographyTableImpl extends ContainerCartography { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerCartographyTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerCartography.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/EnchantingTableInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..42018e6c --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/EnchantingTableInventoryImpl.java @@ -0,0 +1,194 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.ENCHANTMENT, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerEnchantingTableImpl extends ContainerEnchantTable { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.enchantSlotsField = ContainerEnchantTable.class.getDeclaredField("enchantSlots"); + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + IInventory input = (IInventory) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((IInventory) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/GrindstoneInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..d582f5fc --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/GrindstoneInventoryImpl.java @@ -0,0 +1,227 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerGrindstone; + + int id = containerGrindstone.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.GRINDSTONE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.8.0 + */ + private class ContainerGrindstoneImpl extends ContainerGrindstone { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field craftInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerGrindstoneImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.craftInventoryField = ContainerGrindstone.class.getDeclaredField("craftInventory"); + this.craftInventoryField.setAccessible(true); + + this.resultInventoryField = ContainerGrindstone.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getCraftInventory() { + try { + return (IInventory) craftInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/StonecutterInventoryImpl.java b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/StonecutterInventoryImpl.java new file mode 100644 index 00000000..ded6bb0d --- /dev/null +++ b/nms/1_15_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_15_R1/StonecutterInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_15_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import net.minecraft.server.v1_15_R1.*; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.15 R1 + * + * @since 0.8.0 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.STONECUTTER, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.a, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.a)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerStonecutterImpl extends ContainerStonecutter { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerStonecutterImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerStonecutter.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R1/pom.xml b/nms/1_16_R1/pom.xml new file mode 100644 index 00000000..ce566490 --- /dev/null +++ b/nms/1_16_R1/pom.xml @@ -0,0 +1,29 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + 1_16_R1 + + + + org.spigotmc + spigot + 1.16.1-R0.1-SNAPSHOT + provided + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + \ No newline at end of file diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/AnvilInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/AnvilInventoryImpl.java new file mode 100644 index 00000000..5da3e3f2 --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/AnvilInventoryImpl.java @@ -0,0 +1,241 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal anvil inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerAnvil; + + int id = containerAnvil.windowId; + ChatMessage message = new ChatMessage(title); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.8.0 + */ + private class ContainerAnvilImpl extends ContainerAnvil { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Creates a new custom anvil container for the specified player + * + * @param entityPlayer the player for who this anvil container is + * @since 0.8.0 + */ + public ContainerAnvilImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = containerAccess.getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, repairInventory, resultInventory, + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void a(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, resultInventory.getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/BeaconInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/BeaconInventoryImpl.java new file mode 100644 index 00000000..3bfc1f68 --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/BeaconInventoryImpl.java @@ -0,0 +1,181 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(entityPlayer, item); + + entityPlayer.activeContainer = containerBeacon; + + int id = containerBeacon.windowId; + ChatMessage message = new ChatMessage("Beacon"); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.BEACON, message)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.a( + ItemStack.b, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), items)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.8.0 + */ + private class ContainerBeaconImpl extends ContainerBeacon { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull EntityPlayer entityPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.beaconField = ContainerBeacon.class.getDeclaredField("beacon"); + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((IInventory) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((IInventory) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/CartographyTableInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..e4d3895a --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/CartographyTableInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + entityPlayer, items + ); + + entityPlayer.activeContainer = containerCartographyTable; + + int id = containerCartographyTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.CARTOGRAPHY_TABLE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.8.0 + */ + private class ContainerCartographyTableImpl extends ContainerCartography { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerCartographyTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerCartography.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/EnchantingTableInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..901cceb5 --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/EnchantingTableInventoryImpl.java @@ -0,0 +1,194 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.ENCHANTMENT, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerEnchantingTableImpl extends ContainerEnchantTable { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.enchantSlotsField = ContainerEnchantTable.class.getDeclaredField("enchantSlots"); + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + IInventory input = (IInventory) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((IInventory) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/GrindstoneInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..291db39c --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/GrindstoneInventoryImpl.java @@ -0,0 +1,227 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerGrindstone; + + int id = containerGrindstone.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.GRINDSTONE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.8.0 + */ + private class ContainerGrindstoneImpl extends ContainerGrindstone { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field craftInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerGrindstoneImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.craftInventoryField = ContainerGrindstone.class.getDeclaredField("craftInventory"); + this.craftInventoryField.setAccessible(true); + + this.resultInventoryField = ContainerGrindstone.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getCraftInventory() { + try { + return (IInventory) craftInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/SmithingTableInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/SmithingTableInventoryImpl.java new file mode 100644 index 00000000..c9e30f97 --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/SmithingTableInventoryImpl.java @@ -0,0 +1,226 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.SmithingTableInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventorySmithing; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal smithing table inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class SmithingTableInventoryImpl extends SmithingTableInventory { + + public SmithingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerSmithingTableImpl containerSmithingTable = new ContainerSmithingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerSmithingTable; + + int id = containerSmithingTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.SMITHING, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container smithing table + * + * @since 0.8.0 + */ + private class ContainerSmithingTableImpl extends ContainerSmithing { + + /** + * The player for this smithing table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container smithing table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + public ContainerSmithingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventorySmithing(repairInventory, resultInventory) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/StonecutterInventoryImpl.java b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/StonecutterInventoryImpl.java new file mode 100644 index 00000000..8c76fb84 --- /dev/null +++ b/nms/1_16_R1/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R1/StonecutterInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R1; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import net.minecraft.server.v1_16_R1.*; +import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.16 R1 + * + * @since 0.8.0 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.STONECUTTER, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerStonecutterImpl extends ContainerStonecutter { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerStonecutterImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerStonecutter.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R2/pom.xml b/nms/1_16_R2/pom.xml new file mode 100644 index 00000000..cf4e7050 --- /dev/null +++ b/nms/1_16_R2/pom.xml @@ -0,0 +1,29 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + 1_16_R2 + + + + org.spigotmc + spigot + 1.16.3-R0.1-SNAPSHOT + provided + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + \ No newline at end of file diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/AnvilInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/AnvilInventoryImpl.java new file mode 100644 index 00000000..b0fc4bd7 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/AnvilInventoryImpl.java @@ -0,0 +1,241 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal anvil inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerAnvil; + + int id = containerAnvil.windowId; + ChatMessage message = new ChatMessage(title); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.8.0 + */ + private class ContainerAnvilImpl extends ContainerAnvil { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Creates a new custom anvil container for the specified player + * + * @param entityPlayer the player for who this anvil container is + * @since 0.8.0 + */ + public ContainerAnvilImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = containerAccess.getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, repairInventory, resultInventory, + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void a(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, resultInventory.getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/BeaconInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/BeaconInventoryImpl.java new file mode 100644 index 00000000..2a8d3cc6 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/BeaconInventoryImpl.java @@ -0,0 +1,178 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(entityPlayer, item); + + entityPlayer.activeContainer = containerBeacon; + + int id = containerBeacon.windowId; + ChatMessage message = new ChatMessage("Beacon"); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.BEACON, message)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.a( + ItemStack.b, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), items)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.8.0 + */ + private class ContainerBeaconImpl extends ContainerBeacon { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull EntityPlayer entityPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.beaconField = ContainerBeacon.class.getDeclaredField("beacon"); + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((IInventory) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((IInventory) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/CartographyTableInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..b11ac0f2 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/CartographyTableInventoryImpl.java @@ -0,0 +1,196 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + entityPlayer, items + ); + + entityPlayer.activeContainer = containerCartographyTable; + + int id = containerCartographyTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.CARTOGRAPHY_TABLE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.8.0 + */ + private class ContainerCartographyTableImpl extends ContainerCartography { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerCartographyTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerCartography.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/EnchantingTableInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..89145689 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/EnchantingTableInventoryImpl.java @@ -0,0 +1,191 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.ENCHANTMENT, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerEnchantingTableImpl extends ContainerEnchantTable { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.enchantSlotsField = ContainerEnchantTable.class.getDeclaredField("enchantSlots"); + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + IInventory input = (IInventory) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((IInventory) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/GrindstoneInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..48bf2f02 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/GrindstoneInventoryImpl.java @@ -0,0 +1,224 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerGrindstone; + + int id = containerGrindstone.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.GRINDSTONE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.8.0 + */ + private class ContainerGrindstoneImpl extends ContainerGrindstone { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field craftInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerGrindstoneImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.craftInventoryField = ContainerGrindstone.class.getDeclaredField("craftInventory"); + this.craftInventoryField.setAccessible(true); + + this.resultInventoryField = ContainerGrindstone.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getCraftInventory() { + try { + return (IInventory) craftInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/SmithingTableInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/SmithingTableInventoryImpl.java new file mode 100644 index 00000000..82779d96 --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/SmithingTableInventoryImpl.java @@ -0,0 +1,224 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.SmithingTableInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal smithing table inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class SmithingTableInventoryImpl extends SmithingTableInventory { + + public SmithingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerSmithingTableImpl containerSmithingTable = new ContainerSmithingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerSmithingTable; + + int id = containerSmithingTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.SMITHING, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container smithing table + * + * @since 0.8.0 + */ + private class ContainerSmithingTableImpl extends ContainerSmithing { + + /** + * The player for this smithing table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container smithing table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + public ContainerSmithingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventorySmithing(containerAccess.getLocation(), repairInventory, + resultInventory) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/StonecutterInventoryImpl.java b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/StonecutterInventoryImpl.java new file mode 100644 index 00000000..83d8d88d --- /dev/null +++ b/nms/1_16_R2/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R2/StonecutterInventoryImpl.java @@ -0,0 +1,196 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R2; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R2.inventory.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.16 R2 + * + * @since 0.8.0 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.STONECUTTER, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerStonecutterImpl extends ContainerStonecutter { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerStonecutterImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerStonecutter.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R3/pom.xml b/nms/1_16_R3/pom.xml new file mode 100644 index 00000000..7466da3a --- /dev/null +++ b/nms/1_16_R3/pom.xml @@ -0,0 +1,30 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + 1_16_R3 + + + + com.github.stefvanschie.inventoryframework + abstraction + 0.7.2 + compile + + + org.spigotmc + spigot + 1.16.4-R0.1-SNAPSHOT + provided + + + + \ No newline at end of file diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/AnvilInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/AnvilInventoryImpl.java new file mode 100644 index 00000000..636d6ce5 --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/AnvilInventoryImpl.java @@ -0,0 +1,241 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.AnvilInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal anvil inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class AnvilInventoryImpl extends AnvilInventory { + + public AnvilInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for an anvil should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerAnvilImpl containerAnvil = new ContainerAnvilImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerAnvil; + + int id = containerAnvil.windowId; + ChatMessage message = new ChatMessage(title); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.ANVIL, message)); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container anvil for responding to item renaming + * + * @since 0.8.0 + */ + private class ContainerAnvilImpl extends ContainerAnvil { + + /** + * The player for whom this anvil container is + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container anvil + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Creates a new custom anvil container for the specified player + * + * @param entityPlayer the player for who this anvil container is + * @since 0.8.0 + */ + public ContainerAnvilImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + Location location = containerAccess.getLocation(); + CraftInventory inventory = new CraftInventoryAnvil(location, repairInventory, resultInventory, + this) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Override + public void a(@Nullable String name) { + text = name == null ? "" : name; + + sendResultItem(player, resultInventory.getItem(0)); + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/BeaconInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/BeaconInventoryImpl.java new file mode 100644 index 00000000..b1a433ab --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/BeaconInventoryImpl.java @@ -0,0 +1,181 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.BeaconInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal beacon inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class BeaconInventoryImpl extends BeaconInventory { + + public BeaconInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerBeaconImpl containerBeacon = new ContainerBeaconImpl(entityPlayer, item); + + entityPlayer.activeContainer = containerBeacon; + + int id = containerBeacon.windowId; + ChatMessage message = new ChatMessage("Beacon"); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(id, Containers.BEACON, message)); + + sendItem(player, item); + } + + @Override + public void sendItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + NonNullList items = NonNullList.a( + ItemStack.b, //the first item doesn't count for some reason, so send a dummy item + CraftItemStack.asNMSCopy(item) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), items)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container beacon + * + * @since 0.8.0 + */ + private class ContainerBeaconImpl extends ContainerBeacon { + + /** + * The player for this beacon container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container beacon + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the beacon field + */ + @NotNull + private final Field beaconField; + + public ContainerBeaconImpl(@NotNull EntityPlayer entityPlayer, @Nullable org.bukkit.inventory.ItemStack item) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.beaconField = ContainerBeacon.class.getDeclaredField("beacon"); + this.beaconField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + ItemStack itemStack = CraftItemStack.asNMSCopy(item); + + ((IInventory) beaconField.get(this)).setItem(0, itemStack); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryBeacon((IInventory) beaconField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/CartographyTableInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/CartographyTableInventoryImpl.java new file mode 100644 index 00000000..e63aba2f --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/CartographyTableInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.CartographyTableInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal cartography table inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class CartographyTableInventoryImpl extends CartographyTableInventory { + + public CartographyTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a cartography table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerCartographyTableImpl containerCartographyTable = new ContainerCartographyTableImpl( + entityPlayer, items + ); + + entityPlayer.activeContainer = containerCartographyTable; + + int id = containerCartographyTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.CARTOGRAPHY_TABLE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container cartography table + * + * @since 0.8.0 + */ + private class ContainerCartographyTableImpl extends ContainerCartography { + + /** + * The player for this cartography table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container cartography table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerCartographyTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerCartography.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + inventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryCartography(super.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/EnchantingTableInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/EnchantingTableInventoryImpl.java new file mode 100644 index 00000000..7c358432 --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/EnchantingTableInventoryImpl.java @@ -0,0 +1,194 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.EnchantingTableInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal enchanting table inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class EnchantingTableInventoryImpl extends EnchantingTableInventory { + + public EnchantingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for an enchanting table should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerEnchantingTableImpl containerEnchantmentTable = new ContainerEnchantingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.ENCHANTMENT, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerEnchantingTableImpl extends ContainerEnchantTable { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the enchant slots field + */ + @NotNull + private final Field enchantSlotsField; + + public ContainerEnchantingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.enchantSlotsField = ContainerEnchantTable.class.getDeclaredField("enchantSlots"); + this.enchantSlotsField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + try { + IInventory input = (IInventory) enchantSlotsField.get(this); + + input.setItem(0, CraftItemStack.asNMSCopy(items[0])); + input.setItem(1, CraftItemStack.asNMSCopy(items[1])); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + try { + CraftInventory inventory = new CraftInventoryEnchanting((IInventory) enchantSlotsField.get(this)) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } catch (IllegalAccessException exception) { + exception.printStackTrace(); + } + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/GrindstoneInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/GrindstoneInventoryImpl.java new file mode 100644 index 00000000..140cf4d7 --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/GrindstoneInventoryImpl.java @@ -0,0 +1,227 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.GrindstoneInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal grindstone inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class GrindstoneInventoryImpl extends GrindstoneInventory { + + public GrindstoneInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a grindstone should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerGrindstoneImpl containerGrindstone = new ContainerGrindstoneImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerGrindstone; + + int id = containerGrindstone.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.GRINDSTONE, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container grindstone + * + * @since 0.8.0 + */ + private class ContainerGrindstoneImpl extends ContainerGrindstone { + + /** + * The player for this grindstone container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container grindstone + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the craft inventory field + */ + @NotNull + private final Field craftInventoryField; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerGrindstoneImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.craftInventoryField = ContainerGrindstone.class.getDeclaredField("craftInventory"); + this.craftInventoryField.setAccessible(true); + + this.resultInventoryField = ContainerGrindstone.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + getCraftInventory().setItem(0, CraftItemStack.asNMSCopy(items[0])); + getCraftInventory().setItem(1, CraftItemStack.asNMSCopy(items[1])); + + getResultInventory().setItem(2, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryGrindstone(getCraftInventory(), getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the craft inventory + * + * @return the craft inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getCraftInventory() { + try { + return (IInventory) craftInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/SmithingTableInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/SmithingTableInventoryImpl.java new file mode 100644 index 00000000..a9e9e5d6 --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/SmithingTableInventoryImpl.java @@ -0,0 +1,227 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.SmithingTableInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventorySmithing; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Internal smithing table inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class SmithingTableInventoryImpl extends SmithingTableInventory { + + public SmithingTableInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 3) { + throw new IllegalArgumentException( + "The amount of items for a smithing table should be 3, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerSmithingTableImpl containerSmithingTable = new ContainerSmithingTableImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerSmithingTable; + + int id = containerSmithingTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.SMITHING, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]), + CraftItemStack.asNMSCopy(items[2]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void sendFirstItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 0, nmsItem)); + } + + @Override + public void sendSecondItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + ItemStack nmsItem = CraftItemStack.asNMSCopy(item); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 1, nmsItem)); + } + + @Override + public void sendResultItem(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack item) { + sendResultItem(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearResultItem(@NotNull Player player) { + sendResultItem(player, ItemStack.b); + } + + @Override + public void setCursor(@NotNull Player player, @NotNull org.bukkit.inventory.ItemStack item) { + setCursor(player, CraftItemStack.asNMSCopy(item)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + private void setCursor(@NotNull Player player, @NotNull ItemStack item) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, item)); + } + + /** + * Sends the result item to the specified player with the given item + * + * @param player the player to send the result item to + * @param item the result item + * @since 0.8.0 + */ + private void sendResultItem(@NotNull Player player, @NotNull ItemStack item) { + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutSetSlot(getWindowId(entityPlayer), 2, item)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container smithing table + * + * @since 0.8.0 + */ + private class ContainerSmithingTableImpl extends ContainerSmithing { + + /** + * The player for this smithing table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container smithing table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + public ContainerSmithingTableImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory, + ContainerAccess.at(entityPlayer.getWorld(), new BlockPosition(0, 0, 0))); + + this.player = entityPlayer.getBukkitEntity(); + + repairInventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + repairInventory.setItem(1, CraftItemStack.asNMSCopy(items[1])); + resultInventory.setItem(0, CraftItemStack.asNMSCopy(items[2])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventorySmithing(containerAccess.getLocation(), repairInventory, + resultInventory) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + } +} diff --git a/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/StonecutterInventoryImpl.java b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/StonecutterInventoryImpl.java new file mode 100644 index 00000000..2e9db691 --- /dev/null +++ b/nms/1_16_R3/src/main/java/com/github/stefvanschie/inventoryframework/nms/v1_16_R3/StonecutterInventoryImpl.java @@ -0,0 +1,199 @@ +package com.github.stefvanschie.inventoryframework.nms.v1_16_R3; + +import com.github.stefvanschie.inventoryframework.abstraction.StonecutterInventory; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; + +/** + * Internal stonecutter inventory for 1.16 R3 + * + * @since 0.8.0 + */ +public class StonecutterInventoryImpl extends StonecutterInventory { + + public StonecutterInventoryImpl(@NotNull InventoryHolder inventoryHolder) { + super(inventoryHolder); + } + + @Override + public void openInventory(@NotNull Player player, @NotNull String title, + @Nullable org.bukkit.inventory.ItemStack[] items) { + int itemAmount = items.length; + + if (itemAmount != 2) { + throw new IllegalArgumentException( + "The amount of items for a stonecutter should be 2, but is '" + itemAmount + "'" + ); + } + + EntityPlayer entityPlayer = getEntityPlayer(player); + ContainerStonecutterImpl containerEnchantmentTable = new ContainerStonecutterImpl(entityPlayer, items); + + entityPlayer.activeContainer = containerEnchantmentTable; + + int id = containerEnchantmentTable.windowId; + ChatMessage message = new ChatMessage(title); + PacketPlayOutOpenWindow packet = new PacketPlayOutOpenWindow(id, Containers.STONECUTTER, message); + + entityPlayer.playerConnection.sendPacket(packet); + + sendItems(player, items); + } + + @Override + public void sendItems(@NotNull Player player, @Nullable org.bukkit.inventory.ItemStack[] items) { + NonNullList nmsItems = NonNullList.a( + ItemStack.b, + CraftItemStack.asNMSCopy(items[0]), + CraftItemStack.asNMSCopy(items[1]) + ); + + EntityPlayer entityPlayer = getEntityPlayer(player); + + getPlayerConnection(entityPlayer).sendPacket(new PacketPlayOutWindowItems(getWindowId(entityPlayer), nmsItems)); + } + + @Override + public void clearCursor(@NotNull Player player) { + getPlayerConnection(getEntityPlayer(player)).sendPacket(new PacketPlayOutSetSlot(-1, -1, ItemStack.b)); + } + + /** + * Gets the window id for the inventory view the player currently has open + * + * @param entityPlayer the player to get the window id for + * @return the window id + * @since 0.8.0 + */ + @Contract(pure = true) + private int getWindowId(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.activeContainer.windowId; + } + + /** + * Gets the player connection for the specified player + * + * @param entityPlayer the player to get the player connection from + * @return the player connection + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private PlayerConnection getPlayerConnection(@NotNull EntityPlayer entityPlayer) { + return entityPlayer.playerConnection; + } + + /** + * Gets the entity player associated to this player + * + * @param player the player to get the entity player from + * @return the entity player + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + private EntityPlayer getEntityPlayer(@NotNull Player player) { + return ((CraftPlayer) player).getHandle(); + } + + /** + * A custom container enchanting table + * + * @since 0.8.0 + */ + private class ContainerStonecutterImpl extends ContainerStonecutter { + + /** + * The player for this enchanting table container + */ + @NotNull + private final Player player; + + /** + * The internal bukkit entity for this container enchanting table + */ + @Nullable + private CraftInventoryView bukkitEntity; + + /** + * Field for accessing the result inventory field + */ + @NotNull + private final Field resultInventoryField; + + public ContainerStonecutterImpl(@NotNull EntityPlayer entityPlayer, + @Nullable org.bukkit.inventory.ItemStack[] items) { + super(entityPlayer.nextContainerCounter(), entityPlayer.inventory); + + this.player = entityPlayer.getBukkitEntity(); + + try { + this.resultInventoryField = ContainerStonecutter.class.getDeclaredField("resultInventory"); + this.resultInventoryField.setAccessible(true); + } catch (NoSuchFieldException exception) { + throw new RuntimeException(exception); + } + + inventory.setItem(0, CraftItemStack.asNMSCopy(items[0])); + getResultInventory().setItem(0, CraftItemStack.asNMSCopy(items[1])); + } + + @NotNull + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + CraftInventory inventory = new CraftInventoryStonecutter(this.inventory, getResultInventory()) { + @NotNull + @Contract(pure = true) + @Override + public InventoryHolder getHolder() { + return inventoryHolder; + } + }; + + bukkitEntity = new CraftInventoryView(player, inventory, this); + } + + return bukkitEntity; + } + + @Contract(pure = true, value = "_ -> true") + @Override + public boolean canUse(@Nullable EntityHuman entityhuman) { + return true; + } + + @Override + public void a(IInventory inventory) {} + + @Override + public void b(EntityHuman entityhuman) {} + + /** + * Gets the result inventory + * + * @return the result inventory + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public IInventory getResultInventory() { + try { + return (IInventory) resultInventoryField.get(this); + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + } +} diff --git a/nms/abstraction/pom.xml b/nms/abstraction/pom.xml new file mode 100644 index 00000000..09520281 --- /dev/null +++ b/nms/abstraction/pom.xml @@ -0,0 +1,24 @@ + + + + IF-parent + com.github.stefvanschie.inventoryframework + 0.7.2 + ../../pom.xml + + 4.0.0 + + abstraction + + + org.spigotmc + spigot + 1.16.4-R0.1-SNAPSHOT + provided + + + + + \ No newline at end of file diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/AnvilInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/AnvilInventory.java new file mode 100644 index 00000000..e70fdf48 --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/AnvilInventory.java @@ -0,0 +1,121 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * An anvil inventory + * + * @since 0.8.0 + */ +public abstract class AnvilInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * The rename text + */ + @NotNull + protected String text = ""; + + /** + * Creates a new anvil inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public AnvilInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the items to show + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the anvil + * @param items the items to send + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Sends the result item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendResultItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sends the first item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendFirstItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sends the second item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendSecondItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + public abstract void setCursor(@NotNull Player player, @NotNull ItemStack item); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); + + /** + * Clears the result item for the specified player + * + * @param player the player to clear the result item of + * @since 0.8.0 + */ + public abstract void clearResultItem(@NotNull Player player); + + /** + * Gets the text shown in the rename slot of the anvil + * + * @return the rename text + * @since 0.8.0 + */ + @NotNull + @Contract(pure = true) + public String getRenameText() { + return text; + } +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/BeaconInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/BeaconInventory.java new file mode 100644 index 00000000..ec708b27 --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/BeaconInventory.java @@ -0,0 +1,57 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A beacon inventory + * + * @since 0.8.0 + */ +public abstract class BeaconInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new beacon inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public BeaconInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param item the item to send + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sends the top item to the inventory for the specified player. + * + * @param player the player for which to open the beacon + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/CartographyTableInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/CartographyTableInventory.java new file mode 100644 index 00000000..da4f1db5 --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/CartographyTableInventory.java @@ -0,0 +1,58 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A cartography table inventory + * + * @since 0.8.0 + */ +public abstract class CartographyTableInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new cartography table inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public CartographyTableInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the top items of the inventory + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the cartography table + * @param items the top items of the inventory + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/EnchantingTableInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/EnchantingTableInventory.java new file mode 100644 index 00000000..dc8b97bf --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/EnchantingTableInventory.java @@ -0,0 +1,58 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * An enchanting table inventory + * + * @since 0.8.0 + */ +public abstract class EnchantingTableInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new enchanting table inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public EnchantingTableInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the top items + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the enchanting table + * @param items the items to send + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/GrindstoneInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/GrindstoneInventory.java new file mode 100644 index 00000000..314eb199 --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/GrindstoneInventory.java @@ -0,0 +1,58 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A grindstone inventory + * + * @since 0.8.0 + */ +public abstract class GrindstoneInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new grindstone inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public GrindstoneInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the top items + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the grindstone + * @param items the items to send + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/SmithingTableInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/SmithingTableInventory.java new file mode 100644 index 00000000..e34f65ea --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/SmithingTableInventory.java @@ -0,0 +1,102 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A smithing table inventory + * + * @since 0.8.0 + */ +public abstract class SmithingTableInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new smithing table inventory for the specified inventory holder + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public SmithingTableInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the top items + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the smithing table + * @param items the items to send + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Sends the result item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendResultItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sends the first item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendFirstItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sends the second item to the specified player + * + * @param player the player to send the item to + * @param item the item to send + * @since 0.8.0 + */ + public abstract void sendSecondItem(@NotNull Player player, @Nullable ItemStack item); + + /** + * Sets the cursor of the given player + * + * @param player the player to set the cursor + * @param item the item to set the cursor to + * @since 0.8.0 + */ + public abstract void setCursor(@NotNull Player player, @NotNull ItemStack item); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); + + /** + * Clears the result item for the specified player + * + * @param player the player to clear the result item of + * @since 0.8.0 + */ + public abstract void clearResultItem(@NotNull Player player); +} diff --git a/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/StonecutterInventory.java b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/StonecutterInventory.java new file mode 100644 index 00000000..7481979d --- /dev/null +++ b/nms/abstraction/src/main/java/com/github/stefvanschie/inventoryframework/abstraction/StonecutterInventory.java @@ -0,0 +1,58 @@ +package com.github.stefvanschie.inventoryframework.abstraction; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A stonecutter inventory + * + * @since 0.8.0 + */ +public abstract class StonecutterInventory { + + /** + * The inventory holder + */ + @NotNull + protected InventoryHolder inventoryHolder; + + /** + * Creates a new stonecutter inventory for the specified stonecutter gui + * + * @param inventoryHolder the inventory holder + * @since 0.8.0 + */ + public StonecutterInventory(@NotNull InventoryHolder inventoryHolder) { + this.inventoryHolder = inventoryHolder; + } + + /** + * Opens the inventory for the specified player + * + * @param player the player to open the inventory for + * @param title the title of the inventory + * @param items the top items + * @since 0.8.0 + */ + public abstract void openInventory(@NotNull Player player, @NotNull String title, @Nullable ItemStack[] items); + + /** + * Sends the top items to the inventory for the specified player. + * + * @param player the player for which to open the stonecutter + * @param items the items to send + * @since 0.8.0 + */ + public abstract void sendItems(@NotNull Player player, @Nullable ItemStack[] items); + + /** + * Clears the cursor of the specified player + * + * @param player the player to clear the cursor of + * @since 0.8.0 + */ + public abstract void clearCursor(@NotNull Player player); +} diff --git a/pom.xml b/pom.xml index 8a5eb5d4..ac4864b8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,6 +4,16 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + + IF + nms/abstraction + nms/1_16_R3 + nms/1_16_R2 + nms/1_16_R1 + nms/1_15_R1 + nms/1_14_R1 + + 1.8 1.8 @@ -11,9 +21,9 @@ com.github.stefvanschie.inventoryframework - IF + IF-parent 0.7.2 - jar + pom IF An inventory framework for managing GUIs @@ -38,46 +48,13 @@ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - mojang-repo - https://libraries.minecraft.net/ - - - jitpack.io - https://jitpack.io - - - - - org.spigotmc - spigot-api - 1.15-R0.1-SNAPSHOT - provided - - - com.mojang - authlib - 1.5.21 - provided - org.jetbrains annotations 19.0.0 provided - - org.junit.jupiter - junit-jupiter-api - 5.3.1 - test - From 74b7e8df14dead3973b25d2ea3fb8389c83d1664 Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Sun, 15 Nov 2020 20:58:04 +0100 Subject: [PATCH 2/7] Add GitHub workflow from master branch --- .github/workflows/maven.yml | 61 +++++++++++++++++++++++++++++++++++++ .gitignore | 3 +- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/maven.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 00000000..d12d7761 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,61 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Java CI with Maven + +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] + workflow_dispatch: + branches: [ '*' ] + +jobs: + set-up-1-14-R1: + runs-on: ubuntu-latest + name: 'Set up 1.14 R1' + steps: + - run: | + wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar + java -jar BuildTools.jar --rev 1.14.4 + set-up-1-15-R1: + runs-on: ubuntu-latest + name: 'Set up 1.15 R1' + steps: + - run: | + wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar + java -jar BuildTools.jar --rev 1.15.2 + set-up-1-16-R1: + runs-on: ubuntu-latest + name: 'Set up 1.16 R1' + steps: + - run: | + wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar + java -jar BuildTools.jar --rev 1.16.1 + set-up-1-16-R2: + runs-on: ubuntu-latest + name: 'Set up 1.16 R2' + steps: + - run: | + wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar + java -jar BuildTools.jar --rev 1.16.3 + set-up-1-16-R3: + runs-on: ubuntu-latest + name: 'Set up 1.16 R3' + steps: + - run: | + wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar + java -jar BuildTools.jar --rev 1.16.4 + build: + runs-on: ubuntu-latest + needs: [set-up-1-14-R1, set-up-1-15-R1, set-up-1-16-R1, set-up-1-16-R2, set-up-1-16-R3] + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Maven + run: mvn -B package --file pom.xml \ No newline at end of file diff --git a/.gitignore b/.gitignore index 29c9ccdf..77a4b112 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ out target IF-Test *.iml -*.txt \ No newline at end of file +*.txt +dependency-reduced-pom.xml \ No newline at end of file From 5b8f287f31e19066716b7a9d6e8811dc7c32581a Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Sun, 15 Nov 2020 21:14:06 +0100 Subject: [PATCH 3/7] Cache Maven .m2 repository --- .github/workflows/maven.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d12d7761..df9b7a92 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -19,6 +19,12 @@ jobs: - run: | wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar java -jar BuildTools.jar --rev 1.14.4 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- set-up-1-15-R1: runs-on: ubuntu-latest name: 'Set up 1.15 R1' @@ -26,6 +32,12 @@ jobs: - run: | wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar java -jar BuildTools.jar --rev 1.15.2 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- set-up-1-16-R1: runs-on: ubuntu-latest name: 'Set up 1.16 R1' @@ -33,6 +45,12 @@ jobs: - run: | wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar java -jar BuildTools.jar --rev 1.16.1 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- set-up-1-16-R2: runs-on: ubuntu-latest name: 'Set up 1.16 R2' @@ -40,6 +58,12 @@ jobs: - run: | wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar java -jar BuildTools.jar --rev 1.16.3 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- set-up-1-16-R3: runs-on: ubuntu-latest name: 'Set up 1.16 R3' @@ -47,6 +71,12 @@ jobs: - run: | wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar -O BuildTools.jar java -jar BuildTools.jar --rev 1.16.4 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- build: runs-on: ubuntu-latest needs: [set-up-1-14-R1, set-up-1-15-R1, set-up-1-16-R1, set-up-1-16-R2, set-up-1-16-R3] @@ -58,4 +88,4 @@ jobs: with: java-version: 1.8 - name: Build with Maven - run: mvn -B package --file pom.xml \ No newline at end of file + run: mvn -B package --file pom.xml From a4240ecea3a6beb5fcfe16481973f9686931825d Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Sun, 15 Nov 2020 21:18:31 +0100 Subject: [PATCH 4/7] Change abstraction dependency from spigot to spigot-api --- nms/abstraction/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nms/abstraction/pom.xml b/nms/abstraction/pom.xml index 09520281..b1f72ec2 100644 --- a/nms/abstraction/pom.xml +++ b/nms/abstraction/pom.xml @@ -14,7 +14,7 @@ org.spigotmc - spigot + spigot-api 1.16.4-R0.1-SNAPSHOT provided From 7cf2c1ee2402b849d6a3e5abe4d50bc179f95f78 Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Mon, 16 Nov 2020 19:35:44 +0100 Subject: [PATCH 5/7] Add repository to abstraction pom --- nms/abstraction/pom.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nms/abstraction/pom.xml b/nms/abstraction/pom.xml index b1f72ec2..71ba3ce8 100644 --- a/nms/abstraction/pom.xml +++ b/nms/abstraction/pom.xml @@ -11,6 +11,14 @@ 4.0.0 abstraction + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + org.spigotmc @@ -19,6 +27,4 @@ provided - - \ No newline at end of file From 7da3cc055049bdd3a2f9c702cac42ab60cac2763 Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Mon, 16 Nov 2020 20:55:03 +0100 Subject: [PATCH 6/7] V 0.8.0 --- .travis.yml | 1 - IF/pom.xml | 18 +++++++++++------- nms/1_14_R1/pom.xml | 4 ++-- nms/1_15_R1/pom.xml | 4 ++-- nms/1_16_R1/pom.xml | 4 ++-- nms/1_16_R2/pom.xml | 4 ++-- nms/1_16_R3/pom.xml | 4 ++-- nms/abstraction/pom.xml | 2 +- pom.xml | 3 ++- 9 files changed, 24 insertions(+), 20 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f5c99a7f..00000000 --- a/.travis.yml +++ /dev/null @@ -1 +0,0 @@ -language: java \ No newline at end of file diff --git a/IF/pom.xml b/IF/pom.xml index 64481c4d..bb05e75f 100644 --- a/IF/pom.xml +++ b/IF/pom.xml @@ -5,13 +5,17 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 4.0.0 IF jar + + false + + spigot-repo @@ -27,37 +31,37 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile com.github.stefvanschie.inventoryframework 1_14_R1 - 0.7.2 + ${project.version} compile com.github.stefvanschie.inventoryframework 1_15_R1 - 0.7.2 + ${project.version} compile com.github.stefvanschie.inventoryframework 1_16_R1 - 0.7.2 + ${project.version} compile com.github.stefvanschie.inventoryframework 1_16_R2 - 0.7.2 + ${project.version} compile com.github.stefvanschie.inventoryframework 1_16_R3 - 0.7.2 + ${project.version} compile diff --git a/nms/1_14_R1/pom.xml b/nms/1_14_R1/pom.xml index b7a37c32..de9f438d 100644 --- a/nms/1_14_R1/pom.xml +++ b/nms/1_14_R1/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 @@ -22,7 +22,7 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile diff --git a/nms/1_15_R1/pom.xml b/nms/1_15_R1/pom.xml index cee27afa..9ec9c145 100644 --- a/nms/1_15_R1/pom.xml +++ b/nms/1_15_R1/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 @@ -22,7 +22,7 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile diff --git a/nms/1_16_R1/pom.xml b/nms/1_16_R1/pom.xml index ce566490..ec26f716 100644 --- a/nms/1_16_R1/pom.xml +++ b/nms/1_16_R1/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 @@ -22,7 +22,7 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile diff --git a/nms/1_16_R2/pom.xml b/nms/1_16_R2/pom.xml index cf4e7050..77d8aa92 100644 --- a/nms/1_16_R2/pom.xml +++ b/nms/1_16_R2/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 @@ -22,7 +22,7 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile diff --git a/nms/1_16_R3/pom.xml b/nms/1_16_R3/pom.xml index 7466da3a..7bbd4db9 100644 --- a/nms/1_16_R3/pom.xml +++ b/nms/1_16_R3/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 @@ -16,7 +16,7 @@ com.github.stefvanschie.inventoryframework abstraction - 0.7.2 + ${project.version} compile diff --git a/nms/abstraction/pom.xml b/nms/abstraction/pom.xml index 71ba3ce8..319922b9 100644 --- a/nms/abstraction/pom.xml +++ b/nms/abstraction/pom.xml @@ -5,7 +5,7 @@ IF-parent com.github.stefvanschie.inventoryframework - 0.7.2 + 0.8.0 ../../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index ac4864b8..e7faaf78 100644 --- a/pom.xml +++ b/pom.xml @@ -17,12 +17,13 @@ 1.8 1.8 + true UTF-8 com.github.stefvanschie.inventoryframework IF-parent - 0.7.2 + 0.8.0 pom IF From 7568f4ab5e7558d57151d7b53f180a3664960e1b Mon Sep 17 00:00:00 2001 From: stefvanschie Date: Tue, 17 Nov 2020 19:08:34 +0100 Subject: [PATCH 7/7] Final 0.8.0 changes --- README.md | 4 ++-- nms/1_14_R1/pom.xml | 4 ++++ nms/1_15_R1/pom.xml | 4 ++++ nms/1_16_R1/pom.xml | 4 ++++ nms/1_16_R2/pom.xml | 4 ++++ nms/1_16_R3/pom.xml | 4 ++++ nms/abstraction/pom.xml | 4 ++++ 7 files changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ad01e25..30fb033d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ To add this project as a dependency to your pom.xml, add the following to your p com.github.stefvanschie.inventoryframework IF - 0.7.2 + 0.8.0 ``` The project is in the Central Repository, so specifying a repository is not needed. @@ -47,7 +47,7 @@ Replace [YOUR PACKAGE] with the top-level package of your project. To add this project as a dependency for your Gradle project, make sure your `dependencies` section of your build.gradle looks like the following: ```Groovy dependencies { - compile 'com.github.stefvanschie.inventoryframework:IF:0.7.2' + compile 'com.github.stefvanschie.inventoryframework:IF:0.8.0' // ... } ``` diff --git a/nms/1_14_R1/pom.xml b/nms/1_14_R1/pom.xml index de9f438d..f5187dc7 100644 --- a/nms/1_14_R1/pom.xml +++ b/nms/1_14_R1/pom.xml @@ -12,6 +12,10 @@ 1_14_R1 + + true + + org.spigotmc diff --git a/nms/1_15_R1/pom.xml b/nms/1_15_R1/pom.xml index 9ec9c145..5a14113e 100644 --- a/nms/1_15_R1/pom.xml +++ b/nms/1_15_R1/pom.xml @@ -12,6 +12,10 @@ 1_15_R1 + + true + + org.spigotmc diff --git a/nms/1_16_R1/pom.xml b/nms/1_16_R1/pom.xml index ec26f716..8e871f81 100644 --- a/nms/1_16_R1/pom.xml +++ b/nms/1_16_R1/pom.xml @@ -12,6 +12,10 @@ 1_16_R1 + + true + + org.spigotmc diff --git a/nms/1_16_R2/pom.xml b/nms/1_16_R2/pom.xml index 77d8aa92..cabd1305 100644 --- a/nms/1_16_R2/pom.xml +++ b/nms/1_16_R2/pom.xml @@ -12,6 +12,10 @@ 1_16_R2 + + true + + org.spigotmc diff --git a/nms/1_16_R3/pom.xml b/nms/1_16_R3/pom.xml index 7bbd4db9..4188a797 100644 --- a/nms/1_16_R3/pom.xml +++ b/nms/1_16_R3/pom.xml @@ -12,6 +12,10 @@ 1_16_R3 + + true + + com.github.stefvanschie.inventoryframework diff --git a/nms/abstraction/pom.xml b/nms/abstraction/pom.xml index 319922b9..aa2415b4 100644 --- a/nms/abstraction/pom.xml +++ b/nms/abstraction/pom.xml @@ -12,6 +12,10 @@ abstraction + + true + + spigot-repo