Added start of demo code.
This commit is contained in:
parent
8b1ac0a7d1
commit
6cb6ba8c11
12 changed files with 900 additions and 19 deletions
|
|
@ -0,0 +1,29 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiCond;
|
||||
import imgui.type.ImBoolean;
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.ImGuiRendererMain;
|
||||
|
||||
public class BasicConsoleRenderer extends ImGuiRendererMain {
|
||||
|
||||
public BasicConsoleRenderer(Demo4DMain main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ImBoolean widgetOpen) {
|
||||
ImGui.setNextWindowPos(300, 300, ImGuiCond.FirstUseEver);
|
||||
ImGui.setNextWindowSize(320, 240, ImGuiCond.FirstUseEver);
|
||||
ImGui.begin("The BASIC Shahada of DUNE", widgetOpen);
|
||||
ImGui.text("10 PRINT \"THERE IS NO GOD BUT @Ω\u4ed9⁴\"");
|
||||
ImGui.text("20 PRINT \"THERE IS NO RULE BUT CONSENT\"");
|
||||
ImGui.text("30 PRINT \"THERE IS NO FAILURE BUT DEATH\"");
|
||||
ImGui.text("40 PRINT \"TERRY A. DAVIS WAS THE PROPHET OF @Ω\u4ed9⁴\"");
|
||||
ImGui.text("50 PRINT \"TERRY A. DAVIS WAS THE FIRST TRUE MENTAT\"");
|
||||
ImGui.text("60 PRINT \"TERRY A. DAVIS WAS THE BEST CODER ALIVE\"");
|
||||
ImGui.text("RUN");
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiCond;
|
||||
import imgui.flag.ImGuiTableFlags;
|
||||
import imgui.type.ImBoolean;
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.ImGuiRendererMain;
|
||||
import love.distributedrebirth.demo4d.fraction4d.HebrewGê̄ld;
|
||||
|
||||
public class HebrewWalletRenderer extends ImGuiRendererMain {
|
||||
|
||||
public HebrewWalletRenderer(Demo4DMain main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ImBoolean widgetOpen) {
|
||||
ImGui.setNextWindowPos(200, 200, ImGuiCond.FirstUseEver);
|
||||
ImGui.setNextWindowSize(640, 480, ImGuiCond.FirstUseEver);
|
||||
ImGui.begin("Hebrew Wallet", widgetOpen);
|
||||
|
||||
ImGui.text("Current amount:");
|
||||
ImGui.sameLine();
|
||||
ImGui.text("0000");
|
||||
ImGui.separator();
|
||||
if (ImGui.button("Pay")) {
|
||||
}
|
||||
int flags = ImGuiTableFlags.ScrollX | ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.BordersV;
|
||||
ImGui.beginTable("wallet", 4, flags);
|
||||
ImGui.tableSetupColumn("In/Out");
|
||||
ImGui.tableSetupColumn("AmountRaw");
|
||||
ImGui.tableSetupColumn("AmountFix");
|
||||
ImGui.tableSetupColumn("Decimal");
|
||||
ImGui.tableHeadersRow();
|
||||
|
||||
String[] walletData = {
|
||||
"ה","מ","מָ","ח","חֱ","חֱמָא",
|
||||
"א","בד","ב","ד","ץףן",
|
||||
"הזפץ","מספר","צצצצ","ץאאא","דואר"
|
||||
};
|
||||
for (String data:walletData) {
|
||||
HebrewGê̄ld geld = new HebrewGê̄ld(data);
|
||||
ImGui.tableNextRow();
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text(data.length()==2||data.length()==3?"OUT":"IN");
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text(data);
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text(geld.toHebrewString(true)); // true=reverse for ImGui
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text(Double.toString(geld.getTotalDecimalValue()));
|
||||
}
|
||||
ImGui.endTable();
|
||||
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Screen;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.music.MusicSongType;
|
||||
|
||||
public class ScreenCredits extends ScrollScreenAdapter {
|
||||
private final String creditsText = String.join("\n",
|
||||
"Credits;",
|
||||
"At-Ohm-Allah-to-the-power-of-Four",
|
||||
"The King of kings",
|
||||
"Thy Lord of Lords",
|
||||
"Thee God of Gods",
|
||||
"Abstract superset over all religions.",
|
||||
" ",
|
||||
"There is no god but AtohmAllah^4",
|
||||
"There is no rule but consent",
|
||||
"There is no failure but death",
|
||||
" ",
|
||||
"One long long day,",
|
||||
"In a far far, fat-oddly-rounded galaxy,",
|
||||
"Thy father is near.",
|
||||
" ",
|
||||
"Terry A. Davis;",
|
||||
"- TempleOS",
|
||||
"- HolyC",
|
||||
"- Poems",
|
||||
"- Abba music",
|
||||
"- Baby fat",
|
||||
" ",
|
||||
"ID Tech;",
|
||||
"- Ultimate DOOM",
|
||||
"- SIGIL Beast Box",
|
||||
"- DOOM Eternal",
|
||||
" ",
|
||||
"Sanctumwave Music;",
|
||||
"- (music) TempleOS Hymn Risen",
|
||||
"- (music) DIVINE INTELLECT",
|
||||
"- (music) TERRY DAVIS NIGHTWALK",
|
||||
" ",
|
||||
"The Self Help Group;",
|
||||
"- (music) The Self Help-Group Temple OS",
|
||||
" ",
|
||||
"PanoramaCircle;",
|
||||
"- (music) TempleOS 'Waterfowl' poem on real hardware",
|
||||
" ",
|
||||
"Willem Abraham Cazander;",
|
||||
"- http://distributedrebith.love",
|
||||
" ",
|
||||
"=============================================",
|
||||
" ",
|
||||
"The BASIC Shahada",
|
||||
"10 PRINT \"THERE IS NO GOD BUT AT_OHM_ALLAH^4\"",
|
||||
"20 PRINT \"THERE IS NO RULE BUT CONSENT\"",
|
||||
"30 PRINT \"THERE IS THERE IS NO FAILURE BUT DEATH\"",
|
||||
"40 PRINT \"TERRY A. DAVIS WAS THE PROPHET OF GOD\"",
|
||||
"50 PRINT \"TERRY A. DAVIS WAS THE FIRST TRUE MENTAT\"",
|
||||
"60 PRINT \"TERRY A. DAVIS WAS THE BEST CODER ALIVE\"",
|
||||
"RUN",
|
||||
" "
|
||||
);
|
||||
|
||||
public ScreenCredits(final Demo4DMain main) {
|
||||
super(main, "background/doom-credits.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getScrollText() {
|
||||
return creditsText;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Screen> getNextScreen(Demo4DMain main) {
|
||||
return ScreenDefault.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show () {
|
||||
main.music.play(MusicSongType.CREDITS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide () {
|
||||
main.music.play(MusicSongType.BACKGROUND);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.ScreenUtils;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
|
||||
public class ScreenDefault extends ScreenAdapter {
|
||||
private final Demo4DMain main;
|
||||
private Texture backgroundImage;
|
||||
|
||||
public ScreenDefault(final Demo4DMain main) {
|
||||
this.main = main;
|
||||
backgroundImage = new Texture(Gdx.files.internal("background/terrydavis-front.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
ScreenUtils.clear(0f, 0f, 0f, 1f);
|
||||
main.batch.begin();
|
||||
main.batch.draw(backgroundImage, 0, 0, main.viewWidth, main.viewHeight);
|
||||
main.batch.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
backgroundImage.dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Screen;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
|
||||
public class ScreenHelp extends ScrollScreenAdapter {
|
||||
private final String creditsText = String.join("\n",
|
||||
"Genesis 11",
|
||||
" ",
|
||||
"1 And the whole earth was of one language, and of one speech.",
|
||||
" ",
|
||||
"2 And it came to pass, as they journeyed from the east,",
|
||||
" that they found a plain in the land of Shinar;",
|
||||
" and they dwelt there.",
|
||||
" ",
|
||||
"3 And they said one to another, Go to, let us make brick,",
|
||||
" and burn them thoroughly. And they had brick for stone,",
|
||||
" and slime had they for mortar.",
|
||||
" ",
|
||||
"4 And they said, Go to, let us build us a city, and a tower,",
|
||||
" whose top may reach unto heaven; and let us make us a name,",
|
||||
" lest we be scattered abroad upon the face of the whole earth.",
|
||||
" ",
|
||||
"5 And the LORD came down to see the city and the tower,",
|
||||
" which the children of men builded.",
|
||||
" ",
|
||||
"6 And the LORD said, Behold, the people is one,",
|
||||
" and they have all one language; and this they begin to do:",
|
||||
" and now nothing will be restrained from them,",
|
||||
" which they have imagined to do.",
|
||||
" ",
|
||||
"7 Go to, let us go down, and there confound their language,",
|
||||
" that they may not understand one another's speech.",
|
||||
" ",
|
||||
"8 So the LORD scattered them abroad from thence upon the face",
|
||||
" of all the earth: and they left off to build the city.",
|
||||
" ",
|
||||
"9 Therefore is the name of it called Babel; because the LORD",
|
||||
" did there confound the language of all the earth: and from",
|
||||
" thence did the LORD scatter them abroad upon",
|
||||
" the face of all the earth.",
|
||||
" "
|
||||
);
|
||||
|
||||
public ScreenHelp(final Demo4DMain main) {
|
||||
super(main, "background/terrydavis-nose.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getScrollText() {
|
||||
return creditsText;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Screen> getNextScreen(Demo4DMain main) {
|
||||
return ScreenDefault.class;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.ScreenUtils;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.music.MusicSongType;
|
||||
|
||||
public class ScreenIntro extends ScreenAdapter {
|
||||
private final Demo4DMain main;
|
||||
private Texture backgroundImage;
|
||||
private float colorDeltaTime = 0f;
|
||||
private boolean colorPositive = true;
|
||||
|
||||
public ScreenIntro(final Demo4DMain main) {
|
||||
this.main = main;
|
||||
backgroundImage = new Texture(Gdx.files.internal("background/temple-os.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
if (colorPositive) {
|
||||
colorDeltaTime += Gdx.graphics.getDeltaTime()/2;
|
||||
} else {
|
||||
colorDeltaTime -= Gdx.graphics.getDeltaTime()/2;
|
||||
}
|
||||
if (colorDeltaTime > 1f) {
|
||||
colorPositive = false;
|
||||
} else if (colorDeltaTime < 0f) {
|
||||
colorPositive = true;
|
||||
}
|
||||
ScreenUtils.clear(0.333f, colorDeltaTime, colorDeltaTime, 1);
|
||||
|
||||
main.batch.begin();
|
||||
main.batch.draw(backgroundImage, 0, 0, main.viewWidth, main.viewHeight);
|
||||
main.font.draw(main.batch, "Tap anywhere to begin!", main.viewWidth/2 - 73, 33);
|
||||
main.batch.end();
|
||||
|
||||
if (Gdx.input.isTouched() || Gdx.input.isKeyPressed(Keys.ENTER) || Gdx.input.isKeyPressed(Keys.SPACE)) {
|
||||
main.setScreen(new ScreenIntroMission(main));
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
main.music.play(MusicSongType.INTRO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
backgroundImage.dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Screen;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.music.MusicSongType;
|
||||
|
||||
public class ScreenIntroMission extends ScrollScreenAdapter {
|
||||
private final String missionText = String.join("\n",
|
||||
"To a Waterfowl",
|
||||
" -- by William Cullen Bryant --",
|
||||
" ",
|
||||
"Whither, 'midst falling dew,",
|
||||
"While glow the heavens with the last steps of day,",
|
||||
"Far, through their rosy depths, dost thou pursue",
|
||||
"Thy solitary way?",
|
||||
" ",
|
||||
"Vainly the fowler's eye",
|
||||
"Might mark thy distant flight to do thee wrong,",
|
||||
"As, darkly painted on the crimson sky,",
|
||||
"Thy figure floats along.",
|
||||
" ",
|
||||
"Seek'st thou the plashy brink",
|
||||
"Of weedy lake, or marge of river wide,",
|
||||
"Or where the rocking billows rise and sink",
|
||||
"On the chafed ocean side?",
|
||||
" ",
|
||||
"There is a Power whose care",
|
||||
"Teaches thy way along that pathless coast,--",
|
||||
"The desert and illimitable air,--",
|
||||
"Lone wandering, but not lost.",
|
||||
" ",
|
||||
"All day thy wings have fann'd",
|
||||
"At that far height, the cold thin atmosphere:",
|
||||
"Yet stoop not, weary, to the welcome land,",
|
||||
"Though the dark night is near.",
|
||||
" ",
|
||||
"And soon that toil shall end,",
|
||||
"Soon shalt thou find a summer home, and rest,",
|
||||
"And scream among thy fellows; reed shall bend",
|
||||
"Soon o'er thy sheltered nest.",
|
||||
" ",
|
||||
"Thou'rt gone, the abyss of heaven",
|
||||
"Hath swallowed up thy form; yet, on my heart",
|
||||
"Deeply hath sunk the lesson thou hast given,",
|
||||
"And shall not soon depart.",
|
||||
" ",
|
||||
"He, who, from zone to zone,",
|
||||
"Guides through the boundless sky thy certain flight,",
|
||||
"In the long way that I must tread alone,",
|
||||
"Will lead my steps aright.",
|
||||
" "
|
||||
);
|
||||
|
||||
|
||||
|
||||
public ScreenIntroMission(final Demo4DMain main) {
|
||||
super(main, "background/terrydavis-nose.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getScrollText() {
|
||||
return missionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Screen> getNextScreen(Demo4DMain main) {
|
||||
return ScreenDefault.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide () {
|
||||
main.music.play(MusicSongType.BACKGROUND);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import imgui.ImColor;
|
||||
import imgui.ImDrawList;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImVec2;
|
||||
import imgui.flag.ImGuiCond;
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.Demo4DMainAdapter;
|
||||
|
||||
public class ScreenUnicode4D extends Demo4DMainAdapter {
|
||||
|
||||
public ScreenUnicode4D(final Demo4DMain main) {
|
||||
super(main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
main.batch.begin();
|
||||
main.font.draw(main.batch, "Tap anywhere to begin!", main.viewWidth/2 - 73, 33);
|
||||
main.batch.end();
|
||||
|
||||
ImGui.setNextWindowPos(400, 200, ImGuiCond.FirstUseEver);
|
||||
ImGui.setNextWindowSize(320, 240, ImGuiCond.FirstUseEver);
|
||||
ImGui.begin("Unicode4D test");
|
||||
ImGui.text("There is unicode and unicode4D");
|
||||
ImVec2 size = new ImVec2(144f, 48f);
|
||||
ImGui.invisibleButton("canvas", size.x, size.y);
|
||||
ImVec2 p0 = ImGui.getItemRectMin();
|
||||
ImVec2 p1 = ImGui.getItemRectMax();
|
||||
ImDrawList drawList = ImGui.getWindowDrawList();
|
||||
drawList.pushClipRect(p0.x, p0.y, p1.x, p1.y);
|
||||
// draw unicode4D
|
||||
//System.out.println("p0.x="+p0.x+" p0.y="+p0.y);
|
||||
//System.out.println("p1.x="+p1.x+" p1.y="+p1.y);
|
||||
|
||||
// for (int n = 0; n < (1.0f + Math.sin(ImGui.getTime() * 5.7f)) * 40.0f; n++) {
|
||||
// drawList.addCircle(p0.x + size.x * 0.5f, p0.y + size.y * 0.5f, size.y * (0.01f + n * 0.03f),
|
||||
// ImColor.intToColor(255, 140 - n * 4, n * 3, 255)
|
||||
// );
|
||||
// }
|
||||
|
||||
drawList.addQuad(p0.x, p0.y, p0.x+size.x, p0.y, p1.x, p1.y, p0.x, p0.y+size.y,
|
||||
ImColor.intToColor(127, 127, 255, 255), 5f);
|
||||
|
||||
drawList.addLine(p0.x+10, p0.y+40, p0.x+20, p0.y+10, ImColor.intToColor(255, 127, 63, 255));
|
||||
drawList.addLine(p0.x+30, p0.y+40, p0.x+20, p0.y+10, ImColor.intToColor(255, 127, 63, 255));
|
||||
drawList.addLine(p0.x+13, p0.y+30, p0.x+27, p0.y+30, ImColor.intToColor(255, 127, 63, 255));
|
||||
|
||||
drawList.popClipRect();
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package love.distributedrebirth.demo4d.screen;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.utils.ScreenUtils;
|
||||
|
||||
import love.distributedrebirth.demo4d.Demo4DMain;
|
||||
import love.distributedrebirth.demo4d.Demo4DMainAdapter;
|
||||
|
||||
abstract public class ScrollScreenAdapter extends Demo4DMainAdapter {
|
||||
private static final int LINE_HEIGHT = 16;
|
||||
private float scrollDeltaTime = 0f;
|
||||
private String scrollText = "";
|
||||
private int scrollIndex = 0;
|
||||
private int scrollLine = LINE_HEIGHT;
|
||||
private final Texture backgroundImage;
|
||||
|
||||
public ScrollScreenAdapter(final Demo4DMain main, String background) {
|
||||
super(main);
|
||||
backgroundImage = new Texture(Gdx.files.internal(background));
|
||||
}
|
||||
|
||||
abstract protected String getScrollText();
|
||||
|
||||
abstract protected Class<? extends Screen> getNextScreen(Demo4DMain main);
|
||||
|
||||
@Override
|
||||
public final void render(float delta) {
|
||||
ScreenUtils.clear(0f, 0f, 0f, 1f);
|
||||
main.batch.begin();
|
||||
main.batch.draw(backgroundImage, 0, 0, main.viewWidth, main.viewHeight);
|
||||
|
||||
scrollDeltaTime += delta;
|
||||
if (scrollDeltaTime > 0.04f) {
|
||||
scrollDeltaTime = 0f;
|
||||
scrollLine++;
|
||||
if (scrollLine > LINE_HEIGHT && scrollIndex != -1) {
|
||||
scrollIndex = getScrollText().indexOf("\n", scrollIndex+1);
|
||||
if (scrollIndex > 0) {
|
||||
scrollText = getScrollText().substring(0, scrollIndex);
|
||||
scrollLine = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drawLine = 0;
|
||||
String[] lines = scrollText.split("\n");
|
||||
for (int i=lines.length;i>0;i--) {
|
||||
String line = lines[i-1];
|
||||
main.font.draw(main.batch, line, 100, scrollLine + (drawLine*LINE_HEIGHT));
|
||||
drawLine++;
|
||||
}
|
||||
main.batch.end();
|
||||
|
||||
if (scrollText.length() >= 33) {
|
||||
if (scrollLine >= main.viewHeight || Gdx.input.isTouched() || Gdx.input.isKeyPressed(Keys.ENTER) || Gdx.input.isKeyPressed(Keys.SPACE)) {
|
||||
main.selectScreen(getNextScreen(main));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
scrollText = "";
|
||||
scrollIndex = 0;
|
||||
scrollLine = LINE_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void dispose() {
|
||||
backgroundImage.dispose();
|
||||
disposeScreen(main);
|
||||
}
|
||||
|
||||
protected void disposeScreen(Demo4DMain main) {
|
||||
// override if needed
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue