Cleanup.
This commit is contained in:
parent
f38f9ce74e
commit
8047266f13
19 changed files with 186 additions and 178 deletions
|
@ -14,13 +14,13 @@ import java.time.*;
|
|||
public final class ReleaseInfo {
|
||||
public final static String PROJECT = "mobibot";
|
||||
public final static LocalDateTime BUILDDATE =
|
||||
LocalDateTime.ofInstant(Instant.ofEpochMilli(1555731762870L), ZoneId.systemDefault());
|
||||
LocalDateTime.ofInstant(Instant.ofEpochMilli(1555742153981L), ZoneId.systemDefault());
|
||||
public final static int MAJOR = 0;
|
||||
public final static int MINOR = 7;
|
||||
public final static int PATCH = 3;
|
||||
public final static String PRERELEASE = "beta";
|
||||
public final static String BUILDMETA = "303";
|
||||
public final static String VERSION = "0.7.3-beta+303";
|
||||
public final static String BUILDMETA = "306";
|
||||
public final static String VERSION = "0.7.3-beta+306";
|
||||
|
||||
/**
|
||||
* Disables the default constructor.
|
||||
|
|
|
@ -40,120 +40,98 @@ package net.thauvin.erik.mobibot;
|
|||
* @since 1.0
|
||||
*/
|
||||
public final class Commands {
|
||||
/**
|
||||
* The add (back)log command.
|
||||
*/
|
||||
public static final String ADDLOG_CMD = "addlog";
|
||||
|
||||
/**
|
||||
* The cycle command.
|
||||
*/
|
||||
public static final String CYCLE_CMD = "cycle";
|
||||
|
||||
/**
|
||||
* Debug command line argument.
|
||||
*/
|
||||
public static final String DEBUG_ARG = "debug";
|
||||
|
||||
/**
|
||||
* The debug command.
|
||||
*/
|
||||
public static final String DEBUG_CMD = "debug";
|
||||
|
||||
/**
|
||||
* The die command.
|
||||
*/
|
||||
public static final String DIE_CMD = "die";
|
||||
|
||||
/**
|
||||
* Help command line argument.
|
||||
*/
|
||||
public static final String HELP_ARG = "help";
|
||||
|
||||
/**
|
||||
* The help command.
|
||||
*/
|
||||
public static final String HELP_CMD = "help";
|
||||
|
||||
/**
|
||||
* The help on posting keyword.
|
||||
*/
|
||||
public static final String HELP_POSTING_KEYWORD = "posting";
|
||||
|
||||
/**
|
||||
* The help on tags keyword.
|
||||
*/
|
||||
public static final String HELP_TAGS_KEYWORD = "tags";
|
||||
|
||||
/**
|
||||
* The ignore command.
|
||||
*/
|
||||
public static final String IGNORE_CMD = "ignore";
|
||||
|
||||
/**
|
||||
* The ignore <code>me</code> keyword.
|
||||
*/
|
||||
public static final String IGNORE_ME_KEYWORD = "me";
|
||||
|
||||
/**
|
||||
* The info command.
|
||||
*/
|
||||
public static final String INFO_CMD = "info";
|
||||
|
||||
/**
|
||||
* The link command.
|
||||
*/
|
||||
public static final String LINK_CMD = "L";
|
||||
|
||||
/**
|
||||
* The me command.
|
||||
*/
|
||||
public static final String ME_CMD = "me";
|
||||
|
||||
/**
|
||||
* The msg command.
|
||||
*/
|
||||
public static final String MSG_CMD = "msg";
|
||||
|
||||
/**
|
||||
* The nick command.
|
||||
*/
|
||||
public static final String NICK_CMD = "nick";
|
||||
|
||||
/**
|
||||
* Properties command line argument.
|
||||
*/
|
||||
public static final String PROPS_ARG = "properties";
|
||||
|
||||
/**
|
||||
* The recap command.
|
||||
*/
|
||||
public static final String RECAP_CMD = "recap";
|
||||
|
||||
/**
|
||||
* The say command.
|
||||
*/
|
||||
public static final String SAY_CMD = "say";
|
||||
|
||||
/**
|
||||
* The users command.
|
||||
*/
|
||||
public static final String USERS_CMD = "users";
|
||||
|
||||
/**
|
||||
* Properties version line argument.
|
||||
*/
|
||||
public static final String VERSION_ARG = "version";
|
||||
|
||||
/**
|
||||
* The version command.
|
||||
*/
|
||||
public static final String VERSION_CMD = "version";
|
||||
|
||||
/**
|
||||
* The view command.
|
||||
*/
|
||||
public static final String VIEW_CMD = "view";
|
||||
/**
|
||||
* The add (back)log command.
|
||||
*/
|
||||
static final String ADDLOG_CMD = "addlog";
|
||||
/**
|
||||
* The cycle command.
|
||||
*/
|
||||
static final String CYCLE_CMD = "cycle";
|
||||
/**
|
||||
* Debug command line argument.
|
||||
*/
|
||||
static final String DEBUG_ARG = "debug";
|
||||
/**
|
||||
* The debug command.
|
||||
*/
|
||||
static final String DEBUG_CMD = "debug";
|
||||
/**
|
||||
* The die command.
|
||||
*/
|
||||
static final String DIE_CMD = "die";
|
||||
/**
|
||||
* Help command line argument.
|
||||
*/
|
||||
static final String HELP_ARG = "help";
|
||||
/**
|
||||
* The help command.
|
||||
*/
|
||||
static final String HELP_CMD = "help";
|
||||
/**
|
||||
* The help on posting keyword.
|
||||
*/
|
||||
static final String HELP_POSTING_KEYWORD = "posting";
|
||||
/**
|
||||
* The help on tags keyword.
|
||||
*/
|
||||
static final String HELP_TAGS_KEYWORD = "tags";
|
||||
/**
|
||||
* The ignore command.
|
||||
*/
|
||||
static final String IGNORE_CMD = "ignore";
|
||||
/**
|
||||
* The ignore <code>me</code> keyword.
|
||||
*/
|
||||
static final String IGNORE_ME_KEYWORD = "me";
|
||||
/**
|
||||
* The info command.
|
||||
*/
|
||||
static final String INFO_CMD = "info";
|
||||
/**
|
||||
* The me command.
|
||||
*/
|
||||
static final String ME_CMD = "me";
|
||||
/**
|
||||
* The msg command.
|
||||
*/
|
||||
static final String MSG_CMD = "msg";
|
||||
/**
|
||||
* The nick command.
|
||||
*/
|
||||
static final String NICK_CMD = "nick";
|
||||
/**
|
||||
* Properties command line argument.
|
||||
*/
|
||||
static final String PROPS_ARG = "properties";
|
||||
/**
|
||||
* The recap command.
|
||||
*/
|
||||
static final String RECAP_CMD = "recap";
|
||||
/**
|
||||
* The say command.
|
||||
*/
|
||||
static final String SAY_CMD = "say";
|
||||
/**
|
||||
* The users command.
|
||||
*/
|
||||
static final String USERS_CMD = "users";
|
||||
/**
|
||||
* Properties version line argument.
|
||||
*/
|
||||
static final String VERSION_ARG = "version";
|
||||
/**
|
||||
* The version command.
|
||||
*/
|
||||
static final String VERSION_CMD = "version";
|
||||
|
||||
/**
|
||||
* Disables the default constructor.
|
||||
|
|
|
@ -72,7 +72,7 @@ class FeedReader implements Runnable {
|
|||
* @param sender The nick of the person who sent the message.
|
||||
* @param url The URL to fetch.
|
||||
*/
|
||||
public FeedReader(final Mobibot bot, final String sender, final String url) {
|
||||
FeedReader(final Mobibot bot, final String sender, final String url) {
|
||||
this.bot = bot;
|
||||
this.sender = sender;
|
||||
this.url = url;
|
||||
|
|
|
@ -58,7 +58,9 @@ public class Calc extends AbstractModule {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate.
|
||||
* Performs a calculation.
|
||||
*
|
||||
* <p>1 + 1 * 2</p>
|
||||
*
|
||||
* @param query The query.
|
||||
* @return The calculation result.
|
||||
|
|
|
@ -82,6 +82,15 @@ public final class CurrencyConverter extends ThreadedModule {
|
|||
commands.add(CURRENCY_CMD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from a currency to another.
|
||||
*
|
||||
* <p>100 USD to EUR</p>
|
||||
*
|
||||
* @param query The query.
|
||||
* @return The {@link Message} contained the converted currency.
|
||||
* @throws ModuleException If an error occurs while converting.
|
||||
*/
|
||||
static Message convertCurrency(final String query) throws ModuleException {
|
||||
if (EXCHANGE_RATES.isEmpty()) {
|
||||
try {
|
||||
|
@ -177,22 +186,6 @@ public final class CurrencyConverter extends ThreadedModule {
|
|||
super.commandResponse(bot, sender, args, isPrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void helpResponse(final Mobibot bot, final String sender, final String args, final boolean isPrivate) {
|
||||
bot.send(sender, "To convert from one currency to another:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD + " [100 USD to EUR]"));
|
||||
|
||||
if (args.endsWith(CURRENCY_CMD)) {
|
||||
bot.send(sender, "For a listing of currency rates:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD) + ' ' + CURRENCY_RATES_KEYWORD);
|
||||
bot.send(sender, "For a listing of supported currencies:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified currencies.
|
||||
*/
|
||||
|
@ -215,4 +208,20 @@ public final class CurrencyConverter extends ThreadedModule {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void helpResponse(final Mobibot bot, final String sender, final String args, final boolean isPrivate) {
|
||||
bot.send(sender, "To convert from one currency to another:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD + " [100 USD to EUR]"));
|
||||
|
||||
if (args.endsWith(CURRENCY_CMD)) {
|
||||
bot.send(sender, "For a listing of currency rates:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD) + ' ' + CURRENCY_RATES_KEYWORD);
|
||||
bot.send(sender, "For a listing of supported currencies:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + CURRENCY_CMD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,8 +81,9 @@ public final class GoogleSearch extends ThreadedModule {
|
|||
*
|
||||
* @param query The search query.
|
||||
* @param apiKey The Google API key.
|
||||
* The Google CSE key.
|
||||
* @param cseKey The Google search results.
|
||||
* @param cseKey The Google CSE key.
|
||||
* @return The {@link Message} array containing the search results.
|
||||
* @throws ModuleException If an error occurs while searching.
|
||||
*/
|
||||
@SuppressFBWarnings(value = {"URLCONNECTION_SSRF_FD", "REC_CATCH_EXCEPTION"})
|
||||
static ArrayList<Message> searchGoogle(final String query, final String apiKey, final String cseKey)
|
||||
|
|
|
@ -68,7 +68,8 @@ public final class Joke extends ThreadedModule {
|
|||
/**
|
||||
* Retrieves a random joke.
|
||||
*
|
||||
* @return The new joke.
|
||||
* @return The {@link Message} containing the new joke.
|
||||
* @throws ModuleException If an error occurs while retrieving a new joke.
|
||||
*/
|
||||
static Message randomJoke() throws ModuleException {
|
||||
try {
|
||||
|
@ -103,15 +104,6 @@ public final class Joke extends ThreadedModule {
|
|||
new Thread(() -> run(bot, sender, args)).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void helpResponse(final Mobibot bot, final String sender, final String args, final boolean isPrivate) {
|
||||
bot.send(sender, "To retrieve a random joke:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + JOKE_CMD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random joke from <a href="http://www.icndb.com/">The Internet Chuck Norris Database</a>.
|
||||
*/
|
||||
|
@ -123,4 +115,13 @@ public final class Joke extends ThreadedModule {
|
|||
bot.send(sender, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void helpResponse(final Mobibot bot, final String sender, final String args, final boolean isPrivate) {
|
||||
bot.send(sender, "To retrieve a random joke:");
|
||||
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + JOKE_CMD));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,9 @@ public class Ping extends AbstractModule {
|
|||
*/
|
||||
private static final String PING_CMD = "ping";
|
||||
|
||||
// The ping responses.
|
||||
/**
|
||||
* The ping responses.
|
||||
*/
|
||||
static final List<String> PINGS =
|
||||
Arrays.asList(
|
||||
"is barely alive.",
|
||||
|
|
|
@ -74,10 +74,10 @@ public final class StockQuote extends ThreadedModule {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a stock quote.
|
||||
* Retrieves a stock quote.
|
||||
*
|
||||
* @param symbol The stock symbol.
|
||||
* @return The stock quote.
|
||||
* @return The {@link Message} array containing the stock quote.
|
||||
* @throws ModuleException If an errors occurs.
|
||||
*/
|
||||
static ArrayList<Message> getQuote(final String symbol, final String apiKey) throws ModuleException {
|
||||
|
|
|
@ -68,7 +68,7 @@ public final class Twitter extends ThreadedModule {
|
|||
}
|
||||
|
||||
/**
|
||||
* Post on Twitter.
|
||||
* Posts on Twitter.
|
||||
*
|
||||
* @param consumerKey The consumer key.
|
||||
* @param consumerSecret The consumer secret.
|
||||
|
@ -77,7 +77,7 @@ public final class Twitter extends ThreadedModule {
|
|||
* @param handle The Twitter handle (dm) or nickname.
|
||||
* @param message The message to post.
|
||||
* @param isDm The direct message flag.
|
||||
* @return The {@link Message} to send back.
|
||||
* @return The confirmation {@link Message}.
|
||||
* @throws ModuleException If an error occurs while posting.
|
||||
*/
|
||||
static Message twitterPost(final String consumerKey,
|
||||
|
@ -125,7 +125,7 @@ public final class Twitter extends ThreadedModule {
|
|||
}
|
||||
|
||||
/**
|
||||
* Post on Twitter.
|
||||
* Posts on Twitter.
|
||||
*
|
||||
* @param handle The Twitter handle (dm) or nickname.
|
||||
* @param message The message to post.
|
||||
|
|
|
@ -73,12 +73,6 @@ public class Weather2 extends ThreadedModule {
|
|||
properties.put(OWM_API_KEY_PROP, "");
|
||||
}
|
||||
|
||||
@SuppressWarnings("AvoidEscapedUnicodeCharacters")
|
||||
private static String getTemps(final Double d) {
|
||||
final double c = (d - 32) * 5 / 9;
|
||||
return Math.round(d) + " \u00B0F, " + Math.round(c) + " \u00B0C";
|
||||
}
|
||||
|
||||
private static OWM.Country getCountry(final String countryCode) {
|
||||
for (final OWM.Country c : OWM.Country.values()) {
|
||||
if (c.name().equalsIgnoreCase(countryCode)) {
|
||||
|
@ -89,6 +83,25 @@ public class Weather2 extends ThreadedModule {
|
|||
return OWM.Country.UNITED_STATES;
|
||||
}
|
||||
|
||||
@SuppressWarnings("AvoidEscapedUnicodeCharacters")
|
||||
private static String getTemps(final Double d) {
|
||||
final double c = (d - 32) * 5 / 9;
|
||||
return Math.round(d) + " \u00B0F, " + Math.round(c) + " \u00B0C";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the weather data.
|
||||
*
|
||||
* <ul>
|
||||
* <li>98204</li>
|
||||
* <li>London, UK</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param query The query.
|
||||
* @param apiKey The API key.
|
||||
* @return The {@link Message} array containing the weather data.
|
||||
* @throws ModuleException If an error occurs while retrieving the weather data.
|
||||
*/
|
||||
static ArrayList<Message> getWeather(final String query, final String apiKey) throws ModuleException {
|
||||
if (!Utils.isValidString(apiKey)) {
|
||||
throw new ModuleException(Utils.capitalize(WEATHER_CMD) + " is disabled. The API key is missing.");
|
||||
|
|
|
@ -164,6 +164,17 @@ public final class WorldTime extends AbstractModule {
|
|||
return String.format("%c%03d", '@', beats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world time.
|
||||
*
|
||||
* <ul>
|
||||
* <li>PST</li>
|
||||
* <li>BEATS</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param query The query.
|
||||
* @return The {@link Message} containing the world time.
|
||||
*/
|
||||
static Message worldTime(final String query) {
|
||||
final String tz = (COUNTRIES_MAP.get((query.substring(query.indexOf(' ') + 1).trim().toUpperCase())));
|
||||
final String response;
|
||||
|
|
|
@ -57,6 +57,7 @@ public class ErrorMessage extends Message {
|
|||
* @param message The message.
|
||||
* @param color The message color.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public ErrorMessage(final String message, final String color) {
|
||||
this.setMessage(message);
|
||||
this.setError(true);
|
||||
|
|
|
@ -39,6 +39,7 @@ package net.thauvin.erik.mobibot.msg;
|
|||
* @created 2019-04-09
|
||||
* @since 1.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class PrivateMessage extends Message {
|
||||
public PrivateMessage(final String message) {
|
||||
this.setMessage(message);
|
||||
|
|
|
@ -44,6 +44,7 @@ public class PublicMessage extends Message {
|
|||
this.setMessage(message);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public PublicMessage(final String message, final String color) {
|
||||
this.setMessage(message);
|
||||
this.setColor(color);
|
||||
|
|
|
@ -47,42 +47,30 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
* @since 1.0
|
||||
*/
|
||||
public class Tell {
|
||||
/**
|
||||
* The all keyword.
|
||||
*/
|
||||
public static final String TELL_ALL_KEYWORD = "all";
|
||||
|
||||
/**
|
||||
* The tell command.
|
||||
*/
|
||||
public static final String TELL_CMD = "tell";
|
||||
|
||||
/**
|
||||
* The delete command.
|
||||
*/
|
||||
public static final String TELL_DEL_KEYWORD = "del";
|
||||
|
||||
// The default maximum number of days to keep messages.
|
||||
private static final int DEFAULT_TELL_MAX_DAYS = 7;
|
||||
|
||||
// The default message max queue size.
|
||||
private static final int DEFAULT_TELL_MAX_SIZE = 50;
|
||||
|
||||
// The serialized object file extension.
|
||||
private static final String SER_EXT = ".ser";
|
||||
// The all keyword.
|
||||
private static final String TELL_ALL_KEYWORD = "all";
|
||||
//T he delete command.
|
||||
private static final String TELL_DEL_KEYWORD = "del";
|
||||
|
||||
// The bot instance.
|
||||
private final Mobibot bot;
|
||||
|
||||
// The maximum number of days to keep messages.
|
||||
private final int maxDays;
|
||||
|
||||
// The message maximum queue size.
|
||||
private final int maxSize;
|
||||
|
||||
// The messages queue.
|
||||
private final List<TellMessage> messages = new CopyOnWriteArrayList<>();
|
||||
|
||||
// The serialized object file.
|
||||
private final String serializedObject;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public class TellMessage implements Serializable {
|
|||
* @param recipient The recipient's nick.
|
||||
* @param message The message.
|
||||
*/
|
||||
public TellMessage(final String sender, final String recipient, final String message) {
|
||||
TellMessage(final String sender, final String recipient, final String message) {
|
||||
this.sender = sender;
|
||||
this.recipient = recipient;
|
||||
this.message = message;
|
||||
|
@ -94,7 +94,7 @@ public class TellMessage implements Serializable {
|
|||
*
|
||||
* @return <code>true</code> if the message is queued.
|
||||
*/
|
||||
public LocalDateTime getQueued() {
|
||||
LocalDateTime getQueued() {
|
||||
return queued;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ public class TellMessage implements Serializable {
|
|||
*
|
||||
* @return The recipient of the message.
|
||||
*/
|
||||
public String getRecipient() {
|
||||
String getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class TellMessage implements Serializable {
|
|||
* @param nick The nickname to match with.
|
||||
* @return <code>true</code> if the nickname matches.
|
||||
*/
|
||||
public boolean isMatch(final String nick) {
|
||||
boolean isMatch(final String nick) {
|
||||
return (sender.equalsIgnoreCase(nick) || recipient.equalsIgnoreCase(nick));
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ public class TellMessage implements Serializable {
|
|||
* @param id The ID to match with.
|
||||
* @return <code>true</code> if the id matches.
|
||||
*/
|
||||
public boolean isMatchId(final String id) {
|
||||
boolean isMatchId(final String id) {
|
||||
return this.id.equals(id);
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ public class TellMessage implements Serializable {
|
|||
*
|
||||
* @return <code>true</code> if the sender has been notified.
|
||||
*/
|
||||
public boolean isNotified() {
|
||||
boolean isNotified() {
|
||||
return isNotified;
|
||||
}
|
||||
|
||||
|
@ -166,14 +166,14 @@ public class TellMessage implements Serializable {
|
|||
/**
|
||||
* Sets the notified flag.
|
||||
*/
|
||||
public void setIsNotified() {
|
||||
void setIsNotified() {
|
||||
isNotified = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the received flag.
|
||||
*/
|
||||
public void setIsReceived() {
|
||||
void setIsReceived() {
|
||||
received = LocalDateTime.now(Clock.systemUTC());
|
||||
isReceived = true;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ final class TellMessagesMgr {
|
|||
* @param tellMaxDays The maximum number of days to keep messages for.
|
||||
* @return <code>True</code> if the queue was cleaned.
|
||||
*/
|
||||
public static boolean clean(final List<TellMessage> tellMessages, final int tellMaxDays) {
|
||||
static boolean clean(final List<TellMessage> tellMessages, final int tellMaxDays) {
|
||||
final LocalDateTime today = LocalDateTime.now(Clock.systemUTC());
|
||||
boolean cleaned = false;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Generated by the Semver Plugin for Gradle
|
||||
#Fri Apr 19 20:42:41 PDT 2019
|
||||
version.buildmeta=303
|
||||
#Fri Apr 19 23:35:53 PDT 2019
|
||||
version.buildmeta=306
|
||||
version.major=0
|
||||
version.minor=7
|
||||
version.patch=3
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue