import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import java.util.function.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.awt.geom.*; import javax.imageio.*; import java.math.*; import net.dv8tion.jda.api.events.Event; import net.dv8tion.jda.api.events.user.update.*; import net.dv8tion.jda.api.managers.AudioManager; import net.dv8tion.jda.api.audio.*; import net.dv8tion.jda.api.events.guild.voice.*; import com.sedmelluq.discord.lavaplayer.player.*; import com.sedmelluq.discord.lavaplayer.player.event.*; import com.sedmelluq.discord.lavaplayer.track.*; import com.sedmelluq.discord.lavaplayer.track.playback.*; import com.sedmelluq.discord.lavaplayer.source.*; import com.sedmelluq.discord.lavaplayer.tools.*; import x30_pkg.x30_util; import static x30_pkg.x30_util.VF1; import static x30_pkg.x30_util.l; import static x30_pkg.x30_util.indexOf; import static x30_pkg.x30_util.getOpt; import static x30_pkg.x30_util.setOpt; import static x30_pkg.x30_util.callOpt; import static x30_pkg.x30_util.newWeakHashMap; import static x30_pkg.x30_util.newDangerousWeakHashMap; import static x30_pkg.x30_util.get; import static x30_pkg.x30_util.get_raw; import static x30_pkg.x30_util.assertTrue; import static x30_pkg.x30_util.isHeadless; import static x30_pkg.x30_util.isAndroid; import static x30_pkg.x30_util.isTrue; import x30_pkg.x30_util.DynamicObject; import loadableUtils.utils; import static loadableUtils.utils._threadInfo; import static loadableUtils.utils._threadInheritInfo; import static loadableUtils.utils.dm_currentModule; import static loadableUtils.utils.dm_current_mandatory; import static loadableUtils.utils.match; import static loadableUtils.utils.fieldType; import static loadableUtils.utils.vm_generalIdentityHashSet; import static loadableUtils.utils.vm_generalHashMap; import static loadableUtils.utils.vm_generalWeakSubMap; import static loadableUtils.utils.bindToComponent; import static loadableUtils.utils.struct; import static loadableUtils.utils.structure; import static loadableUtils.utils.loadPage; import static loadableUtils.utils.loadPageSilently; import static loadableUtils.utils.loadSnippet; import static loadableUtils.utils.componentPopupMenu; import static loadableUtils.utils.componentPopupMenu_initForComponent; import static loadableUtils.utils.dm_current_generic; import static loadableUtils.utils.dm_current_mandatory_generic; import static loadableUtils.utils.DynamicObject_loading; import static loadableUtils.utils.rethrow; import loadableUtils.utils.F0; import loadableUtils.utils.F1; import loadableUtils.utils.IF0; import loadableUtils.utils.IF1; import loadableUtils.utils.IVF1; import loadableUtils.utils.IVF2; import loadableUtils.utils.Matches; import loadableUtils.utils.BetterLabel; import loadableUtils.utils.SingleComponentPanel; import loadableUtils.utils.Q; import loadableUtils.utils.structure_Data; import loadableUtils.utils.structure_ClassInfo; import loadableUtils.utils.RGBImage; import loadableUtils.utils.MultiSet; import loadableUtils.utils.Concept; import loadableUtils.utils.Concepts; import loadableUtils.utils.RC; import loadableUtils.utils.IterableIterator; import loadableUtils.utils.PersistableThrowable; import loadableUtils.utils.DynModule; import loadableUtils.utils.DynPrintLog; import loadableUtils.utils.Rect; import loadableUtils.utils.Pt; import java.text.SimpleDateFormat; import java.text.NumberFormat; import java.nio.charset.Charset; import java.text.*; import java.util.TimeZone; import net.dv8tion.jda.api.events.guild.member.*; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.requests.restaction.MessageAction; import net.dv8tion.jda.api.requests.RestAction; import java.util.function.Consumer; import javax.swing.undo.UndoManager; import java.awt.datatransfer.StringSelection; import java.awt.geom.*; import javax.imageio.metadata.*; import javax.imageio.stream.*; import net.dv8tion.jda.api.*; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.hooks.*; import net.dv8tion.jda.api.events.message.*; import net.dv8tion.jda.api.events.message.react.*; import static net.dv8tion.jda.api.requests.GatewayIntent.*; import javax.swing.border.*; class main { abstract static public class DynTalkBot2 extends DynServerAwareDiscordBot { static public boolean _switchableField_myName = true; public String myName = "Anonymous bot"; transient public boolean useAGIBlueForDropPunctuation = true; transient public boolean preprocessAtSelfToMyName = true; transient public boolean dropPunctuation = true; transient public boolean ngbCommands = true; public List authorizedUsers = ll(547706854680297473L); static public class ISaid implements IFieldsToList { public long channelID; public long date; public String text; public ISaid() { } public ISaid(long channelID, long date, String text) { this.text = text; this.date = date; this.channelID = channelID; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + channelID + ", " + date + ", " + text + ")"; } public boolean equals(Object o) { if (!(o instanceof ISaid)) return false; ISaid __10 = (ISaid) o; return channelID == __10.channelID && date == __10.date && eq(text, __10.text); } public int hashCode() { int h = 69986258; h = boostHashCombine(h, _hashCode(channelID)); h = boostHashCombine(h, _hashCode(date)); h = boostHashCombine(h, _hashCode(text)); return h; } public Object[] _fieldsToList() { return new Object[] { channelID, date, text }; } } public void init() { super.init(); onPostedInChannel.add((channel, msg) -> { if (channel instanceof GuildChannel) { Guild guild = ((GuildChannel) channel).getGuild(); if (guild == null) return; ByServer bs = getByServer(guild); long channelID = ((GuildChannel) channel).getIdLong(); mapPut(bs.lastSaidInChannel, channelID, nu(ISaid.class, "channelID", channelID, "text", msg)); change(); } }); dm_vmBus_onMessage_q("discordGuildJoin", new VF1() { public void get(Map map) { try { { if (!(map.get("module") == module())) return; } print("Got join"); getByServer(getLong("guildID", map), true).onUserJoin(getLong("userID", map), map); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret unless map.get('module) == module();\r\n print(\"Got join\");\r\n get..."; } }); onDiscordEvent(e -> { if (e instanceof UserUpdateOnlineStatusEvent) getByServer(((UserUpdateOnlineStatusEvent) e).getGuild()).onOnlineStatusChange((UserUpdateOnlineStatusEvent) e); }); } public class ByServer extends DynServerAwareDiscordBot.ByServer { transient public Lock lock; public List guildAuthorizedUsers = synchroList(); public Map lastSaidInChannel = synchroMap(); public long preferredChannelInGuild; public DynTalkBot2 m2() { return DynTalkBot2.this; } public void onUserJoin(long userID, Object... __) { } public void onOnlineStatusChange(UserUpdateOnlineStatusEvent e) { } public String myName() { return myName; } @Override public String answer(String input, Map map) { if (preferredChannelInGuild == 0) { long channelID = longPar("channelID", map); if (channelID != 0) { preferredChannelInGuild = channelID; change(); } } String answer = processLine(input, map); { String __3 = super.answer(input, map); if (!empty(__3)) return __3; } return answer; } public String dropMyPrefixOpt(String s) { return or(dropMyPrefixOrNull(s), s); } public String dropMyPrefixOrNull(String s) { String sOld = s; s = dropPrefixICTrim_orNull(myPrefix(), s); if (s == null) print("no got prefix: " + quote(myPrefix()) + " / " + quote(sOld)); return s; } public String processLine(String s, Object... __) { s = preprocess(s, __); return processSimplifiedLine(s, __); } public String preprocess(String s, Object... __) { print("Preprocessing: " + quote(s)); if (preprocessAtSelfToMyName && discordBotID != 0) { List l = ll(atSelf(), atExclamSelf()); print("Replacing " + sfu(l)); s = replace_multi(s, l, " " + myName + " "); print("Got " + quote(s)); } if (dropPunctuation) s = dropPunctuation3_withAGIBlue(useAGIBlueForDropPunctuation, s); s = trim(simpleSpaces_noTok(s)); print("simplified >> " + quote(s)); return s; } public String myPrefix() { return preprocessAtSelfToMyName ? (endsWithLetterOrDigit(myName()) ? myName() + " " : myName()) : (dropPunctuation ? replace(atSelf(), "@", "") : atSelf()) + " "; } synchronized public Lock myLock() { if (lock == null) lock = lock(); return lock; } public String processSimplifiedLine(String input, Object... __) { Lock __1 = myLock(); lock(__1); try { Matches m = new Matches(); input = dropMyPrefixOrNull(input); if (input == null) return null; if (ngbCommands) { if (eqicOneOf(input, "support channel", "support server", "support")) return "Get support for me here: " + nextGenBotsDiscordInvite(); if (eqicOneOf(input, "source", "sources", "source code")) return snippetLink(programID()); } if (swic_trim(input, "add master ", m)) { String __4 = checkAuth(__); if (!empty(__4)) return __4; setAdd(authorizedUsers, parseFirstLong(m.rest())); change(); return "Okidoki. Have " + n2(l(authorizedUsers), "master"); } if (eqic(input, "masters")) return linesLL("General: " + renderMasters(), "For this guild: " + renderGuildMasters()); if (eqic(input, "guild masters")) return renderGuildMasters(); if (swic_trim(input, "delete master ", m)) { String __5 = checkAuth(__); if (!empty(__5)) return __5; remove(authorizedUsers, parseFirstLong(m.rest())); change(); return "Okidoki. Have " + n2(l(authorizedUsers), "master"); } if (swic_trim(input, "add guild master ", m)) { String __6 = checkPerGuildAuth(__); if (!empty(__6)) return __6; setAdd(guildAuthorizedUsers, parseFirstLong(m.rest())); change(); return "Okidoki. " + renderGuildMasters(); } if (swic_trim(input, "delete guild master ", m)) { String __7 = checkPerGuildAuth(__); if (!empty(__7)) return __7; remove(guildAuthorizedUsers, parseFirstLong(m.rest())); change(); return "Okidoki. " + renderGuildMasters(); } if (eqic(input, "guild count")) { String __8 = checkAuth(__); if (!empty(__8)) return __8; return renderGuildCount(); } if (eqic(input, "guild names")) { String __9 = checkAuth(__); if (!empty(__9)) return __9; return renderGuildNames(); } return null; } finally { unlock(__1); } } public String renderGuildMasters() { return empty(guildAuthorizedUsers) ? "Only this guild's owner can control me." : "I am controlled by this guild's owner and these people: " + joinWithComma(map(__51 -> discordAtPlusID(__51), guildAuthorizedUsers)); } public String renderGuildCount() { return "Total guilds joined: " + guildCount + ". Live guilds: " + liveGuildCount(); } public String renderGuildNames() { return lines(map(discord.getGuilds(), g -> g.getName())); } public boolean authed(Object... __) { return contains(authorizedUsers, optPar("userID", __)); } public boolean perGuildAuthed(Object... __) { long userID = longPar("userID", __); return contains(guildAuthorizedUsers, userID) || guildID != 0 && userID == getGuild().getOwnerIdLong(); } public Guild getGuild() { return guildID == 0 ? null : discord.getGuildById(guildID); } public String checkAuth(Object... __) { long userID = longPar("userID", __); boolean result = authed(__); print("Auth-checking user ID: " + userID + " => " + result); if (!result) return "You are not authorized"; return null; } public String checkPerGuildAuth(Object... __) { if (authed(__)) return null; long userID = longPar("userID", __); boolean result = perGuildAuthed(__); print("Guild-auth-checking user ID: " + userID + " => " + result); if (!result) return "You are not authorized"; return null; } public String guildStructure() { return structure_nullingInstancesOfClass(_getClass(module()), this); } public String atSelfOrMyName() { return preprocessAtSelfToMyName ? myName() : atSelf(); } public String atSelfOrMyName_space() { return preprocessAtSelfToMyName ? appendSpaceIfEndsWithLetter(myName) : atSelf(); } public String guildMastersHelp() { return "\r\n@me **masters** -- show who controls me\r\n@me **add guild master @user** -- allow @user to control me\r\n@me **delete guild master @user** -- @user can no longer control me\r\n"; } } public String serveGuildBackup(MessageChannel channel, Guild guild, String data) { if (guild == null) return "Do this in a guild"; if (containsDiscordToken(data)) return "DISCORD TOKEN EXPOSED ALARM!! NOTIFY ADMINISTRATOR"; String baseName = urlencode(jda_selfUserName(discord)) + "-" + guild.getIdLong() + "-" + ymd_minus_hms(); String zipName = baseName + ".zip"; File zip = programFile("backups/" + zipName); createZipFileWithSingleTextFile(zip, baseName + ".txt", data); channel.sendMessage("Here's my latest brain contents for this guild.").addFile(zip).queue(); return null; } public String serveGuildBackup(MessageChannel channel, Guild guild, ByServer bs) { return serveGuildBackup(channel, guild, bs.guildStructure()); } public String renderMasters() { return empty(authorizedUsers) ? "I have no masters." : "My masters are: " + joinWithComma(map(__52 -> discordAtPlusID(__52), authorizedUsers)); } } static public class MKLabFM extends DynTalkBot2 { static public boolean _switchableField_radioURL = true; public String radioURL = "http://streamlive2.hearthis.at:8080/26450.ogg"; static public boolean _switchableField_currentSongURL = true; public String currentSongURL = "https://widgets.autopo.st/widgets/public/MKLabFM/nowplaying.php"; static public boolean _switchableField_coverArtURL = true; public String coverArtURL = "http://95.154.196.33:26687/playingart?sid=1&rand="; static public boolean _switchableField_enableShadowStop = true; public boolean enableShadowStop = true; static public boolean _switchableField_putSongInStatus = true; public boolean putSongInStatus = true; transient public double bufferSeconds = 30.0; transient public int grabInterval = 15; transient public double considerDownInterval = 60.0; transient public double autoRestartInterval = 20.0; static public boolean _switchableField_madeBy = true; public String madeBy = trim("\r\nMKLab: \r\nSupport channel: \r\nBot by: \r\nYou like this bot? Donate: \r\n"); static public boolean _switchableField_voteLink = true; public String voteLink = "\n\nPlease help us grow by voting here: "; static public boolean _switchableField_npMsg = true; public String npMsg = "Now playing: - Listen at }{ https://tinyurl.com/mklab-live-fm }{ #edm #music #radio #ibiza #dance #chillout #psy #live #miami #memes #detroit #techno #dj #synthwave #housemusic #deephouse #onair"; static public boolean _switchableField_uploadImagesAsFiles = true; public boolean uploadImagesAsFiles = true; transient public SimpleCircularBuffer buffer; transient public AudioPlayer player; static public boolean _switchableField_restartNow = true; transient public boolean simulateStreamDown, restartNow; transient public long lastFrameReceived, lastActualFrameReceived; transient public long moduleStarted; transient public NotTooOften postRestarting = onlyEveryHour(); transient public String currentSong; transient public AtomicLong framesReceived = new AtomicLong(); transient public AtomicLong canProvideCalls = new AtomicLong(); transient public AtomicLong provideCalls = new AtomicLong(); transient public AtomicLong dataSent = new AtomicLong(); public Object _getReloadData() { return currentSong; } public void _setReloadData(String data) { currentSong = data; } public void init() { super.init(); myName = "!!!"; makeByServer = () -> new ByServer(); dropPunctuation = false; preprocessAtSelfToMyName = true; ngbCommands = false; sendToPostedLinesCRUD = false; initStream(); onDiscordStarted(new Runnable() { public void run() { try { AutoCloseable __27 = enter(); try { print("Bot back up"); for (Map.Entry __22 : _entrySet(cloneMap(dataByServer))) { Long id = __22.getKey(); ByServer bs = __22.getValue(); try { bs.restart(discord.getGuildById(id)); } catch (Throwable __e) { printStackTrace(__e); } } postInChannel(nextGenBotsTestRoomID(), "Rebooted " + computerID() + "/" + dm_moduleID()); } finally { _close(__27); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter();\r\n print(\"Bot back up\");\r\n for (Map.Entry { if (e instanceof GenericGuildVoiceEvent) getByServer(((GenericGuildVoiceEvent) e).getGuild()).handleVoiceUpdateEvent((GenericGuildVoiceEvent) e); }); doEveryAndNow(20.0, new Runnable() { public void run() { try { grabSong(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "grabSong();"; } }); doEvery(60.0, new Runnable() { public void run() { try { updateVoiceChannelCount_allServers(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateVoiceChannelCount_allServers();"; } }); } public void initStream() { buffer = new SimpleCircularBuffer(iround(bufferSeconds * 50)); player = lavaPlayer_createPlayer(); lavaPlayer_printPlayerEvents(player); print("Have player"); doEvery(grabInterval, new Runnable() { public void run() { try { AutoCloseable __28 = enter(); try { if (!simulateStreamDown) { AudioFrame frame = player.provide(); if (frame != null) { buffer.add(frame.getData()); inc(framesReceived); lastFrameReceived = lastActualFrameReceived = sysNow(); } } } finally { _close(__28); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter();\r\n if (!simulateStreamDown) {\r\n AudioFrame frame = p..."; } }); doEvery(1.0, new Runnable() { public void run() { try { AutoCloseable __29 = enter(); try { if (discord == null) return; if (restartNow || elapsedSeconds(lastFrameReceived) >= autoRestartInterval) { if (postRestarting.yo()) postInChannel(nextGenBotsTestRoomID(), "Restarting radio stream"); simulateStreamDown = restartNow = false; lastFrameReceived = sysNow(); loadTrack(); lastFrameReceived = sysNow(); } } finally { _close(__29); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter();\r\n if (discord == null) return;\r\n if (restartNow || el..."; } }); } public class ByServer extends DynTalkBot2.ByServer { public boolean shouldBePlaying = false; public long voiceChannelID, lastVoiceChannelID; public long songChannelID; transient public String voiceChannelName; transient public VoiceChannel vc; transient public MyAudioSendHandler sendHandler; transient public Set usersInVoiceChannel = synchroSet(); synchronized public String processSimplifiedLine(String s, Object... __) { AutoCloseable __30 = enter(); try { try { return processSimplifiedLine2(s, __); } catch (Throwable e) { printStackTrace(e); if (cic(str(e), "InsufficientPermission")) return "There were insufficient permissions to perform this action."; return "Sorry, an error occurred trying to perform this action."; } } finally { _close(__30); } } synchronized public String processSimplifiedLine2(String s, Object... __) { String __24 = super.processSimplifiedLine(s, __); if (!empty(__24)) return __24; Matches m = new Matches(); print("myPrefix", quote(myPrefix())); s = dropMyPrefixOrNull(s); print("dropped", quote(s)); if (s == null) return null; Message msg = (Message) (optPar("msg", __)); Guild guild = msg.getGuild(); Member member = msg == null ? null : msg.getMember(); if (eqic(s, "help")) { MessageChannel channel = (MessageChannel) (optPar("channel", __)); String syntax = trim("\r\n`@me play | start` - start playing\r\n`@me stop | pause` - stop playing\r\n`@me leave` - leave voice channel\r\n`@me help` - show this help\r\n`@me np` - show currently playing song\r\n`@me join` - join any voice channel\r\n`@me set channel` - post now playing track names in current channel\r\n`@me stop posting` - stop posting track names\r\n[MORE]\r\n".replace("\n[MORE]", renderChannelListIfNotOne(guild)).replace("@me ", myPrefix())) + voteLink; EmbedBuilder eb = new EmbedBuilder(); eb.setColor(Color.yellow); eb.setAuthor("MKLab FM Bot", null, null); eb.setTitle("Purpose", null); eb.setDescription("I play MKLab FM, the best Electronic Dance Music Radio, in a voice channel of your choice."); discordEmbed_addField(eb, "Syntax", syntax); if (authed(__)) eb.addField("Admin commands", rtrim("\r\n`@me guild count/guild names` - show stats\r\n`@me reboot` - reboot the whole bot (if music stream is completely broken for some reason)\r\n`@me dm owners: ` - DM all guild owners where radio is playing\r\n`@me stream url http...` - set stream URL. current: $STREAMURL\r\n`@me np url http...` - set current song URL. current: $NPURL\r\n`@me cover url http...` - set cover art URL. current: $COVERURL\r\n`@me cover url -` - disable cover art\r\n`@me np msg Playing ...` - set nowplaying message. current: $NPMSG\r\n`@me listeners` - full list of listeners\r\n").replace("@me ", myPrefix()).replace("$STREAMURL", backtickQuote(radioURL)).replace("$NPURL", backtickQuote(currentSongURL)).replace("$NPMSG", backtickQuote(npMsg)).replace("$COVERURL", backtickQuote(coverArtURL)), false); eb.addField("Made by", madeBy, false); eb.setThumbnail(imageSnippetURL("#1102722")); channel.sendMessage(eb.build()).queue(); return null; } if (guild == null) return null; if (authed(__)) { if (match("reboot", s)) { doAfter(2.0, new Runnable() { public void run() { try { AutoCloseable __35 = enter(); try { dm_reload(); } finally { _close(__35); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); dm_reload();"; } }); return "OK, rebooting bot"; } if (match("simulate stream down", s)) { simulateStreamDown = true; return "OK"; } if (swic_trim(s, "dm owners:", m)) return dmOwners(m.unq(0)); if (swic_trim(s, "stream url ", m) && isWebURL(m.rest())) { if (!MKLabFM.this.setField("radioURL", m.rest())) return "No change"; restartNow = true; return "OK, restarting with radio URL " + radioURL; } if (swic_trim(s, "np url ", m) && isWebURL(m.rest())) { if (!MKLabFM.this.setField("currentSongURL", m.rest())) return "No change"; return "Current song URL changed to " + currentSongURL; } if (swic_trim(s, "cover url ", m)) { if (!MKLabFM.this.setField("coverArtURL", m.rest())) return "No change"; return "Cover art URL changed to " + coverArtURL; } if (swic_trim(s, "np msg ", m)) { if (!MKLabFM.this.setField("npMsg", m.rest())) return "No change"; return "Nowplaying message changed to " + npMsg; } if (match("listeners", s)) return or2(listeningUsers_full(), "No listeners"); } if (matchX2("play ...|start...|radio|radio on", s)) return action_play(guild, member); if (matchX2("stop ...|pause ...|quiet|silence|shut up|... off", s) && !match("stop posting", s)) return action_stop(guild); if (matchX2("leave|leave channel|leave voice channel", s)) return action_leave(guild); if (matchX2("join|join channel|join voice channel", s)) return action_join(guild, member); if (matchX2("... channel *", s, m) && isInteger(m.unq(0))) return action_selectChannel(guild, parseInt(m.unq(0))); if (matchX2("np|n p|... song ...|... playing ...", s)) return "MKLab FM is currently playing: " + (nempty(currentSong) ? backtickQuote(currentSong) : "Hmm. Not sure, I think something went wrong."); if (matchX2("set channel|post here|set np", s)) { long channelID = longPar("channelID", __); if (channelID == 0) return "Please do this in a channel"; if (songChannelID != channelID) { songChannelID = channelID; change(); } doAfter(2.0, new Runnable() { public void run() { try { postSong(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "postSong();"; } }); return "OK, I will post the currently playing tracks in this channel. Type `" + atSelfOrMyName_space() + "stop posting` to stop."; } if (matchX2("stop posting|no channel", s)) { songChannelID = 0; change(); return "OK"; } if (match("users in channel", s)) return "Users in voice channel: " + n2(usersInVoiceChannel); if (match("internal stats", s)) return "Frames received: " + n2(framesReceived.get()) + ", canProvide calls: " + n2(canProvideCalls.get()) + ", provide calls: " + n2(provideCalls.get()) + ", bytes sent: " + n2(dataSent.get()); return null; } public String renderGuildCount() { List guilds = discord.getGuilds(); int shouldPlayCount = 0, shadowCount = 0; for (Guild guild : guilds) { ByServer bs = getByServer(guild.getIdLong(), true); if (bs != null) { if (bs.shouldBePlaying) { ++shouldPlayCount; if (bs.shadowStopped()) ++shadowCount; } } } return super.renderGuildCount() + ". " + nRadios(shouldPlayCount - shadowCount) + " playing to " + n2(listeningUsers(), "listener") + ", " + shadowCount + " playing without listeners"; } public void joinVoiceChannel(Guild guild) { vc = guild.getVoiceChannelById(voiceChannelID); guild.getAudioManager().openAudioConnection(vc); voiceChannelName = vc.getName(); updateVoiceChannelCount(); } public void updateVoiceChannelCount() { if (vc == null) { usersInVoiceChannel.clear(); return; } List members = vc.getMembers(); int n = l(usersInVoiceChannel); replaceCollection(usersInVoiceChannel, mapNonNulls_pcall(members, m -> { User user = m.getUser(); return user.isBot() ? null : user.getIdLong(); })); int n2 = l(usersInVoiceChannel); if (n != n2) print(guildID + " voice channel count corrected: " + n + " -> " + n2); } public boolean shadowStopped() { return enableShadowStop && empty(usersInVoiceChannel); } public class MyAudioSendHandler implements AudioSendHandler { public long counter = -1; public byte[] data; public boolean canProvide() { AutoCloseable __31 = enter(); try { inc(canProvideCalls); if (!shouldBePlaying) return false; if (shadowStopped()) { counter = -1; return false; } synchronized (buffer) { if (!buffer.isFull()) return false; data = buffer.get(counter); if (data == null) { long oldCounter = counter; counter = buffer.getBase() + buffer.size() / 2; if (oldCounter >= 0) printWithTime("RESETTING " + oldCounter + " => " + counter + " (delta=" + (counter - oldCounter) + ")"); data = buffer.get(counter); } ++counter; return true; } } finally { _close(__31); } } public java.nio.ByteBuffer provide20MsAudio() { inc(provideCalls); inc(dataSent, l(data)); java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(data); return buf; } public boolean isOpus() { return true; } } public String startPlaying(Guild guild) { AudioManager am = guild.getAudioManager(); sendHandler = new MyAudioSendHandler(); am.setSendingHandler(sendHandler); return "Playing radio in channel " + quote(voiceChannelName); } public String selectAVoiceChannel(Guild guild, Member member) { print("selectAVoiceChannel member=" + member); if (member != null) { GuildVoiceState vs = member.getVoiceState(); VoiceChannel vc = vs.getChannel(); print("selectAVoiceChannel vc=" + vc); if (vc != null) { voiceChannelID = lastVoiceChannelID = vc.getIdLong(); { change(); return null; } } } if (voiceChannelID != 0) return null; List allChannels = guild.getVoiceChannels(); List channels = filter(allChannels, c -> isJoinableVoiceChannel(guild, c)); if (empty(channels)) if (empty(allChannels)) return "Please create a voice channel."; else return "Sorry, I am not allowed to enter any of your voice channels. Maybe my invite link was wrong?"; if (lastVoiceChannelID != 0 && !hasWhereMethodReturns("getIdLong", channels, lastVoiceChannelID)) { lastVoiceChannelID = 0; change(); } voiceChannelID = lastVoiceChannelID != 0 ? lastVoiceChannelID : first(channels).getIdLong(); change(); return null; } public String action_play(Guild guild, Member member) { if (shouldBePlaying && sendHandler != null) return "I am playing already!"; { String __25 = selectAVoiceChannel(guild, member); if (!empty(__25)) return __25; } joinVoiceChannel(guild); shouldBePlaying = true; change(); return startPlaying(guild); } public String action_stop(Guild guild) { if (shouldBePlaying) { shouldBePlaying = false; change(); return "OK, radio switched off"; } return "I am stopped, I think. No?"; } public String action_leave(Guild guild) { voiceChannelID = 0; change(); this.vc = null; GuildVoiceState state = getSelfMember(guild).getVoiceState(); VoiceChannel vc = state.getChannel(); if (vc == null) return "I don't think I am in any voice channel"; guild.getAudioManager().closeAudioConnection(); return "OK, leaving channel " + quote(vc.getName()); } public String action_join(Guild guild, Member member) { GuildVoiceState state = getSelfMember(guild).getVoiceState(); VoiceChannel vc = state.getChannel(); { String __26 = selectAVoiceChannel(guild, member); if (!empty(__26)) return __26; } joinVoiceChannel(guild); return "OK, joined voice channel " + quote(voiceChannelName); } public String action_selectChannel(Guild guild, int i) { List channels = guild.getVoiceChannels(); channels = filter(channels, c -> isJoinableVoiceChannel(guild, c)); VoiceChannel vc = _get(channels, i - 1); if (vc == null) return "Sorry, I count only " + nChannels(channels); voiceChannelID = lastVoiceChannelID = vc.getIdLong(); change(); joinVoiceChannel(guild); return "OK, joined voice channel " + quote(voiceChannelName); } public String renderChannelListIfNotOne(Guild guild) { if (guild == null) return ""; List channels = guild.getVoiceChannels(); channels = filter(channels, c -> isJoinableVoiceChannel(guild, c)); if (empty(channels)) return "\nNote: You don't have any voice channels."; if (l(channels) == 1) return ""; List out = new ArrayList(); for (int i = 0; i < l(channels); i++) out.add("`@me join channel " + (i + 1) + "` - join channel " + quote(channels.get(i).getName())); return "\n" + lines_rtrim(out); } public boolean isJoinableVoiceChannel(Guild guild, VoiceChannel vc) { if (vc == null || guild == null) return false; try { return guild.getSelfMember().hasPermission(vc, Permission.VOICE_CONNECT); } catch (Throwable e) { printStackTrace(e); return false; } } public void restart(Guild guild) { if (guild == null) return; if (shouldBePlaying) { print("RESTARTING RADIO in " + guild); print(action_play(guild, null)); } else if (voiceChannelID != 0) { print("Rejoining voice channel in " + guild); print(action_join(guild, null)); } } public void postSong() { if (songChannelID == 0) return; postInChannel(songChannelID, npMsg.replace("", backtickQuote(currentSong))); if (isWebURL(coverArtURL)) { String imageURL = appendQueryToURL(coverArtURL, "rand", randomInt()); if (uploadImagesAsFiles) uploadFileInChannel(songChannelID, loadBinaryPage(imageURL), "cover-art.jpg", "", null); else postImage(getChannel(songChannelID), imageURL, ""); } } public void handleUserJoined(long userID, VoiceChannel joined) { if (joined != null && joined.getIdLong() == voiceChannelID) { usersInVoiceChannel.add(userID); print(guildID + " adding user to voice channel: " + userID + " (n=" + l(usersInVoiceChannel)); } } public void handleVoiceUpdateEvent(GenericGuildVoiceEvent e) { User user = ((GenericGuildVoiceEvent) e).getMember().getUser(); if (user.isBot()) return; long userID = user.getIdLong(); if (e instanceof GuildVoiceUpdateEvent) { VoiceChannel left = ((GuildVoiceUpdateEvent) e).getChannelLeft(); if (((GuildVoiceUpdateEvent) e).getChannelLeft().getIdLong() == voiceChannelID) { usersInVoiceChannel.remove(userID); print(guildID + " removed user from voice channel: " + userID + " (n=" + l(usersInVoiceChannel)); } } if (e instanceof GuildVoiceMoveEvent) handleUserJoined(userID, ((GuildVoiceMoveEvent) e).getChannelJoined()); if (e instanceof GuildVoiceJoinEvent) handleUserJoined(userID, ((GuildVoiceJoinEvent) e).getChannelJoined()); } } public String dmOwners(String msg) { List guilds = discord.getGuilds(); int n = 0; for (Guild guild : guilds) { try { ByServer bs = getByServer(guild.getIdLong(), true); if (bs != null && bs.shouldBePlaying) { gazelle_dmGuildOwner(guild, msg); ++n; } } catch (Throwable __e) { printStackTrace(__e); } } return n2(n, "guild owner") + " contacted."; } public void loadTrack() { if (!isURL(radioURL)) return; lavaPlayer_loadItem(module(), lavaPlayer_playerManager(), player, radioURL.replace("", str(randomInt()))); } public String currentSong() { AutoCloseable __32 = tempSetTL(loadPage_sizeLimit, 128 * 1024L); try { if (l(currentSongURL) <= 1) return ""; if (cic(currentSongURL, "autopo.st/")) return trackTitleFromAutoPostWidget(loadPageWithTimeout(currentSongURL, 10.0)); if (cic(currentSongURL, "caster.fm/")) return (String) mapGet(jsonDecodeMap(loadPageWithHeaders(currentSongURL, "X-Requested-With", "XMLHttpRequest")), "playing"); if (endsWith(currentSongURL, "status.xsl")) return trackTitleFromIceCastStatusXSL(loadPageWithTimeout(currentSongURL, 10.0)); return loadPageWithTimeout(currentSongURL, 10.0); } finally { _close(__32); } } public void grabSong() { AutoCloseable __33 = enter(); try { if (discord == null) return; String song = currentSong(); boolean post = nempty(currentSong) && nempty(song) && neq(currentSong, song); currentSong = song; if (post) postSong_allServers(); if (putSongInStatus) { String s = currentSong; if (elapsedSeconds(lastActualFrameReceived) >= considerDownInterval && elapsedSeconds(moduleStarted) >= considerDownInterval) s = "Stream currently down"; if (nempty(s)) gazelle_discord_playingGame(s); } } finally { _close(__33); } } public void postSong_allServers() { List guilds = discord.getGuilds(); for (Guild guild : guilds) { try { ByServer bs = getByServer(guild); if (bs != null) bs.postSong(); } catch (Throwable __e) { printStackTrace(__e); } } } public void updateVoiceChannelCount_allServers() { if (discord == null) return; for (ByServer bs : cloneValues(dataByServer)) bs.updateVoiceChannelCount(); } public int listeningUsers() { int n = 0; for (Guild guild : discord.getGuilds()) { ByServer bs = getByServer(guild.getIdLong(), true); if (bs != null && bs.shouldBePlaying) n += l(bs.usersInVoiceChannel); } return n; } public String listeningUsers_full() { List out = new ArrayList(); for (Guild guild : discord.getGuilds()) { ByServer bs = getByServer(guild.getIdLong(), true); if (bs != null && bs.shouldBePlaying) { List users = cloneList(bs.usersInVoiceChannel); if (empty(users)) continue; out.add(guild.getName() + ": playing to " + joinWithComma(map(users, id -> or2(discord_memberIDToEffectiveName(guild, id), str(id))))); } } return lines(out); } } static public boolean _moduleClass_MKLabFM = true; static public String programID; static public void _onLoad_initUtils() { utils.__javax = javax(); } static public void _onLoad_defaultClassFinder() { setDefaultClassFinder(new F1() { public Class get(String name) { Class c = findClass_fullName(name); if (c != null) return c; if (name.startsWith("main$")) return loadableUtils.utils.findClass_fullName("loadableUtils.utils" + name.substring(4)); return null; } }); } static public ThreadLocal dynamicObjectIsLoading_threadLocal() { return DynamicObject_loading; } static volatile public Concepts mainConcepts; static public Concepts db_mainConcepts() { if (mainConcepts == null) mainConcepts = newConceptsWithClassFinder(getDBProgramID()); return mainConcepts; } static public void cleanMeUp_concepts() { if (db_mainConcepts() != null) db_mainConcepts().cleanMeUp(); } static public List ll(A... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (A x : a) l.add(x); return l; } static public String shortClassName_dropNumberPrefix(Object o) { return dropNumberPrefix(shortClassName(o)); } static public boolean eq(Object a, Object b) { return a == b || a != null && b != null && a.equals(b); } static public boolean eq(Symbol a, String b) { return eq(str(a), b); } static public int boostHashCombine(int a, int b) { return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2)); } static public int _hashCode(Object a) { return a == null ? 0 : a.hashCode(); } static public void mapPut(Map map, A key, B value) { if (map != null && key != null && value != null) map.put(key, value); } static public void mapPut(Map map, Pair p) { if (map != null && p != null) map.put(p.a, p.b); } static public A nu(Class c, Object... values) { A a = nuObject(c); setAll(a, values); return a; } static public void change() { callOpt(getOptMC("mainConcepts"), "allChanged"); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final VF1 onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF1() { public void get(final A a) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final IVF1 onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF1() { public void get(final A a) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final IVF2 onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF2() { public void get(A a, B b) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a, b);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a, b);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final IVF3 onMessage) { DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF3() { public void get(A a, B b, C c) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a, b, c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a, b, c);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a, b, c);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final VF2 onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF2() { public void get(final A a, final B b) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a, b);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a, b);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final VF3 onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF3() { public void get(final A a, final B b, final C c) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage, a, b, c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, a, b, c);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage, a, b, c);"; } }); } static public AutoCloseable dm_vmBus_onMessage_q(final String msg, final Runnable onMessage) { final DynModule m = dm_current_mandatory(); return dm_vmBus_onMessage(msg, new VF1() { public void get(final A a) { try { m.q().add(new Runnable() { public void run() { try { callF(onMessage); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(onMessage);"; } }); } static volatile public StringBuffer local_log = new StringBuffer(); static public boolean printAlsoToSystemOut = true; static volatile public Appendable print_log = local_log; static volatile public int print_log_max = 1024 * 1024; static volatile public int local_log_max = 100 * 1024; static public boolean print_silent = false; static public Object print_byThread_lock = new Object(); static volatile public ThreadLocal print_byThread; static volatile public Object print_allThreads; static volatile public Object print_preprocess; static public void print() { print(""); } static public A print(String s, A o) { print(combinePrintParameters(s, o)); return o; } static public A print(A o) { ping_okInCleanUp(); if (print_silent) return o; String s = o + "\n"; print_noNewLine(s); return o; } static public void print_noNewLine(String s) { try { Object f = getThreadLocal(print_byThread_dontCreate()); if (f == null) f = print_allThreads; if (f != null) if (isFalse(f instanceof F1 ? ((F1) f).get(s) : callF(f, s))) return; } catch (Throwable e) { System.out.println(getStackTrace(e)); } print_raw(s); } static public void print_raw(String s) { if (print_preprocess != null) s = (String) callF(print_preprocess, s); s = fixNewLines(s); Appendable loc = local_log; Appendable buf = print_log; int loc_max = print_log_max; if (buf != loc && buf != null) { print_append(buf, s, print_log_max); loc_max = local_log_max; } if (loc != null) print_append(loc, s, loc_max); if (printAlsoToSystemOut) System.out.print(s); vmBus_send("printed", mc(), s); } static public void print_autoRotate() { } static public long getLong(Object o, String field) { return toLong(getOpt(o, field)); } static public long getLong(String field, Object o) { return getLong(o, field); } static public List synchroList() { return synchroList(new ArrayList()); } static public List synchroList(List l) { return Collections.synchronizedList(l); } static public Map synchroMap() { return synchroHashMap(); } static public Map synchroMap(Map map) { return Collections.synchronizedMap(map); } static public long longPar(String name, Object... params) { return toLong(optPar(name, params)); } static public boolean empty(Collection c) { return c == null || c.isEmpty(); } static public boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); } static public boolean empty(CharSequence s) { return s == null || s.length() == 0; } static public boolean empty(Map map) { return map == null || map.isEmpty(); } static public boolean empty(Object[] o) { return o == null || o.length == 0; } static public boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); } static public boolean empty(Object o) { if (o instanceof Collection) return empty((Collection) o); if (o instanceof String) return empty((String) o); if (o instanceof Map) return empty((Map) o); if (o instanceof Object[]) return empty((Object[]) o); if (o instanceof byte[]) return empty((byte[]) o); if (o == null) return true; throw fail("unknown type for 'empty': " + getType(o)); } static public boolean empty(Iterator i) { return i == null || !i.hasNext(); } static public boolean empty(double[] a) { return a == null || a.length == 0; } static public boolean empty(float[] a) { return a == null || a.length == 0; } static public boolean empty(int[] a) { return a == null || a.length == 0; } static public boolean empty(long[] a) { return a == null || a.length == 0; } static public boolean empty(byte[] a) { return a == null || a.length == 0; } static public boolean empty(short[] a) { return a == null || a.length == 0; } static public boolean empty(MultiSet ms) { return ms == null || ms.isEmpty(); } static public boolean empty(MultiMap mm) { return mm == null || mm.isEmpty(); } static public boolean empty(File f) { return getFileSize(f) == 0; } static public boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); } static public A or(A a, A b) { return a != null ? a : b; } static public String dropPrefixICTrim_orNull(String prefix, String s) { return swic(s, prefix) ? trim(s.substring(l(prefix))) : null; } static public String quote(Object o) { if (o == null) return "null"; return quote(str(o)); } static public String quote(String s) { if (s == null) return "null"; StringBuilder out = new StringBuilder((int) (l(s) * 1.5 + 2)); quote_impl(s, out); return out.toString(); } static public void quote_impl(String s, StringBuilder out) { out.append('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') out.append('\\').append(c); else if (c == '\r') out.append("\\r"); else if (c == '\n') out.append("\\n"); else if (c == '\t') out.append("\\t"); else if (c == '\0') out.append("\\0"); else out.append(c); } out.append('"'); } static public String sfu(Object o) { return structureForUser(o); } static public String replace_multi(String s, Collection a, String b) { if (s == null || empty(a) || b == null) return s; for (String aa : a) s = s.replace(aa, b); return s; } static public String replace_multi(String s, String... replacements) { if (empty(s) || empty(replacements)) return s; for (int i = 0; i + 1 < l(replacements); i += 2) s = s.replace(replacements[i], replacements[i + 1]); return s; } static public String dropPunctuation3_withAGIBlue(boolean useAGIBlue, String s) { return useAGIBlue ? dropPunctuation3_withAGIBlue(s) : dropPunctuation3(s); } static public String dropPunctuation3_withAGIBlue(String s) { if (!agiBlue_validPageName(s)) return dropPunctuation3(s); String y = dropPunctuation3_cache.get(s); if (y != null) return y; { String __1 = agiBlue_lookupInSlice_pcall("xwxxvxozhdlwsxzj", s, "dropPunctuation"); if (!empty(__1)) return __1; } y = dropPunctuation3(s); agiBlue_postInSlice_pcall("xwxxvxozhdlwsxzj", s, "dropPunctuation", y); return y; } static public String trim(String s) { return s == null ? null : s.trim(); } static public String trim(StringBuilder buf) { return buf.toString().trim(); } static public String trim(StringBuffer buf) { return buf.toString().trim(); } static public String simpleSpaces_noTok(String s) { return s == null ? null : s.replaceAll("\\s+", " "); } static public boolean endsWithLetterOrDigit(String s) { return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length() - 1)); } static public List replace(List l, A a, A b) { for (int i = 0; i < l(l); i++) if (eq(l.get(i), a)) l.set(i, b); return l; } static public List replace(A a, A b, List l) { return replace(l, a, b); } static public String replace(String s, String a, String b) { return s == null ? null : a == null || b == null ? s : s.replace(a, b); } static public String replace(String s, char a, char b) { return s == null ? null : s.replace(a, b); } static public void lock(Lock lock) { try { ping(); if (lock == null) return; try { vmBus_send("locking", lock, "thread", currentThread()); lock.lockInterruptibly(); vmBus_send("locked", lock, "thread", currentThread()); } catch (InterruptedException e) { Object reason = vm_threadInterruptionReasonsMap().get(currentThread()); print("Locking interrupted! Reason: " + strOr(reason, "Unknown")); printStackTrace(e); rethrow(e); } } catch (Exception __e) { throw rethrow(__e); } } static public void lock(Lock lock, String msg) { print("Locking: " + msg); lock(lock); } static public void lock(Lock lock, String msg, long timeout) { print("Locking: " + msg); lockOrFail(lock, timeout); } static public ReentrantLock lock() { return fairLock(); } static public boolean eqicOneOf(String s, String... l) { for (String x : l) if (eqic(s, x)) return true; return false; } static public String nextGenBotsDiscordInvite() { return "https://discord.gg/kcKKZEg"; } static public String snippetLink(String id) { return empty(id) ? id : snippetLink(parseSnippetID(id)); } static public String snippetLink(long id) { return "https://code.botcompany.de/" + id; } static public String programID() { return getProgramID(); } static public String programID(Object o) { return getProgramID(o); } static public boolean swic_trim(String a, String b, Matches m) { if (!swic(a, b)) return false; m.m = new String[] { trim(substring(a, l(b))) }; return true; } static public boolean setAdd(Collection c, A a) { if (c == null || c.contains(a)) return false; c.add(a); return true; } static public long parseFirstLong(String s) { return parseLong(jextract("", s)); } static public String n2(long l) { return formatWithThousands(l); } static public String n2(AtomicLong l) { return n2(l.get()); } static public String n2(Collection l) { return n2(l(l)); } static public String n2(Map map) { return n2(l(map)); } static public String n2(double l, String singular) { return empty(singular) ? str(l) : n2(l, singular, singular + "s"); } static public String n2(double l, String singular, String plural) { if (fraction(l) == 0) return n2((long) l, singular, plural); else return l + " " + plural; } static public String n2(long l, String singular, String plural) { return n_fancy2(l, singular, plural); } static public String n2(long l, String singular) { return empty(singular) ? n2(l) : n_fancy2(l, singular, singular + "s"); } static public String n2(Collection l, String singular) { return n2(l(l), singular); } static public String n2(Collection l, String singular, String plural) { return n_fancy2(l, singular, plural); } static public String n2(Map m, String singular, String plural) { return n_fancy2(m, singular, plural); } static public String n2(Map m, String singular) { return n2(l(m), singular); } static public String n2(long[] a, String singular) { return n2(l(a), singular); } static public String n2(Object[] a, String singular) { return n2(l(a), singular); } static public String n2(Object[] a, String singular, String plural) { return n_fancy2(a, singular, plural); } static public String n2(MultiSet ms, String singular, String plural) { return n_fancy2(ms, singular, plural); } static public boolean eqic(String a, String b) { if ((a == null) != (b == null)) return false; if (a == null) return true; return a.equalsIgnoreCase(b); } static public boolean eqic(Symbol a, Symbol b) { return eq(a, b); } static public boolean eqic(Symbol a, String b) { return eqic(asString(a), b); } static public boolean eqic(char a, char b) { if (a == b) return true; char u1 = Character.toUpperCase(a); char u2 = Character.toUpperCase(b); if (u1 == u2) return true; return Character.toLowerCase(u1) == Character.toLowerCase(u2); } static public String linesLL(Object... x) { return lines(ll(x)); } static public void remove(List l, int i) { if (l != null && i >= 0 && i < l(l)) l.remove(i); } static public void remove(Collection l, A a) { if (l != null) l.remove(a); } static public B remove(Map map, Object a) { return map == null ? null : map.remove(a); } static public void remove(BitSet bs, int i) { bs.clear(i); } static public void unlock(Lock lock, String msg) { if (lock == null) return; lock.unlock(); vmBus_send("unlocked", lock, "thread", currentThread()); print("Unlocked: " + msg); } static public void unlock(Lock lock) { if (lock == null) return; lock.unlock(); vmBus_send("unlocked", lock, "thread", currentThread()); } static public String joinWithComma(Collection c) { return join(", ", c); } static public String joinWithComma(Object... c) { return join(", ", c); } static public String joinWithComma(String... c) { return join(", ", c); } static public String joinWithComma(Pair p) { return p == null ? "" : joinWithComma(str(p.a), str(p.b)); } static public List map(Iterable l, Object f) { return map(f, l); } static public List map(Object f, Iterable l) { List x = emptyList(l); if (l != null) for (Object o : l) { ping(); x.add(callF(f, o)); } return x; } static public List map(Iterable l, F1 f) { return map(f, l); } static public List map(F1 f, Iterable l) { List x = emptyList(l); if (l != null) for (A o : l) { ping(); x.add(callF(f, o)); } return x; } static public List map(IF1 f, Iterable l) { return map(l, f); } static public List map(Iterable l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) { ping(); x.add(f.get(o)); } return x; } static public List map(IF1 f, A[] l) { return map(l, f); } static public List map(A[] l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) { ping(); x.add(f.get(o)); } return x; } static public List map(Object f, Object[] l) { return map(f, asList(l)); } static public List map(Object[] l, Object f) { return map(f, l); } static public List map(Object f, Map map) { return map(map, f); } static public List map(Map map, Object f) { List x = new ArrayList(); if (map != null) for (Object _e : map.entrySet()) { ping(); Map.Entry e = (Map.Entry) _e; x.add(callF(f, e.getKey(), e.getValue())); } return x; } static public List map(Map map, IF2 f) { return map(map, (Object) f); } static public List map(IF1 f, A data1, A... moreData) { List x = emptyList(l(moreData) + 1); x.add(f.get(data1)); if (moreData != null) for (A o : moreData) { ping(); x.add(f.get(o)); } return x; } static public String discordAtPlusID(long userID) { return userID == 0 ? "unknown person" : "<@" + userID + "> (" + userID + ")"; } static public String lines(Iterable lines) { return fromLines(lines); } static public String lines(Object[] lines) { return fromLines(asList(lines)); } static public List lines(String s) { return toLines(s); } static public String lines(Iterable l, IF1 f) { return mapToLines(l, f); } static public boolean contains(Collection c, Object o) { return c != null && c.contains(o); } static public boolean contains(Iterable it, Object a) { if (it != null) for (Object o : it) if (eq(a, o)) return true; return false; } static public boolean contains(Object[] x, Object o) { if (x != null) for (Object a : x) if (eq(a, o)) return true; return false; } static public boolean contains(String s, char c) { return s != null && s.indexOf(c) >= 0; } static public boolean contains(String s, String b) { return s != null && s.indexOf(b) >= 0; } static public boolean contains(BitSet bs, int i) { return bs != null && bs.get(i); } static public A optPar(ThreadLocal tl, A defaultValue) { A a = tl.get(); if (a != null) { tl.set(null); return a; } return defaultValue; } static public A optPar(ThreadLocal tl) { return optPar(tl, null); } static public Object optPar(Object[] params, String name) { return optParam(params, name); } static public Object optPar(String name, Object[] params) { return optParam(params, name); } static public Object optPar(String name, Map params) { return optParam(name, params); } static public A optPar(Object[] params, String name, A defaultValue) { return optParam(params, name, defaultValue); } static public A optPar(String name, Object[] params, A defaultValue) { return optParam(params, name, defaultValue); } static public String structure_nullingInstancesOfClass(Class c, Object o) { if (c == null) return structure(o); structure_Data data = new structure_Data(); structure_ClassInfo info = new structure_ClassInfo(); info.special = info.nullInstances = true; data.infoByClass.put(c, info); return structure(o, data); } static public Class _getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; } } static public Class _getClass(Object o) { return o == null ? null : o instanceof Class ? (Class) o : o.getClass(); } static public Class _getClass(Object realm, String name) { try { return classLoaderForObject(realm).loadClass(classNameToVM(name)); } catch (ClassNotFoundException e) { return null; } } static public String appendSpaceIfEndsWithLetter(String s) { return endsWithLetter(s) ? s + " " : s; } static public boolean containsDiscordToken(String s) { return regexpFind(discordTokenRegexp(), s); } static public String urlencode(String x) { try { return URLEncoder.encode(unnull(x), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } static public String jda_selfUserName(JDA jda) { return jda_selfUser(jda).getName(); } static public String ymd_minus_hms() { return ymd() + "-" + hms(); } static public File programFile(String name) { return prepareProgramFile(name); } static public File programFile(String progID, String name) { return prepareProgramFile(progID, name); } static public File createZipFileWithSingleTextFile(File zipFile, String name, String text) { ZipOutputStream outZip = newZipOutputStream(zipFile); try { zip_addTextFile(outZip, name, text); return zipFile; } finally { _close(outZip); } } static public NotTooOften onlyEveryHour() { return new NotTooOften(hoursToMS(1)); } static public Set> _entrySet(Map map) { return map == null ? Collections.EMPTY_SET : map.entrySet(); } static public Map cloneMap(Map map) { if (map == null) return new HashMap(); synchronized (map) { return map instanceof TreeMap ? new TreeMap((TreeMap) map) : map instanceof LinkedHashMap ? new LinkedHashMap(map) : new HashMap(map); } } static public List cloneMap(Iterable l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : cloneList(l)) x.add(f.get(o)); return x; } static public A printStackTrace(A e) { if (e != null) print(getStackTrace(e)); return e; } static public void printStackTrace() { printStackTrace(new Throwable()); } static public void printStackTrace(String msg) { printStackTrace(new Throwable(msg)); } static public void printStackTrace(String msg, Throwable e) { printStackTrace(new Throwable(msg, e)); } static public long nextGenBotsTestRoomID() { return 635940070305824794L; } static public String _computerID; static public Lock computerID_lock = lock(); public static String computerID() { if (_computerID == null) { Lock __0 = computerID_lock; lock(__0); try { if (_computerID != null) return _computerID; File file = computerIDFile(); _computerID = loadTextFile(file.getPath()); if (_computerID == null) { _computerID = loadTextFile(userDir(".tinybrain/computer-id")); if (_computerID == null) _computerID = makeRandomID(12, new SecureRandom()); saveTextFile(file, _computerID); } } finally { unlock(__0); } } return _computerID; } static public String dm_moduleID(Object module) { return strOrNull(getOpt(dm_getStem(module), "id")); } static public String dm_moduleID() { return dm_moduleID(dm_current_mandatory_generic()); } static public void _close(AutoCloseable c) { if (c != null) try { c.close(); } catch (Throwable e) { if (c instanceof javax.imageio.stream.ImageOutputStream) return; else throw rethrow(e); } } static public FixedRateTimer doEveryAndNow(int delay, Object r) { return doEveryStartingNow(delay, r); } static public FixedRateTimer doEveryAndNow(double delay, Object r) { return doEveryStartingNow(toInt(toMS(delay)), r); } static public FixedRateTimer doEvery(long delay, final Object r) { return doEvery(delay, delay, r); } static public FixedRateTimer doEvery(long delay, long firstDelay, final Object r) { FixedRateTimer timer = new FixedRateTimer(shorten(programID() + ": " + r, 80)); timer.scheduleAtFixedRate(smartTimerTask(r, timer, toInt(delay)), toInt(firstDelay), toInt(delay)); return vmBus_timerStarted(timer); } static public FixedRateTimer doEvery(double initialSeconds, double delaySeconds, final Object r) { return doEvery(toMS(delaySeconds), toMS(initialSeconds), r); } static public FixedRateTimer doEvery(double delaySeconds, final Object r) { return doEvery(toMS(delaySeconds), r); } static public int iround(double d) { return (int) Math.round(d); } static public int iround(Number n) { return iround(toDouble(n)); } static public AudioPlayer lavaPlayer_createPlayer() { return vm_registerClassInstance(AudioPlayer.class, lavaPlayer_playerManager().createPlayer()); } static public void lavaPlayer_printPlayerEvents(AudioPlayer player) { DynModule mod = dm_current_mandatory(); player.addListener(e -> { AutoCloseable __1 = dm_enter(mod); try { print("Audio event: " + e); if (e instanceof TrackExceptionEvent) printStackTrace(((TrackExceptionEvent) e).exception); } finally { _close(__1); } }); } static public int inc(AtomicInteger i) { return incAtomicInt(i); } static public int inc(AtomicInteger i, int delta) { return incAtomicInt(i, delta); } static public long inc(AtomicLong l) { return incAtomicLong(l); } static public long inc(AtomicLong l, long b) { return l.addAndGet(b); } static public int inc(IntVar v) { synchronized (v) { int val = v.get() + 1; v.set(val); return val; } } static public long sysNow() { ping(); return System.nanoTime() / 1000000; } static public double elapsedSeconds(long time) { return toSeconds(sysNow() - time); } static public double elapsedSeconds(Timestamp ts) { return ts == null ? Double.NaN : toSeconds(now() - ts.date); } static public Set synchroSet() { return synchroHashSet(); } static public Set synchroSet(Set set) { return Collections.synchronizedSet(set); } static public boolean cic(Collection l, String s) { return containsIgnoreCase(l, s); } static public boolean cic(Collection l, Symbol s) { return contains(l, s); } static public boolean cic(String[] l, String s) { return containsIgnoreCase(l, s); } static public boolean cic(String s, char c) { return containsIgnoreCase(s, c); } static public boolean cic(String a, String b) { return containsIgnoreCase(a, b); } static public String str(Object o) { return o == null ? "null" : o.toString(); } static public String str(char[] c) { return new String(c); } static public int discordEmbed_addField_maxLength = 800; static public void discordEmbed_addField(EmbedBuilder eb, String field, String text) { int n = 1; while (l(text) > discordEmbed_addField_maxLength) { ping(); List lines = lines(text); StringBuilder buf = new StringBuilder(); int i = 0; while (i < l(lines) && l(buf) + l(lines.get(i)) + 1 <= discordEmbed_addField_maxLength) buf.append(lines.get(i++)).append("\n"); String part = str(buf); if (i == 0) { part = takeFirst(text, discordEmbed_addField_maxLength); text = substring(text, discordEmbed_addField_maxLength); } else text = lines(subList(lines, i)); eb.addField(appendNumberUnless1(field, n++), part, false); } if (!emptyAfterTrim(text)) eb.addField(appendNumberUnless1(field, n), text, false); } public static String rtrim(String s) { if (s == null) return null; int i = s.length(); while (i > 0 && " \t\r\n".indexOf(s.charAt(i - 1)) >= 0) --i; return i < s.length() ? s.substring(0, i) : s; } static public String backtickQuote(String s) { return encloseInBackticks(s); } static public String imageSnippetURL(long snippetID) { return snippetImageURL(snippetID); } static public String imageSnippetURL(String snippetID) { return snippetImageURL(snippetID); } static public String imageSnippetURL(String snippetID, String contentType) { return snippetImageURL(snippetID, contentType); } static public java.util.Timer doAfter(long delay, Object r) { return doLater(delay, r); } static public java.util.Timer doAfter(double delaySeconds, Object r) { return doLater(delaySeconds, r); } static public void dm_reload() { dm_reloadMe(); } static public boolean isWebURL(String s) { return startsWithOneOf(s, "http://", "https://"); } static public String or2(String a, String b) { return nempty(a) ? a : b; } static public String or2(String a, String b, String c) { return or2(or2(a, b), c); } static public boolean matchX2(String pat, String s) { return matchX_vbar(pat, s); } static public boolean matchX2(String pat, String s, Matches matches) { return matchX_vbar(pat, s, matches); } static public boolean isInteger(String s) { int n = l(s); if (n == 0) return false; int i = 0; if (s.charAt(0) == '-') if (++i >= n) return false; while (i < n) { char c = s.charAt(i); if (c < '0' || c > '9') return false; ++i; } return true; } static public int parseInt(String s) { return emptyString(s) ? 0 : Integer.parseInt(s); } static public int parseInt(char c) { return Integer.parseInt(str(c)); } static public boolean nempty(Collection c) { return !empty(c); } static public boolean nempty(CharSequence s) { return !empty(s); } static public boolean nempty(Object[] o) { return !empty(o); } static public boolean nempty(byte[] o) { return !empty(o); } static public boolean nempty(int[] o) { return !empty(o); } static public boolean nempty(BitSet bs) { return !empty(bs); } static public boolean nempty(Map m) { return !empty(m); } static public boolean nempty(Iterator i) { return i != null && i.hasNext(); } static public boolean nempty(MultiMap mm) { return mm != null && !mm.isEmpty(); } static public boolean nempty(Object o) { return !empty(o); } static public boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; } static public boolean nempty(MultiSet ms) { return ms != null && !ms.isEmpty(); } static public String nRadios(long n) { return n2(n, "radio"); } static public String nRadios(Collection l) { return nRadios(l(l)); } static public void replaceCollection(Collection dest, Collection src) { if (dest == src) return; dest.clear(); if (src != null) dest.addAll(src); } static public List mapNonNulls_pcall(Iterable l, Object f) { return map_pcall_notNull(l, f); } static public List mapNonNulls_pcall(Object f, Iterable l) { return map_pcall_notNull(f, l); } static public List mapNonNulls_pcall(IF1 f, Iterable l) { return map_pcall_notNull(f, l); } static public List mapNonNulls_pcall(Iterable l, IF1 f) { return map_pcall_notNull(l, f); } static public A printWithTime(A a) { return printWithTime("", a); } static public A printWithTime(String s, A a) { print(hmsWithColons() + ": " + s, a); return a; } static public List filter(Iterable c, Object pred) { if (pred instanceof F1) return filter(c, (F1) pred); List x = new ArrayList(); if (c != null) for (Object o : c) if (isTrue(callF(pred, o))) x.add(o); return x; } static public List filter(Object pred, Iterable c) { return filter(c, pred); } static public List filter(Iterable c, F1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (pred.get(o)) x.add(o); return x; } static public List filter(F1 pred, Iterable c) { return filter(c, pred); } static public List filter(Iterable c, IF1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (pred.get(o)) x.add(o); return x; } static public List filter(B[] c, IF1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (pred.get(o)) x.add(o); return x; } static public List filter(IF1 pred, Iterable c) { return filter(c, pred); } static public boolean hasWhereMethodReturns(String methodName, Iterable l, Object result) { return firstWhereMethodReturns(methodName, l, result) != null; } static public Object first(Object list) { return first((Iterable) list); } static public A first(List list) { return empty(list) ? null : list.get(0); } static public A first(A[] bla) { return bla == null || bla.length == 0 ? null : bla[0]; } static public Pair first(Map map) { return mapEntryToPair(first(entrySet(map))); } static public Pair first(MultiMap mm) { if (mm == null) return null; var e = first(mm.data.entrySet()); if (e == null) return null; return pair(e.getKey(), first(e.getValue())); } static public A first(IterableIterator i) { return first((Iterator) i); } static public A first(Iterator i) { return i == null || !i.hasNext() ? null : i.next(); } static public A first(Iterable i) { if (i == null) return null; Iterator it = i.iterator(); return it.hasNext() ? it.next() : null; } static public Character first(String s) { return empty(s) ? null : s.charAt(0); } static public Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); } static public A first(Pair p) { return p == null ? null : p.a; } static public Byte first(byte[] l) { return empty(l) ? null : l[0]; } static public A first(A[] l, IF1 pred) { return firstThat(l, pred); } static public A first(Iterable l, IF1 pred) { return firstThat(l, pred); } static public A first(IF1 pred, Iterable l) { return firstThat(pred, l); } static public A _get(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } static public Object _get(Object o, String field) { return get(o, field); } static public Object _get(String field, Object o) { return get(o, field); } static public A _get(A[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : null; } static public String nChannels(long n) { return n2(n, "channel"); } static public String nChannels(Collection l) { return nChannels(l(l)); } static public String lines_rtrim(Collection lines) { return rtrim_fromLines(lines); } static public String appendQueryToURL(String url, Map params) { if (url == null) return null; String data = makePostData(params); if (empty(data)) return url; int idx = smartIndexOf(url, '#'); String url2 = takeFirst(url, idx); return url2 + (url2.contains("?") ? "&" : "?") + data + substring(url, idx); } static public String appendQueryToURL(String url, Object... data) { return appendQueryToURL(url, paramsToMap(data)); } static public int randomInt() { return randomInt(null); } static public int randomInt(Random random) { return getRandomizer(random).nextInt(); } static public int randomInt(int n) { return randomInt(null, n); } static public int randomInt(Random random, int n) { return random(random, n); } static public ThreadLocal>> loadBinaryPage_responseHeaders = new ThreadLocal(); static public ThreadLocal> loadBinaryPage_extraHeaders = new ThreadLocal(); static public byte[] loadBinaryPage(String url) { try { print("Loading " + url); return loadBinaryPage(loadPage_openConnection(new URL(url))); } catch (Exception __e) { throw rethrow(__e); } } static public byte[] loadBinaryPage(URLConnection con) { try { Map extraHeaders = getAndClearThreadLocal(loadBinaryPage_extraHeaders); setHeaders(con); for (String key : keys(extraHeaders)) con.setRequestProperty(key, extraHeaders.get(key)); return loadBinaryPage_noHeaders(con); } catch (Exception __e) { throw rethrow(__e); } } static public byte[] loadBinaryPage_noHeaders(URLConnection con) { try { ByteArrayOutputStream buf = new ByteArrayOutputStream(); InputStream inputStream = con.getInputStream(); loadBinaryPage_responseHeaders.set(con.getHeaderFields()); long len = 0; try { len = con.getContentLength(); } catch (Throwable e) { printStackTrace(e); } int n = 0; while (true) { int ch = inputStream.read(); if (ch < 0) break; buf.write(ch); if (++n % 100000 == 0) println(" " + n + (len != 0 ? "/" + len : "") + " bytes loaded."); } inputStream.close(); return buf.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } static public String getChannel() { return getChannelName(); } static public void gazelle_dmGuildOwner(Object guild, String msg) { dm_callMe("sendPM", rcall("getIdLong", rcall("getUser", rcall("getOwner", guild))), msg); } static public boolean isURL(String s) { return startsWithOneOf(s, "http://", "https://", "file:"); } static public void lavaPlayer_loadItem(DynModule mod, AudioPlayerManager playerManager, AudioPlayer player, String trackID) { playerManager.loadItem(print("Loading track: ", trackID), new AudioLoadResultHandler() { public void trackLoaded(AudioTrack track) { AutoCloseable __1 = dm_enter(mod); try { player.startTrack(track, false); print("Started track " + track); } finally { _close(__1); } } public void playlistLoaded(AudioPlaylist playlist) { AutoCloseable __2 = dm_enter(mod); try { print("Ignoring play list"); } finally { _close(__2); } } public void noMatches() { AutoCloseable __3 = dm_enter(mod); try { print("Track " + trackID + ": no matches"); } finally { _close(__3); } } public void loadFailed(FriendlyException e) { AutoCloseable __4 = dm_enter(mod); try { print("Track " + trackID + " load failed: " + e); printStackTrace(e); } finally { _close(__4); } } }); } static public AudioPlayerManager lavaPlayer_playerManager; static public void cleanMeUp_lavaPlayer_playerManager() { if (lavaPlayer_playerManager != null) { try { lavaPlayer_playerManager.shutdown(); } catch (Throwable __e) { printStackTrace(__e); } } lavaPlayer_playerManager = null; } static public AudioPlayerManager lavaPlayer_playerManager() { if (lavaPlayer_playerManager == null) { DefaultAudioPlayerManager playerManager = new DefaultAudioPlayerManager(); AudioSourceManagers.registerLocalSource(playerManager); AudioSourceManagers.registerRemoteSources(playerManager); lavaPlayer_playerManager = playerManager; } return lavaPlayer_playerManager; } static public AutoCloseable tempSetTL(ThreadLocal tl, A a) { return tempSetThreadLocal(tl, a); } static public String trackTitleFromAutoPostWidget(String html) { for (String img : findTagsWithParams("img", html)) { String title = tagParam(img, "title"); if (empty(title)) continue; String s = dropPrefixTrimIC_orNull("listen to ", title); if (s == null) continue; int idx = lastIndexOfIC(s, " on "); if (idx < 0) continue; s = trim(takeFirst(s, idx)); return s; } return null; } static public String loadPageWithTimeout(long timeout, String url) { return loadPageWithTimeout(url, timeout); } static public String loadPageWithTimeout(String url, long timeout) { try { ping(); url = loadPage_preprocess(url); print("Loading with timeout: " + hideCredentials(url)); URL _url = new URL(url); return loadPage(setURLConnectionTimeouts(_url.openConnection(), timeout), _url); } catch (Exception __e) { throw rethrow(__e); } } static public String loadPageWithTimeout(String url, double timeoutSeconds) { return loadPageWithTimeout(url, toMS(timeoutSeconds)); } static public String loadPageWithTimeout(double timeoutSeconds, String url) { return loadPageWithTimeout(url, timeoutSeconds); } static public B mapGet(Map map, A a) { return map == null || a == null ? null : map.get(a); } static public B mapGet(A a, Map map) { return map == null || a == null ? null : map.get(a); } static public Map jsonDecodeMap(String s) { Object o = jsonDecode(s); if (o instanceof List && empty((List) o)) return new HashMap(); if (o instanceof Map) return (Map) o; else throw fail("Not a JSON map: " + s); } static public String loadPageWithHeaders(String url, String... headers) { loadPage_extraHeaders.set(litmap(headers)); return loadPage(url); } static public String loadPageWithHeaders(String url, Map headers) { loadPage_extraHeaders.set(headers); return loadPage(url); } static public boolean endsWith(String a, String b) { return a != null && a.endsWith(b); } static public boolean endsWith(String a, char c) { return nempty(a) && lastChar(a) == c; } static public boolean endsWith(String a, String b, Matches m) { if (!endsWith(a, b)) return false; m.m = new String[] { dropLast(l(b), a) }; return true; } static public String trackTitleFromIceCastStatusXSL(String html) { List> tds = findContainerTagWithParams(html, "td"); for (int i = 0; i < l(tds); i++) if (eqic(trim(joinContentsOfContainerTag(tds.get(i))), "current song:")) return trim(joinContentsOfContainerTag(tds.get(i + 1))); return null; } static public boolean neq(Object a, Object b) { return !eq(a, b); } static public void gazelle_discord_playingGame(String gameName) { Object presence = gazelle_discordPresence(); Object game = call(getClass_vmName(gazelle_jda(), "net.dv8tion.jda.core.entities.Game"), "playing", gameName); if (game != null) call(presence, "setGame", game); else { Object activity = call(getClass_vmName(gazelle_jda(), "net.dv8tion.jda.api.entities.Activity"), "playing", gameName); call(presence, "setActivity", activity); } } static public List cloneValues(Map map) { return cloneList(values(map)); } static public ArrayList cloneList(Iterable l) { return l instanceof Collection ? cloneList((Collection) l) : asList(l); } static public ArrayList cloneList(Collection l) { if (l == null) return new ArrayList(); synchronized (collectionMutex(l)) { return new ArrayList(l); } } static public String discord_memberIDToEffectiveName(Guild guild, long userID) { Member member = guild.getMemberById(userID); return member == null ? null : member.getEffectiveName(); } static public Class javax() { return getJavaX(); } static public void setDefaultClassFinder(Object cf) { _defaultClassFinder_value = cf; } static public HashMap findClass_fullName_cache = new HashMap(); static public Class findClass_fullName(String name) { synchronized (findClass_fullName_cache) { if (findClass_fullName_cache.containsKey(name)) return findClass_fullName_cache.get(name); Class c; try { c = Class.forName(name); } catch (ClassNotFoundException e) { c = null; } findClass_fullName_cache.put(name, c); return c; } } static public AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) { return print_byThread().get() == null ? tempInterceptPrint(f) : null; } static public Object _defaultClassFinder_value = defaultDefaultClassFinder(); static public Object _defaultClassFinder() { return _defaultClassFinder_value; } static public Concepts newConceptsWithClassFinder(String progID) { Concepts cc = new Concepts(progID); cc.classFinder = _defaultClassFinder(); return cc; } static public String getDBProgramID_id; static public String getDBProgramID() { return nempty(getDBProgramID_id) ? getDBProgramID_id : programIDWithCase(); } static public String dropNumberPrefix(String s) { return dropFirst(s, indexOfNonDigit(s)); } static public String shortClassName(Object o) { if (o == null) return null; Class c = o instanceof Class ? (Class) o : o.getClass(); String name = c.getName(); return shortenClassName(name); } static public Object nuObject(String className, Object... args) { try { return nuObject(classForName(className), args); } catch (Exception __e) { throw rethrow(__e); } } static public A nuObject(Class c, Object... args) { try { if (args.length == 0) return nuObjectWithoutArguments(c); Constructor m = nuObject_findConstructor(c, args); makeAccessible(m); return (A) m.newInstance(args); } catch (Exception __e) { throw rethrow(__e); } } static public Constructor nuObject_findConstructor(Class c, Object... args) { for (Constructor m : c.getDeclaredConstructors()) { if (!nuObject_checkArgs(m.getParameterTypes(), args, false)) continue; return m; } throw fail("Constructor " + c.getName() + getClasses(args) + " not found" + (args.length == 0 && (c.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 ? " - hint: it's a non-static class!" : "")); } static public boolean nuObject_checkArgs(Class[] types, Object[] args, boolean debug) { if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static public A setAll(A o, Map fields) { if (fields == null) return o; for (String field : keys(fields)) set(o, field, fields.get(field)); return o; } static public A setAll(A o, Object... values) { failIfOddCount(values); for (int i = 0; i + 1 < l(values); i += 2) { String field = (String) values[i]; Object value = values[i + 1]; set(o, field, value); } return o; } static public Object getOptMC(String field) { return getOpt(mc(), field); } static public AutoCloseable dm_vmBus_onMessage(final String msg, final VF1 onMessage) { return dm_ownResource(vmBus_onMessage(msg, onMessage)); } static public AutoCloseable dm_vmBus_onMessage(final String msg, final IVF1 onMessage) { return dm_ownResource(vmBus_onMessage(msg, ivf1ToVF1(onMessage))); } static public AutoCloseable dm_vmBus_onMessage(final String msg, final IVF2 onMessage) { return dm_ownResource(vmBus_onMessage(msg, ivf2ToVF2(onMessage))); } static public AutoCloseable dm_vmBus_onMessage(String msg, final VF2 onMessage) { return dm_ownResource(vmBus_onMessage(msg, onMessage)); } static public AutoCloseable dm_vmBus_onMessage(String msg, final VF3 onMessage) { return dm_ownResource(vmBus_onMessage(msg, onMessage)); } static public AutoCloseable dm_vmBus_onMessage(String msg, Runnable onMessage) { return dm_ownResource(vmBus_onMessage(msg, onMessage)); } static public Object callF(Object f, Object... args) { try { if (f instanceof String) return callMC((String) f, args); return x30_util.callF(f, args); } catch (Exception __e) { throw rethrow(__e); } } static public A callF(F0 f) { return f == null ? null : f.get(); } static public A callF(IF0 f) { return f == null ? null : f.get(); } static public B callF(F1 f, A a) { return f == null ? null : f.get(a); } static public B callF(IF1 f, A a) { return f == null ? null : f.get(a); } static public C callF(F2 f, A a, B b) { return f == null ? null : f.get(a, b); } static public void callF(VF1 f, A a) { if (f != null) f.get(a); } static public Object callMC(String method, Object... args) { return call(mc(), method, args); } static public Object call(Object o) { return callF(o); } static public Object call(Object o, String method, Object... args) { return call_withVarargs(o, method, args); } static public String combinePrintParameters(String s, Object o) { return (endsWithLetterOrDigit(s) ? s + ": " : s) + o; } static public void ping_okInCleanUp() { if (ping_pauseAll || ping_anyActions) ping_impl(true); } static public Object getThreadLocal(Object o, String name) { ThreadLocal t = (ThreadLocal) (getOpt(o, name)); return t != null ? t.get() : null; } static public A getThreadLocal(ThreadLocal tl) { return tl == null ? null : tl.get(); } static public A getThreadLocal(ThreadLocal tl, A defaultValue) { return or(getThreadLocal(tl), defaultValue); } static public ThreadLocal print_byThread_dontCreate() { return print_byThread; } static public boolean isFalse(Object o) { return eq(false, o); } static public String getStackTrace(Throwable throwable) { lastException(throwable); return getStackTrace_noRecord(throwable); } static public String getStackTrace_noRecord(Throwable throwable) { StringWriter writer = new StringWriter(); throwable.printStackTrace(new PrintWriter(writer)); return hideCredentials(writer.toString()); } static public String getStackTrace() { return getStackTrace_noRecord(new Throwable()); } static public String getStackTrace(String msg) { return getStackTrace_noRecord(new Throwable(msg)); } static public String fixNewLines(String s) { int i = indexOf(s, '\r'); if (i < 0) return s; int l = s.length(); StringBuilder out = new StringBuilder(l); out.append(s, 0, i); for (; i < l; i++) { char c = s.charAt(i); if (c != '\r') out.append(c); else { out.append('\n'); if (i + 1 < l && s.charAt(i + 1) == '\n') ++i; } } return out.toString(); } static public void print_append(Appendable buf, String s, int max) { try { synchronized (buf) { buf.append(s); if (buf instanceof StringBuffer) rotateStringBuffer(((StringBuffer) buf), max); else if (buf instanceof StringBuilder) rotateStringBuilder(((StringBuilder) buf), max); } } catch (Exception __e) { throw rethrow(__e); } } static public void vmBus_send(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); pcallFAll_minimalExceptionHandling(vm_busListeners_live(), msg, arg); pcallFAll_minimalExceptionHandling(vm_busListenersByMessage_live().get(msg), msg, arg); } static public void vmBus_send(String msg) { vmBus_send(msg, (Object) null); } static public Class mc() { return main.class; } static public long toLong(Object o) { if (o instanceof Number) return ((Number) o).longValue(); if (o instanceof String) return parseLong((String) o); return 0; } static public Map synchroHashMap() { return synchronizedMap(new HashMap()); } static public RuntimeException fail() { throw new RuntimeException("fail"); } static public RuntimeException fail(Throwable e) { throw asRuntimeException(e); } static public RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } static public RuntimeException fail(Object... objects) { throw new Fail(objects); } static public RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); } static public RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); } static public String getType(Object o) { return getClassName(o); } static public long getFileSize(String path) { return path == null ? 0 : new File(path).length(); } static public long getFileSize(File f) { return f == null ? 0 : f.length(); } static public boolean swic(String a, String b) { return startsWithIgnoreCase(a, b); } static public boolean swic(String a, String b, Matches m) { if (!swic(a, b)) return false; m.m = new String[] { substring(a, l(b)) }; return true; } static public String structureForUser(Object o) { return beautifyStructure(struct_noStringSharing(o)); } static public List dropPunctuation3_keep = ll("*", "<", ">"); static public Map dropPunctuation3_cache = defaultSizeMRUCache(); static public List dropPunctuation3(List tok) { tok = new ArrayList(tok); for (int i = 1; i < tok.size(); i += 2) { String t = tok.get(i); if (t.length() == 1 && !Character.isLetter(t.charAt(0)) && !Character.isDigit(t.charAt(0)) && !dropPunctuation3_keep.contains(t)) { tok.set(i - 1, or2(tok.get(i - 1) + tok.get(i + 1), " ")); tok.remove(i); tok.remove(i); i -= 2; } } return tok; } static public String dropPunctuation3(String s) { return getOrCreate_f0(dropPunctuation3_cache, s, () -> join(dropPunctuation3(javaTokNoQuotes(s)))); } static public boolean agiBlue_validPageName(String s) { s = trim(s); return nempty(s) && !containsNewLine(s); } static public String agiBlue_lookupInSlice_pcall(String sliceID, String q, String... keys) { try { return agiBlue_lookupInSlice(sliceID, q, keys); } catch (Throwable __e) { return null; } } static public String agiBlue_postInSlice_pcall(String slice, String a, String b, String c) { try { return agiBlue_postInSlice(slice, a, b, c); } catch (Throwable __e) { return null; } } static volatile public boolean ping_pauseAll = false; static public int ping_sleep = 100; static volatile public boolean ping_anyActions = false; static public Map ping_actions = newWeakHashMap(); static public ThreadLocal ping_isCleanUpThread = new ThreadLocal(); static public boolean ping() { newPing(); if (ping_pauseAll || ping_anyActions) ping_impl(true); return true; } static public boolean ping_impl(boolean okInCleanUp) { try { if (ping_pauseAll && !isAWTThread()) { do Thread.sleep(ping_sleep); while (ping_pauseAll); return true; } if (ping_anyActions) { if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get())) failIfUnlicensed(); Object action = null; synchronized (ping_actions) { if (!ping_actions.isEmpty()) { action = ping_actions.get(currentThread()); if (action instanceof Runnable) ping_actions.remove(currentThread()); if (ping_actions.isEmpty()) ping_anyActions = false; } } if (action instanceof Runnable) ((Runnable) action).run(); else if (eq(action, "cancelled")) throw fail("Thread cancelled."); } return false; } catch (Exception __e) { throw rethrow(__e); } } static public Thread currentThread() { return Thread.currentThread(); } static public Map vm_threadInterruptionReasonsMap() { return vm_generalWeakSubMap("Thread interruption reasons"); } static public String strOr(Object o, String ifNull) { return o == null ? ifNull : str(o); } static public void lockOrFail(Lock lock, long timeout) { try { ping(); vmBus_send("locking", lock, "thread", currentThread()); if (!lock.tryLock(timeout, TimeUnit.MILLISECONDS)) { String s = "Couldn't acquire lock after " + timeout + " ms."; if (lock instanceof ReentrantLock) { ReentrantLock l = (ReentrantLock) lock; s += " Hold count: " + l.getHoldCount() + ", owner: " + call(l, "getOwner"); } throw fail(s); } vmBus_send("locked", lock, "thread", currentThread()); ping(); } catch (Exception __e) { throw rethrow(__e); } } static public ReentrantLock fairLock() { return new ReentrantLock(true); } public static long parseSnippetID(String snippetID) { long id = Long.parseLong(shortenSnippetID(snippetID)); if (id == 0) throw fail("0 is not a snippet ID"); return id; } static public String getProgramID() { return nempty(programID) ? formatSnippetIDOpt(programID) : "?"; } static public String getProgramID(Class c) { String id = (String) getOpt(c, "programID"); if (nempty(id)) return formatSnippetID(id); return "?"; } static public String getProgramID(Object o) { return getProgramID(getMainClass(o)); } static public String substring(String s, int x) { return substring(s, x, strL(s)); } static public String substring(String s, int x, int y) { if (s == null) return null; if (x < 0) x = 0; int n = s.length(); if (y < x) y = x; if (y > n) y = n; if (x >= y) return ""; return s.substring(x, y); } static public String substring(String s, CharSequence l) { return substring(s, lCharSequence(l)); } static public long parseLong(String s) { if (empty(s)) return 0; return Long.parseLong(dropSuffix("L", s)); } static public long parseLong(Object s) { return Long.parseLong((String) s); } static public String jextract(String pat, String s) { return jextract(pat, javaTok(s)); } static public String jextract(String pat, List tok) { List tokpat = javaTok(pat); jfind_preprocess(tokpat); int i = jfind(tok, tokpat); if (i < 0) return null; int j = i + l(tokpat) - 2; return joinSubList(tok, i, j); } static public String formatWithThousands(long l) { return formatWithThousandsSeparator(l); } static public double fraction(double d) { return d % 1; } static public String n_fancy2(long l, String singular, String plural) { return formatWithThousandsSeparator(l) + " " + trim(l == 1 ? singular : plural); } static public String n_fancy2(Collection l, String singular, String plural) { return n_fancy2(l(l), singular, plural); } static public String n_fancy2(Map m, String singular, String plural) { return n_fancy2(l(m), singular, plural); } static public String n_fancy2(Object[] a, String singular, String plural) { return n_fancy2(l(a), singular, plural); } static public String n_fancy2(MultiSet ms, String singular, String plural) { return n_fancy2(l(ms), singular, plural); } static public String asString(Object o) { return o == null ? null : o.toString(); } public static String join(String glue, Iterable strings) { if (strings == null) return ""; if (strings instanceof Collection) { if (((Collection) strings).size() == 1) return str(first((Collection) strings)); } StringBuilder buf = new StringBuilder(); Iterator i = strings.iterator(); if (i.hasNext()) { buf.append(i.next()); while (i.hasNext()) buf.append(glue).append(i.next()); } return buf.toString(); } public static String join(String glue, String... strings) { return join(glue, Arrays.asList(strings)); } public static String join(String glue, Object... strings) { return join(glue, Arrays.asList(strings)); } static public String join(Iterable strings) { return join("", strings); } static public String join(Iterable strings, String glue) { return join(glue, strings); } public static String join(String[] strings) { return join("", strings); } static public String join(String glue, Pair p) { return p == null ? "" : str(p.a) + glue + str(p.b); } static public ArrayList emptyList() { return new ArrayList(); } static public ArrayList emptyList(int capacity) { return new ArrayList(max(0, capacity)); } static public ArrayList emptyList(Iterable l) { return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList(); } static public ArrayList emptyList(Object[] l) { return emptyList(l(l)); } static public ArrayList emptyList(Class c) { return new ArrayList(); } static public ArrayList asList(A[] a) { return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a)); } static public ArrayList asList(int[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (int i : a) l.add(i); return l; } static public ArrayList asList(long[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (long i : a) l.add(i); return l; } static public ArrayList asList(float[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (float i : a) l.add(i); return l; } static public ArrayList asList(double[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (double i : a) l.add(i); return l; } static public ArrayList asList(short[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (short i : a) l.add(i); return l; } static public ArrayList asList(Iterator it) { ArrayList l = new ArrayList(); if (it != null) while (it.hasNext()) l.add(it.next()); return l; } static public ArrayList asList(IterableIterator s) { return asList((Iterator) s); } static public ArrayList asList(Iterable s) { if (s instanceof ArrayList) return (ArrayList) s; ArrayList l = new ArrayList(); if (s != null) for (A a : s) l.add(a); return l; } static public ArrayList asList(Enumeration e) { ArrayList l = new ArrayList(); if (e != null) while (e.hasMoreElements()) l.add(e.nextElement()); return l; } static public List asList(Pair p) { return p == null ? null : ll(p.a, p.b); } static public String fromLines(Iterable lines) { StringBuilder buf = new StringBuilder(); if (lines != null) for (Object line : lines) buf.append(str(line)).append('\n'); return buf.toString(); } static public String fromLines(String... lines) { return fromLines(asList(lines)); } static public IterableIterator toLines(File f) { return linesFromFile(f); } static public List toLines(String s) { List lines = new ArrayList(); if (s == null) return lines; int start = 0; while (true) { int i = toLines_nextLineBreak(s, start); if (i < 0) { if (s.length() > start) lines.add(s.substring(start)); break; } lines.add(s.substring(start, i)); if (s.charAt(i) == '\r' && i + 1 < s.length() && s.charAt(i + 1) == '\n') i += 2; else ++i; start = i; } return lines; } static public int toLines_nextLineBreak(String s, int start) { int n = s.length(); for (int i = start; i < n; i++) { char c = s.charAt(i); if (c == '\r' || c == '\n') return i; } return -1; } static public List mapToLines(Map map) { List l = new ArrayList(); for (Object key : keys(map)) l.add(str(key) + " = " + str(map.get(key))); return l; } static public String mapToLines(Map map, Object f) { return lines(map(map, f)); } static public String mapToLines(Object f, Map map) { return lines(map(map, f)); } static public String mapToLines(Object f, Iterable l) { return lines(map(f, l)); } static public String mapToLines(Iterable l, IF1 f) { return mapToLines((Object) f, l); } static public String mapToLines(IF1 f, Iterable l) { return mapToLines((Object) f, l); } static public String mapToLines(Map map, IF2 f) { return lines(map(map, f)); } static public String mapToLines(IF1 f, A data1, A... moreData) { return lines(map(f, data1, moreData)); } static public A optParam(ThreadLocal tl, A defaultValue) { return optPar(tl, defaultValue); } static public A optParam(ThreadLocal tl) { return optPar(tl); } static public Object optParam(String name, Map params) { return mapGet(params, name); } static public A optParam(Object[] opt, String name, A defaultValue) { int n = l(opt); if (n == 1 && opt[0] instanceof Map) { Map map = (Map) (opt[0]); return map.containsKey(name) ? (A) map.get(name) : defaultValue; } if (!even(l(opt))) throw fail("Odd parameter length"); for (int i = 0; i < l(opt); i += 2) if (eq(opt[i], name)) return (A) opt[i + 1]; return defaultValue; } static public Object optParam(Object[] opt, String name) { return optParam(opt, name, null); } static public Object optParam(String name, Object[] params) { return optParam(params, name); } static public ClassLoader classLoaderForObject(Object o) { if (o instanceof ClassLoader) return ((ClassLoader) o); if (o == null) return null; return _getClass(o).getClassLoader(); } static public String classNameToVM(String name) { return name.replace(".", "$"); } static public boolean endsWithLetter(String s) { return nempty(s) && isLetter(last(s)); } static public boolean regexpFind(String pat, String s) { return regexpFinds(pat, s); } static public String discordTokenRegexp() { return "[MN][A-Za-z\\d]{23}\\.[\\w-]{6}\\.[\\w-]{27}"; } static public String unnull(String s) { return s == null ? "" : s; } static public Collection unnull(Collection l) { return l == null ? emptyList() : l; } static public List unnull(List l) { return l == null ? emptyList() : l; } static public int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; } static public char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; } static public double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; } static public Map unnull(Map l) { return l == null ? emptyMap() : l; } static public Iterable unnull(Iterable i) { return i == null ? emptyList() : i; } static public A[] unnull(A[] a) { return a == null ? (A[]) emptyObjectArray() : a; } static public BitSet unnull(BitSet b) { return b == null ? new BitSet() : b; } static public Pt unnull(Pt p) { return p == null ? new Pt() : p; } static public Symbol unnull(Symbol s) { return s == null ? emptySymbol() : s; } static public Pair unnull(Pair p) { return p != null ? p : new Pair(null, null); } static public int unnull(Integer i) { return i == null ? 0 : i; } static public long unnull(Long l) { return l == null ? 0L : l; } static public double unnull(Double l) { return l == null ? 0.0 : l; } static public SelfUser jda_selfUser(JDA jda) { return jda.getSelfUser(); } static public String ymd() { return ymd(now()); } static public String ymd(long now) { return year(now) + formatInt(month(now), 2) + formatInt(dayOfMonth(now), 2); } static public String ymd(long now, TimeZone tz) { return year(now, tz) + formatInt(month(now, tz), 2) + formatInt(dayOfMonth(now, tz), 2); } static public String hms() { return hms(now()); } static public String hms(long time) { return new SimpleDateFormat("HHmmss").format(time); } static public File prepareProgramFile(String name) { return mkdirsForFile(getProgramFile(name)); } static public File prepareProgramFile(String progID, String name) { return mkdirsForFile(getProgramFile(progID, name)); } static public ZipOutputStream newZipOutputStream(String path) { return newZipOutputStream(new File(path)); } static public ZipOutputStream newZipOutputStream(File zip) { try { return new ZipOutputStream(newFileOutputStream(zip)); } catch (Exception __e) { throw rethrow(__e); } } static public void zip_addTextFile(ZipOutputStream outZip, String name, String text) { try { if (text == null) return; byte[] utf8 = toUtf8(text); ZipEntry e = new ZipEntry(name); e.setSize(l(utf8)); outZip.putNextEntry(e); outZip.write(utf8, 0, l(utf8)); } catch (Exception __e) { throw rethrow(__e); } } static public long hoursToMS(double hours) { return round(hours * 60 * 60 * 1000); } static public File computerIDFile() { return javaxDataDir("Basic Info/computer-id.txt"); } static public String loadTextFile(String fileName) { return loadTextFile(fileName, null); } static public String loadTextFile(File f, String defaultContents) { return loadTextFile(f, defaultContents, "UTF-8"); } static public String loadTextFile(File f, String defaultContents, String encoding) { try { checkFileNotTooBigToRead(f); if (f == null || !f.exists()) return defaultContents; FileInputStream fileInputStream = new FileInputStream(f); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, encoding); return loadTextFile(inputStreamReader); } catch (Exception __e) { throw rethrow(__e); } } public static String loadTextFile(File fileName) { return loadTextFile(fileName, null); } static public String loadTextFile(String fileName, String defaultContents) { return fileName == null ? defaultContents : loadTextFile(newFile(fileName), defaultContents); } static public String loadTextFile(Reader reader) throws IOException { StringBuilder builder = new StringBuilder(); try { char[] buffer = new char[1024]; int n; while (-1 != (n = reader.read(buffer))) builder.append(buffer, 0, n); } finally { reader.close(); } return str(builder); } static public File userDir() { return new File(userHome()); } static public File userDir(String path) { return new File(userHome(), path); } static public String makeRandomID(int length) { return makeRandomID(length, defaultRandomGenerator()); } static public String makeRandomID(int length, Random random) { char[] id = new char[length]; for (int i = 0; i < id.length; i++) id[i] = (char) ((int) 'a' + random.nextInt(26)); return new String(id); } static public String makeRandomID(Random r, int length) { return makeRandomID(length, r); } static public File saveTextFile(String fileName, String contents) throws IOException { CriticalAction action = beginCriticalAction("Saving file " + fileName + " (" + l(contents) + " chars)"); try { File file = new File(fileName); mkdirsForFile(file); String tempFileName = fileName + "_temp"; File tempFile = new File(tempFileName); if (contents != null) { if (tempFile.exists()) try { String saveName = tempFileName + ".saved." + now(); copyFile(tempFile, new File(saveName)); } catch (Throwable e) { printStackTrace(e); } FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath()); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); PrintWriter printWriter = new PrintWriter(outputStreamWriter); printWriter.print(contents); printWriter.close(); } if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (contents != null) if (!tempFile.renameTo(file)) throw new IOException("Can't rename " + tempFile + " to " + file); vmBus_send("wroteFile", file); return file; } finally { action.done(); } } static public File saveTextFile(File fileName, String contents) { try { saveTextFile(fileName.getPath(), contents); return fileName; } catch (Exception __e) { throw rethrow(__e); } } static public String strOrNull(Object o) { return o == null ? null : str(o); } static public Object dm_getStem(Object moduleOrID) { if (isString(moduleOrID) && isIdentifier(((String) moduleOrID))) moduleOrID = dm_getService(((String) moduleOrID)); if (isStringOrIntOrLong(moduleOrID)) return dm_getStemByID(moduleOrID); return or(getOpt(dm_getModule(moduleOrID), "_host"), moduleOrID); } static public FixedRateTimer doEveryStartingNow(int delay, Object r) { return doEvery(delay, 0, r); } static public int toInt(Object o) { if (o == null) return 0; if (o instanceof Number) return ((Number) o).intValue(); if (o instanceof String) return parseInt((String) o); if (o instanceof Boolean) return boolToInt((Boolean) o); throw fail("woot not int: " + getClassName(o)); } static public int toInt(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static public long toMS(double seconds) { return (long) (seconds * 1000); } static public int shorten_default = 100; static public String shorten(CharSequence s) { return shorten(s, shorten_default); } static public String shorten(CharSequence s, int max) { return shorten(s, max, "..."); } static public String shorten(CharSequence s, int max, String shortener) { if (s == null) return ""; if (max < 0) return str(s); return s.length() <= max ? str(s) : subCharSequence(s, 0, min(s.length(), max - l(shortener))) + shortener; } static public String shorten(int max, CharSequence s) { return shorten(s, max); } static public TimerTask smartTimerTask(Object r, java.util.Timer timer, long delay) { return new SmartTimerTask(r, timer, delay, _threadInfo()); } static public class SmartTimerTask extends TimerTask implements IFieldsToList { public Object r; public java.util.Timer timer; public long delay; public Object threadInfo; public SmartTimerTask() { } public SmartTimerTask(Object r, java.util.Timer timer, long delay, Object threadInfo) { this.threadInfo = threadInfo; this.delay = delay; this.timer = timer; this.r = r; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + r + ", " + timer + ", " + delay + ", " + threadInfo + ")"; } public Object[] _fieldsToList() { return new Object[] { r, timer, delay, threadInfo }; } public long lastRun; public void run() { if (!licensed()) timer.cancel(); else { _threadInheritInfo(threadInfo); AutoCloseable __1 = tempActivity(r); try { lastRun = fixTimestamp(lastRun); long now = now(); if (now >= lastRun + delay * 0.9) { lastRun = now; if (eq(false, pcallF(r))) timer.cancel(); } } finally { _close(__1); } } } } static public A vmBus_timerStarted(A timer) { vmBus_send("timerStarted", timer, costCenter()); return timer; } static public double toDouble(Object o) { if (o instanceof Number) return ((Number) o).doubleValue(); if (o instanceof BigInteger) return ((BigInteger) o).doubleValue(); if (o instanceof String) return parseDouble((String) o); if (o == null) return 0.0; throw fail(o); } static public B vm_registerClassInstance(Class c, B o) { if (c != null && o != null) vm_registeredInstancesSet(c).add(o); return o; } static public AutoCloseable dm_enter(Object mod) { return (AutoCloseable) callOpt(dm_getModule(mod), "enter"); } static public int incAtomicInt(AtomicInteger i) { return i.incrementAndGet(); } static public int incAtomicInt(AtomicInteger i, int delta) { return i.addAndGet(delta); } static public long incAtomicLong(AtomicLong l) { return l.incrementAndGet(); } static public double toSeconds(long ms) { return ms / 1000.0; } static public String toSeconds(long ms, int digits) { return formatDouble(toSeconds(ms), digits); } static public double toSeconds(double ms) { return ms / 1000.0; } static public String toSeconds(double ms, int digits) { return formatDouble(toSeconds(ms), digits); } static public long now_virtualTime; static public long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } static public Set synchroHashSet() { return synchronizedSet(new HashSet()); } static public boolean containsIgnoreCase(Collection l, String s) { if (l != null) for (String x : l) if (eqic(x, s)) return true; return false; } static public boolean containsIgnoreCase(String[] l, String s) { if (l != null) for (String x : l) if (eqic(x, s)) return true; return false; } static public boolean containsIgnoreCase(String s, char c) { return indexOfIgnoreCase(s, String.valueOf(c)) >= 0; } static public boolean containsIgnoreCase(String a, String b) { return indexOfIgnoreCase(a, b) >= 0; } static public List takeFirst(List l, int n) { return l(l) <= n ? l : newSubListOrSame(l, 0, n); } static public List takeFirst(int n, List l) { return takeFirst(l, n); } static public String takeFirst(int n, String s) { return substring(s, 0, n); } static public String takeFirst(String s, int n) { return substring(s, 0, n); } static public CharSequence takeFirst(int n, CharSequence s) { return subCharSequence(s, 0, n); } static public List takeFirst(int n, Iterator it) { if (it == null) return null; List l = new ArrayList(); for (int _repeat_0 = 0; _repeat_0 < n; _repeat_0++) { if (it.hasNext()) l.add(it.next()); else break; } return l; } static public List takeFirst(int n, Iterable i) { if (i == null) return null; return i == null ? null : takeFirst(n, i.iterator()); } static public List takeFirst(int n, IterableIterator i) { return takeFirst(n, (Iterator) i); } static public int[] takeFirst(int n, int[] a) { return takeFirstOfIntArray(n, a); } static public short[] takeFirst(int n, short[] a) { return takeFirstOfShortArray(n, a); } static public byte[] takeFirst(int n, byte[] a) { return takeFirstOfByteArray(n, a); } static public byte[] takeFirst(byte[] a, int n) { return takeFirstOfByteArray(n, a); } static public double[] takeFirst(int n, double[] a) { return takeFirstOfDoubleArray(n, a); } static public double[] takeFirst(double[] a, int n) { return takeFirstOfDoubleArray(n, a); } static public List subList(List l, int startIndex) { return subList(l, startIndex, l(l)); } static public List subList(int startIndex, List l) { return subList(l, startIndex); } static public List subList(int startIndex, int endIndex, List l) { return subList(l, startIndex, endIndex); } static public List subList(List l, int startIndex, int endIndex) { if (l == null) return null; int n = l(l); startIndex = Math.max(0, startIndex); endIndex = Math.min(n, endIndex); if (startIndex > endIndex) return ll(); if (startIndex == 0 && endIndex == n) return l; return l.subList(startIndex, endIndex); } static public String appendNumberUnless1(String s, int i) { return i == 1 ? s : s + " " + i; } static public boolean emptyAfterTrim(String s) { return empty(trim(s)); } static public String encloseInBackticks(String s) { return s == null ? null : "`" + s + "`"; } static public String snippetImageURL(long snippetID) { return snippetImageURL(fsI(snippetID)); } static public String snippetImageURL(String snippetID) { return snippetImageURL(snippetID, "png"); } static public String snippetImageURL(String snippetID, String contentType) { if (snippetID == null || isURL(snippetID)) return snippetID; long id = parseSnippetID(snippetID); String url; if (isImageServerSnippet(id)) url = imageServerLink(id); else url = "https://botcompany.de/img/" + id; return url; } static public java.util.Timer doLater(long delay, final Object r) { ping(); final java.util.Timer timer = new java.util.Timer(); timer.schedule(timerTask(r, timer), delay); return vmBus_timerStarted(timer); } static public java.util.Timer doLater(double delaySeconds, final Object r) { return doLater(toMS(delaySeconds), r); } static public void dm_reloadMe() { dm_reloadModule(dm_currentModule()); } static public boolean startsWithOneOf(String s, String... l) { for (String x : l) if (startsWith(s, x)) return true; return false; } static public boolean startsWithOneOf(String s, Matches m, String... l) { for (String x : l) if (startsWith(s, x, m)) return true; return false; } static public boolean matchX_vbar(String pat, String s) { return matchX_vbar(pat, s, null); } static public boolean matchX_vbar(String pat, String s, Matches matches) { for (String pat2 : tok_splitAtVerticalBar(pat)) if (matchX(pat2, s, matches)) return true; return false; } static public boolean emptyString(String s) { return s == null || s.length() == 0; } static public List map_pcall_notNull(Iterable l, Object f) { return map_pcall_notNull(f, l); } static public List map_pcall_notNull(Object f, Iterable l) { List x = new ArrayList(); for (Object o : unnullForIteration(l)) { try { addIfNotNull(x, callF(f, o)); } catch (Throwable __e) { printStackTrace(__e); } } return x; } static public List map_pcall_notNull(IF1 f, Iterable l) { List x = new ArrayList(); for (Object o : unnullForIteration(l)) { try { addIfNotNull(x, callF(f, o)); } catch (Throwable __e) { printStackTrace(__e); } } return x; } static public List map_pcall_notNull(Iterable l, IF1 f) { return map_pcall_notNull(f, l); } static public String hmsWithColons() { return hmsWithColons(now()); } static public String hmsWithColons(long time) { return new SimpleDateFormat("HH:mm:ss").format(time); } static public A firstWhereMethodReturns(String methodName, Iterable l, Object result) { return firstThat(l, o -> eq(call(o, methodName), result)); } static public Pair mapEntryToPair(Map.Entry e) { return e == null ? null : pair(e.getKey(), e.getValue()); } static public Set> entrySet(Map map) { return _entrySet(map); } static public Pair pair(A a, B b) { return new Pair(a, b); } static public Pair pair(A a) { return new Pair(a, a); } static public A firstThat(Iterable l, IF1 pred) { for (A a : unnullForIteration(l)) if (pred.get(a)) return a; return null; } static public A firstThat(A[] l, IF1 pred) { for (A a : unnullForIteration(l)) if (pred.get(a)) return a; return null; } static public A firstThat(IF1 pred, Iterable l) { return firstThat(l, pred); } static public A firstThat(IF1 pred, A[] l) { return firstThat(l, pred); } static public String rtrim_fromLines(Collection lines) { StringBuilder buf = new StringBuilder(); if (lines != null) { boolean first = true; for (Object line : lines) { if (first) first = false; else buf.append('\n'); buf.append(str(line)); } } return buf.toString(); } static public String makePostData(Map map) { StringBuilder buf = new StringBuilder(); for (Map.Entry e : castMapToMapO(map).entrySet()) { String key = (String) (e.getKey()); Object val = e.getValue(); if (val != null) { String value = str(val); if (nempty(buf)) buf.append("&"); buf.append(urlencode(key)).append("=").append(urlencode((value))); } } return str(buf); } static public String makePostData(Object... params) { StringBuilder buf = new StringBuilder(); int n = l(params); for (int i = 0; i + 1 < n; i += 2) { String key = (String) (params[i]); Object val = params[i + 1]; if (val != null) { String value = str(val); if (nempty(buf)) buf.append("&"); buf.append(urlencode(key)).append("=").append(urlencode((value))); } } return str(buf); } static public int smartIndexOf(String s, String sub, int i) { if (s == null) return 0; i = s.indexOf(sub, min(i, l(s))); return i >= 0 ? i : l(s); } static public int smartIndexOf(String s, int i, char c) { return smartIndexOf(s, c, i); } static public int smartIndexOf(String s, char c, int i) { if (s == null) return 0; i = s.indexOf(c, min(i, l(s))); return i >= 0 ? i : l(s); } static public int smartIndexOf(String s, String sub) { return smartIndexOf(s, sub, 0); } static public int smartIndexOf(String s, char c) { return smartIndexOf(s, c, 0); } static public int smartIndexOf(List l, A sub) { return smartIndexOf(l, sub, 0); } static public int smartIndexOf(List l, int start, A sub) { return smartIndexOf(l, sub, start); } static public int smartIndexOf(List l, A sub, int start) { int i = indexOf(l, sub, start); return i < 0 ? l(l) : i; } static public Map paramsToMap(Object... params) { int n = l(params); if (l(params) == 1 && params[0] instanceof Map) return (Map) params[0]; LinkedHashMap map = new LinkedHashMap(); for (int i = 0; i + 1 < n; i += 2) mapPut(map, params[i], params[i + 1]); return map; } static public Random getRandomizer(Random r) { return r != null ? r : defaultRandomGenerator(); } static public Random random_random = new Random(); static public int random(int n) { return random(random_random, n); } static public int random(int n, Random r) { return random(r, n); } static public int random(Random r, int n) { return n <= 0 ? 0 : getRandomizer(r).nextInt(n); } static public double random(double max) { return random() * max; } static public double random() { return random_random.nextInt(100001) / 100000.0; } static public double random(double min, double max) { return min + random() * (max - min); } static public int random(int min, int max) { return min + random(max - min); } static public int random(int min, int max, Random r) { return random(r, min, max); } static public int random(Random r, int min, int max) { return min + random(r, max - min); } static public A random(List l) { return oneOf(l); } static public A random(Collection c) { if (c instanceof List) return random((List) c); int i = random(l(c)); return collectionGet(c, i); } static public Pair random(Map map) { return entryToPair(random(entries(map))); } static public int loadPage_defaultTimeout = 60000; static public ThreadLocal loadPage_charset = new ThreadLocal(); static public boolean loadPage_allowGzip = true, loadPage_debug; static public boolean loadPage_anonymous = false; static public int loadPage_verboseness = 100000; static public int loadPage_retries = 1; static public ThreadLocal loadPage_silent = new ThreadLocal(); static volatile public int loadPage_forcedTimeout; static public ThreadLocal loadPage_forcedTimeout_byThread = new ThreadLocal(); static public ThreadLocal>> loadPage_responseHeaders = new ThreadLocal(); static public ThreadLocal> loadPage_extraHeaders = new ThreadLocal(); static public ThreadLocal loadPage_sizeLimit = new ThreadLocal(); public static String loadPageSilently(String url) { try { return loadPageSilently(new URL(loadPage_preprocess(url))); } catch (Exception __e) { throw rethrow(__e); } } public static String loadPageSilently(URL url) { try { if (!networkAllowanceTest(str(url))) throw fail("Not allowed: " + url); IOException e = null; for (int tries = 0; tries < loadPage_retries; tries++) try { URLConnection con = loadPage_openConnection(url); return loadPage(con, url); } catch (IOException _e) { e = _e; if (loadPage_debug) print(exceptionToStringShort(e)); if (tries < loadPage_retries - 1) sleepSeconds(1); } throw e; } catch (Exception __e) { throw rethrow(__e); } } static public String loadPage_preprocess(String url) { if (url.startsWith("tb/")) url = tb_mainServer() + "/" + url; if (url.indexOf("://") < 0) url = "http://" + url; return url; } static public String loadPage(String url) { try { url = loadPage_preprocess(url); if (!isTrue(loadPage_silent.get())) printWithTime("Loading: " + hideCredentials(url)); return loadPageSilently(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static public String loadPage(URL url) { return loadPage(url.toExternalForm()); } static public String loadPage(URLConnection con, URL url) throws IOException { return loadPage(con, url, true); } static public String loadPage(URLConnection con, URL url, boolean addHeaders) throws IOException { Map extraHeaders = getAndClearThreadLocal(loadPage_extraHeaders); Long limit = optPar(loadPage_sizeLimit); if (addHeaders) try { if (!loadPage_anonymous) setHeaders(con); if (loadPage_allowGzip) con.setRequestProperty("Accept-Encoding", "gzip"); con.setRequestProperty("X-No-Cookies", "1"); for (String key : keys(extraHeaders)) con.setRequestProperty(key, extraHeaders.get(key)); } catch (Throwable e) { } vm_generalSubMap("URLConnection per thread").put(currentThread(), con); loadPage_responseHeaders.set(con.getHeaderFields()); InputStream in = null; try { in = urlConnection_getInputStream(con); if (loadPage_debug) print("Put stream in map: " + currentThread()); String contentType = con.getContentType(); if (contentType == null) { throw new IOException("Page could not be read: " + hideCredentials(url)); } String charset = loadPage_charset == null ? null : loadPage_charset.get(); if (charset == null) charset = loadPage_guessCharset(contentType); if ("gzip".equals(con.getContentEncoding())) { if (loadPage_debug) print("loadPage: Using gzip."); in = newGZIPInputStream(in); } Reader r; try { r = new InputStreamReader(in, unquote(charset)); } catch (UnsupportedEncodingException e) { print(toHex(utf8(charset))); throw e; } boolean silent = isTrue(loadPage_silent.get()); StringBuilder buf = new StringBuilder(); int n = 0; while (limit == null || n < limit) { ping(); int ch = r.read(); if (ch < 0) break; buf.append((char) ch); ++n; if (!silent && (n % loadPage_verboseness) == 0) print(" " + n + " chars read"); } return buf.toString(); } finally { if (loadPage_debug) print("loadPage done"); vm_generalSubMap("URLConnection per thread").remove(currentThread()); if (in != null) in.close(); } } static public String loadPage_guessCharset(String contentType) { Matcher m = regexpMatcher("text/[a-z]+;\\s*charset=([^\\s]+)\\s*", contentType); String match = m.matches() ? m.group(1) : null; if (loadPage_debug) print("loadPage: contentType=" + contentType + ", match: " + match); return or(match, "UTF-8"); } static public URLConnection loadPage_openConnection(URL url) { URLConnection con = openConnection(url); int timeout = toInt(loadPage_forcedTimeout_byThread.get()); if (timeout == 0) timeout = loadPage_forcedTimeout; if (timeout != 0) setURLConnectionTimeouts(con, loadPage_forcedTimeout); else setURLConnectionDefaultTimeouts(con, loadPage_defaultTimeout); return con; } static public A getAndClearThreadLocal(ThreadLocal tl) { A a = tl.get(); tl.set(null); return a; } static public void setHeaders(URLConnection con) throws IOException { String computerID = getComputerID_quick(); if (computerID != null) try { con.setRequestProperty("X-ComputerID", computerID); con.setRequestProperty("X-OS", System.getProperty("os.name") + " " + System.getProperty("os.version")); } catch (Throwable e) { } } static public Set keys(Map map) { return map == null ? new HashSet() : map.keySet(); } static public Set keys(Object map) { return keys((Map) map); } static public Set keys(MultiSet ms) { return ms.keySet(); } static public Set keys(MultiMap mm) { return mm.keySet(); } static public A println(A a) { return print(a); } static public String getChannelName() { return (String) callOpt(getMainBot(), "getChannelName"); } static public Object dm_callMe(String method, Object... args) { return dm_callMyself(method, args); } static public Object rcall(String method, Object o, Object... args) { return call_withVarargs(o, method, args); } static public AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) { if (tl == null) return null; final A prev = setThreadLocal(tl, a); return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); } }; } static public AutoCloseable tempSetThreadLocalIfNecessary(ThreadLocal tl, A a) { if (tl == null) return null; A prev = tl.get(); if (eq(prev, a)) return null; tl.set(a); return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); } }; } static public List findTagsWithParams(String tag, List tok, Object... params) { List l = new ArrayList(); for (String t : codeTokens(tok)) if (tagIs(t, tag) && htmlCheckParams(t, params)) l.add(t); return l; } static public List findTagsWithParams(String tag, String html, Object... params) { return findTagsWithParams(tag, htmlTok(html), params); } static public String tagParam(String tag, String key) { return getHtmlTagParameter(tag, key); } static public String tagParam(List tok, String key) { return getHtmlTagParameter(second(tok), key); } static public String dropPrefixTrimIC_orNull(String prefix, String s) { return dropPrefixICTrim_orNull(prefix, s); } static public int lastIndexOfIC(String a, String b) { return lastIndexOfIgnoreCase_manual(a, b); } static public int lastIndexOfIC(String a, char b) { return lastIndexOfIgnoreCase_manual(a, str(b)); } static public String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); } static public String hideCredentials(String url) { try { if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url; } catch (Throwable e) { print("HideCredentials", e); } return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2="); } static public String hideCredentials(Object o) { return hideCredentials(str(o)); } static public URLConnection setURLConnectionTimeouts(URLConnection con, long timeout) { con.setConnectTimeout(toInt(timeout)); con.setReadTimeout(toInt(timeout)); if (con.getConnectTimeout() != timeout || con.getReadTimeout() != timeout) print("Warning: Timeouts not set by JDK."); return con; } static public Object jsonDecode(String text) { return new jsonDecode_Y(text).parse(); } static public class jsonDecode_Y { public String text; public List tok; public boolean useOrderedMaps = false; public int i = 1; public jsonDecode_Y(String text) { this.text = text; tok = jsonTok(text); } transient public IF1 fail; public RuntimeException fail(String msg) { return fail != null ? fail.get(msg) : fail_base(msg); } final public RuntimeException fail_fallback(IF1 _f, String msg) { return _f != null ? _f.get(msg) : fail_base(msg); } public RuntimeException fail_base(String msg) { return main.fail(msg); } public Object parse() { if (l(tok) == 1) return null; return parseExpr(); } public Object parseExpr() { String t = tok.get(i); if (t.startsWith("\"") || t.startsWith("'")) { String s = unquote(tok.get(i)); i += 2; return s; } if (t.equals("{")) return parseMap(); if (t.equals("[")) return this.parseList(); if (t.equals("null")) { i += 2; return null; } if (t.equals("false")) { i += 2; return false; } if (t.equals("true")) { i += 2; return true; } boolean minus = false; if (t.equals("-")) { minus = true; i += 2; t = get(tok, i); } if (isInteger(t)) { int j = i; i += 2; if (eqOneOf(get(tok, i), ".", "e", "E")) { while (isInteger(get(tok, i)) || eqOneOf(get(tok, i), ".", "e", "E", "-")) i += 2; double d = parseDouble(joinSubList(tok, j, i - 1)); if (minus) d = -d; return d; } else { long l = parseLong(t); return boxedIntOrLong(minus ? -l : l); } } throw fail("Unknown token " + (i + 1) + ": " + t + ": " + text); } public Object parseList() { consume("["); List list = new ArrayList(); while (!tok.get(i).equals("]")) { list.add(parseExpr()); if (tok.get(i).equals(",")) i += 2; } consume("]"); return list; } public Object parseMap() { consume("{"); Map map = useOrderedMaps ? new LinkedHashMap() : new TreeMap(); while (!tok.get(i).equals("}")) { String key = unquote(tok.get(i)); i += 2; consume(":"); Object value = parseExpr(); map.put(key, value); if (tok.get(i).equals(",")) i += 2; } consume("}"); return map; } public void consume(String s) { if (!tok.get(i).equals(s)) { String prevToken = i - 2 >= 0 ? tok.get(i - 2) : ""; String nextTokens = join(tok.subList(i, Math.min(i + 4, tok.size()))); throw fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")"); } i += 2; } } static public HashMap litmap(Object... x) { HashMap map = new HashMap(); litmap_impl(map, x); return map; } static public void litmap_impl(Map map, Object... x) { if (x != null) for (int i = 0; i < x.length - 1; i += 2) if (x[i + 1] != null) map.put(x[i], x[i + 1]); } static public char lastChar(String s) { return empty(s) ? '\0' : s.charAt(l(s) - 1); } static public A[] dropLast(A[] a) { return dropLast(a, 1); } static public A[] dropLast(A[] a, int n) { if (a == null) return null; n = Math.min(n, a.length); A[] b = arrayOfSameType(a, a.length - n); System.arraycopy(a, 0, b, 0, b.length); return b; } static public List dropLast(List l) { return subList(l, 0, l(l) - 1); } static public List dropLast(int n, List l) { return subList(l, 0, l(l) - n); } static public List dropLast(Iterable l) { return dropLast(asList(l)); } static public String dropLast(String s) { return substring(s, 0, l(s) - 1); } static public String dropLast(String s, int n) { return substring(s, 0, l(s) - n); } static public String dropLast(int n, String s) { return dropLast(s, n); } static public List> findContainerTagWithParams(List tok, String tag, Object... params) { List> l = new ArrayList(); for (List t : findContainerTag(tok, tag)) if (htmlCheckParams(second(t), params)) l.add(t); return l; } static public List> findContainerTagWithParams(String html, String tag, Object... params) { return findContainerTagWithParams(htmlTok(html), tag, params); } static public String joinContentsOfContainerTag(List tok) { return tok == null ? null : join(contentsOfContainerTag(tok)); } static public Object gazelle_discordPresence() { return call(gazelle_jda(), "getPresence"); } static public Class getClass_vmName(Object realm, String name) { try { try { return getClass(realm).getClassLoader().loadClass(name); } catch (ClassNotFoundException e) { return null; } } catch (Exception __e) { throw rethrow(__e); } } static public Object gazelle_jda() { return getFirstNonNullField(dm_current_mandatory_generic(), "discord", "bot"); } static public Collection values(Map map) { return map == null ? emptyList() : map.values(); } static public Collection values(Object map) { return values((Map) map); } static public Collection values(MultiMap mm) { return mm == null ? emptyList() : concatLists(values(mm.data)); } static public Object collectionMutex(List l) { return l; } static public Object collectionMutex(Object o) { if (o instanceof List) return o; String c = className(o); if (eq(c, "java.util.TreeMap$KeySet")) c = className(o = getOpt(o, "m")); else if (eq(c, "java.util.HashMap$KeySet")) c = className(o = get_raw(o, "this$0")); if (eqOneOf(c, "java.util.TreeMap$AscendingSubMap", "java.util.TreeMap$DescendingSubMap")) c = className(o = get_raw(o, "m")); return o; } static public Class __javax; static public Class getJavaX() { try { return __javax; } catch (Exception __e) { throw rethrow(__e); } } static public void __setJavaX(Class j) { __javax = j; _onJavaXSet(); } static public ThreadLocal print_byThread() { synchronized (print_byThread_lock) { if (print_byThread == null) print_byThread = new ThreadLocal(); } return print_byThread; } static public AutoCloseable tempInterceptPrint(F1 f) { return tempSetThreadLocal(print_byThread(), f); } static public Object defaultDefaultClassFinder() { return new F1() { public Class get(String name) { Class c = get2(name); return c; } public Class get2(String name) { if (eq(name, "
")) return mc(); { Class c = findClass_fullName(name); if (c != null) return c; } if (startsWithAny(name, "loadableUtils.utils$", "main$", mcDollar())) for (String pkg : ll("loadableUtils.utils$", mcDollar())) { String newName = pkg + afterDollar(name); { Class c = findClass_fullName(newName); if (c != null) return c; } } return null; } }; } static public String programIDWithCase() { return nempty(caseID()) ? programID() + "/" + quoteUnlessIdentifierOrInteger(caseID()) : programID(); } static public String[] dropFirst(int n, String[] a) { return drop(n, a); } static public String[] dropFirst(String[] a) { return drop(1, a); } static public Object[] dropFirst(Object[] a) { return drop(1, a); } static public List dropFirst(List l) { return dropFirst(1, l); } static public List dropFirst(int n, Iterable i) { return dropFirst(n, toList(i)); } static public List dropFirst(Iterable i) { return dropFirst(toList(i)); } static public List dropFirst(int n, List l) { return n <= 0 ? l : new ArrayList(l.subList(Math.min(n, l.size()), l.size())); } static public List dropFirst(List l, int n) { return dropFirst(n, l); } static public String dropFirst(int n, String s) { return substring(s, n); } static public String dropFirst(String s, int n) { return substring(s, n); } static public String dropFirst(String s) { return substring(s, 1); } static public int indexOfNonDigit(String s) { int n = l(s); for (int i = 0; i < n; i++) if (!isDigit(s.charAt(i))) return i; return -1; } static public String shortenClassName(String name) { if (name == null) return null; int i = lastIndexOf(name, "$"); if (i < 0) i = lastIndexOf(name, "."); return i < 0 ? name : substring(name, i + 1); } static public Map classForName_cache = synchroHashMap(); static public Class classForName(String name) { return classForName(name, null); } static public Class classForName(String name, Object classFinder) { if (classForName_cache == null || classFinder != null) return classForName_uncached(name, classFinder); Class c = classForName_cache.get(name); if (c == null) classForName_cache.put(name, c = classForName_uncached(name, null)); return c; } static public Class classForName_uncached(String name, Object classFinder) { try { if (classFinder != null) return (Class) callF(classFinder, name); return Class.forName(name); } catch (Exception __e) { throw rethrow(__e); } } static public Map nuObjectWithoutArguments_cache = newDangerousWeakHashMap(); static public Object nuObjectWithoutArguments(String className) { try { return nuObjectWithoutArguments(classForName(className)); } catch (Exception __e) { throw rethrow(__e); } } static public A nuObjectWithoutArguments(Class c) { try { if (nuObjectWithoutArguments_cache == null) return (A) nuObjectWithoutArguments_findConstructor(c).newInstance(); Constructor m = nuObjectWithoutArguments_cache.get(c); if (m == null) nuObjectWithoutArguments_cache.put(c, m = nuObjectWithoutArguments_findConstructor(c)); return (A) m.newInstance(); } catch (Exception __e) { throw rethrow(__e); } } static public Constructor nuObjectWithoutArguments_findConstructor(Class c) { for (Constructor m : c.getDeclaredConstructors()) if (empty(m.getParameterTypes())) { makeAccessible(m); return m; } throw fail("No default constructor found in " + c.getName()); } static public Field makeAccessible(Field f) { try { f.setAccessible(true); } catch (Throwable e) { vmBus_send("makeAccessible_error", e, f); } return f; } static public Method makeAccessible(Method m) { try { m.setAccessible(true); } catch (Throwable e) { vmBus_send("makeAccessible_error", e, m); } return m; } static public Constructor makeAccessible(Constructor c) { try { c.setAccessible(true); } catch (Throwable e) { vmBus_send("makeAccessible_error", e, c); } return c; } static public List getClasses(Object[] array) { List l = emptyList(l(array)); for (Object o : array) l.add(_getClass(o)); return l; } static public boolean isInstanceX(Class type, Object arg) { if (type == boolean.class) return arg instanceof Boolean; if (type == int.class) return arg instanceof Integer; if (type == long.class) return arg instanceof Long; if (type == float.class) return arg instanceof Float; if (type == short.class) return arg instanceof Short; if (type == char.class) return arg instanceof Character; if (type == byte.class) return arg instanceof Byte; if (type == double.class) return arg instanceof Double; return type.isInstance(arg); } static public A set(A o, String field, Object value) { if (o == null) return null; if (o instanceof Class) set((Class) o, field, value); else try { Field f = set_findField(o.getClass(), field); makeAccessible(f); smartSet(f, o, value); } catch (Exception e) { throw new RuntimeException(e); } return o; } static public void set(Class c, String field, Object value) { if (c == null) return; try { Field f = set_findStaticField(c, field); makeAccessible(f); smartSet(f, null, value); } catch (Exception e) { throw new RuntimeException(e); } } static public Field set_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static public Field set_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static public void set(BitSet bs, int idx) { { if (bs != null) bs.set(idx); } } static public void failIfOddCount(Object... list) { if (odd(l(list))) throw fail("Odd list size: " + list); } static public A dm_ownResource(A resource) { dm_currentModuleMandatory().ownResource(resource); return resource; } static public AutoCloseable vmBus_onMessage(String msg, IVF1 onMessage) { return vmBus_onMessage(msg, ivf1ToVF1(onMessage)); } static public AutoCloseable vmBus_onMessage(final String msg, final VF1 onMessage) { Map map = vm_busListenersByMessage_live(); synchronized (map) { Set listeners = map.get(msg); if (listeners == null) map.put(msg, listeners = syncIdentityHashSet()); return tempAdd(listeners, new VF2() { public void get(String _msg, Object arg) { try { callF(onMessage, arg); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, arg)"; } }); } } static public AutoCloseable vmBus_onMessage(String msg, final VF2 onMessage) { return vmBus_onMessage(msg, new VF1() { public void get(Object[] o) { try { callF(onMessage, first(o), second(o)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, first(o), second(o));"; } }); } static public AutoCloseable vmBus_onMessage(String msg, final IVF2 onMessage) { return vmBus_onMessage(msg, new VF1() { public void get(Object[] o) { try { callF(onMessage, first(o), second(o)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, first(o), second(o));"; } }); } static public AutoCloseable vmBus_onMessage(String msg, final VF3 onMessage) { return vmBus_onMessage(msg, new VF1() { public void get(Object[] o) { try { callF(onMessage, first(o), second(o), third(o)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, first(o), second(o), third(o));"; } }); } static public AutoCloseable vmBus_onMessage(String msg, Runnable onMessage) { return vmBus_onMessage(msg, runnableToVF1(onMessage)); } static public VF1 ivf1ToVF1(IVF1 f) { return f == null ? null : new VF1() { public void get(A a) { try { f.get(a); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.get(a)"; } }; } static public VF2 ivf2ToVF2(IVF2 f) { return f == null ? null : new VF2() { public void get(A a, B b) { try { f.get(a, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.get(a, b)"; } }; } static public Object call_withVarargs(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); Method me = cache.findStaticMethod(method, args); if (me != null) return invokeMethod(me, null, args); List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } { if (!(isStaticMethod(m))) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, null, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found"); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(method, args); if (me != null) return invokeMethod(me, o, args); List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, o, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found"); } } catch (Exception __e) { throw rethrow(__e); } } static volatile public PersistableThrowable lastException_lastException; static public PersistableThrowable lastException() { return lastException_lastException; } static public void lastException(Throwable e) { lastException_lastException = persistableThrowable(e); } static public void rotateStringBuffer(StringBuffer buf, int max) { try { if (buf == null) return; synchronized (buf) { if (buf.length() <= max) return; try { int newLength = max / 2; int ofs = buf.length() - newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static public void rotateStringBuilder(StringBuilder buf, int max) { try { if (buf == null) return; synchronized (buf) { if (buf.length() <= max) return; try { int newLength = max / 2; int ofs = buf.length() - newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static public Object vmBus_wrapArgs(Object... args) { return empty(args) ? null : l(args) == 1 ? args[0] : args; } static public void pcallFAll_minimalExceptionHandling(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) { ping(); pcallF_minimalExceptionHandling(f, args); } } static public void pcallFAll_minimalExceptionHandling(Iterator it, Object... args) { while (it.hasNext()) { ping(); pcallF_minimalExceptionHandling(it.next(), args); } } static public Set vm_busListeners_live_cache; static public Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache; } static public Set vm_busListeners_live_load() { return vm_generalIdentityHashSet("busListeners"); } static public Map vm_busListenersByMessage_live_cache; static public Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache; } static public Map vm_busListenersByMessage_live_load() { return vm_generalHashMap("busListenersByMessage"); } static public Map synchronizedMap() { return synchroMap(); } static public Map synchronizedMap(Map map) { return synchroMap(map); } static public RuntimeException asRuntimeException(Throwable t) { if (t instanceof Error) _handleError((Error) t); return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static public String getClassName(Object o) { return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName(); } static public boolean startsWithIgnoreCase(String a, String b) { return regionMatchesIC(a, 0, b, 0, b.length()); } static public String beautifyStructure(String s) { List tok = javaTokForStructure(s); structure_addTokenMarkers(tok); jreplace(tok, "lhm", ""); return join(tok); } static public String struct_noStringSharing(Object o) { structure_Data d = new structure_Data(); d.noStringSharing = true; return structure(o, d); } static public Map defaultSizeMRUCache() { return mruCache(defaultStringTransformerCacheSize()); } static public B getOrCreate_f0(Map map, A key, F0 create) { B b = map.get(key); if (b == null) mapPut(map, key, b = callF(create)); return b; } static public B getOrCreate_f0(Map map, A key, IF0 create) { B b = map.get(key); if (b == null) mapPut(map, key, b = callF(create)); return b; } static public List javaTokNoQuotes(String s) { return quotelessJavaTok(s); } static public boolean containsNewLine(String s) { return contains(s, '\n'); } static public String agiBlue_lookupInSlice(String sliceID, String q, String... keys) { return first((List) loadJSONPage(printHidingCredentials(agiBlue_linkForPhrase(q, paramsPlus(paramsWithSameKey("get", keys), "slice", sliceID))))); } static public ThreadLocal>> agiBlue_postInSlice_queue = new ThreadLocal(); static public String agiBlue_postInSlice(String slice, String a, String b, String c) { List> queue = agiBlue_postInSlice_queue.get(); if (queue != null) { queue.add(ll(slice, a, b, c)); return "Queued"; } else return loadPage(agiBlueURL() + "/bot/post" + hquery("slice", slice, "q", a, "key", b, "value", c)); } static public void newPing() { var tl = newPing_actionTL(); Runnable action = tl == null ? null : tl.get(); { if (action != null) action.run(); } } static public boolean isAWTThread() { if (isAndroid()) return false; if (isHeadless()) return false; return isAWTThread_awt(); } static public boolean isAWTThread_awt() { return SwingUtilities.isEventDispatchThread(); } static public void failIfUnlicensed() { assertTrue("license off", licensed()); } static public String shortenSnippetID(String snippetID) { if (snippetID.startsWith("#")) snippetID = snippetID.substring(1); String httpBlaBla = "http://tinybrain.de/"; if (snippetID.startsWith(httpBlaBla)) snippetID = snippetID.substring(httpBlaBla.length()); return "" + parseLong(snippetID); } static public String formatSnippetIDOpt(String s) { return isSnippetID(s) ? formatSnippetID(s) : s; } static public String formatSnippetID(String id) { return "#" + parseSnippetID(id); } static public String formatSnippetID(long id) { return "#" + id; } static public Class getMainClass() { return mc(); } static public Class getMainClass(Object o) { try { if (o == null) return null; if (o instanceof Class && eq(((Class) o).getName(), "x30")) return (Class) o; ClassLoader cl = (o instanceof Class ? (Class) o : o.getClass()).getClassLoader(); if (cl == null) return null; String name = mainClassNameForClassLoader(cl); return loadClassFromClassLoader_orNull(cl, name); } catch (Exception __e) { throw rethrow(__e); } } static public int strL(String s) { return s == null ? 0 : s.length(); } static public int lCharSequence(CharSequence s) { return s == null ? 0 : s.length(); } static public String dropSuffix(String suffix, String s) { return nempty(suffix) && endsWith(s, suffix) ? s.substring(0, l(s) - l(suffix)) : s; } static public int javaTok_n, javaTok_elements; static public boolean javaTok_opt = false; static public List javaTok(String s) { ++javaTok_n; ArrayList tok = new ArrayList(); int l = s == null ? 0 : s.length(); int i = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !regionMatches(s, j, "*/")); j = Math.min(j + 2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(javaTok_substringN(s, i, j)); i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' && Character.isJavaIdentifierStart(d) && i + 2 < l && "'\\".indexOf(s.charAt(i + 2)) < 0) { j += 2; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))) ++j; } else if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { int c2 = s.charAt(j); if (c2 == opener || c2 == '\n' && opener == '\'') { ++j; break; } else if (c2 == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else if (c == '[' && d == '[') { do ++j; while (j < l && !regionMatches(s, j, "]]")); j = Math.min(j + 2, l); } else if (c == '[' && d == '=' && i + 2 < l && s.charAt(i + 2) == '[') { do ++j; while (j + 2 < l && !regionMatches(s, j, "]=]")); j = Math.min(j + 3, l); } else ++j; tok.add(javaTok_substringC(s, i, j)); i = j; } if ((tok.size() % 2) == 0) tok.add(""); javaTok_elements += tok.size(); return tok; } static public List javaTok(List tok) { return javaTokWithExisting(join(tok), tok); } static public int jfind(String s, String in) { return jfind(javaTok(s), in); } static public int jfind(List tok, String in) { return jfind(tok, 1, in); } static public int jfind(List tok, int startIdx, String in) { return jfind(tok, startIdx, in, null); } static public int jfind(List tok, String in, Object condition) { return jfind(tok, 1, in, condition); } static public int jfind(List tok, String in, ITokCondition condition) { return jfind(tok, 1, in, condition); } static public int jfind(List tok, int startIndex, String in, ITokCondition condition) { return jfind(tok, startIndex, in, (Object) condition); } static public int jfind(List tok, int startIdx, String in, Object condition) { return jfind(tok, startIdx, javaTokForJFind_array(in), condition); } static public int jfind(List tok, List tokin) { return jfind(tok, 1, tokin); } static public int jfind(List tok, int startIdx, List tokin) { return jfind(tok, startIdx, tokin, null); } static public int jfind(List tok, int startIdx, String[] tokinC, Object condition) { return findCodeTokens(tok, startIdx, false, tokinC, condition); } static public int jfind(List tok, int startIdx, List tokin, Object condition) { return jfind(tok, startIdx, codeTokensAsStringArray(tokin), condition); } static public List jfind_preprocess(List tok) { for (String type : litlist("quoted", "id", "int")) replaceSublist(tok, ll("<", "", type, "", ">"), ll("<" + type + ">")); replaceSublist(tok, ll("\\", "", "*"), ll("\\*")); return tok; } static public String joinSubList(List l, int i, int j) { return join(subList(l, i, j)); } static public String joinSubList(List l, int i) { return join(subList(l, i)); } static public String formatWithThousandsSeparator(long l) { return NumberFormat.getInstance(new Locale("en_US")).format(l); } static public int max(int a, int b) { return Math.max(a, b); } static public int max(int a, int b, int c) { return max(max(a, b), c); } static public long max(int a, long b) { return Math.max((long) a, b); } static public long max(long a, long b) { return Math.max(a, b); } static public double max(int a, double b) { return Math.max((double) a, b); } static public float max(float a, float b) { return Math.max(a, b); } static public double max(double a, double b) { return Math.max(a, b); } static public int max(Collection c) { int x = Integer.MIN_VALUE; for (int i : c) x = max(x, i); return x; } static public double max(double[] c) { if (c.length == 0) return Double.MIN_VALUE; double x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static public float max(float[] c) { if (c.length == 0) return Float.MAX_VALUE; float x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static public byte max(byte[] c) { byte x = -128; for (byte d : c) if (d > x) x = d; return x; } static public short max(short[] c) { short x = -0x8000; for (short d : c) if (d > x) x = d; return x; } static public int max(int[] c) { int x = Integer.MIN_VALUE; for (int d : c) if (d > x) x = d; return x; } static public > A max(A a, A b) { return cmp(a, b) >= 0 ? a : b; } static public CloseableIterableIterator linesFromFile(File f) { return linesFromFile(f, null); } static public CloseableIterableIterator linesFromFile(File f, IResourceHolder resourceHolder) { try { if (!f.exists()) return emptyCloseableIterableIterator(); if (ewic(f.getName(), ".gz")) return linesFromReader(utf8bufferedReader(newGZIPInputStream(f)), resourceHolder); return linesFromReader(utf8bufferedReader(f), resourceHolder); } catch (Exception __e) { throw rethrow(__e); } } static public CloseableIterableIterator linesFromFile(String path) { return linesFromFile(path, null); } static public CloseableIterableIterator linesFromFile(String path, IResourceHolder resourceHolder) { return linesFromFile(newFile(path), resourceHolder); } static public boolean even(int i) { return (i & 1) == 0; } static public boolean even(long i) { return (i & 1) == 0; } static public boolean even(BigInteger n) { return even(n.intValue()); } static public boolean isLetter(char c) { return Character.isLetter(c); } static public A last(List l) { return empty(l) ? null : l.get(l.size() - 1); } static public char last(String s) { return empty(s) ? '#' : s.charAt(l(s) - 1); } static public int last(int[] a) { return l(a) != 0 ? a[l(a) - 1] : 0; } static public double last(double[] a) { return l(a) != 0 ? a[l(a) - 1] : 0; } static public A last(A[] a) { return l(a) != 0 ? a[l(a) - 1] : null; } static public A last(Iterator it) { A a = null; while (it.hasNext()) { ping(); a = it.next(); } return a; } static public A last(Collection l) { if (l == null) return null; if (l instanceof List) return (A) last((List) l); if (l instanceof SortedSet) return (A) last((SortedSet) l); Iterator it = iterator(l); A a = null; while (it.hasNext()) { ping(); a = it.next(); } return a; } static public A last(SortedSet l) { return l == null ? null : l.last(); } static public boolean regexpFinds(String pat, String s) { return regexp(pat, s).find(); } static public boolean regexpFinds(Pattern pat, String s) { return regexp(pat, s).find(); } static public int[] emptyIntArray_a = new int[0]; static public int[] emptyIntArray() { return emptyIntArray_a; } static public char[] emptyCharArray = new char[0]; static public char[] emptyCharArray() { return emptyCharArray; } static public double[] emptyDoubleArray = new double[0]; static public double[] emptyDoubleArray() { return emptyDoubleArray; } static public Map emptyMap() { return new HashMap(); } static public Object[] emptyObjectArray_a = new Object[0]; static public Object[] emptyObjectArray() { return emptyObjectArray_a; } static public Symbol emptySymbol_value; static public Symbol emptySymbol() { if (emptySymbol_value == null) emptySymbol_value = symbol(""); return emptySymbol_value; } static public int year() { return localYear(); } static public int year(long now) { return localYear(now); } static public int year(long now, TimeZone tz) { return parseInt(simpleDateFormat("y", tz).format(now)); } static public String formatInt(int i, int digits) { return padLeft(str(i), '0', digits); } static public String formatInt(long l, int digits) { return padLeft(str(l), '0', digits); } static public int month() { return localMonth(); } static public int month(long now) { return localMonth(now); } static public int month(long now, TimeZone tz) { return parseInt(simpleDateFormat("M", tz).format(now)); } static public int dayOfMonth() { return localDayOfMonth(); } static public int dayOfMonth(long now) { return localDayOfMonth(now); } static public int dayOfMonth(long now, TimeZone tz) { return parseInt(simpleDateFormat("d", tz).format(now)); } public static File mkdirsForFile(File file) { File dir = file.getParentFile(); if (dir != null) { dir.mkdirs(); if (!dir.isDirectory()) if (dir.isFile()) throw fail("Please delete the file " + f2s(dir) + " - it is supposed to be a directory!"); else throw fail("Unknown IO exception during mkdirs of " + f2s(file)); } return file; } public static String mkdirsForFile(String path) { mkdirsForFile(new File(path)); return path; } static public File getProgramFile(String progID, String fileName) { if (new File(fileName).isAbsolute()) return new File(fileName); return new File(getProgramDir(progID), fileName); } static public File getProgramFile(String fileName) { return getProgramFile(getProgramID(), fileName); } static public FileOutputStream newFileOutputStream(File path) throws IOException { return newFileOutputStream(path.getPath()); } static public FileOutputStream newFileOutputStream(String path) throws IOException { return newFileOutputStream(path, false); } static public FileOutputStream newFileOutputStream(File path, boolean append) throws IOException { return newFileOutputStream(path.getPath(), append); } static public FileOutputStream newFileOutputStream(String path, boolean append) throws IOException { mkdirsForFile(path); FileOutputStream f = new FileOutputStream(path, append); _registerIO(f, path, true); return f; } static public byte[] toUtf8(String s) { try { return s.getBytes(utf8charset()); } catch (Exception __e) { throw rethrow(__e); } } static public long round(double d) { return Math.round(d); } static public String round(String s) { return roundBracket(s); } static public Complex round(Complex c) { return new Complex(round(c.re), round(c.im)); } static public File javaxDataDir_dir; static public File javaxDataDir() { return javaxDataDir_dir != null ? javaxDataDir_dir : new File(userHome(), "JavaX-Data"); } static public File javaxDataDir(String... subs) { return newFile(javaxDataDir(), subs); } static public ThreadLocal> checkFileNotTooBigToRead_tl = new ThreadLocal(); static public void checkFileNotTooBigToRead(File f) { callF(checkFileNotTooBigToRead_tl.get(), f); } static public File newFile(File base, String... names) { for (String name : names) base = new File(base, name); return base; } static public File newFile(String name) { return name == null ? null : new File(name); } static public File newFile(String base, String... names) { return newFile(newFile(base), names); } static public String _userHome; static public String userHome() { if (_userHome == null) return actualUserHome(); return _userHome; } static public File userHome(String path) { return new File(userDir(), path); } static public Random defaultRandomGenerator() { return ThreadLocalRandom.current(); } static public List beginCriticalAction_inFlight = synchroList(); static public class CriticalAction { public String description; public CriticalAction() { } public CriticalAction(String description) { this.description = description; } public void done() { beginCriticalAction_inFlight.remove(this); } } static public CriticalAction beginCriticalAction(String description) { ping(); CriticalAction c = new CriticalAction(description); beginCriticalAction_inFlight.add(c); return c; } static public void cleanMeUp_beginCriticalAction() { int n = 0; while (nempty(beginCriticalAction_inFlight)) { int m = l(beginCriticalAction_inFlight); if (m != n) { n = m; try { print("Waiting for " + n2(n, "critical actions") + ": " + join(", ", collect(beginCriticalAction_inFlight, "description"))); } catch (Throwable __e) { printStackTrace(__e); } } sleepInCleanUp(10); } } static public File copyFile(File src, File dest) { try { FileInputStream inputStream = new FileInputStream(src.getPath()); FileOutputStream outputStream = newFileOutputStream(dest.getPath()); try { copyStream(inputStream, outputStream); inputStream.close(); } finally { outputStream.close(); } return dest; } catch (Exception __e) { throw rethrow(__e); } } static public boolean isString(Object o) { return o instanceof String; } static public boolean isIdentifier(String s) { return isJavaIdentifier(s); } static public Object dm_getService(String serviceName) { return empty(serviceName) ? null : dm_getModule(vmBus_query(assertIdentifier(serviceName))); } static public boolean isStringOrIntOrLong(Object o) { return o instanceof String || o instanceof Integer || o instanceof Long; } static public Object dm_getStemByID(Object id) { return dm_callOS("getModuleByID", str(id)); } static public Object dm_getModule(Object moduleOrID) { if (moduleOrID == null || eq(moduleOrID, "")) return null; if (isString(moduleOrID) && isIdentifier(((String) moduleOrID))) return dm_getService(((String) moduleOrID)); if (isStringOrIntOrLong(moduleOrID)) return dm_callOS("getDynModuleByID", str(moduleOrID)); return dm_resolveModule(moduleOrID); } static public int boolToInt(boolean b) { return b ? 1 : 0; } static public CharSequence subCharSequence(CharSequence s, int x) { return subCharSequence(s, x, s == null ? 0 : s.length()); } static public CharSequence subCharSequence(CharSequence s, int x, int y) { if (s == null) return null; if (x < 0) x = 0; if (x >= s.length()) return ""; if (y < x) y = x; if (y > s.length()) y = s.length(); return s.subSequence(x, y); } static public int min(int a, int b) { return Math.min(a, b); } static public long min(long a, long b) { return Math.min(a, b); } static public float min(float a, float b) { return Math.min(a, b); } static public float min(float a, float b, float c) { return min(min(a, b), c); } static public double min(double a, double b) { return Math.min(a, b); } static public double min(double[] c) { double x = Double.MAX_VALUE; for (double d : c) x = Math.min(x, d); return x; } static public float min(float[] c) { float x = Float.MAX_VALUE; for (float d : c) x = Math.min(x, d); return x; } static public byte min(byte[] c) { byte x = 127; for (byte d : c) if (d < x) x = d; return x; } static public short min(short[] c) { short x = 0x7FFF; for (short d : c) if (d < x) x = d; return x; } static public int min(int[] c) { int x = Integer.MAX_VALUE; for (int d : c) if (d < x) x = d; return x; } static volatile public boolean licensed_yes = true; static public boolean licensed() { if (!licensed_yes) return false; ping_okInCleanUp(); return true; } static public void licensed_off() { licensed_yes = false; } static public AutoCloseable tempActivity(Object r) { return null; } static public long fixTimestamp(long timestamp) { return timestamp > now() ? 0 : timestamp; } static public Object pcallF(Object f, Object... args) { return pcallFunction(f, args); } static public A pcallF(F0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { return null; } } static public B pcallF(F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static public void pcallF(VF1 f, A a) { try { { if (f != null) f.get(a); } } catch (Throwable __e) { printStackTrace(__e); } } static public Object pcallF(Runnable r) { try { { if (r != null) r.run(); } return null; } catch (Throwable __e) { return null; } } static public A pcallF(IF0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { return null; } } static public B pcallF(IF1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static public Object costCenter() { return mc(); } static public double parseDouble(String s) { return empty(s) ? 0.0 : Double.parseDouble(s); } static public Set vm_registeredInstancesSet(Class c) { return c == null ? null : vm_generalWeakSet("Instances of " + c.getName()); } static public Set vm_registeredInstancesSet(String className) { return className == null ? null : vm_generalWeakSet("Instances of " + className); } static public String formatDouble(double d, int digits) { String format = digits <= 0 ? "0" : "0." + rep(digits, '#'); return decimalFormatEnglish(format, d); } static public String formatDouble(double d) { return str(d); } static public Set synchronizedSet() { return synchroHashSet(); } static public Set synchronizedSet(Set set) { return Collections.synchronizedSet(set); } static public int indexOfIgnoreCase(List a, String b) { return indexOfIgnoreCase(a, b, 0); } static public int indexOfIgnoreCase(List a, String b, int i) { int n = a == null ? 0 : a.size(); for (; i < n; i++) if (eqic(a.get(i), b)) return i; return -1; } static public int indexOfIgnoreCase(String[] a, String b) { return indexOfIgnoreCase(a, b, 0); } static public int indexOfIgnoreCase(String[] a, String b, int i) { int n = a == null ? 0 : a.length; for (; i < n; i++) if (eqic(a[i], b)) return i; return -1; } static public int indexOfIgnoreCase(String a, String b) { return indexOfIgnoreCase_manual(a, b); } static public int indexOfIgnoreCase(String a, String b, int i) { return indexOfIgnoreCase_manual(a, b, i); } static public List newSubListOrSame(List l, int startIndex) { return newSubListOrSame(l, startIndex, l(l)); } static public List newSubListOrSame(List l, int startIndex, int endIndex) { if (l == null) return null; int n = l(l); startIndex = max(0, startIndex); endIndex = min(n, endIndex); if (startIndex >= endIndex) return ll(); if (startIndex == 0 && endIndex == n) return l; return cloneList(l.subList(startIndex, endIndex)); } static public int[] takeFirstOfIntArray(int[] b, int n) { return subIntArray(b, 0, n); } static public int[] takeFirstOfIntArray(int n, int[] b) { return takeFirstOfIntArray(b, n); } static public short[] takeFirstOfShortArray(short[] b, int n) { return subShortArray(b, 0, n); } static public short[] takeFirstOfShortArray(int n, short[] b) { return takeFirstOfShortArray(b, n); } static public byte[] takeFirstOfByteArray(byte[] b, int n) { return subByteArray(b, 0, n); } static public byte[] takeFirstOfByteArray(int n, byte[] b) { return takeFirstOfByteArray(b, n); } static public double[] takeFirstOfDoubleArray(double[] b, int n) { return subDoubleArray(b, 0, n); } static public double[] takeFirstOfDoubleArray(int n, double[] b) { return takeFirstOfDoubleArray(b, n); } static public String fsI(String id) { return formatSnippetID(id); } static public String fsI(long id) { return formatSnippetID(id); } static public boolean isImageServerSnippet(long id) { return id >= 1100000 && id < 1200000; } static public String imageServerLink(String md5OrID) { if (possibleMD5(md5OrID)) return "https://botcompany.de/images/md5/" + md5OrID; return imageServerLink(parseSnippetID(md5OrID)); } static public String imageServerLink(long id) { return "https://botcompany.de/images/" + id; } static public TimerTask timerTask(final Object r, final java.util.Timer timer) { return new TimerTask() { public void run() { if (!licensed()) timer.cancel(); else pcallF(r); } }; } static public void dm_reloadModule(Object module) { dm_reloadModuleInBackground(module); } static public void dm_reloadModule() { dm_reloadModuleInBackground(); } static public boolean startsWith(String a, String b) { return a != null && a.startsWith(unnull(b)); } static public boolean startsWith(String a, char c) { return nemptyString(a) && a.charAt(0) == c; } static public boolean startsWith(String a, String b, Matches m) { if (!startsWith(a, b)) return false; if (m != null) m.m = new String[] { substring(a, strL(b)) }; return true; } static public boolean startsWith(List a, List b) { if (a == null || listL(b) > listL(a)) return false; for (int i = 0; i < listL(b); i++) if (neq(a.get(i), b.get(i))) return false; return true; } static public List tok_splitAtVerticalBar(String s) { if (!contains(s, '|')) return ll(s); return splitAtTokens(javaTokPlusBrackets2(s), tok_splitAtVerticalBar_list); } static public List tok_splitAtVerticalBar_list = ll("|"); static public boolean matchX(String pat, String s) { return matchX(pat, s, null); } static public boolean matchX(String pat, String s, Matches m) { if (endsWith(pat, "...")) { pat = dropSuffixTrim("...", pat); if (startsWith(pat, "...")) return find3(dropPrefixTrim("...", pat), s, m); else return matchStart(pat, s, m); } if (startsWith(pat, "...")) return matchEndX(pat, s, m); return match(pat, s, m); } static public String unnullForIteration(String s) { return s == null ? "" : s; } static public Collection unnullForIteration(Collection l) { return l == null ? immutableEmptyList() : l; } static public List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; } static public int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; } static public char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; } static public double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; } static public short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; } static public Map unnullForIteration(Map l) { return l == null ? immutableEmptyMap() : l; } static public Iterable unnullForIteration(Iterable i) { return i == null ? immutableEmptyList() : i; } static public A[] unnullForIteration(A[] a) { return a == null ? (A[]) emptyObjectArray() : a; } static public BitSet unnullForIteration(BitSet b) { return b == null ? new BitSet() : b; } static public Pt unnullForIteration(Pt p) { return p == null ? new Pt() : p; } static public Symbol unnullForIteration(Symbol s) { return s == null ? emptySymbol() : s; } static public Pair unnullForIteration(Pair p) { return p != null ? p : new Pair(null, null); } static public long unnullForIteration(Long l) { return l == null ? 0L : l; } static public boolean addIfNotNull(Collection l, A a) { return a != null && l != null & l.add(a); } static public void addIfNotNull(MultiSet ms, A a) { if (a != null && ms != null) ms.add(a); } static public Map castMapToMapO(Map map) { return map; } static public A oneOf(List l) { return empty(l) ? null : l.get(new Random().nextInt(l.size())); } static public char oneOf(String s) { return empty(s) ? '?' : s.charAt(random(l(s))); } static public String oneOf(String... l) { return oneOf(asList(l)); } static public A collectionGet(Collection c, int idx) { if (c == null || idx < 0 || idx >= l(c)) return null; if (c instanceof List) return listGet((List) c, idx); Iterator it = c.iterator(); for (int i = 0; i < idx; i++) if (it.hasNext()) it.next(); else return null; return it.hasNext() ? it.next() : null; } static public Pair entryToPair(Map.Entry e) { return mapEntryToPair(e); } static public Set> entries(Map map) { return _entrySet(map); } static public boolean networkAllowanceTest(String url) { return isAllowed("networkAllowanceTest", url); } static public String exceptionToStringShort(Throwable e) { lastException(e); e = getInnerException(e); String msg = hideCredentials(unnull(e.getMessage())); if (msg.indexOf("Error") < 0 && msg.indexOf("Exception") < 0) return baseClassName(e) + prependIfNempty(": ", msg); else return msg; } static public void sleepSeconds(double s) { if (s > 0) sleep(round(s * 1000)); } static public String tb_mainServer_default = "https://code.botcompany.de:9898"; static public Object tb_mainServer_override; static public String tb_mainServer() { if (tb_mainServer_override != null) return (String) callF(tb_mainServer_override); return trim(loadTextFile(tb_mainServer_file(), tb_mainServer_default)); } static public File tb_mainServer_file() { return getProgramFile("#1001638", "mainserver.txt"); } static public boolean tb_mainServer_isDefault() { return eq(tb_mainServer(), tb_mainServer_default); } static public Map vm_generalSubMap(Object name) { synchronized (vm_generalMap()) { Map map = (Map) (vm_generalMap_get(name)); if (map == null) vm_generalMap_put(name, map = synchroMap()); return map; } } static public InputStream urlConnection_getInputStream(URLConnection con) throws IOException { return con.getInputStream(); } static public GZIPInputStream newGZIPInputStream(File f) { return gzInputStream(f); } static public GZIPInputStream newGZIPInputStream(InputStream in) { return gzInputStream(in); } static public String unquote(String s) { if (s == null) return null; if (startsWith(s, '[')) { int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; if (i < s.length() && s.charAt(i) == '[') { String m = s.substring(1, i); if (s.endsWith("]" + m + "]")) return s.substring(i + 1, s.length() - i - 1); } } if (s.length() > 1) { char c = s.charAt(0); if (c == '\"' || c == '\'') { int l = endsWith(s, c) ? s.length() - 1 : s.length(); StringBuilder sb = new StringBuilder(l - 1); for (int i = 1; i < l; i++) { char ch = s.charAt(i); if (ch == '\\') { char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1); if (nextChar >= '0' && nextChar <= '7') { String code = "" + nextChar; i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; } } sb.append((char) Integer.parseInt(code, 8)); continue; } switch(nextChar) { case '\"': ch = '\"'; break; case '\\': ch = '\\'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case '\'': ch = '\''; break; case 'u': if (i >= l - 5) { ch = 'u'; break; } int code = Integer.parseInt("" + s.charAt(i + 2) + s.charAt(i + 3) + s.charAt(i + 4) + s.charAt(i + 5), 16); sb.append(Character.toChars(code)); i += 5; continue; default: ch = nextChar; } i++; } sb.append(ch); } return sb.toString(); } } return s; } static public String toHex(byte[] bytes) { return bytesToHex(bytes); } static public String toHex(byte[] bytes, int ofs, int len) { return bytesToHex(bytes, ofs, len); } static public byte[] utf8(String s) { return toUtf8(s); } static public Matcher regexpMatcher(String pat, String s) { return compileRegexp(pat).matcher(unnull(s)); } static public URLConnection openConnection(String url) { try { return openConnection(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static public URLConnection openConnection(URL url) { try { ping(); callOpt(javax(), "recordOpenURLConnection", str(url)); return url.openConnection(); } catch (Exception __e) { throw rethrow(__e); } } static public URLConnection setURLConnectionDefaultTimeouts(URLConnection con, long timeout) { if (con.getConnectTimeout() == 0) { con.setConnectTimeout(toInt(timeout)); if (con.getConnectTimeout() != timeout) print("Warning: URL connect timeout not set by JDK."); } if (con.getReadTimeout() == 0) { con.setReadTimeout(toInt(timeout)); if (con.getReadTimeout() != timeout) print("Warning: URL read timeout not set by JDK."); } return con; } static public String getComputerID_quick() { return computerID(); } static public Object mainBot; static public Object getMainBot() { return mainBot; } static public Object dm_callMyself(String method, Object... args) { return dm_call(dm_current_mandatory_generic(), method, args); } static public A setThreadLocal(ThreadLocal tl, A value) { if (tl == null) return null; A old = tl.get(); tl.set(value); return old; } static public List codeTokens(List tok) { return codeTokensOnly(tok); } static public boolean tagIs(String token, String tag) { if (!startsWith(token, "<")) return false; int l = l(tag); return regionMatchesIC(token, 1, tag, 0, l) && eqOneOf(charAt(token, l + 1), '>', ' '); } static public boolean htmlCheckParams(String tag, Object... params) { return checkFields(htmlgetparams(tag), params); } static public List htmlTok(String s) { return htmlcoarsetok(s); } static public String getHtmlTagParameter(String tag, String key) { return getHtmlTagParameters(tag).get(key); } static public A second(List l) { return get(l, 1); } static public A second(Iterable l) { if (l == null) return null; Iterator it = iterator(l); if (!it.hasNext()) return null; it.next(); return it.hasNext() ? it.next() : null; } static public A second(A[] bla) { return bla == null || bla.length <= 1 ? null : bla[1]; } static public B second(Pair p) { return p == null ? null : p.b; } static public char second(String s) { return charAt(s, 1); } static public B second(Either e) { return e == null ? null : e.bOpt(); } static public int lastIndexOfIgnoreCase_manual(String a, String b) { int la = strL(a), lb = strL(b); if (la < lb) return -1; int n = la - lb; loop: for (int i = n; i >= 0; i--) { for (int j = 0; j < lb; j++) { char c1 = a.charAt(i + j), c2 = b.charAt(j); if (!eqic(c1, c2)) continue loop; } return i; } return -1; } static public boolean isAGIBlueDomain(String domain) { return domainIsUnder(domain, theAGIBlueDomain()); } static public String hostNameFromURL(String url) { try { return empty(url) ? null : new URL(url).getHost(); } catch (Exception __e) { throw rethrow(__e); } } static public List jsonTok(String s) { List tok = new ArrayList(); int l = l(s); int i = 0; while (i < l) { int j = i; char c; String cc; while (j < l) { c = s.charAt(j); cc = s.substring(j, Math.min(j + 2, l)); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (cc.equals("/*")) { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (cc.equals("//")) { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isLetter(c)) do ++j; while (j < l && Character.isLetter(s.charAt(j))); else if (Character.isDigit(c)) do ++j; while (j < l && Character.isDigit(s.charAt(j))); else ++j; tok.add(s.substring(i, j)); i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public Class main() { return getMainClass(); } static public boolean eqOneOf(Object o, Object... l) { for (Object x : l) if (eq(o, x)) return true; return false; } static public Number boxedIntOrLong(long l) { return l != (int) l ? boxed(l) : boxed((int) l); } static public A[] arrayOfSameType(A[] a, int n) { return newObjectArrayOfSameType(a, n); } static public List> findContainerTag(List tok, String tag) { List> l = new ArrayList(); for (int i = 1; i < l(tok); i += 2) if (isOpeningTag(tok.get(i), tag)) { int j, level = 1; for (j = i + 2; j < tok.size(); j += 2) if (isOpeningTag(tok.get(j), tag)) ++level; else if (isTag(tok.get(j), "/" + tag)) { --level; if (level == 0) { l.add(subList(tok, i - 1, j + 2)); break; } } i = j; } return l; } static public List> findContainerTag(String html, String tag) { return findContainerTag(htmlTok(html), tag); } static public List contentsOfContainerTag(List tok) { return tok == null ? null : subList(tok, 2, l(tok) - 2); } static public List contentsOfContainerTag(List tok, String tagName) { return contentsOfContainerTag(first(findContainerTag(tok, tagName))); } static public Class getClass(String name) { return _getClass(name); } static public Class getClass(Object o) { return _getClass(o); } static public Class getClass(Object realm, String name) { return _getClass(realm, name); } static public Object getFirstNonNullField(Object o, String... fields) { for (String field : unnullForIteration(fields)) { Object __1 = getOpt(o, field); if (__1 != null) return __1; } return null; } static public List concatLists(Iterable... lists) { List l = new ArrayList(); if (lists != null) for (Iterable list : lists) addAll(l, list); return l; } static public List concatLists(Collection> lists) { List l = new ArrayList(); if (lists != null) for (Iterable list : lists) addAll(l, list); return l; } static public String className(Object o) { return getClassName(o); } static public void _onJavaXSet() { } static public Object get2(Object o, String field1, String field2) { return get(get(o, field1), field2); } static public boolean startsWithAny(String a, Collection b) { for (String prefix : unnullForIteration(b)) if (startsWith(a, prefix)) return true; return false; } static public boolean startsWithAny(String a, String... b) { if (b != null) for (String prefix : unnullForIteration(b)) if (startsWith(a, prefix)) return true; return false; } static public boolean startsWithAny(String a, Collection b, Matches m) { for (String prefix : unnullForIteration(b)) if (startsWith(a, prefix, m)) return true; return false; } static public String mcDollar() { return mcName() + "$"; } static public String afterDollar(String s) { return substring(s, smartIndexOf(s, '$') + 1); } static volatile public String caseID_caseID; static public String caseID() { return caseID_caseID; } static public void caseID(String id) { caseID_caseID = id; } static public String quoteUnlessIdentifierOrInteger(String s) { return quoteIfNotIdentifierOrInteger(s); } static public String[] drop(int n, String[] a) { n = Math.min(n, a.length); String[] b = new String[a.length - n]; System.arraycopy(a, n, b, 0, b.length); return b; } static public Object[] drop(int n, Object[] a) { n = Math.min(n, a.length); Object[] b = new Object[a.length - n]; System.arraycopy(a, n, b, 0, b.length); return b; } static public ArrayList toList(A[] a) { return asList(a); } static public ArrayList toList(int[] a) { return asList(a); } static public ArrayList toList(Set s) { return asList(s); } static public ArrayList toList(Iterable s) { return asList(s); } static public boolean isDigit(char c) { return Character.isDigit(c); } static public int lastIndexOf(String a, String b) { return a == null || b == null ? -1 : a.lastIndexOf(b); } static public int lastIndexOf(String a, char b) { return a == null ? -1 : a.lastIndexOf(b); } static public int lastIndexOf(List l, int i, A a) { if (l == null) return -1; for (i = min(l(l), i) - 1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } static public int lastIndexOf(List l, A a) { if (l == null) return -1; for (int i = l(l) - 1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } static public void smartSet(Field f, Object o, Object value) throws Exception { try { f.set(o, value); } catch (Exception e) { Class type = f.getType(); if (type == int.class && value instanceof Long) { f.set(o, ((Long) value).intValue()); return; } if (type == boolean.class && value instanceof String) { f.set(o, isTrueOrYes(((String) value))); return; } if (type == LinkedHashMap.class && value instanceof Map) { f.set(o, asLinkedHashMap((Map) value)); return; } try { if (f.getType() == Concept.Ref.class) { f.set(o, ((Concept) o).new Ref((Concept) value)); return; } if (o instanceof Concept.Ref) { f.set(o, ((Concept.Ref) o).get()); return; } } catch (Throwable _e) { } throw e; } } static public boolean odd(int i) { return (i & 1) != 0; } static public boolean odd(long i) { return (i & 1) != 0; } static public boolean odd(BigInteger i) { return odd(toInt(i)); } static public DynModule dm_currentModuleMandatory() { return dm_current_mandatory(); } static public Set syncIdentityHashSet() { return (Set) synchronizedSet(identityHashSet()); } static public AutoCloseable tempAdd(final Collection l, final A a) { if (l == null || l.contains(a)) return null; l.add(a); return new AutoCloseable() { public String toString() { return "l.remove(a);"; } public void close() throws Exception { l.remove(a); } }; } static public A third(List l) { return _get(l, 2); } static public A third(Iterable l) { if (l == null) return null; Iterator it = iterator(l); for (int _repeat_0 = 0; _repeat_0 < 2; _repeat_0++) { if (!it.hasNext()) return null; it.next(); } return it.hasNext() ? it.next() : null; } static public A third(A[] bla) { return bla == null || bla.length <= 2 ? null : bla[2]; } static public VF1 runnableToVF1(final Runnable r) { return r == null ? null : new VF1() { public void get(A a) { try { r.run(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "r.run()"; } }; } static final public Map callOpt_cache = newDangerousWeakHashMap(); static public Object callOpt_cached(Object o, String methodName, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(methodName, args); if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null; return invokeMethod(me, null, args); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(methodName, args); if (me == null) return null; return invokeMethod(me, o, args); } } catch (Exception __e) { throw rethrow(__e); } } static public _MethodCache callOpt_getCache(Class c) { _MethodCache cache = callOpt_cache.get(c); if (cache == null) callOpt_cache.put(c, cache = new _MethodCache(c)); return cache; } static public Object invokeMethod(Method m, Object o, Object... args) { try { try { return m.invoke(o, args); } catch (InvocationTargetException e) { throw rethrow(getExceptionCause(e)); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args))); } } catch (Exception __e) { throw rethrow(__e); } } static public boolean isStaticMethod(Method m) { return methodIsStatic(m); } static public Object[] massageArgsForVarArgsCall(Method m, Object[] args) { Class[] types = m.getParameterTypes(); int n = types.length - 1, nArgs = args.length; if (nArgs < n) return null; for (int i = 0; i < n; i++) if (!argumentCompatibleWithType(args[i], types[i])) return null; Class varArgType = types[n].getComponentType(); for (int i = n; i < nArgs; i++) if (!argumentCompatibleWithType(args[i], varArgType)) return null; Object[] newArgs = new Object[n + 1]; arraycopy(args, 0, newArgs, 0, n); Object[] varArgs = arrayOfType(varArgType, nArgs - n); arraycopy(args, n, varArgs, 0, nArgs - n); newArgs[n] = varArgs; return newArgs; } static public List classNames(Collection l) { return getClassNames(l); } static public List classNames(Object[] l) { return getClassNames(Arrays.asList(l)); } static public PersistableThrowable persistableThrowable(Throwable e) { return e == null ? null : new PersistableThrowable(e); } static public Object pcallF_minimalExceptionHandling(Object f, Object... args) { try { return callFunction(f, args); } catch (Throwable e) { System.out.println(getStackTrace(e)); _storeException(e); } return null; } static public void _handleError(Error e) { call(javax(), "_handleError", e); } static public boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) { return a != null && a.regionMatches(true, offsetA, b, offsetB, len); } static public List javaTokForStructure(String s) { return javaTok_noMLS(s); } static public String structure_addTokenMarkers(String s) { return join(structure_addTokenMarkers(javaTokForStructure(s))); } static public List structure_addTokenMarkers(List tok) { TreeSet refs = new TreeSet(); for (int i = 1; i < l(tok); i += 2) { String t = tok.get(i); if (t.startsWith("t") && isInteger(t.substring(1))) refs.add(parseInt(t.substring(1))); } if (empty(refs)) return tok; for (int i : refs) { int idx = i * 2 + 1; if (idx >= l(tok)) continue; String t = ""; if (endsWithLetterOrDigit(tok.get(idx - 1))) t = " "; tok.set(idx, t + "m" + i + " " + tok.get(idx)); } return tok; } static public String jreplace(String s, String in, String out) { return jreplace(s, in, out, null); } static public String jreplace(String s, String in, String out, Object condition) { List tok = javaTok(s); return jreplace(tok, in, out, condition) ? join(tok) : s; } static public boolean jreplace(List tok, String in, String out) { return jreplace(tok, in, out, false, true, null); } static public boolean jreplace(List tok, String in, String out, Object condition) { return jreplace(tok, in, out, false, true, condition); } static public boolean jreplace(List tok, String in, String out, IF2, Integer, Boolean> condition) { return jreplace(tok, in, out, (Object) condition); } static public boolean jreplace(List tok, String in, String out, boolean ignoreCase, boolean reTok, Object condition) { String[] toks = javaTokForJFind_array(in); int lTokin = toks.length * 2 + 1; boolean anyChange = false; int i = -1; for (int n = 0; n < 10000; n++) { i = findCodeTokens(tok, i + 1, ignoreCase, toks, condition); if (i < 0) return anyChange; List subList = tok.subList(i - 1, i + lTokin - 1); String expansion = jreplaceExpandRefs(out, subList); int end = i + lTokin - 2; clearAllTokens(tok, i, end); tok.set(i, expansion); if (reTok) reTok(tok, i, end); i = end; anyChange = true; } throw fail("woot? 10000! " + quote(in) + " => " + quote(out)); } static public boolean jreplace_debug = false; static public Map mruCache(int maxSize) { return synchronizedMRUCache(maxSize); } static public int defaultStringTransformerCacheSize() { return 1000; } static public List quotelessJavaTok(String s) { ArrayList tok = new ArrayList(); int l = l(s); int i = 0, n = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(javaTok_substringN(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else ++j; tok.add(javaTok_substringC(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public Object loadJSONPage(String url) { return jsonDecode(loadPage(url)); } static public A printHidingCredentials(A o) { print(hideCredentials(str(o))); return o; } static public String agiBlue_linkForPhrase(String phrase, Object... additionalParams) { return agiBlueURL() + hquery(arrayPlus(additionalParams, "q", phrase)); } static public Object[] paramsPlus(Object[] a1, Object... a2) { if (a2 == null) return a1; if (a1 == null) return a2; if (l(a1) == 1 && a1[0] instanceof Map) return new Object[] { mapPlus((Map) a1[0], a2) }; assertEvenLength(a1); assertEvenLength(a2); Map map = paramsToOrderedMap(a1); int n = l(a2); for (int i = 0; i < n; i += 2) { Object key = a2[i]; if (key != null) map.put(key, a2[i + 1]); } return mapToParams(map); } static public Object[] paramsPlus(Map a1, Object... a2) { return paramsPlus(new Object[] { a1 }, a2); } static public Object[] paramsWithSameKey(Object key, Collection values) { return paramsWithSameKey(key, asObjectArray(values)); } static public Object[] paramsWithSameKey(Object key, Object... values) { int n = l(values); Object[] o = new Object[n * 2]; for (int i = 0; i < n; i++) { o[i * 2] = key; o[i * 2 + 1] = values[i]; } return o; } static public boolean agiBlueURL_noHTTPS = false; static public String agiBlueURL_url = "https://agi.blue"; static public String agiBlueURL() { return agiBlueURL_noHTTPS ? replacePrefix("https://", "http://", agiBlueURL_url) : agiBlueURL_url; } static public String hquery(Map params) { return htmlQuery(params); } static public String hquery(Object... data) { return htmlQuery(data); } static public x30_pkg.x30_util.BetterThreadLocal newPing_actionTL; static public x30_pkg.x30_util.BetterThreadLocal newPing_actionTL() { if (newPing_actionTL == null) newPing_actionTL = vm_generalMap_getOrCreate("newPing_actionTL", () -> { Runnable value = (Runnable) (callF_gen(vm_generalMap_get("newPing_valueForNewThread"))); var tl = new x30_pkg.x30_util.BetterThreadLocal(); tl.set(value); return tl; }); return newPing_actionTL; } public static boolean isSnippetID(String s) { try { parseSnippetID(s); return true; } catch (RuntimeException e) { return false; } } static public String mainClassNameForClassLoader(ClassLoader cl) { return or((String) callOpt(cl, "mainClassName"), "main"); } static public Class loadClassFromClassLoader_orNull(ClassLoader cl, String name) { try { return cl == null ? null : cl.loadClass(name); } catch (ClassNotFoundException e) { return null; } } static public boolean regionMatches(String a, int offsetA, String b, int offsetB, int len) { return a != null && b != null && a.regionMatches(offsetA, b, offsetB, len); } static public boolean regionMatches(String a, int offsetA, String b) { return regionMatches(a, offsetA, b, 0, l(b)); } static public String javaTok_substringN(String s, int i, int j) { if (i == j) return ""; if (j == i + 1 && s.charAt(i) == ' ') return " "; return s.substring(i, j); } static public String javaTok_substringC(String s, int i, int j) { return s.substring(i, j); } static public List javaTokWithExisting(String s, List existing) { ++javaTok_n; int nExisting = javaTok_opt && existing != null ? existing.size() : 0; ArrayList tok = existing != null ? new ArrayList(nExisting) : new ArrayList(); int l = s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j)) tok.add(existing.get(n)); else tok.add(javaTok_substringN(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' && Character.isJavaIdentifierStart(d) && i + 2 < l && "'\\".indexOf(s.charAt(i + 2)) < 0) { j += 2; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))) ++j; } else if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else if (c == '[' && d == '[') { do ++j; while (j + 1 < l && !s.substring(j, j + 2).equals("]]")); j = Math.min(j + 2, l); } else if (c == '[' && d == '=' && i + 2 < l && s.charAt(i + 2) == '[') { do ++j; while (j + 2 < l && !s.substring(j, j + 3).equals("]=]")); j = Math.min(j + 3, l); } else ++j; if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j)) tok.add(existing.get(n)); else tok.add(javaTok_substringC(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); javaTok_elements += tok.size(); return tok; } static public boolean javaTokWithExisting_isCopyable(String t, String s, int i, int j) { return t.length() == j - i && s.regionMatches(i, t, 0, j - i); } static public Map javaTokForJFind_array_cache = synchronizedMRUCache(1000); static public String[] javaTokForJFind_array(String s) { String[] tok = javaTokForJFind_array_cache.get(s); if (tok == null) javaTokForJFind_array_cache.put(s, tok = codeTokensAsStringArray(jfind_preprocess(javaTok(s)))); return tok; } static public int findCodeTokens(List tok, String... tokens) { return findCodeTokens(tok, 1, false, tokens); } static public int findCodeTokens(List tok, boolean ignoreCase, String... tokens) { return findCodeTokens(tok, 1, ignoreCase, tokens); } static public int findCodeTokens(List tok, int startIdx, boolean ignoreCase, String... tokens) { return findCodeTokens(tok, startIdx, ignoreCase, tokens, null); } static public HashSet findCodeTokens_specials = lithashset("*", "", "", "", "\\*"); static public int findCodeTokens_bails, findCodeTokens_nonbails; static public interface findCodeTokens_Matcher { public boolean get(String token); } static public int findCodeTokens(List tok, int startIdx, boolean ignoreCase, String[] tokens, Object condition) { int end = tok.size() - tokens.length * 2 + 2, nTokens = tokens.length; int i = startIdx | 1; if (i >= end) return -1; String firstToken = tokens[0]; if (!ignoreCase && !findCodeTokens_specials.contains(firstToken)) { while (i < end && !firstToken.equals(tok.get(i))) i += 2; } findCodeTokens_Matcher[] matchers = new findCodeTokens_Matcher[nTokens]; for (int j = 0; j < nTokens; j++) { String p = tokens[j]; findCodeTokens_Matcher matcher; if (p.equals("*")) matcher = t -> true; else if (p.equals("")) matcher = t -> isQuoted(t); else if (p.equals("")) matcher = t -> isIdentifier(t); else if (p.equals("")) matcher = t -> isInteger(t); else if (p.equals("\\*")) matcher = t -> t.equals("*"); else if (ignoreCase) matcher = t -> eqic(p, t); else matcher = t -> t.equals(p); matchers[j] = matcher; } outer: for (; i < end; i += 2) { for (int j = 0; j < nTokens; j++) if (!matchers[j].get(tok.get(i + j * 2))) continue outer; if (condition == null || checkTokCondition(condition, tok, i - 1)) return i; } return -1; } static public String[] codeTokensAsStringArray(List tok) { int n = max(0, (l(tok) - 1) / 2); String[] out = new String[n]; for (int i = 0; i < n; i++) out[i] = tok.get(i * 2 + 1); return out; } static public ArrayList litlist(A... a) { ArrayList l = new ArrayList(a.length); for (A x : a) l.add(x); return l; } static public List replaceSublist(List l, List x, List y) { if (x == null) return l; int i = 0; while (true) { i = indexOfSubList(l, x, i); if (i < 0) break; replaceSublist(l, i, i + l(x), y); i += l(y); } return l; } static public List replaceSublist(List l, int fromIndex, int toIndex, List y) { int n = y.size(), toIndex_new = fromIndex + n; if (toIndex_new < toIndex) { removeSubList(l, toIndex_new, toIndex); copyListPart(y, 0, l, fromIndex, n); } else { copyListPart(y, 0, l, fromIndex, toIndex - fromIndex); if (toIndex_new > toIndex) l.addAll(toIndex, subList(y, toIndex - fromIndex)); } return l; } static public int cmp(Number a, Number b) { return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue()); } static public int cmp(double a, double b) { return a < b ? -1 : a == b ? 0 : 1; } static public int cmp(int a, int b) { return a < b ? -1 : a == b ? 0 : 1; } static public int cmp(long a, long b) { return a < b ? -1 : a == b ? 0 : 1; } static public int cmp(Object a, Object b) { if (a == null) return b == null ? 0 : -1; if (b == null) return 1; return ((Comparable) a).compareTo(b); } static public CloseableIterableIterator emptyCloseableIterableIterator_instance = new CloseableIterableIterator() { public Object next() { throw fail(); } public boolean hasNext() { return false; } }; static public CloseableIterableIterator emptyCloseableIterableIterator() { return emptyCloseableIterableIterator_instance; } static public boolean ewic(String a, String b) { return endsWithIgnoreCase(a, b); } static public boolean ewic(String a, String b, Matches m) { return endsWithIgnoreCase(a, b, m); } static public CloseableIterableIterator linesFromReader(Reader r) { return linesFromReader(r, null); } static public CloseableIterableIterator linesFromReader(Reader r, IResourceHolder resourceHolder) { final BufferedReader br = bufferedReader(r); return holdResource(resourceHolder, iteratorFromFunction_f0_autoCloseable(new F0() { public String get() { try { return readLineFromReaderWithClose(br); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret readLineFromReaderWithClose(br);"; } }, _wrapIOCloseable(r))); } static public BufferedReader utf8bufferedReader(InputStream in) { try { return in == null ? null : bufferedReader(_registerIOWrap(new InputStreamReader(in, "UTF-8"), in)); } catch (Exception __e) { throw rethrow(__e); } } static public BufferedReader utf8bufferedReader(File f) { try { return utf8bufferedReader(newFileInputStream(f)); } catch (Exception __e) { throw rethrow(__e); } } static public Iterator iterator(Iterable c) { return c == null ? emptyIterator() : c.iterator(); } static public Matcher regexp(String pat, String s) { return regexp(compileRegexp(pat), unnull(s)); } static public Matcher regexp(java.util.regex.Pattern pat, String s) { return pat.matcher(unnull(s)); } static public java.util.regex.Pattern regexp(String pat) { return compileRegexp(pat); } static public WeakHasherMap symbol_map = new WeakHasherMap(new Hasher() { public int hashCode(Symbol symbol) { return symbol.text.hashCode(); } public boolean equals(Symbol a, Symbol b) { if (a == null) return b == null; return b != null && eq(a.text, b.text); } }); static public Symbol symbol(String s) { if (s == null) return null; synchronized (symbol_map) { Symbol symbol = new Symbol(s, true); Symbol existingSymbol = symbol_map.findKey(symbol); if (existingSymbol == null) symbol_map.put(existingSymbol = symbol, true); return existingSymbol; } } static public Symbol symbol(CharSequence s) { if (s == null) return null; if (s instanceof Symbol) return (Symbol) s; if (s instanceof String) return symbol((String) s); return symbol(str(s)); } static public Symbol symbol(Object o) { return symbol((CharSequence) o); } static public int localYear() { return localYear(now()); } static public int localYear(long time) { return parseInt(simpleDateFormat_local("yyyy").format(time)); } static public java.text.SimpleDateFormat simpleDateFormat(String format, TimeZone timeZone) { java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(format); sdf.setTimeZone(timeZone); return sdf; } static public String padLeft(String s, char c, int n) { return rep(c, n - l(s)) + s; } static public String padLeft(String s, int n) { return padLeft(s, ' ', n); } static public int localMonth(long time) { return parseInt(simpleDateFormat_local("MM").format(time)); } static public int localMonth() { return localMonth(now()); } static public int localDayOfMonth(long time) { return parseInt(simpleDateFormat_local("dd").format(time)); } static public int localDayOfMonth() { return localDayOfMonth(now()); } static public String f2s(File f) { return f == null ? null : f.getAbsolutePath(); } static public String f2s(String s) { return f2s(newFile(s)); } static public String f2s(java.nio.file.Path p) { return p == null ? null : f2s(p.toFile()); } static public File getProgramDir() { return programDir(); } static public File getProgramDir(String snippetID) { return programDir(snippetID); } static public void _registerIO(Object object, String path, boolean opened) { } static public Charset utf8charset_cache; static public Charset utf8charset() { if (utf8charset_cache == null) utf8charset_cache = utf8charset_load(); return utf8charset_cache; } static public Charset utf8charset_load() { return Charset.forName("UTF-8"); } static public String roundBracket(String s) { return "(" + s + ")"; } static public String roundBracket(Object s) { return roundBracket(str(s)); } static public String actualUserHome_value; static public String actualUserHome() { if (actualUserHome_value == null) { if (isAndroid()) actualUserHome_value = "/storage/emulated/0/"; else actualUserHome_value = System.getProperty("user.home"); } return actualUserHome_value; } static public File actualUserHome(String sub) { return newFile(new File(actualUserHome()), sub); } static public List collect(Iterable c, String field) { return collectField(c, field); } static public List collect(String field, Iterable c) { return collectField(c, field); } static public void sleepInCleanUp(long ms) { try { if (ms < 0) return; Thread.sleep(ms); } catch (Exception __e) { throw rethrow(__e); } } static public void copyStream(InputStream in, OutputStream out) { try { byte[] buf = new byte[65536]; while (true) { int n = in.read(buf); if (n <= 0) return; out.write(buf, 0, n); } } catch (Exception __e) { throw rethrow(__e); } } static public boolean isJavaIdentifier(String s) { if (empty(s) || !Character.isJavaIdentifierStart(s.charAt(0))) return false; for (int i = 1; i < s.length(); i++) if (!Character.isJavaIdentifierPart(s.charAt(i))) return false; return true; } static public Object vmBus_query(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); { Object __1 = pcallFAll_returnFirstNotNull(vm_busListeners_live(), msg, arg); if (__1 != null) return __1; } return pcallFAll_returnFirstNotNull(vm_busListenersByMessage_live().get(msg), msg, arg); } static public Object vmBus_query(String msg) { return vmBus_query(msg, (Object) null); } static public String assertIdentifier(String s) { return assertIsIdentifier(s); } static public String assertIdentifier(String msg, String s) { return assertIsIdentifier(msg, s); } static public Object dm_callOS(String functionName, Object... args) { return call(dm_os(), functionName, args); } static public Object dm_resolveModule(Object moduleOrStem) { return dm_callOS("resolveModule", moduleOrStem); } static public Object pcallFunction(Object f, Object... args) { try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public Set vm_generalWeakSet(Object name) { synchronized (vm_generalMap()) { Set set = (Set) (vm_generalMap_get(name)); if (set == null) vm_generalMap_put(name, set = newWeakHashSet()); return set; } } static public String rep(int n, char c) { return repeat(c, n); } static public String rep(char c, int n) { return repeat(c, n); } static public List rep(A a, int n) { return repeat(a, n); } static public List rep(int n, A a) { return repeat(n, a); } static public String decimalFormatEnglish(String format, double d) { return decimalFormatEnglish(format).format(d); } static public java.text.DecimalFormat decimalFormatEnglish(String format) { return new java.text.DecimalFormat(format, new java.text.DecimalFormatSymbols(Locale.ENGLISH)); } static public int indexOfIgnoreCase_manual(String a, String b) { return indexOfIgnoreCase_manual(a, b, 0); } static public int indexOfIgnoreCase_manual(String a, String b, int i) { int la = strL(a), lb = strL(b); if (la < lb) return -1; int n = la - lb; loop: for (; i <= n; i++) { for (int j = 0; j < lb; j++) { char c1 = a.charAt(i + j), c2 = b.charAt(j); if (!eqic(c1, c2)) continue loop; } return i; } return -1; } static public int[] subIntArray(int[] b, int start) { return subIntArray(b, start, l(b)); } static public int[] subIntArray(int[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start == 0 && end == l(b)) return b; if (start >= end) return new int[0]; int[] x = new int[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public short[] subShortArray(short[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start == 0 && end == l(b)) return b; if (start >= end) return new short[0]; short[] x = new short[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public byte[] subByteArray(byte[] b, int start) { return subByteArray(b, start, l(b)); } static public byte[] subByteArray(byte[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start == 0 && end == l(b)) return b; if (start >= end) return new byte[0]; byte[] x = new byte[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public double[] subDoubleArray(double[] b, int start) { return subDoubleArray(b, start, l(b)); } static public double[] subDoubleArray(double[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start == 0 && end == l(b)) return b; if (start >= end) return new double[0]; double[] x = new double[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public boolean possibleMD5(String s) { return isMD5(s); } static public void dm_reloadModuleInBackground(Object module) { dm_callOS("reloadModuleInBackground", dm_getStem(module)); } static public void dm_reloadModuleInBackground() { dm_reloadModuleInBackground(dm_current_mandatory_generic()); } static public boolean nemptyString(String s) { return s != null && s.length() > 0; } static public int listL(Collection l) { return l == null ? 0 : l.size(); } static public List splitAtTokens(String s, List tokens) { return splitAtTokens(javaTok(s), tokens); } static public List splitAtTokens(List tok, List tokens) { List l = new ArrayList(); int i = 0; while (i < l(tok)) { int j = indexOfSubList(tok, tokens, i); if (i >= l(tok)) break; if (j < 0) j = l(tok); l.add(trimJoin(tok.subList(i, j))); i = j + l(tokens); } return l; } static public List splitAtTokens(List tok, String... tokens) { List l = new ArrayList(); int i = 0; while (i < l(tok)) { int j = indexOfSubList(tok, tokens, i); if (i >= l(tok)) break; if (j < 0) j = l(tok); l.add(trimJoin(tok.subList(i, j))); i = j + l(tokens); } return l; } static public List javaTokPlusBrackets2(String s) { return tok_combineRoundCurlySquareBrackets_keep(javaTok(s)); } static public String dropSuffixTrim(String suffix, String s) { return dropSuffixAndTrim(suffix, s); } static public boolean dropSuffixTrim(String suffix, String s, Matches m) { if (!endsWith(s, suffix)) return false; m.m = new String[] { dropLast(l(suffix), s) }; return true; } static public boolean find3(String pat, String s) { return find3(pat, s, null); } static public boolean find3(String pat, String s, Matches matches) { return find3(pat, parse3_cachedInput(s), matches); } static public boolean find3(String pat, List toks, Matches matches) { List tokpat = parse3_cachedPattern(pat); String[] m = find2(tokpat, toks); if (m == null) return false; if (matches != null) matches.m = m; return true; } static public String dropPrefixTrim(String prefix, String s) { return trim(dropPrefix(prefix, s)); } static public boolean matchStart(String pat, String s) { return matchStart(pat, s, null); } static public boolean matchStart(String pat, String s, Matches matches) { if (s == null) return false; return matchStart(pat, parse3_cachedInput(s), matches); } static public boolean matchStart(String pat, List toks, Matches matches) { if (toks == null) return false; List tokpat = parse3_cachedPattern(pat); if (toks.size() < tokpat.size()) return false; String[] m = match2(tokpat, toks.subList(0, tokpat.size())); if (m == null) return false; if (matches != null) { matches.m = new String[m.length + 1]; arraycopy(m, matches.m); matches.m[m.length] = joinSubList(toks, tokpat.size(), toks.size()); } return true; } static public boolean matchEndX(String pat, String s, Matches matches) { return matchEnd(dropPrefix("...", pat), s, matches); } static public List immutableEmptyList() { return Collections.emptyList(); } static public short[] emptyShortArray = new short[0]; static public short[] emptyShortArray() { return emptyShortArray; } static public Map immutableEmptyMap() { return Collections.emptyMap(); } static public A listGet(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } static volatile public Object isAllowed_function; static volatile public boolean isAllowed_all = true; static public boolean isAllowed(String askingMethod, Object... args) { Object f = vm_generalMap_get("isAllowed_function"); if (f != null && !isTrue(callF(f, askingMethod, args))) return false; return isAllowed_all || isTrue(callF(isAllowed_function, askingMethod, args)); } static public Throwable getInnerException(Throwable e) { if (e == null) return null; while (e.getCause() != null) e = e.getCause(); return e; } static public Throwable getInnerException(Runnable r) { return getInnerException(getException(r)); } static public String baseClassName(String className) { return substring(className, className.lastIndexOf('.') + 1); } static public String baseClassName(Object o) { return baseClassName(getClassName(o)); } static public String prependIfNempty(String prefix, String s) { return empty(s) ? unnull(s) : prefix + s; } static volatile public boolean sleep_noSleep = false; static public void sleep(long ms) { ping(); if (ms < 0) return; if (isAWTThread() && ms > 100) throw fail("Should not sleep on AWT thread"); try { Thread.sleep(ms); } catch (Exception e) { throw new RuntimeException(e); } } static public void sleep() { try { if (sleep_noSleep) throw fail("nosleep"); print("Sleeping."); sleepQuietly(); } catch (Exception __e) { throw rethrow(__e); } } static public Map vm_generalMap_map; static public Map vm_generalMap() { if (vm_generalMap_map == null) vm_generalMap_map = (Map) get(javax(), "generalMap"); return vm_generalMap_map; } static public Object vm_generalMap_get(Object key) { return vm_generalMap().get(key); } static public Object vm_generalMap_put(Object key, Object value) { return mapPutOrRemove(vm_generalMap(), key, value); } static public int gzInputStream_defaultBufferSize = 65536; static public GZIPInputStream gzInputStream(File f) { try { return gzInputStream(new FileInputStream(f)); } catch (Exception __e) { throw rethrow(__e); } } static public GZIPInputStream gzInputStream(File f, int bufferSize) { try { return gzInputStream(new FileInputStream(f), bufferSize); } catch (Exception __e) { throw rethrow(__e); } } static public GZIPInputStream gzInputStream(InputStream in) { return gzInputStream(in, gzInputStream_defaultBufferSize); } static public GZIPInputStream gzInputStream(InputStream in, int bufferSize) { try { return _registerIOWrap(new GZIPInputStream(in, gzInputStream_defaultBufferSize), in); } catch (Exception __e) { throw rethrow(__e); } } public static String bytesToHex(byte[] bytes) { return bytesToHex(bytes, 0, bytes.length); } public static String bytesToHex(byte[] bytes, int ofs, int len) { StringBuilder stringBuilder = new StringBuilder(len * 2); for (int i = 0; i < len; i++) { String s = "0" + Integer.toHexString(bytes[ofs + i]); stringBuilder.append(s.substring(s.length() - 2, s.length())); } return stringBuilder.toString(); } static public Map compileRegexp_cache = syncMRUCache(10); static public java.util.regex.Pattern compileRegexp(String pat) { java.util.regex.Pattern p = compileRegexp_cache.get(pat); if (p == null) { compileRegexp_cache.put(pat, p = java.util.regex.Pattern.compile(pat)); } return p; } static public Object dm_call(Object moduleOrID, String method, Object... args) { Object mod = dm_getModule(moduleOrID); if (mod == null) return null; AutoCloseable __1 = dm_enter(mod); try { return call_withVarargs(mod, method, args); } finally { _close(__1); } } static public List codeTokensOnly(List tok) { int n = l(tok); List l = emptyList(n / 2); for (int i = 1; i < n; i += 2) l.add(tok.get(i)); return l; } static public char charAt(String s, int i) { return s != null && i >= 0 && i < s.length() ? s.charAt(i) : '\0'; } static public boolean checkFields(Object x, Object... data) { for (int i = 0; i < l(data); i += 2) if (neq(getOpt(x, (String) data[i]), data[i + 1])) return false; return true; } static public Map htmlgetparams(String tag) { return getHtmlTagParameters(tag); } static public List htmlcoarsetok(String s) { List tok = new ArrayList(); int l = s == null ? 0 : s.length(); int i = 0; while (i < l) { int j = i; char c; while (j < l) { if (s.charAt(j) != '<') ++j; else if (s.substring(j, Math.min(j + 4, l)).equals("")); j = Math.min(j + 3, l); } else { char d = charAt(s, j + 1); if (d == '/' || isLetter(d)) break; else ++j; } } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); if (c == '<') { ++j; while (j < l && s.charAt(j) != '>') ++j; if (j < l) ++j; } tok.add(s.substring(i, j)); i = j; } if ((tok.size() & 1) == 0) tok.add(""); return tok; } static public boolean getHtmlTagParameters_debug = false; static public Map getHtmlTagParameters(String tag) { if (empty(tag)) return null; List tok = codeTokens(tok_joinMinusIdentifiers(htmlFineTok(tag))); if (getHtmlTagParameters_debug) printStruct(tok); assertEquals("<", tok.get(0)); int i = 1; if (eq(tok.get(1), "/")) ++i; String name = tok.get(i++); if (!isMinusIdentifier(name)) throw fail(tag + " (" + name + ")"); Map map = new HashMap(); while (i < l(tok)) { String t = tok.get(i); if (eqOneOf(t, "/", ">")) break; if (!isMinusIdentifier(t)) throw fail(tag + " (" + t + ")"); ++i; String value = "1"; if (eq(tok.get(i), "=")) { ++i; value = htmlunquote(tok.get(i++)); } map.put(t, value); } return map; } static public boolean domainIsUnder(String domain, String mainDomain) { return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain); } static public String theAGIBlueDomain() { return "agi.blue"; } static public Integer boxed(int i) { return i; } static public Long boxed(long l) { return l; } static public A[] newObjectArrayOfSameType(A[] a) { return newObjectArrayOfSameType(a, a.length); } static public A[] newObjectArrayOfSameType(A[] a, int n) { return (A[]) Array.newInstance(a.getClass().getComponentType(), n); } static public boolean isOpeningTag(String token, String tag) { return isTag(token, tag) && !token.endsWith("/>"); } static public boolean isOpeningTag(String token) { return token.startsWith("<") && token.endsWith(">") && !token.endsWith("/>") && isLetter(token.charAt(1)); } static public boolean isTag(String token, String tag) { return token.regionMatches(true, 0, "<" + tag + " ", 0, tag.length() + 2) || token.regionMatches(true, 0, "<" + tag + ">", 0, tag.length() + 2); } static public void addAll(Collection c, Iterable b) { if (c != null && b != null) for (A a : b) c.add(a); } static public boolean addAll(Collection c, Collection b) { return c != null && b != null && c.addAll(b); } static public boolean addAll(Collection c, B... b) { return c != null && b != null && c.addAll(Arrays.asList(b)); } static public Map addAll(Map a, Map b) { if (a != null && b != null) a.putAll(b); return a; } static public String mcName() { return mc().getName(); } static public String quoteIfNotIdentifierOrInteger(String s) { if (s == null) return null; return isJavaIdentifier(s) || isInteger(s) ? s : quote(s); } static public boolean isTrueOrYes(Object o) { return isTrueOpt(o) || o instanceof String && (eqicOneOf(((String) o), "1", "t", "true") || isYes(((String) o))); } static public LinkedHashMap asLinkedHashMap(Map map) { if (map instanceof LinkedHashMap) return (LinkedHashMap) map; LinkedHashMap m = new LinkedHashMap(); if (map != null) synchronized (collectionMutex(map)) { m.putAll(map); } return m; } static public Set identityHashSet() { return Collections.newSetFromMap(new IdentityHashMap()); } static public Throwable getExceptionCause(Throwable e) { Throwable c = e.getCause(); return c != null ? c : e; } static public String joinWithSpace(Iterable c) { return join(" ", c); } static public String joinWithSpace(String... c) { return join(" ", c); } static public boolean methodIsStatic(Method m) { return (m.getModifiers() & Modifier.STATIC) != 0; } static public boolean argumentCompatibleWithType(Object arg, Class type) { return arg == null ? !type.isPrimitive() : isInstanceX(type, arg); } static public void arraycopy(Object[] a, Object[] b) { if (a != null && b != null) arraycopy(a, 0, b, 0, Math.min(a.length, b.length)); } static public void arraycopy(Object src, int srcPos, int destPos, int n) { arraycopy(src, srcPos, src, destPos, n); } static public void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) { if (n != 0) System.arraycopy(src, srcPos, dest, destPos, n); } static public A[] arrayOfType(Class type, int n) { return makeArray(type, n); } static public A[] arrayOfType(int n, Class type) { return arrayOfType(type, n); } static public List getClassNames(Collection l) { List out = new ArrayList(); if (l != null) for (Object o : l) out.add(o == null ? null : getClassName(o)); return out; } static public Object callFunction(Object f, Object... args) { return callF(f, args); } static public Throwable _storeException_value; static public void _storeException(Throwable e) { _storeException_value = e; } static public List javaTok_noMLS(String s) { ArrayList tok = new ArrayList(); int l = s == null ? 0 : s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(javaTok_substringN(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { int c2 = s.charAt(j); if (c2 == opener || c2 == '\n' && opener == '\'') { ++j; break; } else if (c2 == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else ++j; tok.add(javaTok_substringC(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public String jreplaceExpandRefs(String s, List tokref) { if (!contains(s, '$')) return s; List tok = javaTok(s); for (int i = 1; i < l(tok); i += 2) { String t = tok.get(i); if (t.startsWith("$") && isInteger(t.substring(1))) { String x = tokref.get(-1 + parseInt(t.substring(1)) * 2); tok.set(i, x); } else if (t.equals("\\")) { tok.set(i, ""); i += 2; } } return join(tok); } static public void clearAllTokens(List tok) { for (int i = 0; i < tok.size(); i++) tok.set(i, ""); } static public void clearAllTokens(List tok, int i, int j) { for (; i < j; i++) tok.set(i, ""); } static public List reTok(List tok) { replaceCollection(tok, javaTok(tok)); return tok; } static public List reTok(List tok, int i) { return reTok(tok, i, i + 1); } static public List reTok(List tok, int i, int j) { i = max(i & ~1, 0); j = min(l(tok), j | 1); if (i >= j) return tok; List t = javaTok(joinSubList(tok, i, j)); replaceListPart(tok, i, j, t); return tok; } static public Map synchronizedMRUCache(int maxSize) { return synchroMap(new MRUCache(maxSize)); } static public Object[] arrayPlus(Object[] a1, Object... a2) { return concatArrays(a1, a2); } static public Map mapPlus(Map m, Object... data) { m = cloneMap(m); litmap_impl(m, data); return m; } static public Object[] assertEvenLength(Object[] a) { assertTrue(even(l(a))); return a; } static public LinkedHashMap paramsToOrderedMap(Object... params) { return asLinkedHashMap(paramsToMap(params)); } static public Object[] mapToParams(Map map) { return mapToObjectArray(map); } static public Object[] asObjectArray(Collection l) { return toObjectArray(l); } static public String replacePrefix(String prefix, String replacement, String s) { if (!startsWith(s, prefix)) return s; return replacement + substring(s, l(prefix)); } static public String htmlQuery(Map params) { return empty(params) ? "" : "?" + makePostData(params); } static public String htmlQuery(Object... data) { return empty(data) ? "" : "?" + makePostData(data); } static public A vm_generalMap_getOrCreate(Object key, F0 create) { return vm_generalMap_getOrCreate(key, f0ToIF0(create)); } static public A vm_generalMap_getOrCreate(Object key, IF0 create) { Map generalMap = vm_generalMap(); if (generalMap == null) return null; synchronized (generalMap) { A a = (A) (vm_generalMap_get(key)); if (a == null) vm_generalMap_put(key, a = create == null ? null : create.get()); return a; } } static public A callF_gen(F0 f) { return f == null ? null : f.get(); } static public B callF_gen(F1 f, A a) { return f == null ? null : f.get(a); } static public A callF_gen(IF0 f) { return f == null ? null : f.get(); } static public B callF_gen(IF1 f, A a) { return f == null ? null : f.get(a); } static public B callF_gen(A a, IF1 f) { return f == null ? null : f.get(a); } static public C callF_gen(F2 f, A a, B b) { return f == null ? null : f.get(a, b); } static public C callF_gen(IF2 f, A a, B b) { return f == null ? null : f.get(a, b); } static public void callF_gen(VF1 f, A a) { { if (f != null) f.get(a); } } static public void callF_gen(A a, IVF1 f) { { if (f != null) f.get(a); } } static public void callF_gen(IVF1 f, A a) { { if (f != null) f.get(a); } } static public Object callF_gen(Runnable r) { { if (r != null) r.run(); } return null; } static public Object callF_gen(Object f, Object... args) { return callF(f, args); } static public HashSet lithashset(A... items) { HashSet set = new HashSet(); for (A a : items) set.add(a); return set; } static public boolean isQuoted(String s) { if (isNormalQuoted(s)) return true; return isMultilineQuoted(s); } static public boolean checkTokCondition(Object condition, List tok, int i) { if (condition instanceof TokCondition) return ((TokCondition) condition).get(tok, i); return checkCondition(condition, tok, i); } static public int indexOfSubList(List x, List y) { return indexOfSubList(x, y, 0); } static public int indexOfSubList(List x, List y, int i) { outer: for (; i + l(y) <= l(x); i++) { for (int j = 0; j < l(y); j++) if (neq(x.get(i + j), y.get(j))) continue outer; return i; } return -1; } static public int indexOfSubList(List x, A[] y, int i) { outer: for (; i + l(y) <= l(x); i++) { for (int j = 0; j < l(y); j++) if (neq(x.get(i + j), y[j])) continue outer; return i; } return -1; } static public void removeSubList(List l, int from, int to) { if (l != null) subList(l, from, to).clear(); } static public void removeSubList(List l, int from) { if (l != null) subList(l, from).clear(); } static public void copyListPart(List a, int i1, List b, int i2, int n) { if (a == null || b == null) return; for (int i = 0; i < n; i++) b.set(i2 + i, a.get(i1 + i)); } static public boolean endsWithIgnoreCase(String a, String b) { int la = l(a), lb = l(b); return la >= lb && regionMatchesIC(a, la - lb, b, 0, lb); } static public boolean endsWithIgnoreCase(String a, String b, Matches m) { if (!endsWithIgnoreCase(a, b)) return false; if (m != null) m.m = new String[] { substring(a, 0, l(a) - l(b)) }; return true; } static public BufferedReader bufferedReader(Reader r) { return bufferedReader(r, 8192); } static public BufferedReader bufferedReader(Reader r, int bufSize) { if (r == null) return null; return r instanceof BufferedReader ? (BufferedReader) r : _registerIOWrap(new BufferedReader(r, bufSize), r); } static public A holdResource(IResourceHolder holder, A a) { { if (holder != null) holder.add(a); } return a; } static public CloseableIterableIterator iteratorFromFunction_f0_autoCloseable(final F0 f, final AutoCloseable closeable) { class IFF2 extends CloseableIterableIterator { public A a; public boolean done = false; public boolean hasNext() { getNext(); return !done; } public A next() { getNext(); if (done) throw fail(); A _a = a; a = null; return _a; } public void getNext() { if (done || a != null) return; a = f.get(); done = a == null; } public void close() throws Exception { if (closeable != null) closeable.close(); } } ; return new IFF2(); } static public String readLineFromReaderWithClose(BufferedReader r) { try { String s = r.readLine(); if (s == null) r.close(); return s; } catch (Exception __e) { throw rethrow(__e); } } static public AutoCloseable _wrapIOCloseable(final AutoCloseable c) { return c == null ? null : new AutoCloseable() { public String toString() { return "c.close();\r\n _registerIO(c, null, false);"; } public void close() throws Exception { c.close(); _registerIO(c, null, false); } }; } static public A _registerIOWrap(A wrapper, Object wrapped) { return wrapper; } static public FileInputStream newFileInputStream(File path) throws IOException { return newFileInputStream(path.getPath()); } static public FileInputStream newFileInputStream(String path) throws IOException { FileInputStream f = new FileInputStream(path); _registerIO(f, path, true); return f; } static public Iterator emptyIterator() { return Collections.emptyIterator(); } static public SimpleDateFormat simpleDateFormat_local(String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); sdf.setTimeZone(localTimeZone()); return sdf; } static public File programDir_mine; static public File programDir() { return programDir(getProgramID()); } static public File programDir(String snippetID) { boolean me = sameSnippetID(snippetID, programID()); if (programDir_mine != null && me) return programDir_mine; File dir = new File(javaxDataDir(), formatSnippetIDOpt(snippetID)); if (me) { String c = caseID(); if (nempty(c)) dir = newFile(dir, c); } return dir; } static public File programDir(String snippetID, String subPath) { return new File(programDir(snippetID), subPath); } static public List collectField(Iterable c, String field) { List l = new ArrayList(); if (c != null) for (Object a : c) l.add(getOpt(a, field)); return l; } static public List collectField(String field, Iterable c) { return collectField(c, field); } static public Object pcallFAll_returnFirstNotNull(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) { Object __1 = pcallF(f, args); if (__1 != null) return __1; } return null; } static public Object pcallFAll_returnFirstNotNull(Iterator it, Object... args) { while (it.hasNext()) { Object __2 = pcallF(it.next(), args); if (__2 != null) return __2; } return null; } static public String assertIsIdentifier(String s) { if (!isIdentifier(s)) throw fail("Not an identifier: " + quote(s)); return s; } static public String assertIsIdentifier(String msg, String s) { if (!isIdentifier(s)) throw fail(msg + " - Not an identifier: " + quote(s)); return s; } static public Object dm_os() { { Object __1 = vm_generalMap_get("stefansOS"); if (__1 != null) return __1; } return creator(); } static public Set newWeakHashSet() { return synchroWeakHashSet(); } static public String repeat(char c, int n) { n = Math.max(n, 0); char[] chars = new char[n]; for (int i = 0; i < n; i++) chars[i] = c; return new String(chars); } static public List repeat(A a, int n) { n = Math.max(n, 0); List l = new ArrayList(n); for (int i = 0; i < n; i++) l.add(a); return l; } static public List repeat(int n, A a) { return repeat(a, n); } static public boolean isMD5(String s) { return l(s) == 32 && isLowerHexString(s); } static public String trimJoin(List s) { return trim(join(s)); } static public List tok_combineRoundCurlySquareBrackets_keep(List tok) { List l = new ArrayList(); for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i) && eqOneOf(t, "{", "(", "[")) { int j = findEndOfBracketPart2(tok, i); l.add(joinSubList(tok, i, j)); i = j - 1; } else l.add(t); } return l; } static public String dropSuffixAndTrim(String suffix, String s) { return trim(dropSuffix(suffix, s)); } static public Map> parse3_cachedInput_cache = synchronizedMRUCache(1000); static public List parse3_cachedInput(String s) { List tok = parse3_cachedInput_cache.get(s); if (tok == null) parse3_cachedInput_cache.put(s, tok = parse3(s)); return tok; } static public Map> parse3_cachedPattern_cache = synchronizedMRUCache(1000); static synchronized public List parse3_cachedPattern(String s) { List tok = parse3_cachedPattern_cache.get(s); if (tok == null) parse3_cachedPattern_cache.put(s, tok = parse3(s)); return tok; } static public String[] find2(List pat, List tok) { for (int idx = 0; idx < tok.size(); idx += 2) { String[] result = find2(pat, tok, idx); if (result != null) return result; } return null; } static public String[] find2(List pat, List tok, int idx) { if (idx + pat.size() > tok.size()) return null; List result = new ArrayList(); for (int i = 1; i < pat.size(); i += 2) { String p = pat.get(i), t = tok.get(idx + i); if (eq(p, "*")) result.add(t); else if (!p.equalsIgnoreCase(t)) return null; } return toStringArray(result); } static public String dropPrefix(String prefix, String s) { return s == null ? null : s.startsWith(prefix) ? s.substring(l(prefix)) : s; } static public String[] match2(List pat, List tok) { int i = pat.indexOf("..."); if (i < 0) return match2_match(pat, tok); pat = new ArrayList(pat); pat.set(i, "*"); while (pat.size() < tok.size()) { pat.add(i, "*"); pat.add(i + 1, ""); } return match2_match(pat, tok); } static public String[] match2_match(List pat, List tok) { List result = new ArrayList(); if (pat.size() != tok.size()) { return null; } for (int i = 1; i < pat.size(); i += 2) { String p = pat.get(i), t = tok.get(i); if (eq(p, "*")) result.add(t); else if (!equalsIgnoreCase(unquote(p), unquote(t))) return null; } return result.toArray(new String[result.size()]); } static public boolean matchEnd(String pat, String s) { return matchEnd(pat, s, null); } static public boolean matchEnd(String pat, String s, Matches matches) { if (s == null) return false; List tokpat = parse3(pat), toks = parse3(s); if (toks.size() < tokpat.size()) return false; String[] m = match2(tokpat, takeLast(l(tokpat), toks)); if (m == null) return false; if (matches != null) { matches.m = new String[m.length + 1]; arraycopy(m, matches.m); matches.m[m.length] = join(dropLast(l(tokpat), toks)); } return true; } static public Throwable getException(Runnable r) { try { callF(r); return null; } catch (Throwable e) { return e; } } static public Object sleepQuietly_monitor = new Object(); static public void sleepQuietly() { try { assertFalse(isAWTThread()); synchronized (sleepQuietly_monitor) { sleepQuietly_monitor.wait(); } } catch (Exception __e) { throw rethrow(__e); } } static public B mapPutOrRemove(Map map, A key, B value) { if (map != null && key != null) if (value != null) return map.put(key, value); else return map.remove(key); return null; } static public Map syncMRUCache(int size) { return synchroMap(new MRUCache(size)); } static public List tok_joinMinusIdentifiers(List tok) { for (int i = 1; i + 4 < l(tok); i += 2) if (isMinusIdentifier(get(tok, i)) && eq(get(tok, i + 2), "-") && isIdentifier(get(tok, i + 4))) { replaceSublist(tok, i, i + 5, ll(join(subList(tok, i, i + 5)))); i -= 2; } return tok; } static public List htmlFineTok(String s) { List tok = new ArrayList(); int l = s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else break; } tok.add(quickSubstring(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else ++j; tok.add(quickSubstring(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public A printStruct(String prefix, A a) { printStructure(prefix, a); return a; } static public A printStruct(A a) { printStructure(a); return a; } static public A assertEquals(Object x, A y) { return assertEquals("", x, y); } static public A assertEquals(String msg, Object x, A y) { if (assertVerbose()) return assertEqualsVerbose(msg, x, y); if (!(x == null ? y == null : x.equals(y))) throw fail((msg != null ? msg + ": " : "") + y + " != " + x); return y; } static public boolean isMinusIdentifier(String s) { if (empty(s)) return false; if (!Character.isJavaIdentifierStart(s.charAt(0)) && !s.startsWith("-")) return false; for (int i = 1; i < s.length(); i++) if (!Character.isJavaIdentifierPart(s.charAt(i)) && s.charAt(i) != '-') return false; return true; } static public String htmlunquote(String s) { if (s.startsWith("'") && s.endsWith("'") && s.length() >= 2 || s.startsWith("\"") && s.endsWith("\"") && s.length() >= 2) s = s.substring(1, s.length() - 1); return htmldecode(s); } static public boolean isTrueOpt(Object o) { if (o instanceof Boolean) return ((Boolean) o).booleanValue(); return false; } static public boolean isTrueOpt(String field, Object o) { return isTrueOpt(getOpt(field, o)); } static public List isYes_yesses = litlist("y", "yes", "yeah", "y", "yup", "yo", "corect", "sure", "ok", "afirmative"); static public boolean isYes(String s) { return isYes_yesses.contains(collapseWord(toLowerCase(firstWord2(s)))); } static public A[] makeArray(Class type, int n) { return (A[]) Array.newInstance(type, n); } static public void replaceListPart(List l, int i, int j, List l2) { replaceSublist(l, i, j, l2); } static public Object[] concatArrays(Object[]... arrays) { int l = 0; for (Object[] a : arrays) l += l(a); Object[] x = new Object[l]; int i = 0; for (Object[] a : arrays) if (a != null) { System.arraycopy(a, 0, x, i, l(a)); i += l(a); } return x; } static public Object[] mapToObjectArray(Map map) { List l = new ArrayList(); for (Object o : keys(map)) { l.add(o); l.add(map.get(o)); } return toObjectArray(l); } static public Object[] mapToObjectArray(Object f, Collection l) { int n = l(l); Object[] array = new Object[n]; if (n != 0) { Iterator it = iterator(l); for (int i = 0; i < n; i++) array[i] = callF(f, it.next()); } return array; } static public Object[] mapToObjectArray(Object f, Object[] l) { int n = l(l); Object[] array = new Object[n]; for (int i = 0; i < n; i++) array[i] = callF(f, l[i]); return array; } static public Object[] mapToObjectArray(Collection l, IF1 f) { return mapToObjectArray(f, l); } static public Object[] mapToObjectArray(A[] l, IF1 f) { return mapToObjectArray(f, l); } static public Object[] mapToObjectArray(IF1 f, A[] l) { int n = l(l); Object[] array = new Object[n]; for (int i = 0; i < n; i++) array[i] = f.get(l[i]); return array; } static public Object[] mapToObjectArray(IF1 f, Collection l) { int n = l(l); Object[] array = new Object[n]; if (n != 0) { Iterator it = iterator(l); for (int i = 0; i < n; i++) array[i] = callF(f, it.next()); } return array; } static public Object[] toObjectArray(Collection c) { return toObjectArray((Iterable) c); } static public Object[] toObjectArray(Iterable c) { List l = asList(c); return l.toArray(new Object[l.size()]); } static public IF0 f0ToIF0(F0 f) { return f == null ? null : () -> f.get(); } static public boolean isNormalQuoted(String s) { int l = l(s); if (!(l >= 2 && s.charAt(0) == '"' && lastChar(s) == '"')) return false; int j = 1; while (j < l) if (s.charAt(j) == '"') return j == l - 1; else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; return false; } static public boolean isMultilineQuoted(String s) { if (!startsWith(s, "[")) return false; int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; return i < s.length() && s.charAt(i) == '['; } static public boolean checkCondition(Object condition, Object... args) { return isTrue(callF(condition, args)); } static public boolean checkCondition(IF1 condition, A arg) { return isTrue(callF(condition, arg)); } static public TimeZone localTimeZone() { return getTimeZone(standardTimeZone()); } static public boolean sameSnippetID(String a, String b) { if (!isSnippetID(a) || !isSnippetID(b)) return false; return parseSnippetID(a) == parseSnippetID(b); } static public WeakReference creator_class; static public Object creator() { return creator_class == null ? null : creator_class.get(); } static public Set synchroWeakHashSet() { return Collections.newSetFromMap((Map) newWeakHashMap()); } static public boolean isLowerHexString(String s) { for (int i = 0; i < l(s); i++) { char c = s.charAt(i); if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f') { } else return false; } return true; } static public int findEndOfBracketPart2(List cnc, int i) { int j = i + 2, level = 1; while (j < cnc.size()) { if (eqOneOf(cnc.get(j), "{", "(", "[")) ++level; else if (eqOneOf(cnc.get(j), "}", ")", "]")) --level; if (level == 0) return j + 1; ++j; } return cnc.size(); } static public List parse3(String s) { return dropPunctuation(javaTokPlusPeriod(s)); } static public String[] toStringArray(Collection c) { String[] a = new String[l(c)]; Iterator it = c.iterator(); for (int i = 0; i < l(a); i++) a[i] = it.next(); return a; } static public String[] toStringArray(Object o) { if (o instanceof String[]) return (String[]) o; else if (o instanceof Collection) return toStringArray((Collection) o); else throw fail("Not a collection or array: " + getClassName(o)); } static public boolean equalsIgnoreCase(String a, String b) { return eqic(a, b); } static public boolean equalsIgnoreCase(char a, char b) { return eqic(a, b); } static public List takeLast(List l, int n) { return newSubList(l, l(l) - n); } static public List takeLast(int n, List l) { return takeLast(l, n); } static public String takeLast(int n, String s) { return substring(s, l(s) - n); } static public String takeLast(String s, int n) { return substring(s, l(s) - n); } static public void assertFalse(Object o) { if (!(eq(o, false))) throw fail(str(o)); } static public boolean assertFalse(boolean b) { if (b) throw fail("oops"); return b; } static public boolean assertFalse(String msg, boolean b) { if (b) throw fail(msg); return b; } static public String quickSubstring(String s, int i, int j) { if (i == j) return ""; return s.substring(i, j); } static public A printStructure(String prefix, A o) { if (endsWithLetter(prefix)) prefix += ": "; print(prefix + structureForUser(o)); return o; } static public A printStructure(A o) { print(structureForUser(o)); return o; } static public ThreadLocal assertVerbose_value = new ThreadLocal(); static public void assertVerbose(boolean b) { assertVerbose_value.set(b); } static public boolean assertVerbose() { return isTrue(assertVerbose_value.get()); } static public A assertEqualsVerbose(Object x, A y) { assertEqualsVerbose((String) null, x, y); return y; } static public A assertEqualsVerbose(String msg, Object x, A y) { if (!eq(x, y)) { throw fail((nempty(msg) ? msg + ": " : "") + "expected: " + x + ", got: " + y); } else print("OK" + (empty(msg) ? "" : " " + msg) + ": " + (x)); return y; } static public String nullIfEmpty(String s) { return isEmpty(s) ? null : s; } static public Map nullIfEmpty(Map map) { return isEmpty(map) ? null : map; } static public List nullIfEmpty(List l) { return isEmpty(l) ? null : l; } static public String htmldecode(final String input) { if (input == null) return null; final int MIN_ESCAPE = 2; final int MAX_ESCAPE = 6; StringWriter writer = null; int len = input.length(); int i = 1; int st = 0; while (true) { while (i < len && input.charAt(i - 1) != '&') i++; if (i >= len) break; int j = i; while (j < len && j < i + MAX_ESCAPE + 1 && input.charAt(j) != ';') j++; if (j == len || j < i + MIN_ESCAPE || j == i + MAX_ESCAPE + 1) { i++; continue; } if (input.charAt(i) == '#') { int k = i + 1; int radix = 10; final char firstChar = input.charAt(k); if (firstChar == 'x' || firstChar == 'X') { k++; radix = 16; } try { int entityValue = Integer.parseInt(input.substring(k, j), radix); if (writer == null) writer = new StringWriter(input.length()); writer.append(input.substring(st, i - 1)); if (entityValue > 0xFFFF) { final char[] chrs = Character.toChars(entityValue); writer.write(chrs[0]); writer.write(chrs[1]); } else { writer.write(entityValue); } } catch (NumberFormatException ex) { i++; continue; } } else { CharSequence value = htmldecode_lookupMap().get(input.substring(i, j)); if (value == null) { i++; continue; } if (writer == null) writer = new StringWriter(input.length()); writer.append(input.substring(st, i - 1)); writer.append(value); } st = j + 1; i = st; } if (writer != null) { writer.append(input.substring(st, len)); return writer.toString(); } return input; } static public HashMap htmldecode_lookupMap_cache; static public HashMap htmldecode_lookupMap() { if (htmldecode_lookupMap_cache == null) htmldecode_lookupMap_cache = htmldecode_lookupMap_load(); return htmldecode_lookupMap_cache; } static public HashMap htmldecode_lookupMap_load() { var map = new HashMap(); for (CharSequence[] seq : htmldecode_escapes()) map.put(seq[1].toString(), seq[0]); return map; } static public String collapseWord(String s) { if (s == null) return ""; StringBuilder buf = new StringBuilder(); for (int i = 0; i < l(s); i++) if (i == 0 || !charactersEqualIC(s.charAt(i), s.charAt(i - 1))) buf.append(s.charAt(i)); return buf.toString(); } static public List toLowerCase(List strings) { List x = new ArrayList(); for (String s : strings) x.add(s.toLowerCase()); return x; } static public String[] toLowerCase(String[] strings) { String[] x = new String[l(strings)]; for (int i = 0; i < l(strings); i++) x[i] = strings[i].toLowerCase(); return x; } static public String toLowerCase(String s) { return s == null ? "" : s.toLowerCase(); } static public String firstWord2(String s) { s = xltrim(s); if (empty(s)) return ""; if (isLetterOrDigit(first(s))) return takeCharsWhile(__53 -> isLetterOrDigit(__53), s); else return "" + first(s); } static public TimeZone getTimeZone(String name) { return TimeZone.getTimeZone(name); } static public String standardTimeZone_name = "Europe/Berlin"; static public String standardTimeZone() { return standardTimeZone_name; } static public List dropPunctuation_keep = ll("*", "<", ">"); static public List dropPunctuation(List tok) { tok = new ArrayList(tok); for (int i = 1; i < tok.size(); i += 2) { String t = tok.get(i); if (t.length() == 1 && !Character.isLetter(t.charAt(0)) && !Character.isDigit(t.charAt(0)) && !dropPunctuation_keep.contains(t)) { tok.set(i - 1, tok.get(i - 1) + tok.get(i + 1)); tok.remove(i); tok.remove(i); i -= 2; } } return tok; } static public String dropPunctuation(String s) { return join(dropPunctuation(nlTok(s))); } static public List javaTokPlusPeriod(String s) { List tok = new ArrayList(); if (s == null) return tok; int l = s.length(); int i = 0; while (i < l) { int j = i; char c; String cc; while (j < l) { c = s.charAt(j); cc = s.substring(j, Math.min(j + 2, l)); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (cc.equals("/*")) { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (cc.equals("//")) { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); cc = s.substring(i, Math.min(i + 2, l)); if (c == (char) 0x201C || c == (char) 0x201D) c = '"'; if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { char _c = s.charAt(j); if (_c == (char) 0x201C || _c == (char) 0x201D) _c = '"'; if (_c == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } if (j - 1 >= i + 1) { tok.add(opener + s.substring(i + 1, j - 1) + opener); i = j; continue; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); else if (Character.isDigit(c)) do ++j; while (j < l && Character.isDigit(s.charAt(j))); else if (cc.equals("[[")) { do ++j; while (j + 1 < l && !s.substring(j, j + 2).equals("]]")); j = Math.min(j + 2, l); } else if (cc.equals("[=") && i + 2 < l && s.charAt(i + 2) == '[') { do ++j; while (j + 2 < l && !s.substring(j, j + 3).equals("]=]")); j = Math.min(j + 3, l); } else if (s.substring(j, Math.min(j + 3, l)).equals("...")) j += 3; else if (c == '$' || c == '#') do ++j; while (j < l && Character.isDigit(s.charAt(j))); else ++j; tok.add(s.substring(i, j)); i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public List newSubList(List l, int startIndex, int endIndex) { return cloneList(subList(l, startIndex, endIndex)); } static public List newSubList(List l, int startIndex) { return cloneList(subList(l, startIndex)); } static public String appendColonIfNempty(String s) { return empty(s) ? "" : s + ": "; } static public boolean isEmpty(Collection c) { return c == null || c.isEmpty(); } static public boolean isEmpty(CharSequence s) { return s == null || s.length() == 0; } static public boolean isEmpty(Object[] a) { return a == null || a.length == 0; } static public boolean isEmpty(byte[] a) { return a == null || a.length == 0; } static public boolean isEmpty(Map map) { return map == null || map.isEmpty(); } static public String[][] htmldecode_escapes() { return htmldecode_ESCAPES; } static final public String[][] htmldecode_ESCAPES = { { "\"", "quot" }, { "&", "amp" }, { "<", "lt" }, { ">", "gt" }, { "\u00A0", "nbsp" }, { "\u00A1", "iexcl" }, { "\u00A2", "cent" }, { "\u00A3", "pound" }, { "\u00A4", "curren" }, { "\u00A5", "yen" }, { "\u00A6", "brvbar" }, { "\u00A7", "sect" }, { "\u00A8", "uml" }, { "\u00A9", "copy" }, { "\u00AA", "ordf" }, { "\u00AB", "laquo" }, { "\u00AC", "not" }, { "\u00AD", "shy" }, { "\u00AE", "reg" }, { "\u00AF", "macr" }, { "\u00B0", "deg" }, { "\u00B1", "plusmn" }, { "\u00B2", "sup2" }, { "\u00B3", "sup3" }, { "\u00B4", "acute" }, { "\u00B5", "micro" }, { "\u00B6", "para" }, { "\u00B7", "middot" }, { "\u00B8", "cedil" }, { "\u00B9", "sup1" }, { "\u00BA", "ordm" }, { "\u00BB", "raquo" }, { "\u00BC", "frac14" }, { "\u00BD", "frac12" }, { "\u00BE", "frac34" }, { "\u00BF", "iquest" }, { "\u00C0", "Agrave" }, { "\u00C1", "Aacute" }, { "\u00C2", "Acirc" }, { "\u00C3", "Atilde" }, { "\u00C4", "Auml" }, { "\u00C5", "Aring" }, { "\u00C6", "AElig" }, { "\u00C7", "Ccedil" }, { "\u00C8", "Egrave" }, { "\u00C9", "Eacute" }, { "\u00CA", "Ecirc" }, { "\u00CB", "Euml" }, { "\u00CC", "Igrave" }, { "\u00CD", "Iacute" }, { "\u00CE", "Icirc" }, { "\u00CF", "Iuml" }, { "\u00D0", "ETH" }, { "\u00D1", "Ntilde" }, { "\u00D2", "Ograve" }, { "\u00D3", "Oacute" }, { "\u00D4", "Ocirc" }, { "\u00D5", "Otilde" }, { "\u00D6", "Ouml" }, { "\u00D7", "times" }, { "\u00D8", "Oslash" }, { "\u00D9", "Ugrave" }, { "\u00DA", "Uacute" }, { "\u00DB", "Ucirc" }, { "\u00DC", "Uuml" }, { "\u00DD", "Yacute" }, { "\u00DE", "THORN" }, { "\u00DF", "szlig" }, { "\u00E0", "agrave" }, { "\u00E1", "aacute" }, { "\u00E2", "acirc" }, { "\u00E3", "atilde" }, { "\u00E4", "auml" }, { "\u00E5", "aring" }, { "\u00E6", "aelig" }, { "\u00E7", "ccedil" }, { "\u00E8", "egrave" }, { "\u00E9", "eacute" }, { "\u00EA", "ecirc" }, { "\u00EB", "euml" }, { "\u00EC", "igrave" }, { "\u00ED", "iacute" }, { "\u00EE", "icirc" }, { "\u00EF", "iuml" }, { "\u00F0", "eth" }, { "\u00F1", "ntilde" }, { "\u00F2", "ograve" }, { "\u00F3", "oacute" }, { "\u00F4", "ocirc" }, { "\u00F5", "otilde" }, { "\u00F6", "ouml" }, { "\u00F7", "divide" }, { "\u00F8", "oslash" }, { "\u00F9", "ugrave" }, { "\u00FA", "uacute" }, { "\u00FB", "ucirc" }, { "\u00FC", "uuml" }, { "\u00FD", "yacute" }, { "\u00FE", "thorn" }, { "\u00FF", "yuml" }, { "\u2013", "ndash" }, { "\u2018", "lsquo" }, { "\u2019", "rsquo" }, { "\u201D", "rdquo" }, { "\u201C", "ldquo" }, { "\u2014", "mdash" }, { "'", "apos" } }; static public boolean charactersEqualIC(char c1, char c2) { if (c1 == c2) return true; char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); if (u1 == u2) return true; return Character.toLowerCase(u1) == Character.toLowerCase(u2); } static public String xltrim(String s) { int i = 0, n = l(s); while (i < n && contains(" \t\r\n", s.charAt(i))) ++i; return substr(s, i); } static public boolean isLetterOrDigit(char c) { return Character.isLetterOrDigit(c); } static public String takeCharsWhile(String s, Object pred) { int i = 0; while (i < l(s) && isTrue(callF(pred, s.charAt(i)))) ++i; return substring(s, 0, i); } static public String takeCharsWhile(IF1 f, String s) { return takeCharsWhile(s, f); } static public List nlTok(String s) { return javaTokPlusPeriod(s); } static public String substr(String s, int x) { return substring(s, x); } static public String substr(String s, int x, int y) { return substring(s, x, y); } static public interface IResourceHolder { public A add(A a); public Collection takeAll(); } final static public class _MethodCache { final public Class c; final public HashMap> cache = new HashMap(); public _MethodCache(Class c) { this.c = c; _init(); } public void _init() { Class _c = c; while (_c != null) { for (Method m : _c.getDeclaredMethods()) if (!isAbstract(m) && !reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); _c = _c.getSuperclass(); } for (Class intf : allInterfacesImplementedBy(c)) for (Method m : intf.getDeclaredMethods()) if (m.isDefault() && !reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); } public Method findMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } public Method findStaticMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (isStaticMethod(me) && call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } } static abstract public class VF3 { abstract public void get(A a, B b, C c); } static abstract public class VF2 { abstract public void get(A a, B b); } static public class Symbol implements CharSequence { public String text; public Symbol() { } public Symbol(String text, boolean dummy) { this.text = text; } public int hashCode() { return _hashCode(text); } public String toString() { return text; } public boolean equals(Object o) { return this == o; } public int length() { return text.length(); } public char charAt(int index) { return text.charAt(index); } public CharSequence subSequence(int start, int end) { return text.substring(start, end); } } static public interface ITokCondition { public boolean get(List tok, int i); } static abstract public class TokCondition implements ITokCondition { public abstract boolean get(List tok, int i); } static public class IntVar { public int a; public synchronized void set(int v) { if (v != a) { a = v; notifyAll(); } } public synchronized int get() { return a; } synchronized public int waitForValue(int x) { try { while (a != x) wait(); return a; } catch (Exception __e) { throw rethrow(__e); } } } static public class Timestamp implements Comparable, IFieldsToList { public long date; public Timestamp(long date) { this.date = date; } public boolean equals(Object o) { if (!(o instanceof Timestamp)) return false; Timestamp __1 = (Timestamp) o; return date == __1.date; } public int hashCode() { int h = 2059094262; h = boostHashCombine(h, _hashCode(date)); return h; } public Object[] _fieldsToList() { return new Object[] { date }; } public Timestamp() { date = now(); } public long unixDate() { return date; } public String toString() { return formatLocalDateWithSeconds(date); } public int compareTo(Timestamp t) { return t == null ? 1 : cmp(date, t.date); } public Timestamp plus(Seconds seconds) { return plus(seconds == null ? null : seconds.getDouble()); } final public Timestamp plusSeconds(double seconds) { return plus(seconds); } public Timestamp plus(double seconds) { return new Timestamp(date + toMS(seconds)); } public long minus(Timestamp ts) { return unixDate() - ts.unixDate(); } public long sysTime() { return clockTimeToSystemTime(date); } } static public class MRUCache extends LinkedHashMap { public int maxSize = 10; public MRUCache() { } public MRUCache(int maxSize) { this.maxSize = maxSize; } public boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } public Object _serialize() { return ll(maxSize, cloneLinkedHashMap(this)); } static public MRUCache _deserialize(List l) { MRUCache m = new MRUCache(); m.maxSize = (int) first(l); m.putAll((LinkedHashMap) second(l)); return m; } } static public class MultiMap { public Map> data = new HashMap>(); public int fullSize; public MultiMap() { } public MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); } public MultiMap(MultiMap map) { putAll(map); } public MultiMap(Map> data) { this.data = data; } public void put(A key, B value) { synchronized (data) { List list = data.get(key); if (list == null) data.put(key, list = _makeEmptyList()); list.add(value); ++fullSize; } } public void add(A key, B value) { put(key, value); } public void addAll(A key, Collection values) { putAll(key, values); } public void addAllIfNotThere(A key, Collection values) { synchronized (data) { for (B value : values) setPut(key, value); } } public void setPut(A key, B value) { synchronized (data) { if (!containsPair(key, value)) put(key, value); } } public boolean containsPair(A key, B value) { synchronized (data) { return get(key).contains(value); } } public void putAll(Collection keys, B value) { synchronized (data) { for (A key : unnullForIteration(keys)) put(key, value); } } public void putAll(A key, Collection values) { synchronized (data) { if (nempty(values)) getActual(key).addAll(values); } } public void putAll(Iterable> pairs) { synchronized (data) { for (Pair p : unnullForIteration(pairs)) put(p.a, p.b); } } public void removeAll(A key, Collection values) { synchronized (data) { for (B value : values) remove(key, value); } } public List get(A key) { synchronized (data) { List list = data.get(key); return list == null ? Collections.emptyList() : list; } } public List getOpt(A key) { synchronized (data) { return data.get(key); } } public List getAndClear(A key) { synchronized (data) { List l = cloneList(data.get(key)); remove(key); return l; } } public List getActual(A key) { synchronized (data) { List list = data.get(key); if (list == null) data.put(key, list = _makeEmptyList()); return list; } } public void clean(A key) { synchronized (data) { List list = data.get(key); if (list != null && list.isEmpty()) { fullSize -= l(list); data.remove(key); } } } public Set keySet() { synchronized (data) { return data.keySet(); } } public Set keys() { synchronized (data) { return data.keySet(); } } public void remove(A key) { synchronized (data) { fullSize -= l(this.getOpt(key)); data.remove(key); } } final public void remove(Pair p) { removePair(p); } public void removePair(Pair p) { if (p != null) remove(p.a, p.b); } public void remove(A key, B value) { synchronized (data) { List list = data.get(key); if (list != null) { if (list.remove(value)) fullSize--; if (list.isEmpty()) data.remove(key); } } } public void clear() { synchronized (data) { data.clear(); } } public boolean containsKey(A key) { synchronized (data) { return data.containsKey(key); } } public B getFirst(A key) { synchronized (data) { List list = get(key); return list.isEmpty() ? null : list.get(0); } } public void addAll(MultiMap map) { putAll(map); } public void putAll(MultiMap map) { synchronized (data) { for (A key : map.keySet()) putAll(key, map.get(key)); } } public void putAll(Map map) { synchronized (data) { if (map != null) for (Map.Entry e : map.entrySet()) put(e.getKey(), e.getValue()); } } final public int keyCount() { return keysSize(); } public int keysSize() { synchronized (data) { return l(data); } } final public int fullSize() { return size(); } public int size() { synchronized (data) { return fullSize; } } public List reverseGet(B b) { synchronized (data) { List l = new ArrayList(); for (A key : data.keySet()) if (data.get(key).contains(b)) l.add(key); return l; } } public Map> asMap() { synchronized (data) { return cloneMap(data); } } public boolean isEmpty() { synchronized (data) { return data.isEmpty(); } } public List _makeEmptyList() { return new ArrayList(); } public Collection> allLists() { synchronized (data) { return new ArrayList(data.values()); } } public Collection> values() { return allLists(); } public List allValues() { return concatLists(data.values()); } public Object mutex() { return data; } public String toString() { return "mm" + str(data); } } static public interface Hasher { public int hashCode(A a); public boolean equals(A a, A b); } static public class SimpleCircularBuffer { public A[] buffer; public long base; public int size; public SimpleCircularBuffer(int capacity) { buffer = (A[]) new Object[capacity]; } synchronized public void add(A a) { if (size == buffer.length) { --size; ++base; } buffer[(int) ((base + size) % buffer.length)] = a; ++size; } synchronized public A get(long pos) { if (pos < base || pos >= base + size) return null; return buffer[(int) (pos % buffer.length)]; } synchronized public int size() { return size; } synchronized public int capacity() { return buffer.length; } synchronized public boolean isFull() { return size() == capacity(); } public boolean isEmpty() { return size() == 0; } synchronized public long getBase() { return base; } synchronized public A popFirst() { if (isEmpty()) return null; A a = get(base); --size; ++base; return a; } } static abstract public class CloseableIterableIterator extends IterableIterator implements AutoCloseable { public void close() throws Exception { } } static public interface IFieldsToList { public Object[] _fieldsToList(); } static public interface IF2 { public C get(A a, B b); } static public class NotTooOften { public long minDelay; public long lastTime; public NotTooOften() { } public NotTooOften(long minDelay) { this.minDelay = minDelay; } public NotTooOften(double minSeconds) { minDelay = toMS(minSeconds); } final public boolean yo() { return canDoAgain_willDoIfTrue(); } final public boolean get() { return canDoAgain_willDoIfTrue(); } public boolean canDoAgain_willDoIfTrue() { ping(); if (lastTime == 0 || now() >= lastTime + minDelay) { lastTime = now(); return true; } return false; } public void dO(Runnable r) { if (get()) { if (r != null) r.run(); } } } static public interface IVF3 { public void get(A a, B b, C c); } static final public class WeakHasherMap extends AbstractMap implements Map { public Hasher hasher = null; final public boolean keyEquals(Object k1, Object k2) { return (hasher == null ? k1.equals(k2) : hasher.equals(k1, k2)); } final public int keyHashCode(Object k1) { return (hasher == null ? k1.hashCode() : hasher.hashCode(k1)); } final public WeakKey WeakKeyCreate(K k) { if (k == null) return null; else return new WeakKey(k); } final public WeakKey WeakKeyCreate(K k, ReferenceQueue q) { if (k == null) return null; else return new WeakKey(k, q); } final public class WeakKey extends WeakReference { public int hash; public WeakKey(K k) { super(k); hash = keyHashCode(k); } final public WeakKey create(K k) { if (k == null) return null; else return new WeakKey(k); } public WeakKey(K k, ReferenceQueue q) { super(k, q); hash = keyHashCode(k); } final public WeakKey create(K k, ReferenceQueue q) { if (k == null) return null; else return new WeakKey(k, q); } @Override public boolean equals(Object o) { if (o == null) return false; if (this == o) return true; if (!(o.getClass().equals(WeakKey.class))) return false; Object t = this.get(); @SuppressWarnings("unchecked") Object u = ((WeakKey) o).get(); if ((t == null) || (u == null)) return false; if (t == u) return true; return keyEquals(t, u); } @Override public int hashCode() { return hash; } } public HashMap hash; public ReferenceQueue queue = new ReferenceQueue(); @SuppressWarnings("unchecked") final public void processQueue() { WeakKey wk; while ((wk = (WeakKey) queue.poll()) != null) { hash.remove(wk); } } public WeakHasherMap(int initialCapacity, float loadFactor) { hash = new HashMap(initialCapacity, loadFactor); } public WeakHasherMap(int initialCapacity) { hash = new HashMap(initialCapacity); } public WeakHasherMap() { hash = new HashMap(); } public WeakHasherMap(Hasher h) { hash = new HashMap(); hasher = h; } @Override public int size() { return entrySet().size(); } @Override public boolean isEmpty() { return entrySet().isEmpty(); } @Override public boolean containsKey(Object key) { @SuppressWarnings("unchecked") K kkey = (K) key; return hash.containsKey(WeakKeyCreate(kkey)); } @Override public V get(Object key) { @SuppressWarnings("unchecked") K kkey = (K) key; return hash.get(WeakKeyCreate(kkey)); } @Override public V put(K key, V value) { processQueue(); return hash.put(WeakKeyCreate(key, queue), value); } @Override public V remove(Object key) { processQueue(); @SuppressWarnings("unchecked") K kkey = (K) key; return hash.remove(WeakKeyCreate(kkey)); } @Override public void clear() { processQueue(); hash.clear(); } @SuppressWarnings("TypeParameterShadowing") final public class Entry implements Map.Entry { public Map.Entry ent; public K key; public Entry(Map.Entry ent, K key) { this.ent = ent; this.key = key; } @Override public K getKey() { return key; } @Override public V getValue() { return ent.getValue(); } @Override public V setValue(V value) { return ent.setValue(value); } final public boolean keyvalEquals(K o1, K o2) { return (o1 == null) ? (o2 == null) : keyEquals(o1, o2); } final public boolean valEquals(V o1, V o2) { return (o1 == null) ? (o2 == null) : o1.equals(o2); } @SuppressWarnings("NonOverridingEquals") public boolean equals(Map.Entry e) { return (keyvalEquals(key, e.getKey()) && valEquals(getValue(), e.getValue())); } @Override public int hashCode() { V v; return (((key == null) ? 0 : keyHashCode(key)) ^ (((v = getValue()) == null) ? 0 : v.hashCode())); } } final public class EntrySet extends AbstractSet> { public Set> hashEntrySet = hash.entrySet(); @Override public Iterator> iterator() { return new Iterator>() { public Iterator> hashIterator = hashEntrySet.iterator(); public Map.Entry next = null; @Override public boolean hasNext() { while (hashIterator.hasNext()) { Map.Entry ent = hashIterator.next(); WeakKey wk = ent.getKey(); K k = null; if ((wk != null) && ((k = wk.get()) == null)) { continue; } next = new Entry(ent, k); return true; } return false; } @Override public Map.Entry next() { if ((next == null) && !hasNext()) throw new NoSuchElementException(); Map.Entry e = next; next = null; return e; } @Override public void remove() { hashIterator.remove(); } }; } @Override public boolean isEmpty() { return !(iterator().hasNext()); } @Override public int size() { int j = 0; for (Iterator> i = iterator(); i.hasNext(); i.next()) j++; return j; } @Override public boolean remove(Object o) { processQueue(); if (!(o instanceof Map.Entry)) return false; @SuppressWarnings("unchecked") Map.Entry e = (Map.Entry) o; Object ev = e.getValue(); WeakKey wk = WeakKeyCreate(e.getKey()); Object hv = hash.get(wk); if ((hv == null) ? ((ev == null) && hash.containsKey(wk)) : hv.equals(ev)) { hash.remove(wk); return true; } return false; } @Override public int hashCode() { int h = 0; for (Iterator> i = hashEntrySet.iterator(); i.hasNext(); ) { Map.Entry ent = i.next(); WeakKey wk = ent.getKey(); Object v; if (wk == null) continue; h += (wk.hashCode() ^ (((v = ent.getValue()) == null) ? 0 : v.hashCode())); } return h; } } public Set> entrySet = null; @Override public Set> entrySet() { if (entrySet == null) entrySet = new EntrySet(); return entrySet; } public K findKey(Object key) { processQueue(); K kkey = (K) key; WeakKey wkey = WeakKeyCreate(kkey); WeakKey found = hashMap_findKey(hash, wkey); return found == null ? null : found.get(); } } abstract static public class DynServerAwareDiscordBot extends DynDiscordHopper { public Map dataByServer = new HashMap(); public int guildCount; transient public IF0 makeByServer; public void startMe() { super.startMe(); dm_vmBus_onMessage_q("incomingDiscordReaction", new VF1() { public void get(Map map) { try { if (!enabled) return; Object module = map.get("module"); if (!dm_isMe(module)) return; MessageReaction reaction = (MessageReaction) (map.get("reaction")); Guild guild = reaction.getGuild(); if (guild == null) { print("Ignoring reaction without guild"); return; } getByServer(guild).onMessageReaction(map, true); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!enabled) ret;\r\n O module = map.get('module);\r\n if (!dm_isMe(mo..."; } }); dm_vmBus_onMessage_q("discordReactionRemoved", new VF1() { public void get(Map map) { try { if (!enabled) return; Object module = map.get("module"); if (!dm_isMe(module)) return; MessageReaction reaction = (MessageReaction) (map.get("reaction")); Guild guild = reaction.getGuild(); if (guild == null) { print("Ignoring reaction remove without guild"); return; } getByServer(guild).onMessageReaction(map, false); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!enabled) ret;\r\n O module = map.get('module);\r\n if (!dm_isMe(mo..."; } }); } public class ByServer extends DynamicObject { public long guildID; public boolean isGuild = false; transient public Guild guild; public String answer(String s, Map map) { return null; } public boolean setField(String name, Object value) { if (set_trueIfChanged(this, name, value)) return false; { _change(); return true; } } public Member getSelfMember(Guild guild) { return guild.getMember(getSelfUser()); } public void onMessageReaction(Map map, boolean added) { print("onMessageReaction " + added); } } @Override public String answer(String input, Map map) { String __1 = super.answer(input, map); if (!empty(__1)) return __1; long guildID = toLong(map.get("guildID")); Guild guild = (Guild) (map.get("guild")); long id = guildID; print("Guild ID: " + guildID); if (id == 0) { id = toLong(map.get("userID")); print("User ID: " + id); } A data = guild != null ? getByServer(guild) : getByServer(id, id == guildID); Message msg = (Message) (map.get("msg")); if (msg != null && nempty(msg.getAttachments())) return data.answer(input, map); else return lines_rtrim(nempties(map(s -> data.answer(s, map), splitIntoLines(input)))); } public A getByServer(long id, boolean isGuild) { return pairA(getByServer2(id, isGuild)); } public Pair getByServer2(long id, boolean isGuild) { A data; boolean isNew = false; Pair __2 = syncGetOrCreate2(dataByServer, id, makeByServer); data = __2.a; isNew = __2.b; data.isGuild = isGuild; if (isGuild && data.guildID == 0) { data.guildID = id; change(); } if (isNew) { if (data.isGuild) ++guildCount; change(); } return pair(data, isNew); } public A getByServer(Guild guild) { if (guild == null) return null; A a = getByServer(guild.getIdLong(), true); a.guild = guild; return a; } public void start() { try { super.start(); if (guildCount == 0) setField("guildCount", countValuesWhere_sync(dataByServer, "isGuild", true)); } catch (Exception __e) { throw rethrow(__e); } } public int liveGuildCount() { return l(discord.getGuilds()); } public long idForByServer(ByServer bs) { return bs == null ? 0 : toLong(keyForValue_sync(dataByServer, (A) bs)); } public List splitIntoLines(String s) { return tlft(s); } } static public class FixedRateTimer extends java.util.Timer implements AutoCloseable { public FixedRateTimer() { this(false); } public FixedRateTimer(boolean daemon) { this(defaultTimerName(), daemon); } public FixedRateTimer(String name) { this(name, false); } public FixedRateTimer(String name, boolean daemon) { super(name, daemon); _registerTimer(this); } public List entries = synchroList(); static public class Entry implements IFieldsToList { public TimerTask task; public long firstTime; public long period; public Entry() { } public Entry(TimerTask task, long firstTime, long period) { this.period = period; this.firstTime = firstTime; this.task = task; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + task + ", " + firstTime + ", " + period + ")"; } public Object[] _fieldsToList() { return new Object[] { task, firstTime, period }; } } public void scheduleAtFixedRate(TimerTask task, long delay, long period) { entries.add(new Entry(task, now() + delay, period)); super.scheduleAtFixedRate(task, delay, period); } public void cancel() { entries.clear(); super.cancel(); } public int purge() { entries.clear(); return super.purge(); } public FixedRateTimer changeRate(int newPeriod) { Object r = ((SmartTimerTask) first(entries).task).r; cancel(); return doEvery(newPeriod, r); } public void close() { try { cancel(); } catch (Exception __e) { throw rethrow(__e); } } } static public class Fail extends RuntimeException implements IFieldsToList { public Object[] objects; public Fail() { } public Fail(Object... objects) { this.objects = objects; } public Object[] _fieldsToList() { return new Object[] { objects }; } public Fail(Throwable cause, Object... objects) { super(cause); this.objects = objects; } public String toString() { return joinNemptiesWithColon("Fail", commaCombine(getCause(), objects)); } } static public class Pair implements Comparable> { public A a; public B b; public Pair() { } public Pair(A a, B b) { this.b = b; this.a = a; } public int hashCode() { return hashCodeFor(a) + 2 * hashCodeFor(b); } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Pair)) return false; Pair t = (Pair) o; return eq(a, t.a) && eq(b, t.b); } public String toString() { return "<" + a + ", " + b + ">"; } public int compareTo(Pair p) { if (p == null) return 1; int i = ((Comparable) a).compareTo(p.a); if (i != 0) return i; return ((Comparable) b).compareTo(p.b); } } static public class Seconds implements Comparable, IFieldsToList { public double seconds; public Seconds() { } public Seconds(double seconds) { this.seconds = seconds; } public boolean equals(Object o) { if (!(o instanceof Seconds)) return false; Seconds __1 = (Seconds) o; return seconds == __1.seconds; } public int hashCode() { int h = -660217249; h = boostHashCombine(h, _hashCode(seconds)); return h; } public Object[] _fieldsToList() { return new Object[] { seconds }; } final public double get() { return seconds(); } final public double getDouble() { return seconds(); } public double seconds() { return seconds; } public String toString() { return formatDouble(seconds, 3) + " s"; } public int compareTo(Seconds s) { return cmp(seconds, s.seconds); } public Seconds div(double x) { return new Seconds(get() / x); } public Seconds minus(Seconds x) { return new Seconds(get() - x.get()); } } abstract static public class DynDiscordHopper extends DynPrintLogAndEnabled { static public boolean _switchableField_discordToken = true; public String discordToken; public String discordBotName; public long discordBotID; public boolean reactToBots = true; transient public boolean sendToPostedLinesCRUD = true; transient public boolean escapeAtEveryone = false; transient public boolean membersIntent = false; transient public JDA discord; transient public Color discordImageEmbedMysteriousLineColor = colorFromHex("36393f"); transient public List> onPostedInChannel = syncList(); transient public Consumer onQueueError = error -> { AutoCloseable __71 = enter(); try { printStackTrace(error); } finally { _close(__71); } }; public void startDiscord() { if (!discordEnabled()) { print("Not enabled"); return; } vm_cleanPrints(); logModuleOutput(); discord = discordBot40(new ListenerAdapter() { @Override public void onMessageUpdate(MessageUpdateEvent e) { try { AutoCloseable __72 = enter(); try { { if (!discordEnabled() || !licensed()) return; } Message msg = e.getMessage(); long msgID = msg.getIdLong(); User user = e.getAuthor(); long userID = user == null ? 0 : user.getIdLong(); String content = e.getMessage().getContentRaw(); MessageChannel channel = e.getChannel(); long channelID = channel.getIdLong(); String rendered = msgID + ": " + content; vmBus_send("editedDiscordMessage", litmapparams("event", e, "module", dm_me(), "msgID", msgID, "msg", msg, "content", content, "channelID", channelID, "channel", channel, "user", user, "userID", userID)); Object lineConcept = dm_discord_lineForMsgID_unimported(msgID); if (lineConcept == null) return; call(lineConcept, "_setField", "editedText", content); } finally { _close(__72); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onMessageReceived(MessageReceivedEvent e) { try { AutoCloseable __73 = enter(); try { { if (!discordEnabled() || !licensed()) return; } vmBus_send("discord_onMessageReceived", module(), e); User user = e.getAuthor(); if (!reactToUser(user)) { print("Not reacting to user " + user); return; } boolean bot = user.isBot(); long msgID = e.getMessage().getIdLong(); long userID = user.getIdLong(); Guild guild = e.isFromType(ChannelType.TEXT) ? e.getGuild() : null; long guildID = toLong(call(guild, "getIdLong")); Member member = e.getMember(); String userName = member == null ? null : member.getNickname(); if (userName == null && member != null) userName = member.getEffectiveName(); if (userName == null) userName = e.getAuthor().getName(); final Message msg = e.getMessage(); MessageChannel channel = e.getChannel(); long channelID = channel.getIdLong(); boolean isPrivate = e.getChannelType() == ChannelType.PRIVATE; String content = trim(msg.getContentRaw()); print("Msg from " + userName + ": " + content); vmBus_send("incomingDiscordMessage", litmapparams("fromBot", bot, "module", dm_me(), "msgID", msgID, "userID", userID, "userName", userName, "event", e, "guildID", guildID, "guild", guild, "member", member, "msg", msg, "content", content, "isPrivate", isPrivate, "channelID", channelID, "channel", channel)); } finally { _close(__73); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onMessageReactionAdd(MessageReactionAddEvent e) { try { AutoCloseable __74 = enter(); try { { if (!discordEnabled() || !licensed()) return; } MessageReaction r = e.getReaction(); User user = e.getUser(); if (!reactToUser(user)) return; boolean bot = user.isBot(); long msgID = r.getMessageIdLong(); String emoji = r.getReactionEmote().getName(); vmBus_send("incomingDiscordReaction", litmapparams("reaction", r, "fromBot", bot, "user", user, "userID", user.getIdLong(), "module", dm_me(), "msgID", msgID, "emoji", emoji)); } finally { _close(__74); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onMessageReactionRemove(MessageReactionRemoveEvent e) { try { AutoCloseable __75 = enter(); try { { if (!discordEnabled() || !licensed()) return; } MessageReaction r = e.getReaction(); User user = e.getUser(); if (!reactToUser(user)) return; boolean bot = user.isBot(); long msgID = r.getMessageIdLong(); String emoji = r.getReactionEmote().getName(); vmBus_send("discordReactionRemoved", litmapparams("reaction", r, "fromBot", bot, "user", user, "userID", user.getIdLong(), "module", dm_me(), "msgID", msgID, "emoji", emoji)); } finally { _close(__75); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onMessageReactionRemoveAll(MessageReactionRemoveAllEvent e) { try { AutoCloseable __76 = enter(); try { print("TODO: onMessageReactionRemoveAll"); } finally { _close(__76); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onGuildMemberJoin(GuildMemberJoinEvent event) { try { AutoCloseable __77 = enter(); try { print("Got guild join"); { if (!discordEnabled() || !licensed()) return; } print("Join >> getting user ID"); long userID = rcall_long("getIdLong", rcall("getUser", event.getMember())); print("Join >> sending"); vmBus_send("discordGuildJoin", litmapparams("module", dm_me(), "event", event, "userID", userID, "guildID", discord_guildIDFromEvent_gen(event))); } finally { _close(__77); } } catch (Throwable __e) { printStackTrace(__e); } } @Override public void onGuildMemberLeave(GuildMemberLeaveEvent event) { try { AutoCloseable __78 = enter(); try { print("Got guild leave"); { if (!discordEnabled() || !licensed()) return; } long userID = rcall_long("getIdLong", rcall("getUser", event.getMember())); vmBus_send("discordGuildLeave", litmapparams("module", dm_me(), "event", event, "userID", userID)); } finally { _close(__78); } } catch (Throwable __e) { printStackTrace(__e); } } }, "token", discordToken, "membersIntent", membersIntent); dm_registerAs("liveDiscordModule"); dm_vmBus_answerToMessage("activeDiscordTokens", new F0>() { public List get() { try { return ll(discordToken); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret ll(discordToken);"; } }); try { setField("discordBotName", jda_selfUserName(discord)); setField("discordBotID", jda_selfUserID(discord)); } catch (Throwable __e) { printStackTrace(__e); } print("Bot name: " + discordBotName); } public void cleanMeUp() { if (discord != null) { try { print("Shutting down discord"); discord.shutdown(); print("Bot shut down"); } catch (Throwable __e) { printStackTrace(__e); } } discord = null; } public Object userConcept(User user) { String crud = dm_gazelle_linesCRUD(); Object userConcept = dm_call(crud, "uniqUser", user.getIdLong()); dm_call(crud, "cset", userConcept, litobjectarray("name", user.getName())); return userConcept; } public MessageChannel getChannel(long channelID) { return discord.getTextChannelById(channelID); } public void postInChannel(long channelID, String msg) { postInChannel(channelID, msg, null); } public void postInChannel(long channelID, String msg, IVF1 onPost) { if (channelID == 0) return; postInChannel(getChannel(channelID), msg, onPost); } public String uploadFileInChannel(long channelID, File file, String fileName, String msg, IVF1 onPost) { if (channelID == 0) return null; return uploadFileInChannel(getChannel(channelID), file, fileName, msg, onPost); } public void postInChannel(MessageChannel channel, String msg, IVF1 onPost) { String originalMsg = msg; msg = ecapeAndShortenForDiscord(msg); if (empty(msg)) return; String postID = !sendToPostedLinesCRUD ? null : (String) dm_pcall(gazelle_postedLinesCRUD(), "postingLine", channel.getId(), msg); print("Posting in channel " + channel + ": " + msg); pcallFAll(onPostedInChannel, channel, msg); MessageAction a = channel.sendMessage(msg); if (msg != originalMsg) a.addFile(toUtf8(originalMsg), genericTextFileName()); a.queue(m -> msgPosted(m, onPost, postID), onQueueError); } public String genericTextFileName() { return "full-output-" + ymd_minus_hms() + ".txt"; } public void msgPosted(Message m, IVF1 onPost, String postID) { AutoCloseable __79 = enter(); try { if (nempty(postID)) dm_call(gazelle_postedLinesCRUD(), "donePosting", postID, "discord msg " + m.getId()); long msgId = m.getIdLong(); print("I sent msg: " + msgId); pcallF(onPost, m); } finally { _close(__79); } } public void postInChannel(String channel, String msg) { long id = dm_discord_channelID(channel); if (id == 0) throw fail("Channel not found: " + channel); postInChannel(id, msg); } public void postInChannel(MessageChannel channel, String msg) { postInChannel(channel, msg, null); } public void postImage(Map msgMap, String url) { postImage(msgMap, url, ""); } public void postImage(Map msgMap, String url, String description) { postImage((MessageChannel) get("channel", msgMap), url, description); } public void postImage(MessageChannel channel, String url, String description) { print("Posting image: " + url); channel.sendMessage(new EmbedBuilder().setImage(absoluteURL(url)).setDescription(unnull(description)).setColor(discordImageEmbedMysteriousLineColor).build()).queue(null, onQueueError); } public void editMessage(long channelID, long msgID, String text) { getChannel(channelID).editMessageById(str(msgID), text).queue(null, onQueueError); } public void sendPM(long userID, String _text) { String text = ecapeAndShortenForDiscord(_text); if (empty(text)) return; print("Sending PM to " + userID + ": " + text); discord.getUserById(userID).openPrivateChannel().queue(channel -> { channel.sendMessage(text).queue(null, onQueueError); }, onQueueError); print("PM queued"); } public void reply(Map msgMap, String text) { reply(msgMap, text, null); } public void reply(Map msgMap, String text, Object onPost) { if (empty(text = trim(text))) return; postInChannel((MessageChannel) msgMap.get("channel"), text, toIVF1(onPost)); } public void iAmTyping(Map msgMap) { try { ((MessageChannel) msgMap.get("channel")).sendTyping().queue(null, onQueueError); } catch (Throwable __e) { printStackTrace(__e); } } public String startKeepAliveModule() { AutoCloseable __80 = enter(); try { return dm_discord_startKeepAliveModule(module()); } finally { _close(__80); } } public boolean reactToUser(User user) { boolean bot = user.isBot(); if (bot && !reactToBots) return false; if (user.getIdLong() == discordBotID) return false; return true; } public String ecapeAndShortenForDiscord(String s) { if (escapeAtEveryone) s = escapeAtEveryone(s); return shortenForDiscord(s); } public String uploadFileInChannel(MessageChannel channel, File file, String fileName, String msg, IVF1 onPost) { msg = ecapeAndShortenForDiscord(msg); MessageAction a = empty(msg) ? channel.sendFile(file, fileName) : channel.sendMessage(msg).addFile(file, fileName); a.queue(m -> msgPosted(m, onPost, null), onQueueError); return null; } public String uploadFileInChannel(MessageChannel channel, byte[] data, String fileName, String msg, IVF1 onPost) { msg = ecapeAndShortenForDiscord(msg); MessageAction a = empty(msg) ? channel.sendFile(data, fileName) : channel.sendMessage(msg).addFile(data, fileName); a.queue(m -> msgPosted(m, onPost, null), onQueueError); return null; } public String uploadFileInChannel(long channelID, byte[] data, String fileName, String msg, IVF1 onPost) { return uploadFileInChannel(getChannel(channelID), data, fileName, msg, onPost); } public void queue(RestAction action) { action.queue(null, onQueueError); } public boolean discordEnabled() { return enabled; } public boolean printToModule() { return true; } public boolean discordHopperMetaCmdsEnabled = false; public long preferredChannelID; transient public double minutesToKeepRecordedAnswers = 60.0; public List recordedAnswers = syncList(); static public class RecordedAnswer { public long timestamp; public long questionMsgID, answerMsgID, channelID; public String questionText, answerText; public String toString() { return stdToString(this); } } static public boolean _switchableField_verboseEvents = true; transient public boolean verboseEvents = false; transient public List onDiscordStarted = new ArrayList(); transient public List> onDiscordEvent = syncList(); public ListenerAdapter genericListener() { return new ListenerAdapter() { public void onGenericEvent(Event e) { AutoCloseable __1 = enter(); try { if (verboseEvents) print("Discord event: " + e); pcallFAll(onDiscordEvent, e); } finally { _close(__1); } } }; } public void onDiscordEvent(IVF1 e) { onDiscordEvent.add(e); } public void enhanceFrame(Container f) { super.enhanceFrame(f); internalFramePopupMenuItem(f, "Start keep-alive module", runnableThread(new Runnable() { public void run() { try { startKeepAliveModule(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "startKeepAliveModule();"; } })); minFrameSize(f, 300, 300); } public void start() { try { super.start(); startThread("Start", new Runnable() { public void run() { try { AutoCloseable __2 = enter(); try { try { init(); startMe(); } catch (Throwable __e) { printStackTrace(__e); } } finally { _close(__2); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __2 = enter(); try { try {\r\n init();\r\n startMe();\r\n } ca..."; } }); } catch (Exception __e) { throw rethrow(__e); } } public void startMe() { dm_vmBus_onMessage_q("incomingDiscordMessage", new VF1() { public void get(Map map) { try { if (!enabled) return; Object module = map.get("module"); if (!dm_isMe(module)) return; String s = getString("content", map); long channelID = toLong(map.get("channelID")); if (channelID != 0 && preferredChannelID == 0) setField("preferredChannelID", channelID); cleanRecordedAnswers(); String answer = answer(s, map); sendReply(map, answer); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!enabled) ret;\r\n O module = map.get('module);\r\n if (!dm_isMe(mo..."; } }); if (!enabled) return; print("Starting Discord"); startDiscord(); print("Started Discord"); discord.addEventListener(genericListener()); pcallFAll(onDiscordStarted); } public void sendReply(Map map, String answer) { if (empty(answer)) return; cleanRecordedAnswers(); RecordedAnswer a = new RecordedAnswer(); if (minutesToKeepRecordedAnswers > 0) { a.timestamp = now(); a.questionMsgID = getLong("msgID", map); a.channelID = getLong("channelID", map); a.questionText = getString("content", map); a.answerText = answer; print("Recording answer : " + a); recordedAnswers.add(a); change(); } dm_rcall("reply", map.get("module"), map, answer, (IVF1) msg -> { a.answerMsgID = rcall_long("getIdLong", msg); change(); }); } public String answer(String s, Map map) { if (discordHopperMetaCmdsEnabled && eq(s, "!bot count")) return lstr(dm_activeDiscordTokens()); if (eq(s, "!ip address")) return myPublicIP(); List tokens = extractPossibleDiscordTokens(s); for (String token : unnullForIteration(tokens)) { if (getLong("guildID", map) != 0) return "Send tokens only in private messages!!"; String answer = "That's a Discord token!"; if (contains(concatLists((List>) vmBus_queryAll("activeDiscordTokens")), token)) answer += " And I'm there already."; else { answer += " Jumping there!!"; dm_showNewModuleWithParams(dm_moduleLibID(), "discordToken", token); } reply(map, answer); } return null; } public String atSelf() { return discordAt(discordBotID); } public String atExclamSelf() { return discordAtExclam(discordBotID); } public void onDiscordStarted(Runnable r) { onDiscordStarted.add(r); } public User getSelfUser() { return discord.getSelfUser(); } public void init() { dm_watchField("discordToken", new Runnable() { public void run() { try { if (nempty(discordToken) && enabled) dm_reloadModule(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (nempty(discordToken) && enabled) dm_reloadModule()"; } }); dm_reloadOnFieldChange("enabled"); } public void cleanRecordedAnswers() { RecordedAnswer a; boolean change = false; synchronized (recordedAnswers) { while ((a = first(recordedAnswers)) != null && elapsedMinutes_timestamp(a.timestamp) > minutesToKeepRecordedAnswers) { print("Removing old answer: " + a); recordedAnswers.remove(a); } change = true; } if (change) change(); } public JComponent visualize() { JComponent _c = super.visualize(); if (empty(discordToken)) containerAddFirst(buttons, jThreadedButton("Give me a token!", new Runnable() { public void run() { try { AutoCloseable __3 = enter(); try { dm_stringFieldDialog("discordToken"); } finally { _close(__3); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); dm_stringFieldDialog discordToken();"; } })); addToContainer(buttons, jPopDownButton_noText("Export all my data...", runnableThread(new Runnable() { public void run() { try { dm_exportStructureToTextFileDialog(module()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "dm_exportStructureToTextFileDialog(module())"; } }), "Import all my data...", runnableThread(new Runnable() { public void run() { try { dm_importStructureFromTextFileDialog(module()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "dm_importStructureFromTextFileDialog(module())"; } }))); return _c; } public boolean warnOnDelete() { return true; } public String migrateToType(String moduleLibID) { String moduleID = assertNotNull(dm_showNewModuleWithParams(moduleLibID, "discordToken", discordToken)); print("Migrated to new module " + moduleID + ", disabling me"); setEnabled(false); dm_reload(); return moduleID; } } abstract static public class DynPrintLogAndEnabled extends DynPrintLog { public JComponent visualize() { return dm_visualizeWithEnabled(super.visualize()); } volatile public boolean enabled = true; transient public JPanel buttons; transient public SingleComponentPanel scpStretcherControl; public JComponent visualizeWithoutEnabled() { return super.visualize(); } public JComponent dm_visualizeWithEnabled(JComponent main) { return centerAndSouthWithMargins(main, wrapControlArea()); } public JComponent wrapControlArea() { return makeControlArea(); } public JPanel makeControlArea() { if (scpStretcherControl == null) scpStretcherControl = singleComponentPanel(); var cb = makeEnabledCheckBox(); buttons = jrightalignedline(cb); return centerAndEastWithMargin(scpStretcherControl, buttons); } static public JCheckBox makeEnabledCheckBox() { return dm_fieldCheckBox("enabled"); } public void setEnabled(boolean b) { setField("enabled", b); } final public void addControls(Component... components) { addToControlArea(components); } public void addToControlArea(Component... components) { addComponentsFirst(buttons, components); } final public void addControl(Component component) { addButton(component); } public void addButton(Component component) { addComponentsFirst(buttons, component); } public void addControl(Swingable component) { addComponentsFirst(buttons, wrap(component)); } public void setMainControl(JComponent control) { scpSet(scpStretcherControl, control); } } static public boolean isAbstract(Class c) { return (c.getModifiers() & Modifier.ABSTRACT) != 0; } static public boolean isAbstract(Method m) { return (m.getModifiers() & Modifier.ABSTRACT) != 0; } static public boolean reflection_isForbiddenMethod(Method m) { return m.getDeclaringClass() == Object.class && eqOneOf(m.getName(), "finalize", "clone", "registerNatives"); } static public void multiMapPut(Map> map, A a, B b) { List l = map.get(a); if (l == null) map.put(a, l = new ArrayList()); l.add(b); } static public void multiMapPut(MultiMap mm, A key, B value) { if (mm != null && key != null && value != null) mm.put(key, value); } static public Set allInterfacesImplementedBy(Class c) { if (c == null) return null; HashSet set = new HashSet(); allInterfacesImplementedBy_find(c, set); return set; } static public void allInterfacesImplementedBy_find(Class c, Set set) { if (c.isInterface() && !set.add(c)) return; do { for (Class intf : c.getInterfaces()) allInterfacesImplementedBy_find(intf, set); } while ((c = c.getSuperclass()) != null); } static public Method findMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args); } static public boolean findMethod_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static public boolean call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) print("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) { Object arg = args[i]; if (!(arg == null ? !types[i].isPrimitive() : isInstanceX(types[i], arg))) { if (debug) print("Bad parameter " + i + ": " + arg + " vs " + types[i]); return false; } } return true; } static public Method findStaticMethod(Class c, String method, Object... args) { Class _c = c; while (c != null) { for (Method m : c.getDeclaredMethods()) { if (!m.getName().equals(method)) continue; if ((m.getModifiers() & Modifier.STATIC) == 0 || !findStaticMethod_checkArgs(m, args)) continue; return m; } c = c.getSuperclass(); } return null; } static public boolean findStaticMethod_checkArgs(Method m, Object[] args) { Class[] types = m.getParameterTypes(); if (types.length != args.length) return false; for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) return false; return true; } static public String formatLocalDateWithSeconds(long time) { return localDateWithSeconds(time); } static public String formatLocalDateWithSeconds() { return localDateWithSeconds(); } static public BigInteger plus(BigInteger a, BigInteger b) { return a.add(b); } static public BigInteger plus(BigInteger a, long b) { return a.add(bigint(b)); } static public long plus(long a, long b) { return a + b; } static public int plus(int a, int b) { return a + b; } static public float plus(float a, float b) { return a + b; } static public double plus(double a, double b) { return a + b; } static public long clockTimeToSystemTime(long now) { return now == 0 ? 0 : now + clockToSysTimeDiff(); } static public LinkedHashMap cloneLinkedHashMap(Map map) { return map == null ? new LinkedHashMap() : new LinkedHashMap(map); } static public Map putAll(Map a, Map b) { if (a != null && b != null) a.putAll(b); return a; } static public MultiMap putAll(MultiMap a, Map b) { if (a != null) a.putAll((Map) b); return a; } static public Map putAll(Map a, Object... b) { if (a != null) litmap_impl(a, b); return a; } static public void put(Map map, A a, B b) { if (map != null) map.put(a, b); } static public void put(List l, int i, A a) { if (l != null && i >= 0 && i < l(l)) l.set(i, a); } static public A getAndClear(IVar v) { A a = v.get(); v.set(null); return a; } static public Set keySet(Map map) { return map == null ? new HashSet() : map.keySet(); } static public Set keySet(Object map) { return keys((Map) map); } static public Set keySet(MultiSet ms) { return ms.keySet(); } static public Set keySet(MultiMap mm) { return mm.keySet(); } static public int keysSize(MultiMap mm) { return lKeys(mm); } static public A reverseGet(List l, int idx) { if (l == null || idx < 0) return null; int n = l(l); return idx < n ? l.get(n - 1 - idx) : null; } static public Method hashMap_findKey_method; static public A hashMap_findKey(HashMap map, Object key) { try { if (hashMap_findKey_method == null) hashMap_findKey_method = findMethodNamed(HashMap.class, "getNode"); Map.Entry entry = (Map.Entry) hashMap_findKey_method.invoke(map, hashMap_internalHash(key), key); return entry == null ? null : entry.getKey(); } catch (Exception __e) { throw rethrow(__e); } } static public boolean dm_isMe(Object mod) { return dm_getModule(mod) == dm_current_mandatory_generic(); } static public boolean set_trueIfChanged(Object o, String field, Object value) { if (eq(get(o, field), value)) return false; set(o, field, value); return true; } static public boolean set_trueIfChanged(IVar v, A value) { return setVar_trueIfChanged(v, value); } static public List nempties(Collection c) { return filterNempty(c); } static public A pairA(Pair p) { return p == null ? null : p.a; } static public Pair syncGetOrCreate2(Map map, A key, Class c) { try { synchronized (map) { B b = map.get(key); if (b == null) { map.put(key, b = c.newInstance()); return pair(b, true); } return pair(b, false); } } catch (Exception __e) { throw rethrow(__e); } } static public Pair syncGetOrCreate2(Class c, Map map, A key) { return syncGetOrCreate2(map, key, c); } static public Pair syncGetOrCreate2(Map map, A key, F0 f) { try { synchronized (map) { B b = map.get(key); if (b == null) { map.put(key, b = callF(f)); return pair(b, true); } return pair(b, false); } } catch (Exception __e) { throw rethrow(__e); } } static public Pair syncGetOrCreate2(Map map, A key, IF0 f) { try { synchronized (map) { B b = map.get(key); if (b == null) { map.put(key, b = f.get()); return pair(b, true); } return pair(b, false); } } catch (Exception __e) { throw rethrow(__e); } } static public int countValuesWhere_sync(Map map, Object... data) { if (map == null) return 0; synchronized (map) { return countWhere(values(map), data); } } static public A keyForValue_sync(B value, Map map) { return keyForValue_sync(map, value); } static public A keyForValue_sync(Map map, B value) { if (map == null || value == null) return null; synchronized (map) { return keyForValue(map, value); } } static public List tlft(String s) { return toLinesFullTrim(s); } static public List tlft(File f) { return toLinesFullTrim(f); } static public String defaultTimerName_name; static public String defaultTimerName() { if (defaultTimerName_name == null) defaultTimerName_name = "A timer by " + programID(); return defaultTimerName_name; } static public Set _registerTimer_list = newWeakHashSet(); static public void _registerTimer(java.util.Timer timer) { _registerTimer_list.add(timer); } static public void cleanMeUp__registerTimer() { cancelTimers(getAndClearList(_registerTimer_list)); } static public String joinNemptiesWithColon(String... strings) { return joinNempties(": ", strings); } static public String joinNemptiesWithColon(Collection strings) { return joinNempties(": ", strings); } static public String commaCombine(Object... l) { return joinNemptiesWithComma(flattenCollectionsAndArrays(ll(l))); } static public int hashCodeFor(Object a) { return a == null ? 0 : a.hashCode(); } static public int seconds() { return seconds(Calendar.getInstance()); } static public int seconds(Calendar c) { return c.get(Calendar.SECOND); } static public String div(Object contents, Object... params) { return hfulltag("div", contents, params); } static public String div() { return div(""); } static public BigInteger div(BigInteger a, BigInteger b) { return a.divide(b); } static public BigInteger div(BigInteger a, int b) { return a.divide(bigint(b)); } static public Complex div(Complex a, double b) { return new Complex(a.re / b, a.im / b); } static public double div(double a, double b) { return a / b; } static public double div(double a, int b) { return a / b; } static public int div(int a, int b) { return a / b; } static public List minus(Collection a, Object... b) { Set set = asSet(b); List l = new ArrayList(); for (Object s : unnull(a)) if (!set.contains(s)) l.add(s); return l; } static public BigInteger minus(BigInteger a, BigInteger b) { return a.subtract(b); } static public Complex minus(Complex c) { return c == null ? null : complex(-c.re(), -c.im()); } static public List syncList() { return synchroList(); } static public List syncList(List l) { return synchroList(l); } static public String stdToString(Object o) { return standard_toString(o); } static public void pcallFAll(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) pcallF(f, args); } static public void pcallFAll(Iterator it, Object... args) { while (it.hasNext()) pcallF(it.next(), args); } static public void internalFramePopupMenuItem(Container f, final String name, final Object action) { internalFrameTitlePopupMenuItem(((JInternalFrame) f), name, action); } static public Runnable runnableThread(final Runnable r) { return new Runnable() { public void run() { try { startThread(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "startThread(r)"; } }; } static public void minFrameSize(Component c, int w, int h) { minimalFrameSize(c, w, h); } static public Thread startThread(Object runnable) { return startThread(defaultThreadName(), runnable); } static public Thread startThread(String name, Runnable runnable) { runnable = wrapAsActivity(runnable); return startThread(newThread(runnable, name)); } static public Thread startThread(String name, Object runnable) { runnable = wrapAsActivity(runnable); return startThread(newThread(toRunnable(runnable), name)); } static public Thread startThread(Thread t) { _registerThread(t); t.start(); return t; } static public String getString(Map map, Object key) { return map == null ? null : (String) map.get(key); } static public String getString(List l, int idx) { return (String) get(l, idx); } static public String getString(Object o, Object key) { if (o instanceof Map) return getString((Map) o, key); if (key instanceof String) return (String) getOpt(o, (String) key); throw fail("Not a string key: " + getClassName(key)); } static public String getString(String key, Object o) { return getString(o, (Object) key); } static public Object dm_rcall(String method, Object moduleOrID, Object... args) { return dm_call(moduleOrID, method, args); } static public long rcall_long(String method, Object o, Object... args) { return toLong(rcall(method, o, args)); } static public String lstr(Map map) { return str(l(map)); } static public String lstr(Collection c) { return str(l(c)); } static public String lstr(String s) { return str(l(s)); } static public List dm_activeDiscordTokens() { return concatLists((List>) vmBus_queryAll("activeDiscordTokens")); } static public String myPublicIP() { return myFirewallIP(); } static public List extractPossibleDiscordTokens(String s) { return regexpAll(discordTokenRegexp(), s); } static public List vmBus_queryAll(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); List out = new ArrayList(); for (Object o : unnullForIteration(vm_busListeners_live())) addIfNotNull(out, pcallF(o, msg, arg)); for (Object o : unnullForIteration(vm_busListenersByMessage_live().get(msg))) addIfNotNull(out, pcallF(o, msg, arg)); return out; } static public String dm_showNewModuleWithParams(String moduleLibID, Object... params) { String moduleID = dm_makeNewModuleWithParams(moduleLibID, params); dm_showModule(moduleID); return moduleID; } static public String dm_moduleLibID() { return programID() + "/" + shortClassName(dm_current_mandatory_generic()); } static public String dm_moduleLibID(Object mod) { if (mod == null) return null; mod = dm_getModule(mod); if (hasSuperclassShortNamed(mod, "DynModule")) return programID(mod) + "/" + shortClassName(mod); return null; } static public String discordAt(long userID) { return userID == 0 ? "unknown person" : "<@" + userID + ">"; } static public String discordAtExclam(long userID) { return userID == 0 ? "unknown person" : "<@!" + userID + ">"; } static public void dm_watchField(String field, Runnable onChange) { new Dyn_FieldWatcher(dm_current_mandatory(), field, onChange); } static public void dm_reloadOnFieldChange(String... fields) { for (String field : unnullForIteration(fields)) dm_onFieldChange(field, new Runnable() { public void run() { try { dm_reloadModule(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "dm_reloadModule();"; } }); } static public double elapsedMinutes_timestamp(long time) { return toMinutes(now() - time); } static public void containerAddFirst(final Container c, final Component... l) { if (c != null) { swing(() -> { for (int i = 0; i < l(l); i++) c.add(l[i], i); revalidate(c); }); } } static public JButton jThreadedButton(final String text, final Object action) { return swing(new F0() { public JButton get() { try { String text2 = dropPrefix("[disabled] ", text); final JButton btn = new JButton(text2); if (l(text2) < l(text)) btn.setEnabled(false); btn.setToolTipText(btn.getText()); if (action != null) btn.addActionListener(actionListenerInNewThread(action, btn)); return btn; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "S text2 = dropPrefix(\"[disabled] \", text);\r\n final JButton btn = new JButt..."; } }); } static public void dm_stringFieldDialog(final String field, final Object... __) { final DynModule m = dm_current_mandatory(); final String humanized = humanizeFormLabel(field); final JTextField tf = jtextfield(get(m, field)); showFormTitled(or2(stringOptPar(__, "formTitle"), "Set " + humanized), humanized + ":", tf, new Runnable() { public void run() { try { m.setField(field, gtt(tf)); callF(optPar(__, "onSet")); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.setField(field, gtt(tf));\r\n callF(optPar(__, \"onSet\"));"; } }); } static public void addToContainer(Container a, Component... b) { if (a == null) return; { swing(() -> { for (Component c : unnullForIteration(b)) if (c != null) a.add(c); }); } } static public JButton jPopDownButton_noText(final Object... menuParams) { return toolTip("Additional commands", jPopDownButton("", menuParams)); } static public void dm_exportStructureToTextFileDialog(DynModule mod) { inputText("Text file to save data in (" + dm_moduleName(mod) + ")", f2s(dm_structureExportDefaultFile(mod)), new VF1() { public void get(String path) { try { saveTextFileWithInfoBox(newFile(path), javaTokWordWrap(dm_freshModuleStructureWithoutError(mod))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveTextFileWithInfoBox(newFile(path),\r\n javaTokWordWrap(dm_freshModul..."; } }); } static public void dm_importStructureFromTextFileDialog(DynModule mod) { File f = showFileChooserWithDefaultDir("Module data to restore", javaxBackupDir()); if (fileExists(f)) { infoBox("Replacing module with " + f2s(f)); dm_replaceModuleWithStructure(mod, loadTextFile(f)); } } static public A assertNotNull(A a) { assertTrue(a != null); return a; } static public A assertNotNull(String msg, A a) { assertTrue(msg, a != null); return a; } static public A setEnabled(A c, boolean enable) { if (c != null) { swing(() -> { c.setEnabled(enable); }); } return c; } static public A setEnabled(boolean enable, A c) { return setEnabled(c, enable); } static public Method findMethod_cached(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { _MethodCache cache = callOpt_getCache((Class) o); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (isStaticMethod(m) && findMethod_checkArgs(m, args, false)) return m; return null; } else { _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (findMethod_checkArgs(m, args, false)) return m; return null; } } catch (Exception __e) { throw rethrow(__e); } } static public String localDateWithSeconds(long time) { SimpleDateFormat format = simpleDateFormat_local("yyyy/MM/dd HH:mm:ss"); return format.format(time); } static public String localDateWithSeconds() { return localDateWithSeconds(now()); } static public BigInteger bigint(String s) { return new BigInteger(s); } static public BigInteger bigint(long l) { return BigInteger.valueOf(l); } static public long clockToSysTimeDiff() { return sysNow() - now(); } static public int lKeys(MultiMap mm) { return mm == null ? 0 : mm.keysSize(); } static public Method findMethodNamed(Object obj, String method) { if (obj == null) return null; if (obj instanceof Class) return findMethodNamed((Class) obj, method); return findMethodNamed(obj.getClass(), method); } static public Method findMethodNamed(Class c, String method) { while (c != null) { for (Method m : c.getDeclaredMethods()) if (m.getName().equals(method)) { makeAccessible(m); return m; } c = c.getSuperclass(); } return null; } static public int hashMap_internalHash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } static public boolean setVar_trueIfChanged(IVar v, A value) { if (v == null) return false; synchronized (v) { if (eq(v.get(), value)) return false; v.set(value); return true; } } static public List filterNempty(Collection c) { List l = new ArrayList(); for (String x : unnull(c)) if (nempty(x)) l.add(x); return l; } static public int countWhere(Collection c, Object... data) { int n = 0; if (c != null) for (Object x : c) if (checkFields(x, data)) ++n; return n; } static public A keyForValue(B value, Map map) { return reverseLookup(value, map); } static public A keyForValue(Map map, B value) { return reverseLookup(map, value); } static public List toLinesFullTrim(String s) { List l = new ArrayList(); for (String line : toLines(s)) if (nempty(line = trim(line))) l.add(line); return l; } static public List toLinesFullTrim(File f) { List l = new ArrayList(); for (String line : linesFromFile(f)) if (nempty(line = trim(line))) l.add(line); return l; } static public void cancelTimers(Collection timers) { for (Object timer : timers) cancelTimer(timer); } static public List getAndClearList(Collection l) { if (l == null) return emptyList(); synchronized (collectionMutex(l)) { List out = cloneList(l); l.clear(); return out; } } static public String joinNempties(String sep, Object... strings) { return joinStrings(sep, strings); } static public String joinNempties(String sep, Iterable strings) { return joinStrings(sep, strings); } static public String joinNemptiesWithComma(Object... strings) { return joinNempties(", ", strings); } static public String joinNemptiesWithComma(Iterable strings) { return joinNempties(", ", strings); } static public List flattenCollectionsAndArrays(Iterable a) { List l = new ArrayList(); for (Object x : a) if (x instanceof Collection) l.addAll(flattenCollectionsAndArrays((Collection) x)); else if (x instanceof Object[]) l.addAll(flattenCollectionsAndArrays(asList((Object[]) x))); else l.add(x); return l; } static public String hfulltag(String tag) { return hfulltag(tag, ""); } static public String hfulltag(String tag, Object contents, Object... params) { return hopeningTag(tag, params) + str(contents) + ""; } static public Set asSet(Object[] array) { HashSet set = new HashSet(); for (Object o : array) if (o != null) set.add(o); return set; } static public Set asSet(String[] array) { TreeSet set = new TreeSet(); for (String o : array) if (o != null) set.add(o); return set; } static public Set asSet(Iterable l) { if (l instanceof Set) return (Set) l; HashSet set = new HashSet(); for (A o : unnull(l)) if (o != null) set.add(o); return set; } static public Set asSet(MultiSet ms) { return ms == null ? null : ms.asSet(); } static public Complex complex(double re, double im) { return new Complex(re, im); } static public Complex complex(double re) { return new Complex(re, 0.0); } static public Complex complex(double[] reIm) { if (empty(reIm)) return null; if (l(reIm) != 2) throw fail("Need 2 doubles to make complex number"); return complex(reIm[0], reIm[1]); } static public String standard_toString(Object o) { if (o == null) return "null"; String name = shortClassName(o); Set fields = fieldNames(o); if (empty(fields)) return name; return name + "(" + joinWithComma(mapNonNulls(fields, field -> { Object value = get(o, field); if (value == null) return null; return field + "=" + str(value); })) + ")"; } static public void internalFrameTitlePopupMenuItem(JInternalFrame f, final String name, final Object action) { internalFrameTitlePopupMenu(f, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, name, action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, name, action)"; } }); } static public void minimalFrameSize(Component c, int w, int h) { Container f = getPIFrame(c); if (f != null) setSize(f, max(w, getWidth(f)), max(h, getHeight(f))); } static public String defaultThreadName_name; static public String defaultThreadName() { if (defaultThreadName_name == null) defaultThreadName_name = "A thread by " + programID(); return defaultThreadName_name; } static public Runnable wrapAsActivity(Object r) { if (r == null) return null; Runnable r2 = toRunnable(r); Object mod = dm_current_generic(); if (mod == null) return r2; return new Runnable() { public void run() { try { AutoCloseable c = (AutoCloseable) (rcall("enter", mod)); AutoCloseable __1 = c; try { r2.run(); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable c = (AutoCloseable) (rcall enter(mod));\r\n temp c;\r\n r2.r..."; } }; } static public Thread newThread(Object runnable) { return new BetterThread(_topLevelErrorHandling(toRunnable(runnable))); } static public Thread newThread(Object runnable, String name) { if (name == null) name = defaultThreadName(); return new BetterThread(_topLevelErrorHandling(toRunnable(runnable)), name); } static public Thread newThread(String name, Object runnable) { return newThread(runnable, name); } static public Runnable toRunnable(final Object o) { if (o instanceof Runnable) return (Runnable) o; if (o instanceof String) throw fail("callF_legacy"); return new Runnable() { public void run() { try { callF(o); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(o)"; } }; } static public Map _registerThread_threads; static public Object _onRegisterThread; static public Thread _registerThread(Thread t) { if (_registerThread_threads == null) _registerThread_threads = newWeakHashMap(); _registerThread_threads.put(t, true); vm_generalWeakSubMap("thread2mc").put(t, weakRef(mc())); callF(_onRegisterThread, t); return t; } static public void _registerThread() { _registerThread(Thread.currentThread()); } static public String myFirewallIP() { return assertIPv4(loadPage("http://botcompany.de:8081/tb-int/my-ip.php")); } static public List regexpAll(String pattern, String text) { List matches = new ArrayList(); Matcher matcher = regexp(pattern, text); while (matcher.find()) matches.add(matcher.group()); return matches; } static public String dm_makeNewModuleWithParams(String moduleLibID, Object... params) { return (String) dm_callOS("makeNewModule", moduleLibID, false, "beforeStart", new VF1() { public void get(Object mod) { try { print("Got module: " + dm_mod(mod)); dm_call(mod, "setFields", params); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "print(\"Got module: \" + dm_mod(mod));\r\n dm_call(mod, 'setFields, params);"; } }); } static public void dm_showModule(Object module) { Object stem = dm_getStem(module); if (stem != null) dm_callOS("showModule", stem); } static public void dm_showModule() { dm_showModule(dm_current_mandatory_generic()); } static public boolean hasSuperclassShortNamed(Object o, String name) { Class c = _getClass(o); while (c != null) if (shortClassNameIs(c, name)) return true; else c = c.getSuperclass(); return false; } static public void dm_onFieldChange(String field, Runnable onChange) { dm_watchField(field, onChange); } static public void dm_onFieldChange(Collection fields, Runnable onChange) { dm_watchFields(fields, onChange); } static public double toMinutes(long ms) { return ms / 60000.0; } static public Object swing(Object f) { return swingAndWait(f); } static public void swing(Runnable f) { swingAndWait(f); } static public A swing(F0 f) { return (A) swingAndWait(f); } static public A swing(IF0 f) { return (A) swingAndWait(f); } static public A revalidate(final A c) { if (c == null || !c.isShowing()) return c; { swing(() -> { c.revalidate(); c.repaint(); }); } return c; } static public void revalidate(JFrame f) { revalidate((Component) f); } static public void revalidate(JInternalFrame f) { revalidate((Component) f); } static public ActionListener actionListenerInNewThread(final Object runnable) { return actionListenerInNewThread(runnable, null); } static public ActionListener actionListenerInNewThread(final Object runnable, final Object instanceToHold) { if (runnable instanceof ActionListener) return (ActionListener) runnable; return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { startThread("Action Listener", new Runnable() { public void run() { try { AutoCloseable __1 = holdInstance(instanceToHold); try { callF(runnable); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __1 = holdInstance(instanceToHold); try {\r\n callF(runnable..."; } }); } catch (Throwable __e) { messageBox(__e); } } }; } static public Map humanizeFormLabel_replacements = litmap("id", "ID", "md5", "MD5"); static public String humanizeFormLabel(String s) { if (containsSpace(s)) return s; return firstToUpper(joinWithSpace(replaceElementsUsingMap(splitCamelCase(s), humanizeFormLabel_replacements)).replace("I D", "ID")); } static public JTextField jtextfield() { return jTextField(); } static public JTextField jtextfield(String text) { return jTextField(text); } static public JTextField jtextfield(Object o) { return jTextField(o); } static public int showForm_defaultGap = 4; static public int showForm_gapBetweenColumns = 10; static public JPanel showFormTitled(final String title, final Object... _parts) { JDesktopPane desktop = mainDesktopPane(); if (desktop != null) return showInternalFrameFormTitled(desktop, title, _parts); return swing(new F0() { public JPanel get() { try { final Var frame = new Var(); JPanel panel = showForm_makePanel(false, _parts); showForm_makeFrame(title, panel); frame.set(getFrame(panel)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final new Var frame;\r\n JPanel panel = showForm_makePanel(false, _p..."; } }); } static public JPanel showForm_makePanel(Boolean internalFrame, Object... _parts) { List out = showForm_arrange1(showForm_makeComponents(internalFrame, _parts)); return vstackWithSpacing(out, showForm_defaultGap); } static public String stringOptPar(Object[] params, String name) { return (String) optPar(params, name); } static public String gtt(JTextComponent c) { return getTextTrim(c); } static public String gtt(JComboBox cb) { return getTextTrim(cb); } static public A toolTip(A c, final Object toolTip) { return setToolTipText(c, toolTip); } static public A toolTip(Object toolTip, A c) { return setToolTipText(toolTip, c); } static public JButton jPopDownButton(String text, final Object... menuParams) { return jbutton((empty(text) ? "" : text + " ") + unicode_downPointingTriangle(), new Runnable() { public void run() { try { JPopupMenu menu = new JPopupMenu(); int emptyCount = menu.getComponentCount(); String position = (String) (optPar_ignoreOddLength("position", menuParams)); fillJPopupMenu(menu, paramsWithout(menuParams, "position")); if (menu.getComponentCount() != emptyCount) { JButton btn = heldInstance(JButton.class); int x = 0; if (eq(position, "center")) x = (btn.getWidth() - getPreferredWidth(menu)) / 2; else if (eq(position, "right")) x = btn.getWidth() - getPreferredWidth(menu); menu.show(btn, x, btn.getHeight()); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "new JPopupMenu menu;\r\n int emptyCount = menu.getComponentCount();\r\n Str..."; } }); } static public void inputText(final String msg, final Object action) { inputText(msg, "", action); } static public void inputText(final String msg, final String defaultText, final Object action) { final Object threadInfo = _threadInfo(); swingLater(new Runnable() { public void run() { try { final JTextField tf = jtextfield(defaultText); String title = joinStrings(" | ", msg, programName()); JComponent form = showFormTitled(title, unnull(msg), tf, new Runnable() { public void run() { try { vmBus_send("inputtingText_OK", threadInfo, msg, tf); callF_thread(action, getTextTrim(tf)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "vmBus_send(\"inputtingText_OK\", threadInfo, msg, tf);\r\n callF_thread(ac..."; } }); renameSubmitButton(form, "OK"); vmBus_send("inputtingText", threadInfo, msg, tf); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JTextField tf = jtextfield(defaultText);\r\n String title = joinString..."; } }); } static public void inputText(String msg, String defaultText, IVF1 action) { inputText(msg, defaultText, (Object) action); } static public void inputText(String msg, IVF1 action) { inputText(msg, (Object) action); } static public String dm_moduleName() { return dm_moduleName(assertNotNull(dm_current_generic())); } static public String dm_moduleName(Object module) { return (String) callOpt(dm_getStem(module), "moduleName"); } static public File dm_structureExportDefaultFile(DynModule mod) { return javaxBackupDir("module-" + shortClassName(mod) + "-" + ymdMinusHms() + ".txt"); } static public File saveTextFileWithInfoBox(File f, String text) { saveTextFile(f, text); fileSavedInfoBox(f); return f; } static public String javaTokWordWrap(String s) { return javaTokWordWrap(120, s); } static public String javaTokWordWrap(int cols, String s) { int col = 0; List tok = javaTok(s); for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i) && col >= cols && !containsNewLine(t)) tok.set(i, t = rtrimSpaces(t) + "\n"); int idx = t.lastIndexOf('\n'); if (idx >= 0) col = l(t) - (idx + 1); else col += l(t); } return join(tok); } static public String dm_freshModuleStructureWithoutError(Object module) { dm_clearError(module); return dm_freshModuleStructure(module); } static public File showFileChooserWithDefaultDir(String title, File defaultDir) { JFileChooser fc = new JFileChooser(); fc.setDialogTitle(title); fc.setCurrentDirectory(defaultDir); return execFileChooser(fc); } static public File javaxBackupDir_dir; static public File javaxBackupDir() { return javaxBackupDir_dir != null ? javaxBackupDir_dir : new File(userHome(), "JavaX-Backup"); } static public File javaxBackupDir(String sub) { return newFile(javaxBackupDir(), sub); } static public boolean fileExists(String path) { return path != null && new File(path).exists(); } static public boolean fileExists(File f) { return f != null && f.exists(); } static public JWindow infoBox(Object text) { return infoMessage(strOrNull(text)); } static public JWindow infoBox(String text) { return infoMessage(text); } static public JWindow infoBox(String text, double seconds) { return infoMessage(text, seconds); } static public JWindow infoBox(Throwable e) { return infoMessage(e); } static public void dm_replaceModuleWithStructure(Object mod, String struct) { setAll(dm_getStem(mod), "contentsDirty", false, "oStruct", struct); dm_reloadModule(mod); } static public A reverseLookup(B value, Map map) { return reverseLookup(map, value); } static public A reverseLookup(Map map, B value) { if (map != null && value != null) for (A key : map.keySet()) if (eq(map.get(key), value)) return key; return null; } static public void cancelTimer(javax.swing.Timer timer) { if (timer != null) timer.stop(); } static public void cancelTimer(java.util.Timer timer) { if (timer != null) timer.cancel(); } static public void cancelTimer(Object o) { if (o instanceof java.util.Timer) cancelTimer((java.util.Timer) o); else if (o instanceof javax.swing.Timer) cancelTimer((javax.swing.Timer) o); else if (o instanceof AutoCloseable) { try { ((AutoCloseable) o).close(); } catch (Throwable __e) { printStackTrace(__e); } } } static public String joinStrings(String sep, Object... strings) { return joinStrings(sep, Arrays.asList(strings)); } static public String joinStrings(String sep, Iterable strings) { StringBuilder buf = new StringBuilder(); for (Object o : unnull(strings)) { String s = strOrNull(o); if (nempty(s)) { if (nempty(buf)) buf.append(sep); buf.append(s); } } return str(buf); } static public String hopeningTag(String tag, Map params) { return hopeningTag(tag, mapToParams(params)); } static public String hopeningTag(String tag, Object... params) { StringBuilder buf = new StringBuilder(); buf.append("<" + tag); params = unrollParams(params); for (int i = 0; i < l(params); i += 2) { String name = (String) get(params, i); Object val = get(params, i + 1); if (nempty(name) && val != null) { if (eqOneOf(val, html_valueLessParam(), true)) buf.append(" " + name); else { String s = str(val); if (!empty(s)) buf.append(" " + name + "=" + htmlQuote(s)); } } } buf.append(">"); return str(buf); } static public Set fieldNames(Object o) { return allFields(o); } static public List mapNonNulls(Iterable l, Object f) { return mapNonNulls(f, l); } static public List mapNonNulls(Object f, Iterable l) { List x = new ArrayList(); if (l != null) for (Object o : l) addIfNotNull(x, callF(f, o)); return x; } static public List mapNonNulls(Object f, Object[] l) { List x = new ArrayList(); if (l != null) for (Object o : l) addIfNotNull(x, callF(f, o)); return x; } static public List mapNonNulls(Iterable l, F1 f) { return mapNonNulls(f, l); } static public List mapNonNulls(F1 f, Iterable l) { List x = new ArrayList(); if (l != null) for (Object o : l) addIfNotNull(x, callF(f, o)); return x; } static public List mapNonNulls(A[] l, IF1 f) { return mapNonNulls(f, l); } static public List mapNonNulls(Iterable l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) addIfNotNull(x, f.get(o)); return x; } static public List mapNonNulls(IF1 f, Iterable l) { return mapNonNulls(l, f); } static public void internalFrameTitlePopupMenu(final JInternalFrame f, final Object... params) { { swing(() -> { Object menuMaker; if (l(params) == 1 && !(params[0] instanceof JMenu)) menuMaker = params[0]; else menuMaker = new VF1() { public void get(JPopupMenu menu) { try { addMenuItems(menu, params); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItems(menu, params)"; } }; Component titleComponent = getInternalFrameTitlePaneComponent(f); if (!(titleComponent instanceof JComponent)) print("Can't add internal frame title popup menu!"); else { componentPopupMenu((JComponent) titleComponent, menuMaker); setOpt(componentPopupMenu_initForComponent((JComponent) titleComponent), "internalFrameLeftButtonMagic", isTrue(vm_generalMap_get("internalFramePopupOnLeftButton"))); } componentPopupMenu(f, menuMaker); }); } } static public void addMenuItem(JPopupMenu menu, String text, Object action) { menu.add(jmenuItem(text, action)); } static public void addMenuItem(JPopupMenu menu, JMenuItem menuItem) { menu.add(menuItem); } static public void addMenuItem(JMenu menu, String text, Object action) { menu.add(jmenuItem(text, action)); } static public void addMenuItem(Menu menu, String text, Object action) { menu.add(menuItem(text, action)); } static public void addMenuItem(JMenu menu, JMenuItem menuItem) { menu.add(menuItem); } static public void addMenuItem(JMenuBar menuBar, String text, Runnable action) { addMenuItem(menuBar, jmenuItem(text, action)); } static public void addMenuItem(JMenuBar menuBar, JMenuItem menuItem) { addDirectMenuItem(menuBar, menuItem); } static public Container getPIFrame(Component c) { return (Container) getPossiblyInternalFrame(c); } static public A setSize(final A c, final int w, final int h) { if (c != null) { swing(() -> { c.setSize(w, h); }); } return c; } static public void setSize(Component c, Dimension d) { setSize(c, d.width, d.height); } static public int getWidth(Component c) { return c == null ? 0 : (int) swingCall(c, "getWidth"); } static public int getHeight(Component c) { return c == null ? 0 : (int) swingCall(c, "getHeight"); } static public Runnable _topLevelErrorHandling(Runnable r) { if (r == null) return null; Object info = _threadInfo(); Object mod = dm_current_generic(); if (info == null && mod == null) return r; return new Runnable() { public void run() { try { AutoCloseable __1 = (AutoCloseable) (rcall("enter", mod)); try { _threadInheritInfo(info); r.run(); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp (AutoCloseable) rcall enter(mod);\r\n _threadInheritInfo(info);\r\n r...."; } }; } static public WeakReference weakRef(A a) { return newWeakReference(a); } static public String assertIPv4(String s) { assertTrue(s, isIPv4(s)); return s; } static public Object dm_mod(Object moduleOrID) { return dm_getModule(moduleOrID); } static public boolean shortClassNameIs(Object o, String name) { return eq(shortClassName(o), name); } static public boolean shortClassNameIs(String name, Object o) { return shortClassNameIs(o, name); } static public void dm_watchFields(Collection fields, Runnable onChange) { for (String field : unnullForIteration(fields)) dm_watchField(field, onChange); } static public void swingAndWait(Runnable r) { try { if (isAWTThread()) r.run(); else EventQueue.invokeAndWait(addThreadInfoToRunnable(r)); } catch (Exception __e) { throw rethrow(__e); } } static public Object swingAndWait(final Object f) { if (isAWTThread()) return callF(f); else { final Var result = new Var(); swingAndWait(new Runnable() { public void run() { try { result.set(callF(f)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "result.set(callF(f));"; } }); return result.get(); } } static public ThreadLocal> holdInstance_l = new ThreadLocal(); static public AutoCloseable holdInstance(Object o) { if (o == null) return null; listThreadLocalAdd(holdInstance_l, o); return new AutoCloseable() { public void close() { listThreadLocalPopLast(holdInstance_l); } }; } static public void messageBox(final String msg) { if (headless()) print(msg); else { swing(() -> { JOptionPane.showMessageDialog(null, msg, "JavaX", JOptionPane.INFORMATION_MESSAGE); }); } } static public void messageBox(Throwable e) { printStackTrace(e); messageBox(hideCredentials(innerException2(e))); } static public boolean containsSpace(String s) { return containsSpaces(s); } static public String firstToUpper(String s) { if (empty(s)) return s; return Character.toUpperCase(s.charAt(0)) + s.substring(1); } static public List replaceElementsUsingMap(Iterable l, final Map map) { return map(l, new F1() { public A get(A a) { try { return getOrKeep(map, a); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "getOrKeep(map, a)"; } }); } static public List splitCamelCase(String s) { return ai_splitCamelCase(s); } static public JTextField jTextField() { return jTextField(""); } static public JTextField jTextField(final String text) { return swing(new F0() { public JTextField get() { try { JTextField tf = new JTextField(unnull(text)); standardTextFieldPopupMenu(tf); jenableUndoRedo(tf); tf.selectAll(); return tf; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JTextField tf = new JTextField(unnull(text));\r\n standardTextFieldPopupMenu..."; } }); } static public JTextField jTextField(Object o) { return jTextField(strOrEmpty(o)); } static public JDesktopPane mainDesktopPane_value; static public JDesktopPane mainDesktopPane() { return mainDesktopPane_value; } static public JPanel showInternalFrameFormTitled(final JDesktopPane desktop, final String title, final Object... _parts) { JPanel panel = showForm_makePanel(true, _parts); showForm_makeInternalFrame(desktop, title, panel); return panel; } static public IVF2 showForm_makeFrame; static public void showForm_makeFrame(String title, JPanel panel) { if (showForm_makeFrame != null) showForm_makeFrame.get(title, panel); else showForm_makeFrame_base(title, panel); } final static public void showForm_makeFrame_fallback(IVF2 _f, String title, JPanel panel) { if (_f != null) _f.get(title, panel); else showForm_makeFrame_base(title, panel); } static public void showForm_makeFrame_base(String title, JPanel panel) { handleEscapeKey(minFrameWidth(showPackedFrame(title, withMargin(panel)), 400)); } static public JFrame getFrame(final Object _o) { return swing(new F0() { public JFrame get() { try { Object o = _o; if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof JFrame) return (JFrame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n if (o instanceof ButtonGroup) o = first(buttonsInGroup((Button..."; } }); } static public List showForm_arrange1(List> l) { int minW = showForm_leftWidth(l); List out = new ArrayList(); for (List row : l) out.add(westAndCenter(withRightMargin(showForm_gapBetweenColumns, jMinWidthAtLeast(minW, first(row))), second(row))); return out; } static public List> showForm_makeComponents(final Boolean internalFrame, Object... _parts) { List> l = new ArrayList(); List parts = asList(_parts); JButton submitButton = null; for (int i = 0; i < l(parts); i++) { final Object o = parts.get(i), next = get(parts, i + 1); if (o instanceof String && next instanceof Component) setComponentID((Component) next, (String) o); if (o instanceof Component || o instanceof String || next instanceof Component) { l.add(mapLL(__90 -> wrapForSmartAdd_jComponent(__90), o == null ? new JPanel() : o instanceof String ? humanizeFormLabel((String) o) : o, next)); if (next instanceof JButton && submitButton == null) submitButton = (JButton) next; i++; } else if (isRunnable(o)) l.add(mapLL(__91 -> wrapForSmartAdd_jComponent(__91), null, submitButton = jbutton(showFormSubmitButtonName(), new Runnable() { public void run() { try { Object result = call(o); print("Result of form runnable: " + result + ". Button: " + heldInstance(JButton.class)); if (neq(Boolean.FALSE, result)) { if (isTrue(internalFrame)) disposeInternalFrame(heldInstance(JButton.class)); else if (isFalse(internalFrame)) disposeFrame(heldInstance(JButton.class)); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Object result = call(o);\r\n print(\"Result of form runnable: \" + result ..."; } }))); else print("showForm: Unknown element type: " + getClassName(o)); } if (submitButton != null) { final JButton _submitButton = submitButton; onEnterInAllTextFields(concatLists(l), new Runnable() { public void run() { try { clickButton(_submitButton); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "clickButton(_submitButton)"; } }); } for (List row : l) { JComponent left = first(row); if (left instanceof JLabel) makeBold((JLabel) left).setVerticalAlignment(JLabel.TOP); } return l; } static public int vstackWithSpacing_default = 10; static public JPanel vstackWithSpacing(final List parts) { return vstackWithSpacing(parts, vstackWithSpacing_default); } static public JPanel vstackWithSpacing(final List parts, final int spacing) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = new Insets(spacing / 2, 0, (spacing + 1) / 2, 0); smartAddWithLayout(panel, gbc, toObjectArray(nonNulls(parts))); gbc.weighty = 1; gbc.insets = new Insets(0, 0, 0, 0); panel.add(jrigid(), gbc); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new GridBagLayout);\r\n new GridBagConstraints gbc..."; } }); } static public JPanel vstackWithSpacing(Component... parts) { return vstackWithSpacing(asList(parts), vstackWithSpacing_default); } static public JPanel vstackWithSpacing(int spacing, Component... parts) { return vstackWithSpacing(asList(parts), spacing); } static public String getTextTrim(JTextComponent c) { return trim(getText(c)); } static public String getTextTrim(JComboBox cb) { return trim(getText(cb)); } static public String getTextTrim(JComponent c) { if (c instanceof JLabel) return trim(((JLabel) c).getText()); if (c instanceof JComboBox) return getTextTrim((JComboBox) c); return getTextTrim((JTextComponent) c); } static public A setToolTipText(final A c, final Object toolTip) { if (c == null) return null; { swing(() -> { String s = nullIfEmpty(str(toolTip)); if (neq(s, c.getToolTipText())) c.setToolTipText(s); }); } return c; } static public A setToolTipText(Object toolTip, A c) { return setToolTipText(c, toolTip); } static public JButton jbutton(String text, Object action) { return newButton(text, action); } static public JButton jbutton(String text) { return newButton(text, null); } static public JButton jbutton(Action action) { return swingNu(JButton.class, action); } static public String unicode_downPointingTriangle() { return charToString(0x25BC); } static public A optPar_ignoreOddLength(Object[] opt, String name, A defaultValue) { int n = l(opt); if (n == 1 && opt[0] instanceof Map) { Map map = (Map) (opt[0]); return map.containsKey(name) ? (A) map.get(name) : defaultValue; } for (int i = 0; i + 1 < l(opt); i += 2) if (eq(opt[i], name)) return (A) opt[i + 1]; return defaultValue; } static public Object optPar_ignoreOddLength(Object[] opt, String name) { return optPar_ignoreOddLength(opt, name, null); } static public Object optPar_ignoreOddLength(String name, Object[] params) { return optPar_ignoreOddLength(params, name); } static public void fillJPopupMenu(JPopupMenu m, Object... x) { if (x == null) return; for (int i = 0; i < l(x); i++) { Object o = x[i], y = get(x, i + 1); if (o instanceof IVF1) callF(o, m); else if (o instanceof List) fillJPopupMenu(m, asArray((List) o)); else if (isMenuSeparatorIndicator(o)) m.addSeparator(); else if (o instanceof LiveValue && ((LiveValue) o).getType() == String.class && isRunnableX(y)) { final LiveValue lv = (LiveValue) o; final JMenuItem mi = jmenuItem("", y); bindLiveValueListenerToComponent(mi, lv, new Runnable() { public void run() { try { String s = lv.get(); if (isCurlyBracketed(s)) { setEnabled(mi, false); s = unCurlyBracket(s); } else setEnabled(mi, true); setText(mi, s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = lv!;\r\n if (isCurlyBracketed(s)) {\r\n setEnabled(mi,..."; } }); m.add(mi); } else if (o instanceof String && isRunnableX(y)) { m.add(jmenuItem((String) o, y)); ++i; } else if (o instanceof JMenuItem) m.add((JMenuItem) o); else if (o instanceof String || o instanceof Action || o instanceof Component) call(m, "add", o); else if (o != null) print("Unknown menu item: " + o); } } static public Object[] paramsWithout(Object[] a1, Object... keys) { if (l(a1) == 1 && a1[0] instanceof Map) return new Object[] { mapMinus((Map) a1[0], keys) }; Set set = lithashset(keys); List l = new ArrayList(); int n = l(a1); for (int i = 0; i < n; i += 2) if (i == n - 1) l.add(a1[i]); else if (!set.contains(a1[i])) { l.add(a1[i]); l.add(a1[i + 1]); } return toObjectArray(l); } static public A heldInstance(Class c) { List l = holdInstance_l.get(); for (int i = l(l) - 1; i >= 0; i--) { Object o = l.get(i); if (isInstanceOf(o, c)) return (A) o; } throw fail("No instance of " + className(c) + " held"); } static public int getPreferredWidth(Component c) { return preferredWidth(c); } static public void swingLater(long delay, final Object r) { javax.swing.Timer timer = new javax.swing.Timer(toInt(delay), actionListener(wrapAsActivity(r))); timer.setRepeats(false); timer.start(); } static public void swingLater(Object r) { SwingUtilities.invokeLater(toRunnable(r)); } static public String programName() { return getProgramName(); } static public void callF_thread(final Object f, final Object... args) { if (f != null) { startThread(new Runnable() { public void run() { try { callF(f, args); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(f, args);"; } }); } } static public A renameSubmitButton(A form, String newName) { renameButton(form, showFormSubmitButtonName(), newName); return form; } static public A renameSubmitButton(String newName, A form) { return renameSubmitButton(form, newName); } static public String ymdMinusHms() { return ymd_minus_hms(); } static public void fileSavedInfoBox(File f) { infoBox("Saved " + fileInfo(f)); } public static String rtrimSpaces(String s) { if (s == null) return null; int i = s.length(); while (i > 0 && " \t".indexOf(s.charAt(i - 1)) >= 0) --i; return i < s.length() ? s.substring(0, i) : s; } static public void dm_clearError(Object mod) { dm_rcall("clearError", mod); } static public String dm_freshModuleStructure(Object module) { dm_persistModule(module); return dm_getStructure(module); } static public String dm_freshModuleStructure() { return dm_freshModuleStructure(dm_current_generic()); } static public File execFileChooser(JFileChooser fileChooser) { return fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null; } static public boolean infoMessage_alwaysOnTop = true; static public double infoMessage_defaultTime = 5.0; static public JWindow infoMessage(String text) { return infoMessage(text, infoMessage_defaultTime); } static public JWindow infoMessage(final String text, final double seconds) { printHidingCredentials(text); return infoMessage_noprint(text, seconds); } static public JWindow infoMessage_noprint(String text) { return infoMessage_noprint(text, infoMessage_defaultTime); } static public JWindow infoMessage_noprint(final String _text, final double seconds) { final String text = hideCredentials(_text); if (empty(text)) return null; logQuotedWithDate(infoBoxesLogFile(), text); if (isHeadless()) return null; return (JWindow) swingAndWait(new F0() { public Object get() { try { JWindow window = makeWindow(infoMessage_makePanel(text)); window.setSize(300, 150); moveToTopRightCorner(window); if (infoMessage_alwaysOnTop) window.setAlwaysOnTop(true); if (vmBus_noObjections("shouldShowInfoBox", window, text)) window.setVisible(true); if (seconds != 0) disposeWindowAfter(iround(seconds * 1000), window); return window; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JWindow window = makeWindow(infoMessage_makePanel(text));\r\n window.setSize..."; } }); } static public JWindow infoMessage(Throwable e) { printStackTrace(e); return infoMessage(exceptionToStringShort(e)); } static public Object[] unrollParams(Object[] params) { if (l(params) == 1 && params[0] instanceof Map) return mapToParams((Map) params[0]); return params; } static public Object html_valueLessParam_cache; static public Object html_valueLessParam() { if (html_valueLessParam_cache == null) html_valueLessParam_cache = html_valueLessParam_load(); return html_valueLessParam_cache; } static public Object html_valueLessParam_load() { return new Object(); } static public String htmlQuote(String s) { return "\"" + htmlencode_forParams(s) + "\""; } static public Map> allFields_cache = weakHashMap(); static public Set allFields(Object o) { if (o == null) return emptySet(); Class _c = _getClass(o); Set fields = allFields_cache.get(_c); if (fields == null) allFields_cache.put(_c, fields = asTreeSet(keys(getOpt_getFieldMap(o)))); return fields; } static public void addMenuItems(JMenu m, Object... x) { fillJMenu(m, x); } static public void addMenuItems(JPopupMenu m, Object... x) { fillJPopupMenu(m, x); } static public JComponent getInternalFrameTitlePaneComponent(JInternalFrame f) { return (JComponent) childWithClassNameEndingWith(f, "InternalFrameTitlePane"); } static public boolean jmenuItem_newThreads = false; static public JMenuItem jmenuItem(final String text) { return jMenuItem(text, null); } static public JMenuItem jmenuItem(final String text, final Object r) { return swing(new F0() { public JMenuItem get() { try { Pair p = jmenu_autoMnemonic(dropPrefix("[disabled] ", text)); JMenuItem mi = new JMenuItem(p.a); if (startsWith(text, "[disabled] ")) disableMenuItem(mi); if (p.b != 0) mi.setMnemonic(p.b); mi.addActionListener(jmenuItem_newThreads ? actionListenerInNewThread(r) : actionListener(r)); return mi; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Pair p = jmenu_autoMnemonic(dropPrefix(\"[disabled] \", text));\r\n JM..."; } }); } static public MenuItem menuItem(String text, final Object r) { MenuItem mi = new MenuItem(text); mi.addActionListener(actionListener(r)); return mi; } static public void addDirectMenuItem(JMenuBar mb, String text, Object action) { if (mb != null) { swing(() -> { addDirectMenuItem(mb, directJMenuItem(text, action)); }); } } static public void addDirectMenuItem(Component c, String text, Object action) { addDirectMenuItem(addMenuBar(c), text, action); } static public void addDirectMenuItem(JMenuBar mb, JMenuItem menuItem) { if (mb != null) { swing(() -> { mb.add(menuItem); revalidate(mb); }); } } static public RootPaneContainer getPossiblyInternalFrame(Component c) { JInternalFrame f = getInternalFrame(c); if (f != null) return f; return optCast(RootPaneContainer.class, getWindow(c)); } static public Object swingCall(final Object o, final String method, final Object... args) { return swing(new F0() { public Object get() { try { return call(o, method, args); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret call(o, method, args);"; } }); } static public WeakReference newWeakReference(A a) { return a == null ? null : new WeakReference(a); } static public boolean isIPv4(String s) { return s != null && l(javaTokC(s)) == 7 && jfind(javaTok(s), "...") == 1; } static public Runnable addThreadInfoToRunnable(final Object r) { final Object info = _threadInfo(); return info == null ? asRunnable(r) : new Runnable() { public void run() { try { _inheritThreadInfo(info); callF(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_inheritThreadInfo(info); callF(r);"; } }; } static public void listThreadLocalAdd(ThreadLocal> tl, A a) { List l = tl.get(); if (l == null) tl.set(l = new ArrayList()); l.add(a); } static public A listThreadLocalPopLast(ThreadLocal> tl) { List l = tl.get(); if (l == null) return null; A a = popLast(l); if (empty(l)) tl.set(null); return a; } static public boolean headless() { return isHeadless(); } static public Throwable innerException2(Throwable e) { if (e == null) return null; while (empty(e.getMessage()) && e.getCause() != null) e = e.getCause(); return e; } static public boolean containsSpaces(String s) { return indexOf(s, ' ') >= 0; } static public A getOrKeep(Map map, A a) { if (map == null) return a; A v = map.get(a); return v != null ? v : a; } static public List ai_splitCamelCase(String s) { int j = 0; List l = new ArrayList(); if (isAllUpperCase(s)) { l.add(s); return l; } for (int i = 0; i < l(s); i++) if (i > j && isUpperCaseLetter(s.charAt(i))) { l.add(substring(s, j, i)); j = i; } if (j < l(s)) l.add(substring(s, j)); return l; } static public JTextField standardTextFieldPopupMenu(final JTextField tf) { final WeakReference ref = weakRef(tf); componentPopupMenuItem(tf, "Copy text to clipboard", new Runnable() { public void run() { try { copyTextToClipboard(ref.get().getText()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyTextToClipboard(ref.get().getText())"; } }); componentPopupMenuItem(tf, "Paste", new Runnable() { public void run() { try { ref.get().paste(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ref.get().paste()"; } }); return tf; } static public A jenableUndoRedo(final A textcomp) { { swing(() -> { final UndoManager undo = new UndoManager(); vm_generalWeakSet("Undo Managers").add(undo); textcomp.getDocument().addUndoableEditListener(new UndoableEditListener() { public void undoableEditHappened(UndoableEditEvent evt) { undo.addEdit(evt.getEdit()); } }); textcomp.getActionMap().put("Undo", abstractAction("Undo", new Runnable() { public void run() { try { if (undo.canUndo()) undo.undo(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (undo.canUndo()) undo.undo()"; } })); textcomp.getActionMap().put("Redo", abstractAction("Redo", new Runnable() { public void run() { try { if (undo.canRedo()) undo.redo(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (undo.canRedo()) undo.redo()"; } })); textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo"); textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo"); }); } return textcomp; } static public String strOrEmpty(Object o) { return o == null ? "" : str(o); } static public JInternalFrame showForm_makeInternalFrame(JDesktopPane desktop, String title, JPanel panel) { JInternalFrame f = addInternalFrame(desktop, title, withMargin(panel)); minInternalFrameWidth(f, 400); packInternalFrameVertically(f); centerInternalFrame(f); return f; } static public JFrame handleEscapeKey(final JFrame frame) { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); frame.getRootPane().registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { frame.dispose(); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return frame; } static public JFrame minFrameWidth(JFrame frame, int w) { if (frame != null && frame.getWidth() < w) frame.setSize(w, frame.getHeight()); return frame; } static public JFrame minFrameWidth(int w, JFrame frame) { return minFrameWidth(frame, w); } static public JFrame showPackedFrame(String title, Component contents) { return packFrame(showFrame(title, contents)); } static public JFrame showPackedFrame(Component contents) { return packFrame(showFrame(contents)); } static public int withMargin_defaultWidth = 6; static public JPanel withMargin(Component c) { return withMargin(withMargin_defaultWidth, c); } static public JPanel withMargin(int w, Component c) { return withMargin(w, w, c); } static public JPanel withMargin(int w, int h, Component c) { return withMargin(w, h, w, h, c); } static public JPanel withMargin(final int top, final int left, final int bottom, final int right, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = marginPanel(); p.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = marginPanel();\r\n p.setBorder(BorderFactory.createEmptyBorder(to..."; } }); } static public List buttonsInGroup(ButtonGroup g) { if (g == null) return ll(); return asList(g.getElements()); } static public int showForm_leftWidth_safetyMargin = 10; static public int showForm_leftWidth(List> l) { forEachLevel2(l, x -> vmBus_send("updateLayoutNow", x)); int minW = 0; for (List row : l) minW = max(minW, getMinimumSize(first(row)).width); return minW + or((Integer) vmBus_query("formSafetyMargin"), showForm_leftWidth_safetyMargin); } static public JPanel westAndCenter(final Component w, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.WEST, wrap(w)); panel.add(BorderLayout.CENTER, wrap(c)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.WEST..."; } }); } static public int withRightMargin_defaultWidth = 6; static public JPanel withRightMargin(Component c) { return withRightMargin(withRightMargin_defaultWidth, c); } static public JPanel withRightMargin(final int w, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = marginPanel(); p.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, w)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = marginPanel();\r\n p.setBorder(BorderFactory.createEmptyBorder(0,..."; } }); } static public A jMinWidthAtLeast(int w, final A c) { if (c == null) return null; return swing(new F0() { public A get() { try { Dimension size = c.getMinimumSize(); Dimension d = new Dimension(max(w, size.width), size.height); c.setMinimumSize(d); return jPreferWidth(d.width, c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Dimension size = c.getMinimumSize();\r\n Dimension d = new Dimension(max(w, ..."; } }); } static public void setComponentID(Component c, String id) { if (c != null) componentID_map.put(c, id); } static public List mapLL(Object f, Object... data) { return map(f, ll(data)); } static public List mapLL(IF1 f, A... data) { return map(f, ll(data)); } static public JComponent wrapForSmartAdd_jComponent(Object o) { return componentToJComponent(wrapForSmartAdd(o)); } static public boolean isRunnable(Object o) { return o instanceof Runnable || hasMethod(o, "get"); } static public String showFormSubmitButtonName() { return "Submit"; } static public void disposeInternalFrame(Component c) { final JInternalFrame f = getInternalFrame(c); if (f != null) { swing(() -> { vmBus_send("disposingInternalFrame", f); f.dispose(); }); } } static public void disposeFrame(final Component c) { disposeWindow(c); } static public void onEnterInAllTextFields(JComponent c, Object action) { if (action == null) return; for (Component tf : allChildren(c)) onEnterIfTextField(tf, action); } static public void onEnterInAllTextFields(List c, Object action) { for (Object o : unnull(c)) if (o instanceof JComponent) onEnterInAllTextFields((JComponent) o, action); } static public void clickButton(final JButton b) { if (b != null) { swing(() -> { if (b.isEnabled()) b.doClick(); }); } } static public A makeBold(final A c) { if (c != null) { swing(() -> { c.setFont(c.getFont().deriveFont(java.awt.Font.BOLD)); }); } return c; } static public JPanel smartAddWithLayout(JPanel panel, Object layout, List parts) { for (Object o : parts) panel.add(wrapForSmartAdd(o), layout); return panel; } static public JPanel smartAddWithLayout(JPanel panel, Object layout, Object... parts) { return smartAddWithLayout(panel, layout, asList(flattenArray2(parts))); } static public List nonNulls(Iterable l) { return withoutNulls(l); } static public List nonNulls(A[] l) { return withoutNulls(l); } static public Map nonNulls(Map map) { return withoutNulls(map); } static public Component jrigid() { return javax.swing.Box.createRigidArea(new Dimension(0, 0)); } static public String getText(final AbstractButton c) { return c == null ? "" : (String) swingAndWait(new F0() { public Object get() { try { return c.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getText();"; } }); } static public String getText(final JTextComponent c) { return c == null ? "" : (String) swingAndWait(new F0() { public Object get() { try { return c.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getText();"; } }); } static public String getText(final JLabel l) { return l == null ? "" : (String) swingAndWait(new F0() { public Object get() { try { return l.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret l.getText();"; } }); } static public String getText(final JComboBox cb) { if (cb == null) return null; if (isEditableComboBox(cb)) return unnull((String) cb.getEditor().getItem()); else return str(cb.getSelectedItem()); } static public boolean newButton_autoToolTip = true; static public JButton newButton(final String text, final Object action) { return swing(new F0() { public JButton get() { try { String text2 = dropPrefix("[disabled] ", text); final JButton btn = new JButton(text2); if (l(text2) < l(text)) btn.setEnabled(false); if (newButton_autoToolTip) { btn.setToolTipText(btn.getText()); } if (action != null) btn.addActionListener(actionListener(action, btn)); return btn; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "S text2 = dropPrefix(\"[disabled] \", text);\r\n final JButton btn = new JButt..."; } }); } static public A swingNu(final Class c, final Object... args) { return swingConstruct(c, args); } static public String charToString(char c) { return String.valueOf(c); } static public String charToString(int c) { return String.valueOf((char) c); } static public Object[] asArray(List l) { return toObjectArray(l); } static public A[] asArray(Class type, List l) { return (A[]) l.toArray((Object[]) Array.newInstance(type, l.size())); } static public boolean isMenuSeparatorIndicator(Object o) { return eqOneOf(o, "***", "---", "===", ""); } static public boolean isRunnableX(Object o) { if (o == null) return false; if (o instanceof String) return hasMethod(mc(), (String) o); return o instanceof Runnable || hasMethod(o, "get"); } static public A bindLiveValueListenerToComponent(A component, final LiveValue lv, final Runnable listener) { if (lv != null) bindToComponent(component, new Runnable() { public void run() { try { lv.onChangeAndNow(listener); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef bindLiveValueListenerToComponent_debug\r\n print(\"bindLiveValueL..."; } }, new Runnable() { public void run() { try { lv.removeOnChangeListener(listener); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lv.removeOnChangeListener(listener)"; } }); return component; } static public boolean isCurlyBracketed(String s) { return isCurlyBraced(s); } static public String unCurlyBracket(String s) { return tok_unCurlyBracket(s); } static public boolean setText_opt = true; static public A setText(A c, Object text) { setText((JComponent) c, text); return c; } static public A setText(final A c, Object text) { final String s = strUnnull(text); { swing(() -> { c.getEditor().setItem(s); }); } return c; } static public void setText(JLabel c, Object text) { setText((JComponent) c, text); } static public JButton setText(JButton c, Object text) { setText((JComponent) c, jlabel_textAsHTML_center_ifNeeded(strUnnull(text))); return c; } static public A setText(final A c, Object text) { if (c == null) return null; final String s = strUnnull(text); { swing(() -> { if (!setText_opt || neq(callOpt(c, "getText"), s)) call(c, "setText", s); }); } return c; } static public Map mapMinus(Map map, Object... keys) { if (empty(keys)) return map; Map m2 = cloneMap(map); for (Object key : keys) m2.remove(key); return m2; } static public boolean isInstanceOf(Object o, Class type) { return type.isInstance(o); } static public int preferredWidth(Component c) { return c == null ? 0 : getPreferredSize(c).width; } static public ActionListener actionListener(final Object runnable) { return actionListener(runnable, null); } static public ActionListener actionListener(final Object runnable, final Object instanceToHold) { if (runnable instanceof ActionListener) return (ActionListener) runnable; final Object info = _threadInfo(); return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { _threadInheritInfo(info); AutoCloseable __1 = holdInstance(instanceToHold); try { pcallF(runnable); } finally { _close(__1); } } catch (Throwable __e) { messageBox(__e); } } }; } static public String getProgramName_cache; static public String getProgramName() { Lock __0 = downloadLock(); lock(__0); try { if (getProgramName_cache == null) getProgramName_cache = getSnippetTitleOpt(programID()); return getProgramName_cache; } finally { unlock(__0); } } static public void _onLoad_getProgramName() { { startThread(new Runnable() { public void run() { try { getProgramName(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "getProgramName();"; } }); } } static public JButton renameButton(JComponent c, String name) { JButton b = first(childrenOfType(c, JButton.class)); if (b != null) b.setText(name); return b; } static public JButton renameButton(JComponent c, String oldName, String newName) { JButton b = findButton(c, oldName); if (b != null) b.setText(newName); return b; } static public String fileInfo(File f) { return renderFileInfo(f); } static public String fileInfo(String f) { return renderFileInfo(newFile(f)); } static public void dm_persistModule(Object module) { call(dm_getStem(module), "persistContents"); } static public String dm_getStructure(Object module) { return (String) get(dm_getStem(module), "oStruct"); } static public void logQuotedWithDate(String s) { logQuotedWithTime(s); } static public void logQuotedWithDate(String logFile, String s) { logQuotedWithTime(logFile, s); } static public void logQuotedWithDate(File logFile, String s) { logQuotedWithTime(logFile, s); } static public File infoBoxesLogFile() { return new File(javaxDataDir(), "Logs/infoBoxes.txt"); } static public JWindow makeWindow(final Component c) { return swing(new F0() { public JWindow get() { try { JWindow w = new JWindow(); w.add(wrap(c)); return w; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "new JWindow w;\r\n w.add(wrap(c));\r\n ret w;"; } }); } static public JPanel infoMessage_makePanel(String text) { final JTextArea ta = wrappedTextArea(text); onClick(ta, new Runnable() { public void run() { try { disposeWindow(ta); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeWindow(ta)"; } }); int size = 14; if (l(text) <= 50) size *= 2; else if (l(text) < 100) size = iround(size * 1.5); ta.setFont(typeWriterFont(size)); JScrollPane sp = jscroll(ta); return withMargin(sp); } static public int moveToTopRightCorner_inset = 20; static public A moveToTopRightCorner(A a) { return moveToTopRightCorner(moveToTopRightCorner_inset, moveToTopRightCorner_inset, a); } static public A moveToTopRightCorner(int insetX, int insetY, A a) { { swing(() -> { Window w = getWindow(a); if (w != null) { var bounds = preferredScreenBounds(); w.setLocation(bounds.x2() - w.getWidth() - insetX, bounds.y1() + insetY); } }); } return a; } static public boolean vmBus_noObjections(String msg, Object... args) { return !vmBus_anyFalse(msg, args); } static public A disposeWindowAfter(int delay, final A w) { if (w != null) swingLater(delay, new Runnable() { public void run() { try { w.dispose(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "w.dispose();"; } }); return w; } static public A disposeWindowAfter(A w, double seconds) { return disposeWindowAfter(toMS_int(seconds), w); } static public A disposeWindowAfter(double seconds, A w) { return disposeWindowAfter(w, seconds); } static public Map componentID_map = weakHashMap(); static public String componentID(Component c) { return c == null ? null : componentID_map.get(c); } static public ThreadLocal htmlencode_forParams_useV2 = new ThreadLocal(); static public String htmlencode_forParams(String s) { if (s == null) return ""; if (isTrue(htmlencode_forParams_useV2.get())) return htmlencode_forParams_v2(s); StringBuilder out = new StringBuilder(Math.max(16, s.length())); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c > 127 || c == '"' || c == '<' || c == '>') { out.append("&#"); out.append((int) c); out.append(';'); } else out.append(c); } return out.toString(); } static public Map weakHashMap() { return newWeakHashMap(); } static public Set emptySet() { return new HashSet(); } static public TreeSet asTreeSet(Collection set) { return set == null ? null : set instanceof TreeSet ? (TreeSet) set : new TreeSet(set); } static public class getOpt_Map extends WeakHashMap { public getOpt_Map() { if (getOpt_special == null) getOpt_special = new HashMap(); clear(); } public void clear() { super.clear(); put(Class.class, getOpt_special); put(String.class, getOpt_special); } } static final public Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map())); static public HashMap getOpt_special; static public Map getOpt_getFieldMap(Object o) { Class c = _getClass(o); HashMap map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); return map; } static public Object getOpt_cached(Object o, String field) { try { if (o == null) return null; Map map = getOpt_getFieldMap(o); if (map == getOpt_special) { if (o instanceof Class) return getOpt((Class) o, field); if (o instanceof Map) return ((Map) o).get(field); } Field f = map.get(field); if (f != null) return f.get(o); if (o instanceof DynamicObject) return syncMapGet2(((DynamicObject) o).fieldValues, field); return null; } catch (Exception __e) { throw rethrow(__e); } } static public HashMap getOpt_makeCache(Class c) { HashMap map; if (isSubtypeOf(c, Map.class)) map = getOpt_special; else { map = new HashMap(); if (!reflection_classesNotToScan().contains(c.getName())) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) { makeAccessible(f); String name = f.getName(); if (!map.containsKey(name)) map.put(name, f); } _c = _c.getSuperclass(); } while (_c != null); } } if (getOpt_cache != null) getOpt_cache.put(c, map); return map; } static public void fillJMenu(final JMenu m, Object... x) { if (x == null) return; for (int i = 0; i < l(x); i++) { Object o = x[i], y = get(x, i + 1); if (o instanceof List) fillJMenu(m, asArray((List) o)); else if (isMenuSeparatorIndicator(o)) { if (menuItemCount(m) != 0) m.addSeparator(); } else if (o instanceof LiveValue && ((LiveValue) o).getType() == String.class && isRunnableX(y)) { final LiveValue lv = (LiveValue) o; final JMenuItem mi = jmenuItem(or2(unCurlyBracket(lv.get()), "..."), y); bindLiveValueListenerToComponent(mi, lv, new Runnable() { public void run() { try { String s = lv.get(); if (isCurlyBracketed(s)) { setEnabled(mi, false); s = unCurlyBracket(s); } else setEnabled(mi, true); setText(mi, s); revalidate(m); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = lv!;\r\n if (isCurlyBracketed(s)) {\r\n setEnabled(mi,..."; } }); print("bound live value " + lv + " to menu item " + mi); m.add(mi); ++i; } else if (o instanceof String && isRunnableX(y)) { m.add(jmenuItem((String) o, y)); ++i; } else if (o instanceof JMenuItem) m.add((JMenuItem) o); else if (o instanceof String || o instanceof Action || o instanceof Component) call(m, "add", o); else if (o == null && y instanceof Runnable) ++i; else if (o != null) print("Unknown menu item: " + o); } } static public Component childWithClassNameEndingWith(Component c, String suffix) { if (endsWith(className(c), suffix)) return c; Component x; for (Component comp : getComponents(c)) if ((x = childWithClassNameEndingWith(comp, suffix)) != null) return x; return null; } static public JMenuItem jMenuItem(final String text) { return jmenuItem(text); } static public JMenuItem jMenuItem(String text, Object r) { return jmenuItem(text, r); } static public Pair jmenu_autoMnemonic(String s) { int i = indexOf(s, '&'); if (i >= 0 && i < l(s) && isLetterOrDigit(s.charAt(i + 1))) return pair(substring(s, 0, i) + substring(s, i + 1), (int) s.charAt(i + 1)); return pair(s, 0); } static public JMenuItem disableMenuItem(final JMenuItem mi) { if (mi != null) { swing(() -> { mi.setEnabled(false); }); } return mi; } static public JMenuItem directJMenuItem(Action a) { return new JMenuItem(a) { public Dimension getMaximumSize() { return new Dimension(super.getPreferredSize().width, super.getMaximumSize().height); } }; } static public JMenuItem directJMenuItem(String text, Object action) { return directJMenuItem(abstractAction(text, action)); } static public JMenuBar addMenuBar(final Component c) { return swing(new F0() { public JMenuBar get() { try { RootPaneContainer f = getPossiblyInternalFrame(c); if (f == null) return null; JMenuBar bar = (JMenuBar) (call(f, "getJMenuBar")); if (bar == null) { setMenuBar(f, bar = new JMenuBar()); revalidate((Component) f); } return bar; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "RootPaneContainer f = getPossiblyInternalFrame(c);\r\n if (f == null) null;\r..."; } }); } static public JInternalFrame getInternalFrame(final Object _o) { return _o == null ? null : swing(new F0() { public JInternalFrame get() { try { Object o = _o; if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof JInternalFrame) return (JInternalFrame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n if (o instanceof ButtonGroup) o = first(buttonsInGroup((Button..."; } }); } static public A optCast(Class c, Object o) { return isInstance(c, o) ? (A) o : null; } static public Window getWindow(Object o) { if (!(o instanceof Component)) return null; return swing(() -> { Component c = (Component) o; while (c != null) { if (c instanceof Window) return ((Window) c); c = c.getParent(); } return null; }); } static public List javaTokC(String s) { if (s == null) return null; int l = s.length(); ArrayList tok = new ArrayList(); int i = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j + 2, l)).equals("*/")); j = Math.min(j + 2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener || s.charAt(j) == '\n') { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else if (c == '[' && d == '[') { do ++j; while (j + 1 < l && !s.substring(j, j + 2).equals("]]")); j = Math.min(j + 2, l); } else if (c == '[' && d == '=' && i + 2 < l && s.charAt(i + 2) == '[') { do ++j; while (j + 2 < l && !s.substring(j, j + 3).equals("]=]")); j = Math.min(j + 3, l); } else ++j; tok.add(javaTok_substringC(s, i, j)); i = j; } return tok; } static public Runnable asRunnable(Object o) { return toRunnable(o); } static public void _inheritThreadInfo(Object info) { _threadInheritInfo(info); } static public A popLast(List l) { return liftLast(l); } static public List popLast(int n, List l) { return liftLast(n, l); } static public boolean isAllUpperCase(String s) { return hasLettersAllUpperCase(s); } static public boolean isUpperCaseLetter(char c) { return Character.isUpperCase(c); } static public A componentPopupMenuItem(A c, final String name, final Object action) { componentPopupMenu(c, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, name, action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, name, action);"; } }); return c; } static public void componentPopupMenuItem(JComponent c, final JMenuItem menuItem) { componentPopupMenu(c, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, menuItem); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, menuItem);"; } }); } static public String copyTextToClipboard(Object _text) { String text = str(_text); StringSelection selection = new StringSelection(text); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); vmBus_send("newClipboardContents", text); return text; } static public AbstractAction abstractAction(String name, final Object runnable) { return new AbstractAction(name) { public void actionPerformed(ActionEvent evt) { pcallF(runnable); } }; } static public ThreadLocal addInternalFrame_dontSelect = new ThreadLocal(); static public ThreadLocal addInternalFrame_layer = new ThreadLocal(); static public ThreadLocal addInternalFrame_toBack = new ThreadLocal(); static public JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final int x, final int y, final int w, final int h) { return addInternalFrame(desktop, title, x, y, w, h, null); } static public JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final int x, final int y, final int w, final int h, final Component contents) { return addInternalFrame(desktop, title, rect(x, y, w, h), contents); } static public JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final Component contents) { return addInternalFrame(desktop, title, null, contents); } static public JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final Rect r, final Component contents) { final boolean dontSelect = isTrue(optParam(addInternalFrame_dontSelect)); final boolean toBack = isTrue(optParam(addInternalFrame_toBack)); final Integer layer = optParam(addInternalFrame_layer); return swing(new F0() { public JInternalFrame get() { try { JInternalFrame frame; if (contents instanceof JInternalFrame) frame = (JInternalFrame) contents; else { frame = jInternalFrame(title); setInternalFrameContents(frame, contents); } frame.setVisible(true); desktop.add(frame, layer); if (r != null) setBounds(frame, r); else internalFrameDefaultPosition(frame); if (dontSelect) if (toBack) frame.toBack(); else frame.toFront(); else frame.setSelected(true); return fixInternalFrame(frame); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JInternalFrame frame;\r\n if (contents instanceof JInternalFrame)\r\n fra..."; } }); } static public JInternalFrame addInternalFrame(JDesktopPane desktop, String title) { return addInternalFrame(desktop, title, jpanel()); } static public JInternalFrame minInternalFrameWidth(final JInternalFrame frame, final int w) { { swing(() -> { if (frame != null && frame.getWidth() < w) frame.setSize(w, frame.getHeight()); }); } return frame; } static public JInternalFrame minInternalFrameWidth(int w, JInternalFrame frame) { return minInternalFrameWidth(frame, w); } static public A packInternalFrameVertically(A c) { return packInternalFrameVertically(-1, c); } static public A packInternalFrameVertically(int width, A c) { final JInternalFrame win = getInternalFrame(c); if (win == null) return c; final int w = width < 0 ? win.getWidth() : width; { swing(() -> { win.pack(); win.setSize(w, win.getHeight()); fixInternalFrame(win); }); } return c; } static public JInternalFrame centerInternalFrame(final JInternalFrame f) { { swing(() -> { Container c = f.getParent(); if (c != null) { f.setLocation((c.getWidth() - f.getWidth()) / 2, (c.getHeight() - f.getHeight()) / 2); } }); } return f; } static public JInternalFrame centerInternalFrame(final int w, final int h, final JInternalFrame f) { { swing(() -> { f.setSize(w, h); }); } return centerInternalFrame(f); } static public int packFrame_minw = 150, packFrame_minh = 50; static public A packFrame(final A c) { { swing(() -> { Window w = getWindow(c); if (w != null) { w.pack(); int maxW = getScreenWidth() - 50, maxH = getScreenHeight() - 50; w.setSize(min(maxW, max(w.getWidth(), packFrame_minw)), min(maxH, max(w.getHeight(), packFrame_minh))); } }); } return c; } static public JFrame packFrame(ButtonGroup g) { return packFrame(getFrame(g)); } static public JFrame showFrame() { return makeFrame(); } static public JFrame showFrame(Object content) { return makeFrame(content); } static public JFrame showFrame(String title) { return makeFrame(title); } static public JFrame showFrame(String title, Object content) { return makeFrame(title, content); } static public JFrame showFrame(final JFrame f) { if (f != null) { swing(() -> { if (frameTooSmall(f)) frameStandardSize(f); if (!f.isVisible()) f.setVisible(true); if (f.getState() == Frame.ICONIFIED) f.setState(Frame.NORMAL); }); } return f; } static public JFrame showFrame(String title, Object content, JFrame frame) { if (frame == null) return showFrame(title, content); else { frame.setTitle(title); setFrameContents(frame, content); return frame; } } static public JPanel marginPanel() { return jtransparent(borderLayoutPanel()); } static public > void forEachLevel2(Iterable l, IVF1 f) { if (l != null) for (B b : l) forEach(b, f); } static public > void forEachLevel2(IVF1 f, Iterable l) { forEachLevel2(f, l); } static public Dimension getMinimumSize(final Component c) { return c == null ? null : swing(new F0() { public Dimension get() { try { return c.getMinimumSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getMinimumSize();"; } }); } static public JComponent wrap(Object swingable) { return _recordNewSwingComponent(wrap_2(swingable)); } static public JComponent wrap_2(Object swingable) { if (swingable == null) return null; JComponent c; if (swingable instanceof Component) c = componentToJComponent((Component) swingable); else if (swingable instanceof Swingable) c = componentToJComponent(((Swingable) swingable).visualize()); else c = componentToJComponent((Component) callOpt(swingable, "swing")); if (c instanceof JTable || c instanceof JList || c instanceof JTextArea || c instanceof JEditorPane || c instanceof JTextPane || c instanceof JTree) return jscroll(c); return c == null ? jlabel(str(swingable)) : c; } static public A jPreferWidth(int w, A c) { Dimension size = c.getPreferredSize(); c.setPreferredSize(new Dimension(w, size.height)); return c; } static public JComponent componentToJComponent(Component c) { if (c instanceof JComponent) return (JComponent) c; if (c instanceof JFrame) return ((JFrame) c).getRootPane(); if (c == null) return null; throw fail("boohoo " + getClassName(c)); } static public Component wrapForSmartAdd(Object o) { if (o == null) return jpanel(); if (o instanceof String) return jlabel((String) o); return wrap(o); } static public boolean hasMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args) != null; } static public void disposeWindow(final Window window) { if (window != null) { swing(() -> { window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); myFrames_list.remove(window); window.dispose(); }); } } static public void disposeWindow(final Component c) { disposeWindow(getWindow(c)); } static public void disposeWindow(Object o) { if (o != null) disposeWindow(((Component) o)); } static public void disposeWindow() { disposeWindow(heldInstance(Component.class)); } static public List allChildren(Component c) { return childrenOfType(c, Component.class); } static public void onEnterIfTextField(Component c, Object action) { if (action == null) return; if (c instanceof JTextField) onEnter((JTextField) c, action); else if (c instanceof JComboBox) onEnter((JComboBox) c, action); } static public Object[] flattenArray2(Object... a) { List l = new ArrayList(); if (a != null) for (Object x : a) if (x instanceof Object[]) l.addAll(asList((Object[]) x)); else if (x instanceof Collection) l.addAll((Collection) x); else l.add(x); return asObjectArray(l); } static public List withoutNulls(Iterable l) { if (l instanceof List) if (!containsNulls((List) l)) return ((List) l); List l2 = new ArrayList(); for (A a : l) if (a != null) l2.add(a); return l2; } static public Map withoutNulls(Map map) { Map map2 = similarEmptyMap(map); for (A a : keys(map)) if (a != null) { B b = map.get(a); if (b != null) map2.put(a, b); } return map2; } static public List withoutNulls(A[] l) { List l2 = new ArrayList(); if (l != null) for (A a : l) if (a != null) l2.add(a); return l2; } static public boolean isEditableComboBox(final JComboBox cb) { return cb != null && swing(new F0() { public Boolean get() { try { return cb.isEditable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret cb.isEditable();"; } }); } static public A swingConstruct(final Class c, final Object... args) { return swing(new F0() { public A get() { try { return nuObject(c, args); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret nuObject(c, args);"; } }); } static public boolean isCurlyBraced(String s) { List tok = tok_combineCurlyBrackets_keep(javaTok(s)); return l(tok) == 3 && startsWithAndEndsWith(tok.get(1), "{", "}"); } static public String tok_unCurlyBracket(String s) { return isCurlyBraced(s) ? join(dropFirstThreeAndLastThree(javaTok(s))) : s; } static public String strUnnull(Object o) { return o == null ? "" : str(o); } static public String jlabel_textAsHTML_center_ifNeeded(String text) { if (swic(text, "") && ewic(text, "")) return text; if (!containsNewLines(text)) return text; return jlabel_textAsHTML_center(text); } static public Dimension getPreferredSize(final Component c) { return c == null ? null : swing(new F0() { public Dimension get() { try { return c.getPreferredSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getPreferredSize();"; } }); } static public Lock downloadLock_lock = fairLock(); static public Lock downloadLock() { return downloadLock_lock; } static public String getSnippetTitleOpt(String s) { try { return isSnippetID(s) ? getSnippetTitle(s) : s; } catch (Throwable __e) { printStackTrace(__e); } return s; } static public List childrenOfType(Component c, Class theClass) { List l = new ArrayList(); scanForComponents(c, theClass, l); return l; } static public List childrenOfType(Class theClass, Component c) { return childrenOfType(c, theClass); } static public JButton findButton(Component c, String name) { for (JButton b : childrenOfType(c, JButton.class)) if (eq(b.getText(), name)) return b; for (JButton b : childrenOfType(getFrame(c), JButton.class)) if (eq(b.getText(), name)) return b; return null; } static public JButton findButton(Component c) { return childOfType(c, JButton.class); } static public String renderFileInfo(File f) { return f == null ? "-" : f2s(f) + " " + (f.isFile() ? "(file, " + n2(fileSize(f)) + " bytes)" : f.isDirectory() ? "(dir)" : "(not found)"); } static public void logQuotedWithTime(String s) { logQuotedWithTime(standardLogFile(), s); } static public void logQuotedWithTime(File logFile, String s) { logQuoted(logFile, logQuotedWithTime_format(s)); } static public void logQuotedWithTime(String logFile, String s) { logQuoted(logFile, logQuotedWithTime_format(s)); } static public String logQuotedWithTime_format(String s) { return (now()) + " " + s; } static public JTextArea wrappedTextArea(final JTextArea ta) { enableWordWrapForTextArea(ta); return ta; } static public JTextArea wrappedTextArea() { return wrappedTextArea(jtextarea()); } static public JTextArea wrappedTextArea(String text) { JTextArea ta = wrappedTextArea(); setText(ta, text); return ta; } static public A onClick(final A c, final Object runnable) { if (c != null) { swing(() -> { c.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { callF(runnable, e); } }); }); } return c; } static public void onClick(JButton btn, final Object runnable) { onEnter(btn, runnable); } static public Font typeWriterFont() { return typeWriterFont(iround(14 * getSwingFontScale())); } static public Font typeWriterFont(int size) { return new Font("Courier", Font.PLAIN, size); } static public JScrollPane jscroll(final Component c) { return swing(new F0() { public JScrollPane get() { try { return new JScrollPane(c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret new JScrollPane(c);"; } }); } static public Rect preferredScreenBounds() { return screenBounds_safe(preferredScreen()); } static public boolean vmBus_anyFalse(String msg, Object... args) { return contains(vmBus_queryAll(msg, args), false); } static public int toMS_int(double seconds) { return toInt_checked((long) (seconds * 1000)); } static public Map myFrames_list = weakHashMap(); static public List myFrames() { return swing(new F0>() { public List get() { try { return keysList(myFrames_list); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret keysList(myFrames_list);"; } }); } static public String htmlencode_forParams_v2(String s) { if (s == null) return ""; StringBuilder out = new StringBuilder(Math.max(16, s.length())); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') { out.append("&#"); out.append((int) c); out.append(';'); } else out.append(c); } return out.toString(); } static public void clear(Collection c) { if (c != null) c.clear(); } static public void clear(Map map) { if (map != null) map.clear(); } static public List _registerDangerousWeakMap_preList; static public A _registerDangerousWeakMap(A map) { return _registerDangerousWeakMap(map, null); } static public A _registerDangerousWeakMap(A map, Object init) { callF(init, map); if (init instanceof String) { final String f = (String) init; init = new VF1() { public void get(Map map) { try { callMC(f, map); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callMC(f, map)"; } }; } if (javax() == null) { if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList(); _registerDangerousWeakMap_preList.add(pair(map, init)); return map; } call(javax(), "_registerDangerousWeakMap", map, init); return map; } static public void _onLoad_registerDangerousWeakMap() { assertNotNull(javax()); if (_registerDangerousWeakMap_preList == null) return; for (Pair p : _registerDangerousWeakMap_preList) _registerDangerousWeakMap(p.a, p.b); _registerDangerousWeakMap_preList = null; } static public B syncMapGet2(Map map, A a) { if (map == null) return null; synchronized (collectionMutex(map)) { return map.get(a); } } static public B syncMapGet2(A a, Map map) { return syncMapGet2(map, a); } static public boolean isSubtypeOf(Class a, Class b) { return a != null && b != null && b.isAssignableFrom(a); } static public Set reflection_classesNotToScan_value = litset("jdk.internal.loader.URLClassPath"); static public Set reflection_classesNotToScan() { return reflection_classesNotToScan_value; } static public int menuItemCount(JMenu menu) { return menu == null ? 0 : swing(() -> menu.getItemCount()); } static public List getComponents(final Component c) { return !(c instanceof Container) ? emptyList() : asList(swing(new F0() { public Component[] get() { try { return ((Container) c).getComponents(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret ((Container) c).getComponents();"; } })); } static public void setMenuBar(final JMenuBar mb, final RootPaneContainer f) { { swing(() -> { call(f, "setJMenuBar", mb); revalidate((Component) f); }); } } static public void setMenuBar(RootPaneContainer f, JMenuBar mb) { setMenuBar(mb, f); } static public boolean isInstance(Class type, Object arg) { return type.isInstance(arg); } static public A liftLast(List l) { if (empty(l)) return null; int i = l(l) - 1; A a = l.get(i); l.remove(i); return a; } static public List liftLast(int n, List l) { int i = l(l) - n; List part = cloneSubList(l, i); removeSubList(l, i); return part; } static public boolean hasLettersAllUpperCase(String s) { return hasLetters(s) && !containsLowerCase(s); } static public Rect rect(int x, int y, int w, int h) { return new Rect(x, y, w, h); } static public Rect rect(Pt p, int w, int h) { return new Rect(p.x, p.y, w, h); } static public Rect rect(int w, int h) { return new Rect(0, 0, w, h); } static public boolean jInternalFrame_iconifiable = true; static public JInternalFrame jInternalFrame() { return jInternalFrame(""); } static public JInternalFrame jInternalFrame(final String title) { return swing(new F0() { public JInternalFrame get() { try { JInternalFrame f = new JInternalFrame(title, true, true, true, jInternalFrame_iconifiable); f.setVisible(true); return f; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JInternalFrame f = new JInternalFrame(title, true, true, true, jInternalFrame..."; } }); } static public void setInternalFrameContents(final Component c, final Object contents) { { swing(() -> { JInternalFrame frame = getInternalFrame(c); if (frame == null) return; frame.getContentPane().removeAll(); frame.getContentPane().setLayout(new BorderLayout()); if (contents != null) frame.getContentPane().add(wrap(contents)); revalidate(frame); }); } } static public A setBounds(final int x, final int y, final int w, final int h, final A a) { if (a != null) { swing(() -> { a.setBounds(x, y, w, h); }); } return a; } static public A setBounds(A a, Rect r) { if (a != null && r != null) { swing(() -> { a.setBounds(toRectangle(r)); }); } return a; } static public A setBounds(A a, Rectangle r) { if (a != null && r != null) { swing(() -> { a.setBounds(r); }); } return a; } static public A setBounds(Rect r, A a) { return setBounds(a, r); } static public A setBounds(A a, int x, int y, int w, int h) { return setBounds(x, y, w, h, a); } static public void internalFrameDefaultPosition(JInternalFrame f) { f.setSize(500, 300); centerInternalFrame(f); } static public int fixInternalFrame_borderTopLeft = 0; static public int fixInternalFrame_borderBottomRight = 40; static public JInternalFrame fixInternalFrame(final JInternalFrame f) { return swing(new F0() { public JInternalFrame get() { try { Container c = f.getParent(); if (c == null) return f; Rect r = toRect(f.getBounds()); int a = fixInternalFrame_borderTopLeft, b = fixInternalFrame_borderBottomRight; Rect outer = new Rect(a, a, c.getWidth() - b, c.getHeight() - b); if (!rectContains(outer, r)) f.setLocation(max(a, min(r.x, outer.x2())), max(a, min(r.y, outer.y2()))); if (r.w > c.getWidth() || r.h > c.getHeight()) f.setSize(c.getWidth() - a, c.getHeight() - a); return f; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Container c = f.getParent();\r\n if (c == null) ret f;\r\n Rect r = toRect(..."; } }); } static public JPanel jpanel(LayoutManager layout) { return swingNu(JPanel.class, layout); } static public JPanel jpanel() { return swingNu(JPanel.class); } static public int getScreenWidth() { return getScreenSize().width; } static public int getScreenHeight() { return getScreenSize().height; } static public String makeFrame_defaultIcon; static public boolean makeFrame_hideConsole = false; static public ThreadLocal> makeFrame_post = new ThreadLocal(); static public JFrame makeFrame() { return makeFrame((Component) null); } static public JFrame makeFrame(Object content) { return makeFrame(programTitle(), content); } static public JFrame makeFrame(String title) { return makeFrame(title, null); } static public JFrame makeFrame(String title, Object content) { return makeFrame(title, content, true); } static public JFrame makeFrame(final String title, final Object content, final boolean showIt) { final VF1 post = optParam(makeFrame_post); return swing(new F0() { public JFrame get() { try { if (getFrame(content) != null) return getFrame(setFrameTitle((Component) content, title)); final JFrame frame = new JFrame(title); if (makeFrame_defaultIcon != null) setFrameIconLater(frame, makeFrame_defaultIcon); _initFrame(frame); Component wrapped = wrap(content); if (wrapped != null) frame.getContentPane().add(wrapped); frame.setBounds(defaultNewFrameBounds()); callF(post, frame); if (showIt) frame.setVisible(true); if (showIt && makeFrame_hideConsole) { hideConsole(); makeFrame_hideConsole = false; } return frame; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (getFrame(content) != null)\r\n ret getFrame(setFrameTitle((Component) ..."; } }); } static public boolean frameTooSmall(JFrame frame) { return frame.getWidth() < 100 || frame.getHeight() < 50; } static public void frameStandardSize(JFrame frame) { frame.setBounds(300, 100, 500, 400); } static public void setFrameContents(final Component c, final Object contents) { swing(() -> { JFrame frame = getFrame(c); if (frame == null) return; frame.getContentPane().removeAll(); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(wrap(contents)); revalidate(frame); }); } static public A jtransparent(final A a) { { swing(() -> { a.setOpaque(false); }); } return a; } static public JPanel borderLayoutPanel() { return jpanel(new BorderLayout()); } static public void forEach(Iterable l, IVF1 f) { if (f != null && l != null) for (A a : l) callF(f, a); } static public void forEach(IVF1 f, Iterable l) { forEach(l, f); } static public void forEach(A[] l, IVF1 f) { if (f != null && l != null) for (A a : l) callF(f, a); } static public void forEach(IVF1 f, A[] l) { forEach(l, f); } static public void forEach(Map map, IVF2 f) { for (Map.Entry __0 : _entrySet(map)) { A a = __0.getKey(); B b = __0.getValue(); f.get(a, b); } } static public A _recordNewSwingComponent(A c) { if (c != null) callF((Object) vm_generalMap_get("newSwingComponentRegistry"), (Object) c); return c; } static public JLabel jlabel(final String text) { return swingConstruct(BetterLabel.class, text); } static public JLabel jlabel() { return jlabel(" "); } static public JTextField onEnter(final JTextField tf, final Object action) { if (action == null || tf == null) return tf; tf.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { tf.selectAll(); callF(action); } catch (Throwable __e) { messageBox(__e); } } }); return tf; } static public JButton onEnter(JButton btn, final Object action) { if (action == null || btn == null) return btn; btn.addActionListener(actionListener(action)); return btn; } static public JList onEnter(JList list, Object action) { list.addKeyListener(enterKeyListener(rCallOnSelectedListItem(list, action))); return list; } static public JComboBox onEnter(final JComboBox cb, final Object action) { { swing(() -> { if (cb.isEditable()) { JTextField text = (JTextField) cb.getEditor().getEditorComponent(); onEnter(text, action); } else { cb.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "enter"); cb.getActionMap().put("enter", abstractAction("", new Runnable() { public void run() { try { cb.hidePopup(); callF(action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cb.hidePopup(); callF(action);"; } })); } }); } return cb; } static public JTable onEnter(final JTable table, final Object action) { table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter"); table.getActionMap().put("Enter", new AbstractAction() { public void actionPerformed(ActionEvent e) { callF(action, table.getSelectedRow()); } }); return table; } static public JTextField onEnter(Object action, JTextField tf) { return onEnter(tf, action); } static public boolean containsNulls(Collection c) { return contains(c, null); } static public Map similarEmptyMap(Map m) { if (m instanceof TreeMap) return new TreeMap(((TreeMap) m).comparator()); if (m instanceof LinkedHashMap) return new LinkedHashMap(); return new HashMap(); } static public Map similarEmptyMap(Iterable m) { if (m instanceof TreeSet) return new TreeMap(((TreeSet) m).comparator()); if (m instanceof LinkedHashSet) return new LinkedHashMap(); return new HashMap(); } static public List tok_combineCurlyBrackets_keep(List tok) { List l = new ArrayList(); for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i) && eq(t, "{")) { int j = findEndOfCurlyBracketPart(tok, i); l.add(joinSubList(tok, i, j)); i = j - 1; } else l.add(t); } return l; } static public boolean startsWithAndEndsWith(String s, String prefix, String suffix) { return startsWith(s, prefix) && endsWith(s, suffix); } static public List dropFirstThreeAndLastThree(List l) { return dropFirstAndLast(3, l); } static public boolean containsNewLines(String s) { return containsNewLine(s); } static public String jlabel_textAsHTML_center(String text) { return "
" + replace(htmlencode2(text), "\n", "
") + "
"; } static public String getSnippetTitle(String id) { if (id == null) return null; if (!isSnippetID(id)) return "?"; IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.getSnippetTitle(id); return getSnippetTitle_noResourceLoader(id); } static public String getSnippetTitle_noResourceLoader(String id) { try { if (isLocalSnippetID(id)) return localSnippetTitle(id); long parsedID = parseSnippetID(id); String url; if (isImageServerSnippet(parsedID)) url = imageServerURL() + "title/" + parsedID + muricaCredentialsQuery(); else if (isGeneralFileServerSnippet(parsedID)) url = "http://butter.botcompany.de:8080/files/name/" + parsedID; else url = tb_mainServer() + "/tb-int/getfield.php?id=" + parsedID + "&field=title" + standardCredentials_noCookies(); String title = trim(loadPageSilently(url)); if (title != null) try { saveTextFileIfChanged(snippetTitle_cacheFile(id), title); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } return or(title, "?"); } catch (Exception __e) { throw rethrow(__e); } } static public String getSnippetTitle(long id) { return getSnippetTitle(fsI(id)); } static public
void scanForComponents(final Component c, final Class theClass, final List l) { if (theClass.isInstance(c)) l.add((A) c); if (c instanceof Container) { swing(() -> { for (Component comp : ((Container) c).getComponents()) scanForComponents(comp, theClass, l); }); } } static public A childOfType(Component c, Class theClass) { return first(childrenOfType(c, theClass)); } static public A childOfType(Class theClass, Component c) { return childOfType(c, theClass); } static public long fileSize(String path) { return getFileSize(path); } static public long fileSize(File f) { return getFileSize(f); } static public File standardLogFile() { return getProgramFile("log"); } static public void logQuoted(String logFile, String line) { logQuoted(getProgramFile(logFile), line); } static public void logQuoted(File logFile, String line) { appendToFile(logFile, quote(line) + "\n"); } static public JTextArea enableWordWrapForTextArea(JTextArea ta) { return enableWordWrapForTextArea(ta, true); } static public JTextArea enableWordWrapForTextArea(JTextArea ta, boolean enabled) { if (ta != null) { swing(() -> { ta.setLineWrap(enabled); ta.setWrapStyleWord(true); }); } return ta; } static public JTextArea jtextarea() { return jTextArea(); } static public JTextArea jtextarea(String text) { return jTextArea(text); } static public float getSwingFontScale() { return or((Float) vm_generalMap_get("swingFontScale_value"), 1f); } static public Rect screenBounds_safe(int iScreen) { return screenBounds(min(iScreen, screenCount() - 1)); } static public IF0 preferredScreen; static public int preferredScreen() { return preferredScreen != null ? preferredScreen.get() : preferredScreen_base(); } final static public int preferredScreen_fallback(IF0 _f) { return _f != null ? _f.get() : preferredScreen_base(); } static public int preferredScreen_base() { return 0; } static public int toInt_checked(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static public List keysList(Map map) { return cloneListSynchronizingOn(keys(map), map); } static public List keysList(MultiSet ms) { return ms == null ? null : keysList(ms.map); } static public HashSet litset(A... items) { return lithashset(items); } static public List cloneSubList(List l, int startIndex, int endIndex) { return newSubList(l, startIndex, endIndex); } static public List cloneSubList(List l, int startIndex) { return newSubList(l, startIndex); } static public boolean hasLetters(String s) { for (int i = 0; i < s.length(); i++) if (Character.isLetter(s.charAt(i))) return true; return false; } static public boolean containsLowerCase(String s) { for (int i = 0; i < l(s); i++) if (isLowerCase(s.charAt(i))) return true; return false; } static public Rectangle toRectangle(Rect r) { return r == null ? null : r.getRectangle(); } static public Rect toRect(Rectangle r) { return r == null ? null : new Rect(r); } static public Rect toRect(RectangularShape r) { return r == null ? null : toRect(r.getBounds()); } static public Rect toRect(Rect r) { return r; } static public boolean rectContains(int x1, int y1, int w, int h, Pt p) { return p.x >= x1 && p.y >= y1 && p.x < x1 + w && p.y < y1 + h; } static public boolean rectContains(Rect a, Rect b) { return b.x >= a.x && b.y >= a.y && b.x2() <= a.x2() && b.y2() <= a.y2(); } static public boolean rectContains(Rect a, Rectangle b) { return rectContains(a, toRect(b)); } static public boolean rectContains(Rect a, int x, int y) { return a != null && a.contains(x, y); } static public Dimension getScreenSize() { return Toolkit.getDefaultToolkit().getScreenSize(); } static public String programTitle() { return getProgramName(); } static public A setFrameTitle(A c, final String title) { final Frame f = getAWTFrame(c); if (f != null) { swing(() -> { f.setTitle(title); }); } return c; } static public A setFrameTitle(String title, A c) { return setFrameTitle(c, title); } static public JFrame setFrameTitle(String title) { Object f = getOpt(mc(), "frame"); if (f instanceof JFrame) return setFrameTitle((JFrame) f, title); return null; } static public JFrame setFrameIconLater(Component c, final String imageID) { final JFrame frame = getFrame(c); if (frame != null) startThread("Loading Icon", new Runnable() { public void run() { try { final Image i = imageIcon(or2(imageID, "#1005557")).getImage(); swingLater(new Runnable() { public void run() { try { frame.setIconImage(i); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "frame.setIconImage(i);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final Image i = imageIcon(or2(imageID, \"#1005557\")).getImage();\r\n swingL..."; } }); return frame; } static public void _initFrame(JFrame f) { myFrames_list.put(f, Boolean.TRUE); standardTitlePopupMenu(f); } static public Rectangle defaultNewFrameBounds_r = new Rectangle(300, 100, 500, 400); static public Rectangle defaultNewFrameBounds() { return swing(new F0() { public Rectangle get() { try { defaultNewFrameBounds_r.translate(60, 20); var bounds = preferredScreenBounds(); if (!bounds.contains(defaultNewFrameBounds_r)) defaultNewFrameBounds_r.setLocation(centerX(bounds) + random_incl(-30, 30), centerY(bounds) + random_incl(-20, 20)); return new Rectangle(defaultNewFrameBounds_r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "defaultNewFrameBounds_r.translate(60, 20);\r\n var bounds = preferredScreenB..."; } }); } static public void hideConsole() { final JFrame frame = consoleFrame(); if (frame != null) { autoVMExit(); swingLater(new Runnable() { public void run() { try { frame.setVisible(false); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "frame.setVisible(false);"; } }); } } static public KeyListener enterKeyListener(final Object action) { return new KeyAdapter() { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_ENTER) pcallF(action); } }; } static public Runnable rCallOnSelectedListItem(final JList list, final Object action) { return new Runnable() { public void run() { try { pcallF(action, getSelectedItem(list)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(action, getSelectedItem(list))"; } }; } static public int findEndOfCurlyBracketPart(List cnc, int i) { int j = i + 2, level = 1; while (j < cnc.size()) { if (eq(cnc.get(j), "{")) ++level; else if (eq(cnc.get(j), "}")) --level; if (level == 0) return j + 1; ++j; } return cnc.size(); } static public List dropFirstAndLast(int n, List l) { return cloneSubList(l, n, l(l) - n); } static public List dropFirstAndLast(int m, int n, List l) { return cloneSubList(l, m, l(l) - n); } static public List dropFirstAndLast(List l) { return dropFirstAndLast(1, l); } static public String dropFirstAndLast(String s) { return substring(s, 1, l(s) - 1); } static public String htmlencode2(String s) { return htmlencode_noQuotes(s); } static public IResourceLoader vm_getResourceLoader() { return proxy(IResourceLoader.class, vm_generalMap_get("_officialResourceLoader")); } static public boolean isLocalSnippetID(String snippetID) { return isSnippetID(snippetID) && isLocalSnippetID(psI(snippetID)); } static public boolean isLocalSnippetID(long snippetID) { return snippetID >= 1000 && snippetID <= 9999; } static public String localSnippetTitle(String snippetID) { if (!isLocalSnippetID(snippetID)) return null; File f = localSnippetFile(snippetID); if (!f.exists()) return null; return or2(getFileInfoField(dropExtension(f), "Title"), "Unnamed"); } static public String imageServerURL() { return or2(trim(loadTextFile(javaxDataDir("image-server-url.txt"))), "http://botcompany.de/images/raw/"); } static public String muricaCredentialsQuery() { return htmlQuery(muricaCredentials()); } static public boolean isGeneralFileServerSnippet(long id) { return id >= 1400000 && id < 1500000; } static public String standardCredentials_noCookies() { return standardCredentials() + "&noCookies=1"; } static public boolean saveTextFileIfChanged(File f, String contents) { return saveTextFileIfDifferent(f, contents); } static public File snippetTitle_cacheFile(String snippetID) { return javaxCachesDir("Snippet Titles/" + psI(snippetID)); } static public Lock appendToFile_lock = lock(); static public boolean appendToFile_keepOpen = false; static public HashMap appendToFile_writers = new HashMap(); static public void appendToFile(String path, String s) { try { Lock __0 = appendToFile_lock; lock(__0); try { mkdirsForFile(new File(path)); path = getCanonicalPath(path); Writer writer = appendToFile_writers.get(path); if (writer == null) { writer = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(path, true), "UTF-8")); if (appendToFile_keepOpen) appendToFile_writers.put(path, writer); } writer.write(s); if (!appendToFile_keepOpen) writer.close(); } finally { unlock(__0); } } catch (Exception __e) { throw rethrow(__e); } } static public void appendToFile(File path, String s) { if (path != null) appendToFile(path.getPath(), s); } static public void cleanMeUp_appendToFile() { AutoCloseable __3 = tempCleaningUp(); try { Lock __1 = appendToFile_lock; lock(__1); try { closeAllWriters(values(appendToFile_writers)); appendToFile_writers.clear(); } finally { unlock(__1); } } finally { _close(__3); } } static public JTextArea jTextArea() { return jTextArea(""); } static public JTextArea jTextArea(final String text) { return jTextAreaWithUndo(text); } static public Rect screenBounds(GraphicsDevice screen) { return screen == null ? null : toRect(screen.getDefaultConfiguration().getBounds()); } static public Rect screenBounds(int iScreen) { return screenBounds(get(screenDevices(), iScreen)); } static public int screenCount() { return l(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()); } static public ArrayList cloneListSynchronizingOn(Collection l, Object mutex) { if (l == null) return new ArrayList(); synchronized (mutex) { return new ArrayList(l); } } static public boolean isLowerCase(char c) { return Character.isLowerCase(c); } static public Frame getAWTFrame(final Object _o) { return swing(new F0() { public Frame get() { try { Object o = _o; if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof Frame) return (Frame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n /*\r\n ifdef HaveProcessing\r\n if (o instanceof PApplet) ..."; } }); } static public int imageIcon_cacheSize = 10; static public boolean imageIcon_verbose = false; static public Map imageIcon_cache; static public Lock imageIcon_lock = lock(); static public ThreadLocal imageIcon_fixGIF = new ThreadLocal(); static public ImageIcon imageIcon(String imageID) { try { if (imageID == null) return null; Lock __0 = imageIcon_lock; lock(__0); try { if (imageIcon_cache == null) imageIcon_cache = new MRUCache(imageIcon_cacheSize); imageID = fsI(imageID); ImageIcon ii = imageIcon_cache.get(imageID); if (ii == null) { if (imageIcon_verbose) print("Loading image icon: " + imageID); File f = loadBinarySnippet(imageID); Boolean b = imageIcon_fixGIF.get(); if (!isFalse(b)) ii = new ImageIcon(loadBufferedImageFixingGIFs(f)); else ii = new ImageIcon(f.toURI().toURL()); } else imageIcon_cache.remove(imageID); imageIcon_cache.put(imageID, ii); return ii; } finally { unlock(__0); } } catch (Exception __e) { throw rethrow(__e); } } static public ImageIcon imageIcon(File f) { try { return new ImageIcon(f.toURI().toURL()); } catch (Exception __e) { throw rethrow(__e); } } static public ImageIcon imageIcon(Image img) { return new ImageIcon(img); } static public ImageIcon imageIcon(RGBImage img) { return imageIcon(img.getBufferedImage()); } static public void standardTitlePopupMenu(final JFrame frame) { if (!isSubstanceLAF()) return; titlePopupMenu(frame, new VF1() { public void get(JPopupMenu menu) { try { boolean alwaysOnTop = frame.isAlwaysOnTop(); menu.add(jmenuItem("Restart Program", new Runnable() { public void run() { try { restart(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "restart();"; } })); menu.add(jmenuItem("Duplicate Program", new Runnable() { public void run() { try { duplicateThisProgram(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "duplicateThisProgram();"; } })); menu.add(jmenuItem("Show Console", new Runnable() { public void run() { try { showConsole(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showConsole();"; } })); menu.add(jCheckBoxMenuItem("Always On Top", alwaysOnTop, new Runnable() { public void run() { try { toggleAlwaysOnTop(frame); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "toggleAlwaysOnTop(frame)"; } })); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "bool alwaysOnTop = frame.isAlwaysOnTop();\r\n ifndef standardTitlePopupMenu_..."; } }); } static public Integer centerX(Rect r) { return rectCenterX(r); } static public int random_incl(int min, int max) { return random_incl(min, max, defaultRandomizer()); } static public int random_incl(int min, int max, Random random) { return random(min, max + 1, random); } static public int random_incl(int max) { return random(0, max + 1); } static public Integer centerY(Rect r) { return rectCenterY(r); } static public JFrame consoleFrame() { return (JFrame) getOpt(get(getJavaX(), "console"), "frame"); } static public void autoVMExit() { call(getJavaX(), "autoVMExit"); } static public String getSelectedItem(JList l) { return (String) l.getSelectedValue(); } static public String getSelectedItem(JComboBox cb) { return strOrNull(cb.getSelectedItem()); } static public String htmlencode_noQuotes(String s) { if (s == null) return ""; int n = s.length(); StringBuilder out = null; for (int i = 0; i < n; i++) { char c = s.charAt(i); if (c == '<') { if (out == null) out = new StringBuilder(Math.max(16, n)).append(takeFirst(i, s)); out.append("<"); } else if (c == '>') { if (out == null) out = new StringBuilder(Math.max(16, n)).append(takeFirst(i, s)); out.append(">"); } else if (c > 127 || c == '&') { int cp = s.codePointAt(i); if (out == null) out = new StringBuilder(Math.max(16, n)).append(takeFirst(i, s)); out.append("&#x"); out.append(intToHex_flexLength(cp)); out.append(';'); i += Character.charCount(cp) - 1; } else { if (out != null) out.append(c); } } return out == null ? s : out.toString(); } static public A proxy(Class intrface, final Object target) { if (target == null) return null; if (isInstance(intrface, target)) return (A) target; return (A) java.lang.reflect.Proxy.newProxyInstance(intrface.getClassLoader(), new Class[] { intrface }, new proxy_InvocationHandler(target)); } static public A proxy(Object target, Class intrface) { return proxy(intrface, target); } static public long psI(String snippetID) { return parseSnippetID(snippetID); } static public File localSnippetFile(long snippetID) { return localSnippetsDir(snippetID + ".text"); } static public File localSnippetFile(String snippetID) { return localSnippetFile(parseSnippetID(snippetID)); } static public String getFileInfoField(File f, String field) { return getOneLineFileInfoField(f, field); } static public File dropExtension(File f) { return f == null ? null : fileInSameDir(f, dropExtension(f.getName())); } static public String dropExtension(String s) { return takeFirst(s, smartLastIndexOf(s, '.')); } static public Object[] muricaCredentials() { String pass = muricaPassword(); return nempty(pass) ? new Object[] { "_pass", pass } : new Object[0]; } static public String standardCredentials() { String user = standardCredentialsUser(); String pass = standardCredentialsPass(); if (nempty(user) && nempty(pass)) return "&_user=" + urlencode(user) + "&_pass=" + urlencode(pass); return ""; } static public boolean saveTextFileIfDifferent(File f, String contents) { if (eq(loadTextFile(f), contents)) return false; { saveTextFile(f, contents); return true; } } static public File javaxCachesDir_dir; static public File javaxCachesDir() { return javaxCachesDir_dir != null ? javaxCachesDir_dir : new File(userHome(), "JavaX-Caches"); } static public File javaxCachesDir(String sub) { return newFile(javaxCachesDir(), sub); } static public String getCanonicalPath(File f) { try { return f == null ? null : f.getCanonicalPath(); } catch (Exception __e) { throw rethrow(__e); } } static public String getCanonicalPath(String path) { return getCanonicalPath(newFile(path)); } static public AutoCloseable tempCleaningUp() { AutoCloseable result = null; result = tempSetTL(ping_isCleanUpThread, true); return result; } static public void closeAllWriters(Collection l) { for (Writer w : unnull(l)) { try { w.close(); } catch (Throwable __e) { printStackTrace(__e); } } } static public JTextArea jTextAreaWithUndo() { return jTextAreaWithUndo(""); } static public JTextArea jTextAreaWithUndo(final String text) { return jenableUndoRedo(swingNu(JTextArea.class, text)); } static public List screenDevices() { return asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()); } static public File loadBinarySnippet(String snippetID) { IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.loadLibrary(snippetID); return loadBinarySnippet_noResourceLoader(snippetID); } static public File loadBinarySnippet_noResourceLoader(String snippetID) { try { long id = parseSnippetID(snippetID); if (isImageServerSnippet(id)) return loadImageAsFile(snippetID); File f = DiskSnippetCache_getLibrary(id); if (fileSize(f) == 0) f = loadDataSnippetToFile_noResourceLoader(snippetID); return f; } catch (Exception __e) { throw rethrow(__e); } } static public boolean loadBufferedImageFixingGIFs_debug = false; static public ThreadLocal> loadBufferedImageFixingGIFs_output = new ThreadLocal(); static public Image loadBufferedImageFixingGIFs(File file) { try { if (!file.exists()) return null; if (!isGIF(file)) return ImageIO.read(file); if (loadBufferedImageFixingGIFs_debug) print("loadBufferedImageFixingGIFs" + ": checking gif"); ImageReader reader = ImageIO.getImageReadersByFormatName("gif").next(); reader.setInput(ImageIO.createImageInputStream(file)); int numImages = reader.getNumImages(true); IIOMetadata imageMetaData = reader.getImageMetadata(0); String metaFormatName = imageMetaData.getNativeMetadataFormatName(); boolean foundBug = false; for (int i = 0; i < numImages && !foundBug; i++) { IIOMetadataNode root = (IIOMetadataNode) reader.getImageMetadata(i).getAsTree(metaFormatName); int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { org.w3c.dom.Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { String delay = ((IIOMetadataNode) node).getAttribute("delayTime"); if (Integer.parseInt(delay) == 0) { foundBug = true; } break; } } } if (loadBufferedImageFixingGIFs_debug) print("loadBufferedImageFixingGIFs" + ": " + f2s(file) + " foundBug=" + foundBug); Image image; if (!foundBug) { image = Toolkit.getDefaultToolkit().createImage(f2s(file)); } else { ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); { ImageOutputStream ios = ImageIO.createImageOutputStream(baoStream); try { ImageWriter writer = ImageIO.getImageWriter(reader); writer.setOutput(ios); writer.prepareWriteSequence(null); for (int i = 0; i < numImages; i++) { BufferedImage frameIn = reader.read(i); IIOMetadataNode root = (IIOMetadataNode) reader.getImageMetadata(i).getAsTree(metaFormatName); int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { org.w3c.dom.Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { String delay = ((IIOMetadataNode) node).getAttribute("delayTime"); if (Integer.parseInt(delay) == 0) { ((IIOMetadataNode) node).setAttribute("delayTime", "10"); } break; } } IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(frameIn), null); metadata.setFromTree(metadata.getNativeMetadataFormatName(), root); IIOImage frameOut = new IIOImage(frameIn, null, metadata); writer.writeToSequence(frameOut, writer.getDefaultWriteParam()); } writer.endWriteSequence(); } finally { _close(ios); } } byte[] data = baoStream.toByteArray(); setVar(loadBufferedImageFixingGIFs_output.get(), data); if (loadBufferedImageFixingGIFs_debug) print("Data size: " + l(data)); image = Toolkit.getDefaultToolkit().createImage(data); } return image; } catch (Exception __e) { throw rethrow(__e); } } static public boolean isSubstanceLAF() { return substanceLookAndFeelEnabled(); } static public boolean titlePopupMenu(final Component c, final Object menuMaker) { JComponent titleBar = getTitlePaneComponent(getPossiblyInternalFrame(c)); if (titleBar == null) { print("Can't add title right click!"); return false; } else { componentPopupMenu(titleBar, menuMaker); return true; } } static public void restart() { Object j = getJavaX(); call(j, "cleanRestart", get(j, "fullArgs")); } static public void duplicateThisProgram() { nohupJavax(trim(programID() + " " + smartJoin((String[]) get(getJavaX(), "fullArgs")))); } static public void showConsole() { callOpt(get(javax(), "console"), "showConsole"); } static public JCheckBoxMenuItem jCheckBoxMenuItem(String text, boolean checked, final Object r) { final JCheckBoxMenuItem mi = swing(() -> new JCheckBoxMenuItem(text, checked)); addActionListener(mi, new Runnable() { public void run() { try { callF(r, isChecked(mi)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(r, isChecked(mi))"; } }); return mi; } static public JCheckBoxMenuItem jCheckBoxMenuItem(String text, boolean checked, IVF1 r) { return jCheckBoxMenuItem(text, checked, (Object) r); } static public void toggleAlwaysOnTop(Window frame) { if (frame == null) return; { swing(() -> { frame.setAlwaysOnTop(!frame.isAlwaysOnTop()); }); } } static public Integer rectCenterX(Rect r) { return r == null ? null : r.x + r.w / 2; } static public Random defaultRandomizer() { return defaultRandomGenerator(); } static public Integer rectCenterY(Rect r) { return r == null ? null : r.y + r.h / 2; } static public String intToHex_flexLength(int i) { return Integer.toHexString(i); } static public File localSnippetsDir() { return javaxDataDir("Personal Programs"); } static public File localSnippetsDir(String sub) { return newFile(localSnippetsDir(), sub); } static public String getOneLineFileInfoField(File f, String field) { File infoFile = associatedInfosFile(f); List lines = lines(loadTextFile(infoFile)); return firstStartingWithIC_drop(lines, field + ": "); } static public File fileInSameDir(File f, String newName) { return newFile(parentFile(f), newName); } static public int smartLastIndexOf(String s, char c) { if (s == null) return 0; int i = s.lastIndexOf(c); return i >= 0 ? i : l(s); } static public int smartLastIndexOf(List l, A sub) { int i = lastIndexOf(l, sub); return i < 0 ? l(l) : i; } static volatile public boolean muricaPassword_pretendNotAuthed = false; static public String muricaPassword() { if (muricaPassword_pretendNotAuthed) return null; return trim(loadTextFile(muricaPasswordFile())); } static public String standardCredentialsUser() { return trim(loadTextFile(oneOfTheFiles(javaxSecretDir("tinybrain-username"), userDir(".tinybrain/username")))); } static public String standardCredentialsPass() { return trim(loadTextFile(oneOfTheFiles(javaxSecretDir("tinybrain-userpass"), userDir(".tinybrain/userpass")))); } static public File loadImageAsFile(String snippetIDOrURL) { try { if (isURL(snippetIDOrURL)) throw fail("not implemented"); if (!isSnippetID(snippetIDOrURL)) throw fail("Not a URL or snippet ID: " + snippetIDOrURL); String snippetID = "" + parseSnippetID(snippetIDOrURL); File file = imageSnippetCacheFile(snippetID); if (fileSize(file) > 0) return file; String imageURL = snippetImageURL_noHttps(snippetID); System.err.println("Loading image: " + imageURL); byte[] data = loadBinaryPage(imageURL); saveBinaryFile(file, data); return file; } catch (Exception __e) { throw rethrow(__e); } } static public File DiskSnippetCache_file(long snippetID) { return new File(getGlobalCache(), "data_" + snippetID + ".jar"); } public static File DiskSnippetCache_getLibrary(long snippetID) throws IOException { File file = DiskSnippetCache_file(snippetID); return file.exists() ? file : null; } public static void DiskSnippetCache_putLibrary(long snippetID, byte[] data) throws IOException { saveBinaryFile(DiskSnippetCache_file(snippetID), data); } static public byte[] loadDataSnippetImpl(String snippetID) throws IOException { byte[] data; try { URL url = new URL(dataSnippetLink(snippetID)); print("Loading library: " + hideCredentials(url)); try { data = loadBinaryPage(url.openConnection()); } catch (RuntimeException e) { data = null; } if (data == null || data.length == 0) { url = new URL(tb_mainServer() + "/blobs/" + parseSnippetID(snippetID)); print("Loading library: " + hideCredentials(url)); data = loadBinaryPage(url.openConnection()); } print("Bytes loaded: " + data.length); } catch (FileNotFoundException e) { throw new IOException("Binary snippet #" + snippetID + " not found or not public"); } return data; } static public File loadDataSnippetToFile(String snippetID) { try { IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.loadLibrary(snippetID); return loadDataSnippetToFile_noResourceLoader(snippetID); } catch (Exception __e) { throw rethrow(__e); } } static public File loadDataSnippetToFile_noResourceLoader(String snippetID) { try { snippetID = fsI(snippetID); File f = DiskSnippetCache_file(parseSnippetID(snippetID)); List urlsTried = new ArrayList(); List errors = new ArrayList(); try { URL url = addAndReturn(urlsTried, new URL(dataSnippetLink(snippetID))); print("Loading library: " + hideCredentials(url)); try { loadBinaryPageToFile(openConnection(url), f); if (fileSize(f) == 0) throw fail(); } catch (Throwable e) { errors.add(e); url = addAndReturn(urlsTried, new URL(tb_mainServer() + "/blobs/" + psI(snippetID))); print(e); print("Trying other server: " + hideCredentials(url)); loadBinaryPageToFile(openConnection(url), f); print("Got bytes: " + fileSize(f)); } if (fileSize(f) == 0) throw fail(); System.err.println("Bytes loaded: " + fileSize(f)); } catch (Throwable e) { errors.add(e); throw fail("Binary snippet " + snippetID + " not found or not public. URLs tried: " + allToString(urlsTried) + ", errors: " + allToString(errors)); } return f; } catch (Exception __e) { throw rethrow(__e); } } static public byte[] isGIF_magic = bytesFromHex("47494638"); static public boolean isGIF(byte[] data) { return byteArrayStartsWith(data, isGIF_magic); } static public boolean isGIF(File f) { return isGIF(loadBeginningOfBinaryFile(f, l(isGIF_magic))); } static public void setVar(IVar v, A value) { if (v != null) v.set(value); } static public IVF1 setVar(IVar v) { return a -> { if (v != null) v.set(a); }; } static public boolean substanceLookAndFeelEnabled() { return startsWith(getLookAndFeel(), "org.pushingpixels."); } static public JComponent getTitlePaneComponent(RootPaneContainer window) { if (window instanceof JInternalFrame) return getInternalFrameTitlePaneComponent((JInternalFrame) window); if (!substanceLookAndFeelEnabled() || window == null) return null; JRootPane rootPane = window.getRootPane(); if (rootPane != null) { Object ui = rootPane.getUI(); return (JComponent) call(ui, "getTitlePane"); } return null; } static public void nohupJavax(final String javaxargs) { { startThread(new Runnable() { public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "call(hotwireOnce(\"#1008562\"), \"nohupJavax\", javaxargs);"; } }); } } static public void nohupJavax(final String javaxargs, final String vmArgs) { { startThread(new Runnable() { public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs, vmArgs); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "call(hotwireOnce(\"#1008562\"), \"nohupJavax\", javaxargs, vmArgs);"; } }); } } static public String smartJoin(String[] args) { if (empty(args)) return ""; if (args.length == 1) return args[0]; String[] a = new String[args.length]; for (int i = 0; i < a.length; i++) a[i] = !isJavaIdentifier(args[i]) && !isQuoted(args[i]) ? quote(args[i]) : args[i]; return join(" ", a); } static public String smartJoin(List args) { return smartJoin(toStringArray(args)); } static public void addActionListener(JTextField tf, final Runnable action) { onEnter(tf, action); } static public void addActionListener(final JComboBox cb, final Runnable action) { if (cb != null) { swing(() -> { cb.addActionListener(actionListener(action)); }); } } static public void addActionListener(final AbstractButton b, final Runnable action) { if (b != null) { swing(() -> { b.addActionListener(actionListener(action)); }); } } static public boolean isChecked(JCheckBox checkBox) { return checkBox != null && (boolean) swing(new F0() { public Boolean get() { try { return checkBox.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret checkBox.isSelected();"; } }); } static public boolean isChecked(JCheckBoxMenuItem mi) { return mi != null && (boolean) swing(new F0() { public Boolean get() { try { return mi.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret mi.isSelected();"; } }); } static public boolean isChecked(JRadioButton rb) { return rb != null && (boolean) swing(() -> rb.isSelected()); } static public File associatedInfosFile(File f) { return replaceExtension(f, ".infos"); } static public String firstStartingWithIC_drop(Collection l, final String prefix) { for (String s : unnull(l)) if (swic(s, prefix)) return substring(s, l(prefix)); return null; } static public String firstStartingWithIC_drop(String prefix, Collection l) { return firstStartingWithIC_drop(l, prefix); } static public File parentFile(File f) { return dirOfFile(f); } static public File muricaPasswordFile() { return new File(javaxSecretDir(), "murica/muricaPasswordFile"); } static public File oneOfTheFiles(String... paths) { if (paths != null) for (String path : paths) if (fileExists(path)) return newFile(path); return null; } static public File oneOfTheFiles(File... files) { return oneOfTheFiles(asList(files)); } static public File oneOfTheFiles(Iterable files) { if (files != null) for (File f : files) if (fileExists(f)) return f; return null; } static public File javaxSecretDir_dir; static public File javaxSecretDir() { return javaxSecretDir_dir != null ? javaxSecretDir_dir : new File(userHome(), "JavaX-Secret"); } static public File javaxSecretDir(String sub) { return newFile(javaxSecretDir(), sub); } static public boolean loadBufferedImage_useImageCache = true; static public BufferedImage loadBufferedImage(String snippetIDOrURLOrFile) { try { ping(); if (snippetIDOrURLOrFile == null) return null; if (isURL(snippetIDOrURLOrFile)) return imageIO_readURL(snippetIDOrURLOrFile); if (isSnippetID(snippetIDOrURLOrFile)) { String snippetID = "" + parseSnippetID(snippetIDOrURLOrFile); IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return loadBufferedImage(rl.loadLibrary(snippetID)); File dir = imageSnippetsCacheDir(); if (loadBufferedImage_useImageCache) { dir.mkdirs(); File file = new File(dir, snippetID + ".png"); if (file.exists() && file.length() != 0) try { return ImageIO.read(file); } catch (Throwable e) { e.printStackTrace(); } } String imageURL = snippetImageURL_http(snippetID); print("Loading image: " + imageURL); BufferedImage image = imageIO_readURL(imageURL); if (loadBufferedImage_useImageCache) { File tempFile = new File(dir, snippetID + ".tmp." + System.currentTimeMillis()); ImageIO.write(image, "png", tempFile); tempFile.renameTo(new File(dir, snippetID + ".png")); } return image; } else return loadBufferedImage(new File(snippetIDOrURLOrFile)); } catch (Exception __e) { throw rethrow(__e); } } static public BufferedImage loadBufferedImage(File file) { return loadBufferedImageFile(file); } static public File imageSnippetCacheFile(String snippetID) { File dir = imageSnippetsCacheDir(); if (!loadBufferedImage_useImageCache) return null; return new File(dir, parseSnippetID(snippetID) + ".png"); } static public String snippetImageURL_noHttps(String snippetID) { return snippetImageURL_noHttps(snippetID, "png"); } static public String snippetImageURL_noHttps(String snippetID, String contentType) { return snippetImageURL(snippetID, contentType).replace("https://www.botcompany.de:8443/", "http://www.botcompany.de:8080/").replace("https://botcompany.de/", "http://botcompany.de/"); } public static byte[] saveBinaryFile(String fileName, byte[] contents) { try { File file = new File(fileName); File parentFile = file.getParentFile(); if (parentFile != null) parentFile.mkdirs(); String tempFileName = fileName + "_temp"; FileOutputStream fileOutputStream = newFileOutputStream(tempFileName); fileOutputStream.write(contents); fileOutputStream.close(); if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (!new File(tempFileName).renameTo(file)) throw new IOException("Can't rename " + tempFileName + " to " + fileName); vmBus_send("wroteFile", file); return contents; } catch (Exception __e) { throw rethrow(__e); } } static public byte[] saveBinaryFile(File fileName, byte[] contents) { return saveBinaryFile(fileName.getPath(), contents); } static public File getGlobalCache() { File file = new File(javaxCachesDir(), "Binary Snippets"); file.mkdirs(); return file; } static public String dataSnippetLink(String snippetID) { long id = parseSnippetID(snippetID); if (id >= 1100000 && id < 1200000) return imageServerURL() + id; if (id >= 1200000 && id < 1300000) { String pw = muricaPassword(); if (empty(pw)) throw fail("Please set 'murica password by running #1008829"); return "https://botcompany.de/files/" + id + "?_pass=" + pw; } return fileServerURL() + "/" + id; } static public A addAndReturn(Collection c, A a) { if (c != null) c.add(a); return a; } static public void loadBinaryPageToFile(String url, File file) { try { print("Loading " + url); loadBinaryPageToFile(openConnection(new URL(url)), file); } catch (Exception __e) { throw rethrow(__e); } } static public void loadBinaryPageToFile(URLConnection con, File file) { try { setHeaders(con); loadBinaryPageToFile_noHeaders(con, file); } catch (Exception __e) { throw rethrow(__e); } } static public void loadBinaryPageToFile_noHeaders(URLConnection con, File file) { try { File ftemp = new File(f2s(file) + "_temp"); FileOutputStream buf = newFileOutputStream(mkdirsFor(ftemp)); try { InputStream inputStream = con.getInputStream(); long len = 0; try { len = con.getContentLength(); } catch (Throwable e) { printStackTrace(e); } String pat = " {*}" + (len != 0 ? "/" + len : "") + " bytes loaded."; copyStreamWithPrints(inputStream, buf, pat); inputStream.close(); buf.close(); file.delete(); renameFile_assertTrue(ftemp, file); } finally { if (buf != null) buf.close(); } } catch (Exception __e) { throw rethrow(__e); } } static public List allToString(Iterable c) { List l = new ArrayList(); for (Object o : unnull(c)) l.add(str(o)); return l; } static public List allToString(Object[] c) { List l = new ArrayList(); for (Object o : unnull(c)) l.add(str(o)); return l; } static public byte[] bytesFromHex(String s) { return hexToBytes(s); } static public boolean byteArrayStartsWith(byte[] a, byte[] b) { if (a == null || b == null) return false; if (a.length < b.length) return false; for (int i = 0; i < b.length; i++) if (a[i] != b[i]) return false; return true; } static public byte[] loadBeginningOfBinaryFile(File file, int maxBytes) { return loadBinaryFilePart(file, 0, maxBytes); } static public String getLookAndFeel() { return getClassName(UIManager.getLookAndFeel()); } static public Class hotwireOnce(String programID) { return hotwireCached(programID, false); } static public File replaceExtension(File f, String extOld, String extNew) { return newFile(replaceExtension(f2s(f), extOld, extNew)); } static public File replaceExtension(File f, String extNew) { return replaceExtension(f, fileExtension(f), extNew); } static public String replaceExtension(String s, String extOld, String extNew) { s = dropSuffixIC(addPrefixOptIfNempty(".", extOld), s); return s + addPrefixOptIfNempty(".", extNew); } static public String replaceExtension(String name, String extNew) { return replaceExtension(name, fileExtension(name), extNew); } static public File dirOfFile(File f) { return f == null ? null : f.getParentFile(); } static public BufferedImage imageIO_readURL(String url) { try { return ImageIO.read(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static public File imageSnippetsCacheDir() { return javaxCachesDir("Image-Snippets"); } static public String snippetImageURL_http(String snippetID) { return snippetImageURL_http(snippetID, "png"); } static public String snippetImageURL_http(String snippetID, String contentType) { return replacePrefix("https://", "http://", snippetImageURL(snippetID, contentType)).replace(":8443", ":8080"); } static public BufferedImage loadBufferedImageFile(File file) { try { return isFile(file) ? ImageIO.read(file) : null; } catch (Exception __e) { throw rethrow(__e); } } static public String fileServerURL() { return "https://botcompany.de/files"; } public static File mkdirsFor(File file) { return mkdirsForFile(file); } static public void copyStreamWithPrints(InputStream in, OutputStream out, String pat) { try { byte[] buf = new byte[65536]; int total = 0; while (true) { int n = in.read(buf); if (n <= 0) return; out.write(buf, 0, n); if ((total + n) / 100000 > total / 100000) print(pat.replace("{*}", str(roundDownTo(100000, total)))); total += n; } } catch (Exception __e) { throw rethrow(__e); } } static public File renameFile_assertTrue(File a, File b) { try { if (a.equals(b)) return b; if (!a.exists()) throw fail("Source file not found: " + f2s(a)); if (b.exists()) throw fail("Target file exists: " + f2s(b)); mkdirsForFile(b); if (!a.renameTo(b)) throw fail("Can't rename " + f2s(a) + " to " + f2s(b)); return b; } catch (Exception __e) { throw rethrow(__e); } } static public byte[] hexToBytes(String s) { if (odd(l(s))) throw fail("Hex string has odd length: " + quote(shorten(10, s))); int n = l(s) / 2; byte[] bytes = new byte[n]; for (int i = 0; i < n; i++) { int a = parseHexChar(s.charAt(i * 2)); int b = parseHexChar(s.charAt(i * 2 + 1)); if (a < 0 || b < 0) throw fail("Bad hex byte: " + quote(substring(s, i * 2, i * 2 + 2)) + " at " + i * 2 + "/" + l(s)); bytes[i] = (byte) ((a << 4) | b); } return bytes; } static public byte[] loadBinaryFilePart(File file, long start, long end) { try { RandomAccessFile raf = new RandomAccessFile(file, "r"); int n = toInt(min(raf.length(), end - start)); byte[] buffer = new byte[n]; try { raf.seek(start); raf.readFully(buffer, 0, n); return buffer; } finally { raf.close(); } } catch (Exception __e) { throw rethrow(__e); } } static public TreeMap hotwireCached_cache = new TreeMap(); static public Lock hotwireCached_lock = lock(); static public Class hotwireCached(String programID) { return hotwireCached(programID, true); } static public Class hotwireCached(String programID, boolean runMain) { return hotwireCached(programID, runMain, false); } static public Class hotwireCached(String programID, boolean runMain, boolean dependent) { Lock __0 = hotwireCached_lock; lock(__0); try { programID = formatSnippetID(programID); Class c = hotwireCached_cache.get(programID); if (c == null) { c = hotwire(programID); if (dependent) makeDependent(c); if (runMain) callMain(c); hotwireCached_cache.put(programID, c); } return c; } finally { unlock(__0); } } static public String fileExtension(File f) { if (f == null) return null; return fileExtension(f.getName()); } static public String fileExtension(String s) { return substring(s, smartLastIndexOf(s, '.')); } static public String dropSuffixIC(String suffix, String s) { return s == null ? null : ewic(s, suffix) ? s.substring(0, l(s) - l(suffix)) : s; } static public String addPrefixOptIfNempty(String prefix, String s) { return addPrefixIfNotEmpty2(prefix, s); } static public boolean isFile(File f) { return f != null && f.isFile(); } static public boolean isFile(String path) { return isFile(newFile(path)); } static public int roundDownTo(int n, int x) { return x / n * n; } static public long roundDownTo(long n, long x) { return x / n * n; } static public int parseHexChar(char c) { if (c >= '0' && c <= '9') return charDiff(c, '0'); if (c >= 'a' && c <= 'f') return charDiff(c, 'a') + 10; if (c >= 'A' && c <= 'F') return charDiff(c, 'A') + 10; return -1; } static public Class hotwire(String src) { return hotwire(src, __1 -> mainClassNameForClassLoader(__1)); } static public Class hotwire(String src, IF1 calculateMainClass) { assertFalse(_inCore()); Class j = getJavaX(); if (isAndroid()) { synchronized (j) { List libraries = new ArrayList(); File srcDir = (File) call(j, "transpileMain", src, libraries); if (srcDir == null) throw fail("transpileMain returned null (src=" + quote(src) + ")"); Object androidContext = get(j, "androidContext"); return (Class) call(j, "loadx2android", srcDir, src); } } else { Class c = (Class) (call(j, "hotwire", src)); hotwire_copyOver(c); return c; } } static public Object makeDependent_postProcess; static public void makeDependent(Object c) { if (c == null) return; assertTrue("Not a class", c instanceof Class); dependentClasses(); hotwire_classes.add(new WeakReference(c)); Object local_log = getOpt(mc(), "local_log"); if (local_log != null) setOpt(c, "local_log", local_log); Object print_byThread = getOpt(mc(), "print_byThread"); if (print_byThread != null) setOpt(c, "print_byThread", print_byThread); callF(makeDependent_postProcess, c); } static public A callMain(A c, String... args) { callOpt(c, "main", new Object[] { args }); return c; } static public void callMain() { callMain(mc()); } static public String addPrefixIfNotEmpty2(String prefix, String s) { return empty(s) ? "" : addPrefix(prefix, s); } static public int charDiff(char a, char b) { return (int) a - (int) b; } static public int charDiff(String a, char b) { return charDiff(stringToChar(a), b); } static public boolean _inCore() { return false; } static public List hotwire_copyOver_after = synchroList(); static public void hotwire_copyOver(Class c) { for (String field : ll("print_log", "print_silent", "androidContext", "_userHome")) setOptIfNotNull(c, field, getOpt(mc(), field)); setOptIfNotNull(c, "mainBot", getMainBot()); setOpt(c, "creator_class", new WeakReference(mc())); pcallFAll(hotwire_copyOver_after, c); } static public List dependentClasses() { return cleanUpAndGetWeakReferencesList(hotwire_classes); } static public String addPrefix(String prefix, String s) { return s.startsWith(prefix) ? s : prefix + s; } static public List> hotwire_classes = synchroList(); static public Class hotwireDependent(String src) { Class c = hotwire(src); makeDependent(c); return c; } static public char stringToChar(String s) { if (l(s) != 1) throw fail("bad stringToChar: " + s); return firstChar(s); } static public void setOptIfNotNull(Object o, String field, Object value) { if (value != null) setOpt(o, field, value); } static public List cleanUpAndGetWeakReferencesList(List> l) { if (l == null) return null; synchronized (l) { List out = new ArrayList(); for (int i = 0; i < l(l); i++) { A a = l.get(i).get(); if (a == null) l.remove(i--); else out.add(a); } return out; } } static public char firstChar(String s) { return s.charAt(0); } static public interface Swingable { public JComponent visualize(); } static public class Var implements IVar, ISetter { public Var() { } public Var(A v) { this.v = v; } public A v; public synchronized void set(A a) { if (v != a) { v = a; notifyAll(); } } public synchronized A get() { return v; } public synchronized boolean has() { return v != null; } public void clear() { set(null); } public String toString() { return str(this.get()); } } static public interface IResourceLoader { public String loadSnippet(String snippetID); public String getTranspiled(String snippetID); public int getSnippetType(String snippetID); public String getSnippetTitle(String snippetID); public File loadLibrary(String snippetID); default public File pathToJavaXJar() { return pathToJavaxJar_noResourceLoader(); } default public File getSnippetJar(String snippetID, String transpiledSrc) { return null; } } static public class BetterThread extends Thread { public Runnable target; public BetterThread(Runnable target) { this.target = target; _created(); } public BetterThread(Runnable target, String name) { super(name); this.target = target; _created(); } public void _created() { vmBus_send("threadCreated", this); } public void run() { try { try { vmBus_send("threadStarted", this); if (target != null) target.run(); } finally { vmBus_send("threadEnded", this); } } catch (Exception __e) { throw rethrow(__e); } } public Runnable getTarget() { return target; } } static public class proxy_InvocationHandler implements InvocationHandler { public Object target; public proxy_InvocationHandler() { } public proxy_InvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) { return call(target, method.getName(), unnull(args)); } } static abstract public class LiveValue { abstract public Class getType(); abstract public A get(); abstract public void onChange(Runnable l); abstract public void removeOnChangeListener(Runnable l); public void onChangeAndNow(Runnable l) { onChange(l); callF(l); } } static public class Dyn_FieldWatcher { public DynModule module; public String field; public Object value; public Runnable action; transient public IF1 cloneValue; public Object cloneValue(Object o) { return cloneValue != null ? cloneValue.get(o) : cloneValue_base(o); } final public Object cloneValue_fallback(IF1 _f, Object o) { return _f != null ? _f.get(o) : cloneValue_base(o); } public Object cloneValue_base(Object o) { return o; } public Dyn_FieldWatcher(DynModule module, String field, Runnable action) { this(module, field, action, null); } public Dyn_FieldWatcher(DynModule module, String field, Runnable action, IF1 cloneValue) { this.cloneValue = cloneValue; this.action = action; this.field = field; this.module = module; value = cloneValue(get(module, field)); module.onChange(new Runnable() { public void run() { try { check(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "check();"; } }); module.onFieldChange(new VF1() { public void get(String f) { try { if (eq(f, field)) check(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(f, field))\r\n check();"; } }); } public void check() { Object newValue = cloneValue(get(module, field)); if (eq(value, newValue)) return; value = newValue; dm_q(module, action); } } static public interface IVar extends IF0 { public void set(A a); public A get(); default public boolean has() { return get() != null; } default public void clear() { set(null); } } static public class Complex implements IFieldsToList { static final public String _fieldOrder = "re im"; public double re; public double im; public Complex() { } public Complex(double re, double im) { this.im = im; this.re = re; } public boolean equals(Object o) { if (!(o instanceof Complex)) return false; Complex __1 = (Complex) o; return re == __1.re && im == __1.im; } public int hashCode() { int h = -1679819632; h = boostHashCombine(h, _hashCode(re)); h = boostHashCombine(h, _hashCode(im)); return h; } public Object[] _fieldsToList() { return new Object[] { re, im }; } public double abs() { return sqrt(re * re + im * im); } public double re() { return re; } public double im() { return im; } final public double angle() { return phase(); } public double phase() { return Math.atan2(im, re); } public double fracAngle() { return fracNonNeg(angle() / twoPi()); } public String toString() { if (im != 0) return re == 0 ? im + "i" : re + plusPrefixUnlessMinus(str(im)) + "i"; else return str(re); } } static public interface ISetter { public void set(A a); } static public java.awt.Color colorFromHex(String hex) { return awtColor(hex); } static public void vm_cleanPrints() { print_preprocess = new F1() { public String get(String x) { try { return vm_cleanForPrint(x); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "vm_cleanForPrint(x)"; } }; } static public boolean logModuleOutput_installed = false; static public void logModuleOutput() { if (logModuleOutput_installed) return; logModuleOutput_installed = true; final File logFile = getProgramFile("output.txt"); final LineBuffer buf = new LineBuffer(new VF1() { public void get(String line) { try { appendToTextFile(logFile, "[" + localDateWithMilliseconds() + "] " + line + "\n"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "appendToTextFile(logFile, \"[\" + localDateWithMilliseconds() + \"] \" + line + \"..."; } }); print_forAllThreads(new VF1() { public void get(String s) { try { buf.append(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "buf.append(s);"; } }); } static public JDA discordBot40(VF1 onMessage, Object... __) { return discordBot40(new ListenerAdapter() { @Override public void onMessageReceived(MessageReceivedEvent e) { if (e.getAuthor().isBot()) { print(" Msg from bot, skipping"); return; } pcallF(onMessage, e); } }, __); } static public JDA discordBot40(ListenerAdapter listener, Object... __) { try { String token = stringPar("token", __); if (empty(token)) { File tokenFile = javaxSecretDir("discord-bot-token"); token = assertNempty("Need: " + tokenFile, trim(loadTextFile(tokenFile))); } print("Making JDABuilder"); JDABuilder builder = JDABuilder.create(token, GUILD_VOICE_STATES, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, DIRECT_MESSAGES); print("Have JDABuilder"); if (boolPar("membersIntent", __)) builder.enableIntents(GUILD_MEMBERS); builder.addEventListeners(listener); print("Building JDA with token " + shorten(10, token)); JDA jda = builder.build(); print("Got JDA: " + jda); jda.awaitReady(); print("Started Discord bot (token: " + shorten(token, 7) + ")"); return jda; } catch (Exception __e) { throw rethrow(__e); } } static public Object[] litmapparams(Object... l) { return new Object[] { litmap(l) }; } static public DynModule dm_me() { return dm_current_mandatory(); } static public Object dm_discord_lineForMsgID_unimported(long msgID) { return dm_call(dm_gazelle_linesCRUD(), "lineForID", msgID); } static public long discord_guildIDFromEvent_gen(Object event) { return rcall_long("getIdLong", rcall("getGuild", event)); } static public AutoCloseable dm_registerAs(String... msgs) { F0 f = new F0() { public String get() { try { return dm_moduleID(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret dm_moduleID();"; } }; return combineAutoCloseables(map(msgs, msg -> dm_vmBus_answerToMessage(msg, f))); } static public AutoCloseable dm_vmBus_answerToMessage(String msg, final IF0 f) { final DynModule m = dm_current_mandatory(); return dm_ownResource(vmBus_addListener_basic(msg, new F2() { public Object get(String _msg, Object arg) { try { AutoCloseable __1 = m.enter(); try { return callF(f); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp m.enter();\r\n ret callF(f);"; } })); } static public AutoCloseable dm_vmBus_answerToMessage(String msg, final F0 f) { final DynModule m = dm_current_mandatory(); return dm_ownResource(vmBus_addListener_basic(msg, new F2() { public Object get(String _msg, Object arg) { try { AutoCloseable __2 = m.enter(); try { return callF(f); } finally { _close(__2); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp m.enter();\r\n ret callF(f);"; } })); } static public AutoCloseable dm_vmBus_answerToMessage(String msg, final F1 f) { final DynModule m = dm_current_mandatory(); return dm_ownResource(vmBus_addListener_basic(msg, new F2() { public Object get(String _msg, Object arg) { try { AutoCloseable __3 = m.enter(); try { return callF(f, arg); } finally { _close(__3); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp m.enter();\r\n ret callF(f, arg);"; } })); } static public AutoCloseable dm_vmBus_answerToMessage(String msg, F2 f) { final DynModule m = dm_current_mandatory(); return dm_ownResource(vmBus_addListener_basic(msg, new F2() { public Object get(String _msg, Object arg) { try { if (arg instanceof Object[]) { if (((Object[]) arg).length != 2) return null; AutoCloseable __4 = m.enter(); try { return callF(f, ((Object[]) arg)[0], ((Object[]) arg)[1]); } finally { _close(__4); } } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (arg cast O[]) {\r\n if (arg.length != 2) null;\r\n temp m.enter();\r..."; } })); } static public AutoCloseable dm_vmBus_answerToMessage(String msg, F3 f) { final DynModule m = dm_current_mandatory(); return dm_ownResource(vmBus_addListener_basic(msg, new F2() { public Object get(String _msg, Object arg) { try { if (arg instanceof Object[]) { if (((Object[]) arg).length != 3) return null; AutoCloseable __5 = m.enter(); try { return callF(f, ((Object[]) arg)[0], ((Object[]) arg)[1], ((Object[]) arg)[2]); } finally { _close(__5); } } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (arg cast O[]) {\r\n if (arg.length != 3) null;\r\n temp m.enter();\r..."; } })); } static public long jda_selfUserID(JDA jda) { return jda.getSelfUser().getIdLong(); } static public String dm_gazelle_linesCRUD() { return dm_require("#1021628/GLines"); } static public Object[] litobjectarray(Object... l) { return litObjectArray(l); } static public Object dm_pcall(Object moduleOrID, String method, Object... args) { try { return dm_call(moduleOrID, method, args); } catch (Throwable __e) { return null; } } static public String gazelle_postedLinesCRUD() { return dm_require("#1022603/GPostedLines"); } static public long dm_discord_channelID(String name) { return (long) dm_call(dm_gazelle_linesCRUD(), "getChannelID", name); } static public String absoluteURL(String url) { return isAbsoluteURL(url) ? url : "http://" + url; } static public IVF1 toIVF1(final Object f) { if (f == null) return null; if (f instanceof IVF1) return (IVF1) f; if (isString(f)) return mainFunctionToIVF1((String) f); return (IVF1) a -> { callF(f, a); }; } static public String dm_discord_startKeepAliveModule(Object mod) { String discordToken = (String) (dm_get(mod, "discordToken")); return dm_showNewModuleWithParams("#1024196/DiscordKeepAlive", "discordToken", discordToken); } static public String escapeAtEveryone(String s) { return replace(s, "@everyone", "@_everyone"); } static public String shortenForDiscord(String msg) { return shorten(msg, 2000); } static public JPanel centerAndSouthWithMargins(Component c, Component s) { return applyDefaultMargin(centerAndSouth(c, withTopMargin(s))); } static public JPanel centerAndSouthWithMargins(int margin, Component c, Component s) { return applyMargin(margin, centerAndSouth(c, withTopMargin(margin, s))); } static public SingleComponentPanel singleComponentPanel() { return singleComponentPanel(null); } static public SingleComponentPanel singleComponentPanel(final Component c) { return swing(new F0() { public SingleComponentPanel get() { try { return new SingleComponentPanel(c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret new SingleComponentPanel(c);"; } }); } static public JPanel jrightalignedline(Component... components) { return jrightAlignedLine(components); } static public JPanel jrightalignedline(List components) { return jrightAlignedLine(components); } static public JPanel centerAndEastWithMargin(Component c, Component e) { return centerAndEastWithMarginInbetween(c, e); } static public JCheckBox dm_fieldCheckBox(String field) { return dm_fieldCheckBox(humanizeFormLabel(field), field); } static public JCheckBox dm_fieldCheckBox(String text, String field) { if (isIdentifier(text) && !isIdentifier(field)) { String temp = field; field = text; text = temp; } return jLiveValueCheckBox(text, dm_fieldLiveValue(field)); } static public void addComponentsFirst(Container c, Component... l) { containerAddFirst(c, l); } static public void scpSet(SingleComponentPanel scp, Component c) { setSCPComponent(scp, c); } static public File loadLibrary(String snippetID) { return loadBinarySnippet(snippetID); } static public File pathToJavaxJar() { IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.pathToJavaXJar(); return pathToJavaxJar_noResourceLoader(); } static public File pathToJavaxJar_noResourceLoader() { try { int x = latestInstalledJavaX(); File xfile = new File(userHome(), ".javax/x" + Math.max(x, 30) + ".jar"); if (!xfile.isFile()) { print("Saving " + f2s(xfile)); String url = x30JarServerURL(); byte[] data = loadBinaryPage(url); if (data.length < 1000000) throw fail("Could not load " + url); saveBinaryFile(xfile.getPath(), data); } return xfile; } catch (Exception __e) { throw rethrow(__e); } } static public A onChange(A spinner, Object r) { return onChange(spinner, toRunnable(r)); } static public A onChange(A spinner, Runnable r) { if (r != null) { swing(() -> { spinner.addChangeListener(changeListener(r)); }); } return spinner; } static public A onChange(A b, Object r) { { swing(() -> { b.addItemListener(itemListener(r)); }); } return b; } static public void onChange(JTextComponent tc, Object r) { onUpdate(tc, r); } static public A onChange(A slider, final Object r) { { swing(() -> { slider.addChangeListener(changeListener(r)); }); } return slider; } static public JComboBox onChange(JComboBox cb, IVF1 f) { if (f != null) addActionListener(cb, () -> f.get(getSelectedItem_typed(cb))); return cb; } static public JComboBox onChange(Object r, JComboBox cb) { return onChange(cb, r); } static public JComboBox onChange(JComboBox cb, final Object r) { if (isEditableComboBox(cb)) onChange(textFieldFromComboBox(cb), r); else onSelectedItem(cb, new VF1() { public void get(String s) { try { callF(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(r)"; } }); return cb; } static public A onChange(A tabs, Runnable r) { { swing(() -> { tabs.addChangeListener(changeListener(r)); }); } return tabs; } static public Q dm_q() { return dm_current_mandatory().q(); } static public void dm_q(Runnable r) { dm_inQ(r); } static public void dm_q(DynModule module, Runnable r) { module.q().add(r); } static public A dm_q(IF0 f) { return dm_evalInQ(if0ToF0(f)); } static public double sqrt(double x) { return Math.sqrt(x); } static public double fracNonNeg(double d) { return frac_nonNeg(d); } static public double twoPi() { return Math.PI * 2; } static public String plusPrefixUnlessMinus(String s) { return startsWith(s, "-") ? s : "+" + s; } static public java.awt.Color awtColor(String hex) { byte[] b = bytesFromHex(dropPrefix("#", hex)); return new Color(ubyteToInt(b[0]), ubyteToInt(b[1]), ubyteToInt(b[2])); } static public String vm_cleanForPrint(Object o) { String s = str(o); return or((String) vmBus_query("cleanForPrint", s), s); } static public void appendToTextFile(File file, String s) { appendToFile(file, s); } static public void appendToTextFile(String file, String s) { appendToTextFile(programFile(file), s); } static public String localDateWithMilliseconds(Date time) { return localDateWithMilliseconds(time.getTime()); } static public String localDateWithMilliseconds(long time) { SimpleDateFormat format = simpleDateFormat_local("yyyy/MM/dd HH:mm:ss''SSSS"); return format.format(time); } static public String localDateWithMilliseconds() { return localDateWithMilliseconds(now()); } static public void print_forAllThreads(Object f) { assertNull("todo", print_allThreads); print_allThreads = f; } static public String stringPar(Object[] params, String name) { return stringOptPar(params, name); } static public String stringPar(String name, Object[] params) { return stringOptPar(params, name); } static public String stringPar(String name, Map params) { return (String) optPar(name, params); } static public String stringPar(String name, Object[] params, String defaultValue) { return optPar(name, params, defaultValue); } static public A assertNempty(A a) { return assertNempty("empty", a); } static public A assertNempty(String msg, A a) { if (empty(a)) throw fail(msg + ": " + a); return a; } static public boolean boolPar(ThreadLocal tl) { return boolOptParam(tl); } static public boolean boolPar(Object[] __, String name) { return boolOptParam(__, name); } static public boolean boolPar(String name, Object[] __) { return boolOptParam(__, name); } static public boolean boolPar(String name, Map __) { return boolOptParam(name, __); } static public boolean boolPar(String name, Object[] params, boolean defaultValue) { return optParam(params, name, defaultValue); } static public AutoCloseable combineAutoCloseables(final AutoCloseable a, final AutoCloseable b) { return a == null ? b : b == null ? a : new AutoCloseable() { public String toString() { return "pClose(a); pClose(b);"; } public void close() throws Exception { pClose(a); pClose(b); } }; } static public AutoCloseable combineAutoCloseables(AutoCloseable a, AutoCloseable b, AutoCloseable c, AutoCloseable... more) { return combineAutoCloseables(concatLists(ll(a, b, c), asList(more))); } static public AutoCloseable combineAutoCloseables(Iterable l) { return foldl(new F2() { public AutoCloseable get(AutoCloseable a, AutoCloseable b) { try { return combineAutoCloseables(a, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "combineAutoCloseables(a,b)"; } }, null, l); } static public AutoCloseable vmBus_addListener_basic(String msg, Object listener) { Map map = vm_busListenersByMessage_live(); synchronized (map) { Set listeners = map.get(msg); if (listeners == null) map.put(msg, listeners = syncIdentityHashSet()); return tempAdd(listeners, listener); } } static public String dm_require(String moduleLibID) { return dm_makeModule(moduleLibID); } static public Object[] litObjectArray(Object... l) { return l; } static public boolean isAbsoluteURL(String s) { return isURL(s); } static public IVF1 mainFunctionToIVF1(final String fname) { return (IVF1) a -> { callMC(fname, a); }; } static public Object dm_get(Object moduleOrID, String field) { return get(dm_getModule(moduleOrID), field); } static public Object dm_get(String field, long moduleID) { return dm_get(moduleID, field); } static public Object dm_get(String field, Object moduleID) { return dm_get(moduleID, field); } static public Object dm_get(Object mod) { return dm_heldObject(mod); } static public A applyDefaultMargin(final A c) { if (c != null) { swing(() -> { c.setBorder(BorderFactory.createEmptyBorder(withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth)); }); } return c; } static public JPanel centerAndSouth(final Component c, final Component s) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.CENTER, wrap(c)); if (s != null) panel.add(BorderLayout.SOUTH, wrap(s)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.CENT..."; } }); } static public int withTopMargin_defaultWidth = 6; static public JPanel withTopMargin(Component c) { return withTopMargin(withTopMargin_defaultWidth, c); } static public JPanel withTopMargin(final int w, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(w, 0, 0, 0)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; } }); } static public A applyMargin(int top, int left, int bottom, int right, A c) { return addMargin(top, left, bottom, right, c); } static public A applyMargin(int w, A c) { return addMargin(w, c); } static public JPanel jrightAlignedLine(final Component... components) { return swing(new F0() { public RightAlignedLine get() { try { return new RightAlignedLine(components); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret RightAlignedLine(components);"; } }); } static public JPanel jrightAlignedLine(List components) { return jrightAlignedLine(asArray(Component.class, components)); } static public JPanel centerAndEastWithMarginInbetween(Component c, final Component e) { return centerAndEast(c, withLeftMargin(e)); } static public JCheckBox jLiveValueCheckBox(String text, final SimpleLiveValue lv) { final JCheckBox cb = jCheckBox(text); bindCheckBoxToLiveValue(cb, lv); return cb; } static public SimpleLiveValue dm_fieldLiveValue(String fieldName) { return dm_fieldLiveValue(dm_current_mandatory(), fieldName); } static public SimpleLiveValue dm_fieldLiveValue(DynModule module, String fieldName) { Lock __0 = module.lock; lock(__0); try { AutoCloseable __2 = module.enter(); try { Class type = getFieldType(module, fieldName); final SimpleLiveValue value = new SimpleLiveValue(type, get(module, fieldName)); dm_watchField(fieldName, new Runnable() { public void run() { try { Object o = get(module, fieldName); value.set(o); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef dm_fieldLiveValue_debug\r\n print(\"dm_fieldLiveValue: setting \" + fi..."; } }); value.onChange(new Runnable() { public void run() { try { module.setField(fieldName, value.get()); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef dm_fieldLiveValue_debug\r\n print(\"dm_fieldLiveValue: setting 2 \" + ..."; } }); return value; } finally { _close(__2); } } finally { unlock(__0); } } static public SimpleLiveValue dm_fieldLiveValue(String fieldName, DynModule module) { return dm_fieldLiveValue(module, fieldName); } static public void setSCPComponent(SingleComponentPanel scp, Component c) { if (scp != null) scp.setComponent(c); } static public int latestInstalledJavaX() { File[] files = new File(userHome(), ".javax").listFiles(); int v = 0; if (files != null) for (File f : files) { Matcher m = regexpMatcher("x(\\d\\d\\d?)\\.jar", f.getName()); if (m.matches()) v = Math.max(v, Integer.parseInt(m.group(1))); } return v; } static public String x30JarServerURL() { return "http://botcompany.de:8081/x30.jar"; } static public ChangeListener changeListener(final Object r) { return new ChangeListener() { public void stateChanged(ChangeEvent e) { pcallF(r); } }; } static public ItemListener itemListener(final Object r) { return new ItemListener() { public void itemStateChanged(ItemEvent e) { pcallF(r); } }; } static public void onUpdate(JComponent c, Runnable r) { onUpdate(c, (Object) r); } static public void onUpdate(JComponent c, Object r) { if (c instanceof JTextComponent) ((JTextComponent) c).getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { call(r); } public void removeUpdate(DocumentEvent e) { call(r); } public void changedUpdate(DocumentEvent e) { call(r); } }); else if (c instanceof ItemSelectable) ((ItemSelectable) c).addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { call(r); } }); else print("Warning: onUpdate doesn't know " + getClassName(c)); } static public void onUpdate(List l, Object r) { for (JComponent c : l) onUpdate(c, r); } static public A getSelectedItem_typed(JList l) { return swing(() -> l.getSelectedValue()); } static public A getSelectedItem_typed(JComboBox cb) { return swing(() -> (A) cb.getSelectedItem()); } static public JTextField textFieldFromComboBox(JComboBox cb) { return (JTextField) cb.getEditor().getEditorComponent(); } static public JComboBox onSelectedItem(final JComboBox cb, final VF1 f) { addActionListener(cb, new Runnable() { public void run() { try { pcallF(f, selectedItem(cb)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(f, selectedItem(cb))"; } }); return cb; } static public JComboBox onSelectedItem(final JComboBox cb, IVF1 f) { addActionListener(cb, new Runnable() { public void run() { try { pcallF(f, selectedItem(cb)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(f, selectedItem(cb))"; } }); return cb; } static public void dm_inQ(Runnable r) { dm_q().add(r); } static public void dm_inQ(DynModule mod, Runnable r) { dm_q(mod, r); } static public A dm_evalInQ(F0 f) { return dm_evalInQ(dm_current_mandatory(), f); } static public A dm_evalInQ(IF0 f) { return dm_evalInQ(dm_current_mandatory(), if0ToF0(f)); } static public A dm_evalInQ(DynModule module, F0 f) { return evalInQ(module.q(), f); } static public F0 if0ToF0(IF0 f) { return f == null ? null : new F0() { public A get() { try { return f.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret f.get();"; } }; } static public double frac_nonNeg(double d) { return mod(d, 1); } static public int ubyteToInt(byte b) { return b & 0x0FF; } static public int ubyteToInt(char c) { return c & 0x0FF; } static public A assertNull(A a) { assertTrue(a == null); return a; } static public A assertNull(String msg, A a) { assertTrue(msg, a == null); return a; } static public boolean boolOptParam(ThreadLocal tl) { return isTrue(optPar(tl)); } static public boolean boolOptParam(Object[] __, String name) { return isTrue(optParam(__, name)); } static public boolean boolOptParam(String name, Object[] __) { return boolOptParam(__, name); } static public boolean boolOptParam(String name, Map __) { return isTrue(optPar(name, __)); } static public void pClose(AutoCloseable c) { close_pcall(c); } static public A foldl(F2 f, A seed, Iterable l) { A a = seed; if (l != null) for (B b : l) a = callF(f, a, b); return a; } static public A foldl(F2 f, A seed, B[] l) { A a = seed; if (l != null) for (B b : l) a = callF(f, a, b); return a; } static public A foldl(Object f, A seed, B[] l) { A a = seed; if (l != null) for (B b : l) a = (A) callF(f, a, b); return a; } static public String dm_makeModule(String moduleLibID) { return (String) dm_callOS("makeModule", moduleLibID); } static public Object dm_heldObject(Object mod) { return dm_rcall("get", mod); } static public A addMargin(final int top, final int left, final int bottom, final int right, final A c) { if (c != null) { swing(() -> { Border margin = BorderFactory.createEmptyBorder(top, left, bottom, right); c.setBorder(jCompoundBorder(c.getBorder(), margin)); }); } return c; } static public A addMargin(int w, A c) { return addMargin(w, w, w, w, c); } static public JPanel centerAndEast(final Component c, final Component e) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.CENTER, wrap(c)); panel.add(BorderLayout.EAST, wrap(e)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.CENT..."; } }); } static public int withLeftMargin_defaultWidth = 6; static public JPanel withLeftMargin(Component c) { return withLeftMargin(withLeftMargin_defaultWidth, c); } static public JPanel withLeftMargin(final int margin, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(0, margin, 0, 0)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; } }); } static public JCheckBox jCheckBox() { return swingNu(JCheckBox.class); } static public JCheckBox jCheckBox(boolean checked) { return swingNu(JCheckBox.class, "", checked); } static public JCheckBox jCheckBox(String text, boolean checked) { return swingNu(JCheckBox.class, text, checked); } static public JCheckBox jCheckBox(String text) { return swingNu(JCheckBox.class, text); } static public JCheckBox jCheckBox(String text, boolean checked, final Object onChange) { JCheckBox cb = jCheckBox(checked, onChange); cb.setText(text); return cb; } static public JCheckBox jCheckBox(boolean checked, final Object onChange) { final JCheckBox cb = jCheckBox(checked); cb.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { pcallF(onChange, cb.isSelected()); } }); return cb; } static public A bindCheckBoxToLiveValue(final A cb, final SimpleLiveValue lv) { bindLiveValueListenerToComponent(cb, lv, new Runnable() { public void run() { try { setChecked(cb, isTrue(lv.get())); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef bindCheckBoxToLiveValue_debug\r\n print(\"bindCheckBoxToLiveValue: se..."; } }); onChange(cb, new Runnable() { public void run() { try { lv.set(isChecked(cb)); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef bindCheckBoxToLiveValue_debug\r\n print(\"bindCheckBoxToLiveValue: se..."; } }); return cb; } static public Class getFieldType(Object o, String field) { return fieldType(o, field); } static public String selectedItem(JList l) { return getSelectedItem(l); } static public String selectedItem(JComboBox cb) { return getSelectedItem(cb); } static public A evalInQ(Q q, final F0 f) { if (isInQ(q)) return callF(f); final Var> var = new Var(); q.add(new Runnable() { public void run() { try { try { var.set(eitherA(callF(f))); } catch (Throwable e) { var.set(eitherB(e)); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n var.set(eitherA(callF(f)));\r\n } catch (Throwable e) {\r\n ..."; } }); return returnOrThrow_either(waitForVarToBeNotNull(var)); } static public int mod(int n, int m) { return (n % m + m) % m; } static public long mod(long n, long m) { return (n % m + m) % m; } static public BigInteger mod(BigInteger n, int m) { return n.mod(bigint(m)); } static public double mod(double n, double m) { return (n % m + m) % m; } static public void close_pcall(AutoCloseable c) { if (c != null) { try { c.close(); } catch (Throwable __e) { printStackTrace(__e); } } } static public Border jCompoundBorder(Border inner, Border outer) { if (inner == null) return outer; if (outer == null) return inner; return BorderFactory.createCompoundBorder(inner, outer); } static public void setChecked(JCheckBox checkBox, boolean b) { if (checkBox != null) { swing(() -> { if (isChecked(checkBox) != b) checkBox.setSelected(b); }); } } static public void setChecked(JCheckBoxMenuItem mi, boolean b) { if (mi != null) { swing(() -> { mi.setSelected(b); }); } } static public boolean isInQ(Q q) { return q != null && isCurrentThread(q.rst.thread); } static public Either eitherA(A a) { return new Either(1, a); } static public Either eitherB(B b) { return new Either(2, b); } static public A returnOrThrow_either(Either e) { if (isEitherB(e)) throw rethrow(e.b()); return eitherAOpt(e); } static public A waitForVarToBeNotNull(Var v) { try { synchronized (v) { while (!v.has()) v.wait(); return v.get(); } } catch (Exception __e) { throw rethrow(__e); } } static public boolean isCurrentThread(Thread t) { return t != null && t == currentThread(); } static public boolean isEitherB(Either e) { return eitherIsB(e); } static public A eitherAOpt(Either e) { return e != null && e.isA() ? e.a() : null; } static public boolean eitherIsB(Either e) { return e != null && e.isB(); } static public class SimpleLiveValue extends LiveValue { public Class type; volatile public A value; transient public List onChange = synchroList(); public SimpleLiveValue(Class type) { this.type = type; } public SimpleLiveValue(Class type, A value) { this.value = value; this.type = type; } public Class getType() { return type; } public A get() { return value; } public void onChange(Runnable l) { onChange.add(l); } public void onChangeAndNow(Runnable l) { onChange(l); callF(l); } public void removeOnChangeListener(Runnable l) { onChange.remove(l); } public void fireChanged() { pcallFAll(onChange); } public void set(A a) { if (neq(value, a)) { value = a; fireChanged(); } } } static public class LineBuffer { public VF1 onLine; public StringBuilder currentLine = new StringBuilder(); public LineBuffer() { } public LineBuffer(VF1 onLine) { this.onLine = onLine; } public void append(String s) { append(s, onLine); } public void append(String s, VF1 onLine) { currentLine.append(s); if (contains(s, '\n')) { int i = 0, j; s = str(currentLine); while ((j = indexOf(s, i, '\n')) >= 0) { String line = dropTrailingBackslashR(substring(s, i, j)); callF(onLine, line); i = j + 1; } currentLine = new StringBuilder(substring(s, i)); } } public int size() { return l(currentLine); } } static public class Either { public byte which; public Object value; public Either() { } public Either(int which, Object value) { this.which = (byte) which; this.value = value; } public boolean isA() { return which == 1; } public boolean isB() { return which == 2; } public A a() { if (which != 1) _failMe(); return (A) value; } public B b() { if (which != 2) _failMe(); return (B) value; } public A aOpt() { return which != 1 ? null : (A) value; } public B bOpt() { return which != 2 ? null : (B) value; } public void _failMe() { throw fail("Either object is of wrong type: " + shortClassName(value)); } public String toString() { return "Either" + (isA() ? "A" : "B") + "(" + value + ")"; } } static abstract public class F2 { abstract public C get(A a, B b); } static abstract public class F3 { abstract public D get(A a, B b, C c); } static public class RightAlignedLine extends JPanel { public RightAlignedLine(Component... components) { setLayout(LetterLayout.rightAlignedRow()); for (Component component : components) if (component != null) add(component); } public void add(String text) { add(new JLabel(text)); } } static public class LetterLayout implements LayoutManager { public String[] lines; public Map map = new TreeMap(); public Map constraints = new HashMap(); public RC[] rows; public RC[] cols; public Cell[][] cells; public int spacingX = 10, spacingY = 10; public int insetTop, insetBottom, insetLeft, insetRight; public int template; public boolean formWideLeftSide, formWideRightSide; static final public int STALACTITE = 1, LEFT_ALIGNED_ROW = 2, CENTERED_ROW = 3, FORM = 4, RIGHT_ALIGNED_ROW = 5; public boolean debug = false; public void setLeftBorder(int border) { insetLeft = border; } public void setRightBorder(int border) { insetRight = border; } public static JComponent withBorder(JComponent component, int border) { JPanel panel = new JPanel(new LetterLayout("C").setBorder(border)); panel.add("C", component); return panel; } public static JPanel panel(String... lines) { return new JPanel(new LetterLayout(lines)); } public static JPanel stalactitePanel() { return new JPanel(stalactite()); } static public class DummyComponent extends JComponent { } static public class Cell { public boolean aux = false; public int minWidth, minHeight; public Component component; public int colspan, rowspan; public double weightX, weightY; } static public class RC { public int min; public double weightSum; public int start; public int minEnd; } public LetterLayout(int template) { this.template = template; } public LetterLayout(String... lines) { this.lines = lines; } public void layoutContainer(Container container) { prepareLayout(container); if (debug) System.out.println("Container size: " + container.getSize()); Insets insets = getInsets(container); for (int r = 0; r < rows.length; r++) { for (int i = 0; i < cols.length; ) { Cell cell = cells[i][r]; if (cell.aux) ++i; else { if (cell.component != null) { int x1 = cols[i].start; int y1 = rows[r].start; int x2 = i + cell.colspan < cols.length ? cols[i + cell.colspan].start - spacingX : container.getWidth() - insets.right; int y2 = r + cell.rowspan < rows.length ? rows[r + cell.rowspan].start - spacingY : container.getHeight() - insets.bottom; if (debug) System.out.println("Layouting (" + i + ", " + r + ", " + cell.component.getClass().getName() + "): " + x1 + " " + y1 + " " + x2 + " " + y2); cell.component.setBounds(x1, y1, x2 - x1, y2 - y1); } i += cells[i][r].colspan; } } } } final public void prepareLayout(Container container) { applyTemplate(container); int numRows = lines.length, numCols = lines[0].length(); for (int i = 1; i < numRows; i++) if (lines[i].length() != numCols) throw new IllegalArgumentException("Lines have varying length"); cells = new Cell[numCols][numRows]; rows = new RC[numRows]; cols = new RC[numCols]; for (int r = 0; r < numRows; r++) rows[r] = new RC(); for (int i = 0; i < numCols; i++) cols[i] = new RC(); for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r] = new Cell(); for (int r = 0; r < numRows; r++) { String line = lines[r]; for (int i = 0; i < numCols; ) { Cell cell = cells[i][r]; if (cell.aux) { ++i; continue; } char ch = line.charAt(i); int iNext = i; do ++iNext; while (iNext < numCols && ch == line.charAt(iNext)); int rNext = r; do ++rNext; while (rNext < numRows && ch == lines[rNext].charAt(i)); cell.weightX = numCols == 1 || iNext > i + 1 ? 1.0 : 0.0; cell.weightY = numRows == 1 || rNext > r + 1 ? 1.0 : 0.0; Component c = map.get(String.valueOf(ch)); cell.component = c; if (c != null) { cell.minWidth = c.getMinimumSize().width + spacingX; cell.minHeight = getMinimumHeight(c) + spacingY; } cell.colspan = iNext - i; cell.rowspan = rNext - r; if (cell.colspan == 1) cols[i].min = Math.max(cols[i].min, cell.minWidth); if (cell.rowspan == 1) rows[r].min = Math.max(rows[r].min, cell.minHeight); for (int r2 = r; r2 < rNext; r2++) for (int i2 = i; i2 < iNext; i2++) if (r2 != r || i2 != i) cells[i2][r2].aux = true; i = iNext; } } while (true) { for (int i = 0; i < numCols; i++) { int minStart = i == 0 ? 0 : cols[i - 1].minEnd; double weightStart = i == 0 ? 0.0 : cols[i - 1].weightSum; for (int r = 0; r < numRows; r++) { Cell cell = cells[i][r]; if (!cell.aux) { RC rc = cols[i + cell.colspan - 1]; rc.minEnd = Math.max(rc.minEnd, minStart + cell.minWidth); rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightX); } } } for (int r = 0; r < numRows; r++) { int minStart = r == 0 ? 0 : rows[r - 1].minEnd; double weightStart = r == 0 ? 0.0 : rows[r - 1].weightSum; for (int i = 0; i < numCols; i++) { Cell cell = cells[i][r]; if (!cell.aux) { RC rc = rows[r + cell.rowspan - 1]; rc.minEnd = Math.max(rc.minEnd, minStart + cell.minHeight); rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightY); } } } if (allWeightsZero(cols)) { for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r].weightX = 1.0; continue; } if (allWeightsZero(rows)) { for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r].weightY = 1.0; continue; } break; } Insets insets = getInsets(container); determineStarts(cols, insets.left, container.getWidth() - insets.left - insets.right + spacingX, spacingX); determineStarts(rows, insets.top, container.getHeight() - insets.top - insets.bottom + spacingY, spacingY); } final public boolean allWeightsZero(RC[] rcs) { for (int i = 0; i < rcs.length; i++) if (rcs[i].weightSum != 0.0) return false; return true; } static public int getMinimumHeight(Component c) { return c.getMinimumSize().height; } final public void applyTemplate(Container container) { if (template == STALACTITE) { Component[] components = container.getComponents(); lines = new String[components.length + 2]; map.clear(); for (int i = 0; i < components.length; i++) { String s = String.valueOf(makeIndexChar(i)); map.put(s, components[i]); lines[i] = s; } lines[components.length] = lines[components.length + 1] = " "; } else if (template == FORM) { Component[] components = container.getComponents(); int numRows = components.length / 2; lines = new String[numRows + 2]; map.clear(); for (int row = 0; row < numRows; row++) { String lower = String.valueOf(makeIndexChar(row)); String upper = String.valueOf(makeAlternateIndexChar(row)); Component rightComponent = components[row * 2 + 1]; if (rightComponent instanceof DummyComponent) upper = lower; lines[row] = (formWideLeftSide ? lower + lower : lower) + (formWideRightSide ? upper + upper : upper); map.put(lower, components[row * 2]); if (!(rightComponent instanceof DummyComponent)) map.put(upper, rightComponent); } lines[numRows] = lines[numRows + 1] = (formWideLeftSide ? " " : " ") + (formWideRightSide ? " " : " "); } else if (template == LEFT_ALIGNED_ROW) { lines = new String[] { makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; } else if (template == CENTERED_ROW) { lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; } else if (template == RIGHT_ALIGNED_ROW) { lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) }; } } final public String makeSingleRow(Container container) { Component[] components = container.getComponents(); StringBuffer buf = new StringBuffer(); map.clear(); for (int i = 0; i < components.length; i++) { var c = components[i]; String s = constraints.get(c); if (isOneOfSingleChars(s, LEFT_CHAR, RIGHT_CHAR)) continue; s = str(makeAlternateIndexChar(i)); setConstraints(c, s); buf.append(s); } return buf.toString(); } static public void determineStarts(RC[] rcs, int start, int totalSize, int spacing) { int minTotal = rcs[rcs.length - 1].minEnd; double weightSum = rcs[rcs.length - 1].weightSum; int spare = (int) ((totalSize - minTotal) / (weightSum == 0.0 ? 1.0 : weightSum)); int x = start, minSum = 0; double prevWeightSum = 0.0; for (int i = 0; i < rcs.length; i++) { int width = rcs[i].minEnd - minSum + (int) ((rcs[i].weightSum - prevWeightSum) * spare) - spacing; rcs[i].start = x; x += width + spacing; prevWeightSum = rcs[i].weightSum; minSum = rcs[i].minEnd; } } public void addLayoutComponent(String s, Component component) { setConstraints(component, s); } public void setConstraints(Component component, String s) { mapPutOrRemove(map, s, component); mapPutOrRemove(constraints, component, s); } public void removeLayoutComponent(Component component) { map.values().remove(component); constraints.remove(component); } public Dimension minimumLayoutSize(Container container) { prepareLayout(container); Insets insets = getInsets(container); Dimension result = new Dimension(insets.left + cols[cols.length - 1].minEnd + insets.right - spacingX, insets.top + rows[rows.length - 1].minEnd + insets.bottom - spacingY); return result; } final public Insets getInsets(Container container) { Insets insets = container.getInsets(); return new Insets(insets.top + insetTop, insets.left + insetLeft, insets.bottom + insetBottom, insets.right + insetRight); } public Dimension preferredLayoutSize(Container container) { return minimumLayoutSize(container); } public LetterLayout setSpacing(int x, int y) { spacingX = x; spacingY = y; return this; } public LetterLayout setSpacing(int spacing) { return setSpacing(spacing, spacing); } public LetterLayout setBorder(int top, int left, int bottom, int right) { insetTop = top; insetLeft = left; insetBottom = bottom; insetRight = right; return this; } public LetterLayout setBorder(int inset) { return setBorder(inset, inset, inset, inset); } public LetterLayout setTopBorder(int inset) { insetTop = inset; return this; } public static LetterLayout stalactite() { return new LetterLayout(STALACTITE); } public static LetterLayout leftAlignedRow() { return new LetterLayout(LEFT_ALIGNED_ROW); } public static LetterLayout leftAlignedRow(int spacing) { return leftAlignedRow().setSpacing(spacing); } public static LetterLayout centeredRow() { return new LetterLayout(CENTERED_ROW); } public static LetterLayout rightAlignedRow() { return new LetterLayout(RIGHT_ALIGNED_ROW); } public static JPanel rightAlignedRowPanel(JComponent... components) { return makePanel(new LetterLayout(RIGHT_ALIGNED_ROW), components); } static public JPanel makePanel(LetterLayout letterLayout, JComponent[] components) { JPanel panel = new JPanel(letterLayout); for (JComponent component : components) { panel.add(component); } return panel; } public static LetterLayout form() { LetterLayout letterLayout = new LetterLayout(FORM); letterLayout.formWideLeftSide = true; letterLayout.formWideRightSide = true; return letterLayout; } public static LetterLayout formWideRightSide() { LetterLayout letterLayout = new LetterLayout(FORM); letterLayout.formWideRightSide = true; return letterLayout; } public static Component getDummyComponent() { return new DummyComponent(); } public static JPanel newPanel(String... lines) { return new JPanel(new LetterLayout(lines)); } public boolean isDebug() { return debug; } public void setDebug(boolean debug) { this.debug = debug; } public static char makeIndexChar(int idx) { return (char) ('a' + idx * 2); } public static char makeAlternateIndexChar(int idx) { return (char) ('b' + idx * 2); } public static char LEFT_CHAR = ',', RIGHT_CHAR = '.'; public static void main(String[] args) { System.out.println((int) makeIndexChar(0)); System.out.println((int) makeAlternateIndexChar(0)); System.out.println((int) makeIndexChar(32000)); System.out.println((int) makeAlternateIndexChar(32000)); System.out.println((int) LEFT_CHAR); System.out.println((int) RIGHT_CHAR); } } static public String dropTrailingBackslashR(String s) { int i = l(s); while (i > 0 && s.charAt(i - 1) == '\r') --i; return substring(s, 0, i); } static public String b(Object contents, Object... params) { return tag("b", contents, params); } static public boolean isA(Either e) { return eitherIsA(e); } static public void add(BitSet bs, int i) { bs.set(i); } static public boolean add(Collection c, A a) { return c != null && c.add(a); } static public void add(Container c, Component x) { addToContainer(c, x); } static public long add(AtomicLong l, long b) { return l.addAndGet(b); } static public boolean isOneOfSingleChars(String s, char... chars) { if (l(s) != 1) return false; char real = s.charAt(0); for (char c : unnullForIteration(chars)) if (real == c) return true; return false; } static public A setBorder(Border border, A c) { if (c != null) { swing(() -> { c.setBorder(border); }); } return c; } static public String tag(String tag) { return htag(tag); } static public String tag(String tag, Object contents, Object... params) { return htag(tag, str(contents), params); } static public String tag(String tag, StringBuilder contents, Object... params) { return htag(tag, contents, params); } static public String tag(String tag, StringBuffer contents, Object... params) { return htag(tag, contents, params); } static public boolean eitherIsA(Either e) { return e != null && e.isA(); } static public String htag(String tag) { return htag(tag, ""); } static public String htag(String tag, Object contents, Object... params) { String openingTag = hopeningTag(tag, params); String s = str(contents); if (empty(s) && neqic(tag, "script")) return dropLast(openingTag) + "/>"; return openingTag + s + ""; } static public boolean neqic(String a, String b) { return !eqic(a, b); } static public boolean neqic(char a, char b) { return !eqic(a, b); } }