Fix holograms

This commit is contained in:
Tofaa2 2024-06-10 17:23:54 +04:00
parent 4c0ca7008c
commit 2a3732fa83
8 changed files with 170 additions and 97 deletions

View file

@ -5,7 +5,14 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment=""> <list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestHologramsCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/utils/Check.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/utils/Check.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/test-plugin/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/build.gradle" afterDir="false" />
<change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -34,37 +41,7 @@
</task> </task>
<projects_view> <projects_view>
<tree_state> <tree_state>
<expand> <expand />
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="run paper" type="c8890929:TasksNode$1" />
</path>
<path>
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
<item name="EntityLib" type="f1a62948:ProjectNode" />
<item name="test-plugin" type="2d1252cf:ModuleNode" />
<item name="Tasks" type="e4a08cd1:TasksNode" />
<item name="run task shared" type="c8890929:TasksNode$1" />
</path>
</expand>
<select /> <select />
</tree_state> </tree_state>
</projects_view> </projects_view>
@ -106,51 +83,51 @@
<option name="showExcludedFiles" value="false" /> <option name="showExcludedFiles" value="false" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;Downloaded.Files.Path.Enabled&quot;: &quot;false&quot;, "Downloaded.Files.Path.Enabled": "false",
&quot;Gradle.Build EntityLib.executor&quot;: &quot;Run&quot;, "Gradle.Build EntityLib.executor": "Run",
&quot;Gradle.EntityLib [dependencies].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib [dependencies].executor": "Run",
&quot;Gradle.EntityLib [publish].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib [publish].executor": "Run",
&quot;Gradle.EntityLib [runServer] (1).executor&quot;: &quot;Run&quot;, "Gradle.EntityLib [runServer] (1).executor": "Run",
&quot;Gradle.EntityLib [runServer].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib [runServer].executor": "Run",
&quot;Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:code-gen [:code-gen:Main.main()].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [cleanAllRunTaskCaches].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [cleanAllRunTaskCaches].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [cleanCustomServiceCaches].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [cleanCustomServiceCaches].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [cleanPaperCache].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [cleanPaperCache].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [cleanPaperPluginsCache].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [cleanPaperPluginsCache].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [publish].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [publish].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [runServer].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [runServer].executor": "Run",
&quot;Gradle.EntityLib:test-plugin [shadowJar].executor&quot;: &quot;Run&quot;, "Gradle.EntityLib:test-plugin [shadowJar].executor": "Run",
&quot;JAR Application.Unnamed.executor&quot;: &quot;Run&quot;, "JAR Application.Unnamed.executor": "Run",
&quot;Repository.Attach.Annotations&quot;: &quot;false&quot;, "Repository.Attach.Annotations": "false",
&quot;Repository.Attach.JavaDocs&quot;: &quot;false&quot;, "Repository.Attach.JavaDocs": "false",
&quot;Repository.Attach.Sources&quot;: &quot;false&quot;, "Repository.Attach.Sources": "false",
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;, "RunOnceActivity.OpenProjectViewOnStart": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;, "WebServerToolWindowFactoryState": "false",
&quot;git-widget-placeholder&quot;: &quot;master&quot;, "git-widget-placeholder": "master",
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;, "ignore.virus.scanning.warn.message": "true",
&quot;jdk.selected.JAVA_MODULE&quot;: &quot;corretto-17&quot;, "jdk.selected.JAVA_MODULE": "corretto-17",
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;, "kotlin-language-version-configured": "true",
&quot;last_opened_file_path&quot;: &quot;/home/tofaa/Github/EntityLib/model-engine-addon&quot;, "last_opened_file_path": "D:/Github/EntityLib",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "nodejs_package_manager_path": "npm",
&quot;project.structure.last.edited&quot;: &quot;Modules&quot;, "project.structure.last.edited": "Modules",
&quot;project.structure.proportion&quot;: &quot;0.15&quot;, "project.structure.proportion": "0.15",
&quot;project.structure.side.proportion&quot;: &quot;0.2&quot;, "project.structure.side.proportion": "0.2",
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.editor&quot;, "settings.editor.selected.configurable": "preferences.editor",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "vue.rearranger.settings.migration": "true"
}, },
&quot;keyToStringList&quot;: { "keyToStringList": {
&quot;kotlin-gradle-user-dirs&quot;: [ "kotlin-gradle-user-dirs": [
&quot;/home/tofaa/.gradle&quot; "/home/tofaa/.gradle"
] ]
} }
}</component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/model-engine-addon" /> <recent name="$PROJECT_DIR$/model-engine-addon" />
@ -313,8 +290,8 @@
<component name="SharedIndexes"> <component name="SharedIndexes">
<attachedChunks> <attachedChunks>
<set> <set>
<option value="bundled-jdk-9f38398b9061-18abd8497189-intellij.indexing.shared.core-IU-241.14494.240" /> <option value="bundled-jdk-9f38398b9061-39b83d9b5494-intellij.indexing.shared.core-IU-241.15989.150" />
<option value="bundled-js-predefined-1d06a55b98c1-74d2a5396914-JavaScript-IU-241.14494.240" /> <option value="bundled-js-predefined-1d06a55b98c1-91d5c284f522-JavaScript-IU-241.15989.150" />
</set> </set>
</attachedChunks> </attachedChunks>
</component> </component>
@ -408,6 +385,7 @@
<workItem from="1716488324710" duration="3710000" /> <workItem from="1716488324710" duration="3710000" />
<workItem from="1716722129881" duration="965000" /> <workItem from="1716722129881" duration="965000" />
<workItem from="1716926795264" duration="1000" /> <workItem from="1716926795264" duration="1000" />
<workItem from="1718023888535" duration="1738000" />
</task> </task>
<servers /> <servers />
</component> </component>
@ -428,7 +406,7 @@
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="java-line"> <line-breakpoint enabled="true" type="java-line">
<url>file://$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java</url> <url>file://$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java</url>
<line>33</line> <line>42</line>
<option name="timeStamp" value="3" /> <option name="timeStamp" value="3" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="java-line"> <line-breakpoint enabled="true" type="java-line">

View file

@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
@ -14,6 +15,18 @@ public final class Check {
private Check() {} private Check() {}
public static <T> void arrayLength(List<T> lines, int index, T e) {
if (index >= lines.size()) {
for (int i = lines.size(); i < index; i++) {
lines.add(null);
}
lines.add(e);
}
else {lines.set(index, e);
}
}
@Contract("null, _ -> fail") @Contract("null, _ -> fail")
public static void notNull(@Nullable Object object, @NotNull String reason) { public static void notNull(@Nullable Object object, @NotNull String reason) {
if (Objects.isNull(object)) { if (Objects.isNull(object)) {

View file

@ -1,5 +1,6 @@
package me.tofaa.entitylib.wrapper.hologram; package me.tofaa.entitylib.wrapper.hologram;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.protocol.world.Location;
import me.tofaa.entitylib.meta.display.TextDisplayMeta; import me.tofaa.entitylib.meta.display.TextDisplayMeta;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -7,24 +8,26 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
public interface Hologram<W> { public interface Hologram {
static <C> Hologram.@NotNull Legacy<C> legacy(@NotNull Location location) { static Hologram.@NotNull Legacy legacy(@NotNull Location location) {
return new LegacyHologram<>(location); return new LegacyHologram(location);
} }
static <C> Hologram.@NotNull Legacy<C> legacy(@NotNull Location location, List<Component> lines) { static Hologram.@NotNull Legacy legacy(@NotNull Location location, List<Component> lines) {
return new LegacyHologram<>(location, lines); return new LegacyHologram(location, lines);
} }
static <C> Hologram.@NotNull Modern<C> modern(@NotNull Location location) {
return new ModernHologram<>(location); static Hologram.@NotNull Modern modern(@NotNull Location location) {
return new ModernHologram(location);
} }
static <C> Hologram.@NotNull Modern<C> modern(@NotNull Location location, List<Component> lines) { static Hologram.@NotNull Modern modern(@NotNull Location location, List<Component> lines) {
return new ModernHologram<>(location, lines); return new ModernHologram(location, lines);
} }
@NotNull Location getLocation(); @NotNull Location getLocation();
@ -44,13 +47,18 @@ public interface Hologram<W> {
void addLine(@Nullable Component line); void addLine(@Nullable Component line);
interface Modern<W> extends Hologram<W> { void addViewer(@NotNull UUID viewer);
default void addViewer(@NotNull User user) {
addViewer(user.getUUID());
}
interface Modern extends Hologram {
// I got too lazy // I got too lazy
void setModifier(@NotNull Consumer<TextDisplayMeta> consumer); void setModifier(@NotNull Consumer<TextDisplayMeta> consumer);
} }
interface Legacy<W> extends Hologram<W> { interface Legacy extends Hologram {
float getLineOffset(boolean marker); float getLineOffset(boolean marker);

View file

@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.protocol.world.Location;
import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.EntityLib;
import me.tofaa.entitylib.meta.other.ArmorStandMeta; import me.tofaa.entitylib.meta.other.ArmorStandMeta;
import me.tofaa.entitylib.utils.Check;
import me.tofaa.entitylib.wrapper.WrapperEntity; import me.tofaa.entitylib.wrapper.WrapperEntity;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,11 +12,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
final class LegacyHologram<W> implements Hologram.Legacy<W> { final class LegacyHologram implements Hologram.Legacy {
private Location location; private Location location;
private List<WrapperEntity> lines = new ArrayList<>(3); private final List<WrapperEntity> lines = new ArrayList<>(3);
private float lineOffset = -0.9875f; private float lineOffset = -0.9875f;
private float markerOffset = -0.40625f; private float markerOffset = -0.40625f;
private boolean marker; private boolean marker;
@ -31,6 +33,13 @@ final class LegacyHologram<W> implements Hologram.Legacy<W> {
} }
} }
@Override
public void addViewer(@NotNull UUID viewer) {
for (WrapperEntity line : lines) {
line.addViewer(viewer);
}
}
@Override @Override
public boolean isMarker() { public boolean isMarker() {
return marker; return marker;
@ -95,7 +104,7 @@ final class LegacyHologram<W> implements Hologram.Legacy<W> {
meta.setHasNoGravity(true); meta.setHasNoGravity(true);
meta.setSmall(true); meta.setSmall(true);
meta.setMarker(marker); meta.setMarker(marker);
this.lines.set(index, e); Check.arrayLength(lines, index, e);
e.spawn(location); e.spawn(location);
teleport(location); teleport(location);
} }

View file

@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.protocol.world.Location;
import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.EntityLib;
import me.tofaa.entitylib.meta.display.TextDisplayMeta; import me.tofaa.entitylib.meta.display.TextDisplayMeta;
import me.tofaa.entitylib.utils.Check;
import me.tofaa.entitylib.wrapper.WrapperEntity; import me.tofaa.entitylib.wrapper.WrapperEntity;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,13 +12,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
final class ModernHologram<W> implements Hologram.Modern<W> { final class ModernHologram implements Hologram.Modern {
private Location location; private Location location;
private List<WrapperEntity> lines = new ArrayList<>(3); private final List<WrapperEntity> lines = new ArrayList<>(3);
private Consumer<TextDisplayMeta> modifier; private Consumer<TextDisplayMeta> modifier;
private boolean spawned = false;
ModernHologram(@NotNull Location location) { ModernHologram(@NotNull Location location) {
this.location = location; this.location = location;
@ -36,6 +39,7 @@ final class ModernHologram<W> implements Hologram.Modern<W> {
line.spawn(location); line.spawn(location);
} }
teleport(location); teleport(location);
spawned = true;
} }
@Override @Override
@ -43,6 +47,7 @@ final class ModernHologram<W> implements Hologram.Modern<W> {
for (WrapperEntity line : lines) { for (WrapperEntity line : lines) {
line.despawn(); line.despawn();
} }
spawned = false;
} }
@Override @Override
@ -72,17 +77,28 @@ final class ModernHologram<W> implements Hologram.Modern<W> {
meta.setInvisible(true); meta.setInvisible(true);
meta.setHasNoGravity(true); meta.setHasNoGravity(true);
meta.setText(line); meta.setText(line);
if (this.modifier != null) {
this.modifier.accept(meta); this.modifier.accept(meta);
this.lines.set(index, e); }
Check.arrayLength(lines, index, e);
if (spawned) {
e.spawn(location); e.spawn(location);
teleport(location); teleport(location);
} }
}
@Override @Override
public void addLine(@Nullable Component line) { public void addLine(@Nullable Component line) {
setLine(lines.size(), line); setLine(lines.size(), line);
} }
@Override
public void addViewer(@NotNull UUID viewer) {
for (WrapperEntity line : lines) {
line.addViewer(viewer);
}
}
@Override @Override
public int length() { public int length() {

View file

@ -34,7 +34,7 @@ dependencies {
compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT') compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT')
compileOnly('com.github.retrooper.packetevents:spigot:2.3.0') compileOnly('com.github.retrooper.packetevents:spigot:2.3.0')
// implementation(project(":platforms:spigot")) // implementation(project(":platforms:spigot"))
implementation("com.github.Tofaa2.EntityLib:spigot:2.2.0-SNAPSHOT") implementation(project(":platforms:spigot"))
} }

View file

@ -42,6 +42,7 @@ public class TestEntityLibPlugin extends JavaPlugin {
commandMap = (CommandMap) Bukkit.getServer().getClass().getMethod("getCommandMap").invoke(Bukkit.getServer()); commandMap = (CommandMap) Bukkit.getServer().getClass().getMethod("getCommandMap").invoke(Bukkit.getServer());
commandMap.register("testapi", new TestTextDisplayCommand()); commandMap.register("testapi", new TestTextDisplayCommand());
commandMap.register("testplayer", new TestPlayerCommand()); commandMap.register("testplayer", new TestPlayerCommand());
commandMap.register("testholo", new TestHologramsCommand());
} }
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -0,0 +1,48 @@
package me.tofaa.testentitylib;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import me.tofaa.entitylib.wrapper.hologram.Hologram;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class TestHologramsCommand extends BukkitCommand {
TestHologramsCommand () {
super("testholo");
}
@Override
public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
if (strings.length == 0) {
commandSender.sendMessage("Usage: /testholo <legacy|modern>");
return true;
}
Player player = (Player) commandSender;
if (strings[0].equalsIgnoreCase("modern")) {
Hologram.Modern holo =Hologram.modern(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
holo.addLine(Component.text("Hello, World!"));
holo.show();
holo.addViewer(player.getUniqueId());
}
if (strings[0].equalsIgnoreCase("legacy")) {
Hologram.Legacy holo = Hologram.legacy(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
holo.addLine(Component.text("Hello, World!"));
holo.show();
holo.addViewer(player.getUniqueId());
}
return true;
}
@NotNull
@Override
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
return Arrays.asList("legacy", "modern");
}
}