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 java.time.Duration; import javax.swing.border.*; import java.awt.geom.*; import java.awt.datatransfer.StringSelection; import javax.swing.undo.UndoManager; import java.text.NumberFormat; import javax.imageio.metadata.*; import javax.imageio.stream.*; import java.text.SimpleDateFormat; import java.nio.charset.Charset; import static x30_pkg.x30_util.DynamicObject; import org.fife.ui.autocomplete.*; import org.fife.rsta.ui.CollapsibleSectionPanel; import org.fife.rsta.ui.GoToDialog; import org.fife.rsta.ui.SizeGripIcon; import org.fife.rsta.ui.search.FindDialog; import org.fife.rsta.ui.search.ReplaceDialog; import org.fife.rsta.ui.search.ReplaceToolBar; import org.fife.rsta.ui.search.SearchEvent; import org.fife.rsta.ui.search.SearchListener; import org.fife.rsta.ui.search.FindToolBar; import org.fife.ui.rsyntaxtextarea.ErrorStrip; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.RTextScrollPane; import org.fife.ui.rtextarea.SearchContext; import org.fife.ui.rtextarea.SearchEngine; import org.fife.ui.rtextarea.SearchResult; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; import org.fife.ui.rsyntaxtextarea.SyntaxScheme; import javax.swing.Icon; import java.nio.file.*; import static java.nio.file.StandardWatchEventKinds.*; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.Const; import org.apache.bcel.generic.*; import java.lang.reflect.Type; import javax.swing.border.TitledBorder; import java.awt.geom.Line2D; import java.util.jar.*; import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.DataFlavor; import java.text.*; import org.fife.ui.rsyntaxtextarea.*; import java.nio.file.Path; import javax.swing.event.AncestorListener; import javax.swing.event.AncestorEvent; import javax.swing.Timer; import java.util.TimeZone; import java.awt.datatransfer.UnsupportedFlavorException; public class main { static public class JG22NetworkElement implements Swingable, IFieldsToList { public G22Utils g22utils; public JG22Network parent; public G22NetworkElement element; public JG22NetworkElement() { } public JG22NetworkElement(G22Utils g22utils, JG22Network parent, G22NetworkElement element) { this.element = element; this.parent = parent; this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils, parent, element }; } public CollapsibleLeftPanel collapsiblePanel; public JLeftArrowScriptIDE ide; public SingleComponentPanel scpContent = scp(); public JLabel lblDirty = jlabel(); transient public BoolVarWithNotify visualizing = new BoolVarWithNotify(); { visualizing.onChange(() -> updateDirtyFlag()); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { ide = g22utils.leftArrowIDE(); ide.makeParser = () -> { var parser = ide.makeParser_base(); element.configureParser(parser); return parser; }; ide.withResultPanel(false); ide.lvScript(element.varCode()); ide.runScript = () -> calculate(); var popDownButton = withRightMargin(jfullcenter(jPopDownButton_noText("Calculate", runnableThread(new Runnable() { public void run() { try { calculate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "calculate();"; } }), "Visualize", runnableThread(new Runnable() { public void run() { try { visualizeNode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "visualizeNode();"; } }), "Configure", runnableThread(new Runnable() { public void run() { try { configureNode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "configureNode();"; } }), "Create input ports", runnableThread(new Runnable() { public void run() { try { autoCreateInputPorts(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "autoCreateInputPorts();"; } }), "Create output port", runnableThread(new Runnable() { public void run() { try { autoCreateOutputPort(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "autoCreateOutputPort();"; } }), "Copy code", runnableThread(new Runnable() { public void run() { try { copyCode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyCode();"; } }), "Delete node", runnableThread(new Runnable() { public void run() { try { deleteElement(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "deleteElement();"; } })))); var lblNodeID = toolTip("Click here to drag node around", jlabel("Node:")); componentPopupMenuItem(lblDirty, "Show error", runnableThread(new Runnable() { public void run() { try { showError(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showError();"; } })); collapsiblePanel = new CollapsibleLeftPanel(false, "Code", jMinWidth(0, ide.visualize()), jMinWidth(0, northAndCenter(centerAndEastWithMargin(withLabel(lblNodeID, centerTextField(jVarTextField(element.varIdentifier()))), jline(lblDirty, popDownButton)), scpContent))); bindVarToVar(element.varCodeVisible(), collapsiblePanel.varExpanded()); var box = collapsiblePanel.visualize(); jMinSize(80, 50, box); setBorder(box, BorderFactory.createLineBorder(Color.green, 5)); onMouseDown(lblNodeID, event -> { new ComponentDragger(box, event).bringToFront(true).start(); }); new ComponentResizeDragger(box, box); var bounds = or(element.bounds, rect(50, 50, 400, 300)); setBounds(box, bounds); onBoundsChange(box, new Runnable() { public void run() { try { element.bounds(toRect(getBounds(box))); element.network.change(); parent.mainPanel.revalidateMe(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "element.bounds(toRect(getBounds(box)));\r\n element.network.change();\r\n ..."; } }); return box; } public void deleteElement() { parent.deleteElement(this); } public void calculate() { try { parent.networkInstance.calculateNode(g22utils, element); visualizeNode(); } catch (Throwable __e) { infoBox(__e); } } public void configureNode() { try { element.configureBlueprint(g22utils); } catch (Throwable __e) { infoBox(__e); } } public void visualizeNode() { try { AutoCloseable __1 = tempSetBoolVar(visualizing); try { var parsedScript = element.compile(g22utils).get(); callVisualizeFunction(parsedScript); } finally { _close(__1); } } catch (Throwable __e) { infoBox(__e); } } public void callVisualizeFunction(GazelleV_LeftArrowScript.Script parsedScript) { var visualizeFunction = parsedScript.getFunction("visualize"); Object elementInstance = myInstance(); Component visualized = null; if (visualizeFunction != null) { var val = myValue(); Object valueHandler = new Object() { public void setValue(Object o) { parent.networkInstance.setObject(element, val, o); } }; RunResultWithTimestamps value = runResultWithTimestamps(() -> wrap(visualizeFunction.call(new FlexibleVarContext(), elementInstance, valueHandler, element))); ide.showScriptResult(value); if (value.isOK()) visualized = wrap(value.get()); else visualized = jErrorView(value.error()); } else visualized = new G22JavaObjectVisualizer(g22utils, elementInstance).visualize(); print("visualized", visualized); scpContent.set(visualized); } public void updateDirtyFlag() { var value = myValue(); setText(lblDirty, value == null ? " " : visualizing.get() ? "Visualizing" : value.calculating() ? "Calculating" : value.hasError() ? "Error" : value.dirty() ? "Dirty" : "Clean"); } public Object myInstance() { Object elementInstance = null; var ni = parent.networkInstance; if (ni != null) elementInstance = ni.getObjectForBlueprint(element); return elementInstance; } public G22NetworkInstance.Value myValue() { Object elementInstance = null; var ni = parent.networkInstance; return ni == null ? null : ni.valuesByBlueprint.get(element); } public void copyCode() { copyTextToClipboardVerbose(element.code()); } public void showError() { showErrorFrame(myValue().error()); } public void autoCreateOutputPort() { element.autoCreateOutputPort(myValue()); } public void autoCreateInputPorts() { element.autoCreateInputPorts(g22utils); } } static public SingleComponentPanel scp() { return singleComponentPanel(); } static public SingleComponentPanel scp(Component c) { return singleComponentPanel(c); } static public JLabel jlabel(final String text) { return swingConstruct(BetterLabel.class, text); } static public JLabel jlabel() { return jlabel(" "); } static public A markVisualizer(Object visualizer, A a) { return setMetaSrc(a, visualizer); } 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 JPanel jfullcenter(Component c) { return jFullCenter(c); } static public JButton jPopDownButton_noText(final Object... menuParams) { return toolTip("Additional commands", jPopDownButton("", menuParams)); } 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 RuntimeException rethrow(Throwable t) { if (t instanceof Error) _handleError((Error) t); throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static public RuntimeException rethrow(String msg, Throwable t) { throw new RuntimeException(msg, t); } 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 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 A jMinWidth(final int w, final A c) { if (c == null) return null; return swing(new F0() { public A get() { try { Dimension size = c.getMinimumSize(); c.setMinimumSize(new Dimension(w, size.height)); return jPreferWidth(w, c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Dimension size = c.getMinimumSize();\r\n c.setMinimumSize(new Dimension(/*ma..."; } }); } static public JPanel northAndCenter(Component n, Component c) { return centerAndNorth(c, n); } static public JPanel centerAndEastWithMargin(Swingable c, Swingable e) { return centerAndEastWithMargin(c, toComponent(e)); } static public JPanel centerAndEastWithMargin(Swingable c, Component e) { return centerAndEastWithMargin(toComponent(c), e); } static public JPanel centerAndEastWithMargin(Component c, Swingable e) { return centerAndEastWithMargin(c, toComponent(e)); } static public JPanel centerAndEastWithMargin(Component c, Component e) { return centerAndEastWithMarginInbetween(c, e); } static public JComponent withLabel(String label, JComponent component) { return westAndCenter(jlabel(label + " "), component); } static public JComponent withLabel(JComponent label, JComponent component) { return westAndCenterWithMargin(label, component); } static public A centerTextField(A tf) { tf.setHorizontalAlignment(JTextField.CENTER); return tf; } static public JTextField jVarTextField(IVarWithNotify var) { return bindTextComponentToVarWithNotify(jTextField(), var); } static public JPanel jline(final Component... components) { return swing(() -> { return new LeftAlignedLine(components); }); } static public JPanel jline(List components) { return jline(asArray(Component.class, components)); } static public void bindVarToVar(IVarWithNotify var1, IVarWithNotify var2) { linkVars(var1, var2); } static public A jMinSize(int w, int h, A c) { return jMinWidth(w, jMinHeight(h, c)); } static public A jMinSize(A c, int w, int h) { return jMinSize(w, h, c); } static public A jMinSize(A c, Dimension d) { return jMinSize(d.width, d.height, c); } static public A setBorder(Border border, A c) { if (c != null) { swing(() -> { c.setBorder(border); }); } return c; } static public A setBorder(A c, Border border) { return setBorder(border, c); } static public MouseAdapter onMouseDown(Component c, Runnable r) { return onMouseDown(c, runnableToIVF1(r)); } static public MouseAdapter onMouseDown(Component c, IVF1 f) { return c == null || f == null ? null : swing(() -> { MouseAdapter ma = new MouseAdapter() { public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) f.get(e); } }; c.addMouseListener(ma); return ma; }); } static public A or(A a, A b) { return a != null ? a : b; } 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 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 A onBoundsChange(A c, final Object r) { if (c != null && r != null) { swing(() -> { c.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { pcallF(r); } public void componentMoved(ComponentEvent e) { pcallF(r); } }); }); } return c; } static public A onBoundsChange(Object r, A c) { return onBoundsChange(c, r); } 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(DoubleRect r) { if (r == null) return null; int x = iround(r.x), y = iround(r.y); return new Rect(x, y, iround(r.x2()) - x, iround(r.y2()) - y); } static public Rect toRect(Rect r) { return r; } static public Rectangle getBounds(final Component c) { return c == null ? null : swing(new F0() { public Rectangle get() { try { return c.getBounds(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getBounds();"; } }); } 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 AutoCloseable tempSetBoolVar(BoolVar var) { return tempSetBoolVar(var, true); } static public AutoCloseable tempSetBoolVar(BoolVar var, boolean a) { if (var == null) return null; boolean prev = setBoolVar_returnPrevious(var, a); return () -> var.set(prev); } 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 RunResultWithTimestamps runResultWithTimestamps(IF0 f) { return new RunResultWithTimestamps().run(f); } 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 JComponent jErrorView(Throwable e) { return jSmallErrorView(e); } 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 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 String copyTextToClipboardVerbose(Object _text) { String text = copyTextToClipboard(_text); print("Copied to clipboard (" + n2(l(text), "char") + "): " + quote(shorten(text, 1000))); return text; } static public JComponent showErrorFrame(Throwable e) { if (e == null) return null; return showTextWordWrapped("Error", renderStackTrace((e))); } static public AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) { return print_byThread().get() == null ? tempInterceptPrint(f) : null; } 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 "return new SingleComponentPanel(c);"; } }); } 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 "return nuObject(c, args);"; } }); } static public A setMetaSrc(A a, Object src) { setMetaAndVerify(a, "src", src); return a; } static public A setMetaSrc(A a, Object src) { setMetaAndVerify(a, "src", src); return a; } 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 get(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } static public A get(A[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : null; } static public boolean get(boolean[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : false; } static public Object get(Object o, String field) { try { if (o == null) return null; if (o instanceof Class) return get((Class) o, field); if (o instanceof Map) return ((Map) o).get(field); Field f = getOpt_findField(o.getClass(), field); if (f != null) { makeAccessible(f); return f.get(o); } if (o instanceof DynamicObject) return getOptDynOnly(((DynamicObject) o), field); } catch (Exception e) { throw asRuntimeException(e); } throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName()); } static public Object get_raw(String field, Object o) { return get_raw(o, field); } static public Object get_raw(Object o, String field) { try { if (o == null) return null; Field f = get_findField(o.getClass(), field); makeAccessible(f); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } static public Object get(Class c, String field) { try { Field f = get_findStaticField(c, field); makeAccessible(f); return f.get(null); } catch (Exception e) { throw new RuntimeException(e); } } static public Field get_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 get_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 Object get(String field, Object o) { return get(o, field); } static public boolean get(BitSet bs, int idx) { return bs != null && bs.get(idx); } static public JPanel marginPanel() { return jtransparent(borderLayoutPanel()); } static public JPanel jFullCenter(final Component c) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new GridBagLayout()); panel.add(c); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new GridBagLayout);\r\n panel.add(c);\r\n ret panel;"; } }); } 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 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 void _handleError(Error e) { } static public A setToolTipText(final A c, final Object toolTip) { if (c == null) return null; { swing(() -> { String s = str_nullIfEmpty(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 ThreadLocal componentPopupMenu_mouseEvent; static public void componentPopupMenu_init() { { swing(() -> { if (componentPopupMenu_mouseEvent == null) componentPopupMenu_mouseEvent = (ThreadLocal) vm_generalMap_get("mouseEvent"); if (componentPopupMenu_mouseEvent == null) vm_generalMap_put("componentPopupMenu_mouseEvent", componentPopupMenu_mouseEvent = new ThreadLocal()); }); } } static public void componentPopupMenu(final JComponent component, IVF1 menuMaker) { componentPopupMenu(component, (Object) menuMaker); } static public void componentPopupMenu(final JComponent component, final Object menuMaker) { if (component == null || menuMaker == null) return; { swing(() -> { Object adapter = componentPopupMenu_initForComponent(component); ((List) _get(adapter, "maker")).add(menuMaker); }); } } static public Object componentPopupMenu_initForComponent(final JComponent component) { return component == null ? null : swing(new F0() { public Object get() { try { componentPopupMenu_init(); Object adapter = findComponentPopupMenuListener_gen(component); if (adapter == null) { componentPopupMenu_Adapter a = new componentPopupMenu_Adapter(); component.addMouseListener(a); adapter = a; } return adapter; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "componentPopupMenu_init();\r\n O adapter = findComponentPopupMenuListener_ge..."; } }); } static public class componentPopupMenu_Adapter extends MouseAdapter { public List maker = new ArrayList(); public boolean internalFrameLeftButtonMagic = false; public boolean allowScrolling = true; public Point pressedAt; public void mousePressed(MouseEvent e) { displayMenu(e); pressedAt = internalFrameLeftButtonMagic && e.getClickCount() == 1 && internalFrameActive(e.getComponent()) ? e.getLocationOnScreen() : null; } public void mouseReleased(MouseEvent e) { if (internalFrameLeftButtonMagic && eq(pressedAt, e.getLocationOnScreen())) displayMenu2(e); else displayMenu(e); } public void displayMenu(MouseEvent e) { if (e.getSource() instanceof JInternalFrame) return; if (e.isPopupTrigger()) displayMenu2(e); } public void populate(JPopupMenu menu, MouseEvent e) { AutoCloseable __1 = tempSetTL(componentPopupMenu_mouseEvent, e); try { for (Object menuMaker : maker) pcallF(menuMaker, menu); vmBus_send("showingPopupMenu", e.getComponent(), menu); } finally { _close(__1); } } public void displayMenu2(MouseEvent e) { new PopupMenuMaker(e, menu -> populate(menu, e)).allowScrolling(allowScrolling).run(); } } static public void addMenuItem(JPopupMenu menu, String text, Object action) { menu.add(jmenuItem(text, action)); } static public void addMenuItem(JPopupMenu menu, JMenuItem menuItem) { if (menu != null && menuItem != null) 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 A jPreferWidth(int w, A c) { { swing(() -> { Dimension size = c.getPreferredSize(); c.setPreferredSize(new Dimension(w, size.height)); }); } return c; } static public JPanel centerAndNorth(final Component c, final Component n) { return swing(new F0() { public JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.CENTER, wrap(c)); panel.add(BorderLayout.NORTH, wrap(n)); 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 A toComponent(A c) { return c; } static public Component toComponent(Swingable c) { return c == null ? null : c.visualize(); } static public JPanel centerAndEastWithMarginInbetween(Component c, final Component e) { return centerAndEast(c, withLeftMargin(e)); } 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 JPanel westAndCenterWithMargin(Component w, Component c) { return westAndCenter(withRightMargin(w), c); } static public JPanel westAndCenterWithMargin(int margin, Component w, Component c) { return westAndCenter(withRightMargin(margin, w), c); } static public A bindTextComponentToVarWithNotify(A tc, IVarWithNotify lv) { bindHasChangeListenersToComponent(tc, lv, new Runnable() { public void run() { try { setTextKeepCaret(tc, lv.get()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setTextKeepCaret(tc, lv!)"; } }); onChange(tc, new Runnable() { public void run() { try { lv.set(getText(tc)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lv.set(getText(tc))"; } }); return tc; } 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 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 void linkVars(IVarWithNotify var1, IVarWithNotify var2) { if (var1 == null || var2 == null) return; var2.onChange(value -> var1.set(value)); var1.onChangeAndNow(value -> var2.set(value)); } static public A jMinHeight(A c, int h) { return jMinHeight(h, c); } static public A jMinHeight(int h, A c) { Dimension size = c.getMinimumSize(); c.setMinimumSize(new Dimension(size.width, max(h, size.height))); return jPreferHeight(h, c); } static public IVF1 runnableToIVF1(Runnable r) { return r == null ? null : a -> r.run(); } static public Rectangle toRectangle(Rect r) { return r == null ? null : r.getRectangle(); } 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) { printStackTrace(__e); } return null; } static public B pcallF(F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__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(); } } catch (Throwable __e) { printStackTrace(__e); } return null; } static public A pcallF(IF0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public B pcallF(IF1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public int iround(double d) { return (int) Math.round(d); } static public int iround(Number n) { return iround(toDouble(n)); } 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 String strOrNull(Object o) { return o == null ? null : str(o); } static public boolean setBoolVar_returnPrevious(BoolVar v, boolean value) { synchronized (v) { boolean prev = v.get(); v.set(value); return prev; } } static public A _recordNewSwingComponent(A c) { if (c != null) callF((Object) vm_generalMap_get("newSwingComponentRegistry"), (Object) c); 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 Object callOpt(Object o) { return callF(o); } static public Object callOpt(Object o, String method, Object... args) { return callOpt_withVarargs(o, method, args); } static public JScrollPane jscroll(Component c) { return swing(() -> { return c instanceof JScrollPane ? ((JScrollPane) c) : new JScrollPane(c); }); } static public String str(Object o) { return o == null ? "null" : o.toString(); } static public String str(char[] c) { return new String(c); } static public String str(char[] c, int offset, int count) { return new String(c, offset, count); } static public JComponent jSmallErrorView(Throwable e) { var btn = jimageButtonScaledToWidth(32, errorIconID(), "Show error details", () -> showErrorFrame(e)); var label = jlabel_noAutoToolTip(exceptionType(e)); return jline(btn, label); } 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 Map> callF_cache = newDangerousWeakHashMap(); static public A callF(F0 f) { return f == null ? null : f.get(); } static public B callF(F1 f, A a) { return f == null ? null : f.get(a); } static public A callF(IF0 f) { return f == null ? null : f.get(); } static public B callF(IF1 f, A a) { return f == null ? null : f.get(a); } static public B callF(A a, IF1 f) { return f == null ? null : f.get(a); } static public C callF(IF2 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 void callF(A a, IVF1 f) { if (f != null) f.get(a); } static public void callF(IVF1 f, A a) { if (f != null) f.get(a); } static public Object callF(Runnable r) { { if (r != null) r.run(); } return null; } static public Object callF(Object f, Object... args) { return safeCallF(f, args); } static public Object safeCallF(Object f, Object... args) { if (f instanceof Runnable) { ((Runnable) f).run(); return null; } if (f == null) return null; Class c = f.getClass(); ArrayList methods; synchronized (callF_cache) { methods = callF_cache.get(c); if (methods == null) methods = callF_makeCache(c); } int n = l(methods); if (n == 0) { if (f instanceof String) throw fail("Legacy call: " + f); throw fail("No get method in " + getClassName(c)); } if (n == 1) return invokeMethod(methods.get(0), f, args); for (int i = 0; i < n; i++) { Method m = methods.get(i); if (call_checkArgs(m, args, false)) return invokeMethod(m, f, args); } throw fail("No matching get method in " + getClassName(c)); } static public ArrayList callF_makeCache(Class c) { ArrayList l = new ArrayList(); Class _c = c; do { for (Method m : _c.getDeclaredMethods()) if (m.getName().equals("get")) { makeAccessible(m); l.add(m); } if (!l.isEmpty()) break; _c = _c.getSuperclass(); } while (_c != null); callF_cache.put(c, l); return l; } 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 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 boolean neq(Object a, Object b) { return !eq(a, b); } static public Object call(Object o) { return callF(o); } static public Object call(Object o, String method, String[] arg) { return call(o, method, new Object[] { arg }); } static public Object call(Object o, String method, Object... args) { return call_withVarargs(o, method, args); } 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 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) { return n2(ms, singular, singular + "s"); } static public String n2(MultiSet ms, String singular, String plural) { return n_fancy2(ms, singular, plural); } static public String n2(IMultiMap mm, String singular) { return n2(mm, singular, singular + "s"); } static public String n2(IMultiMap mm, String singular, String plural) { return n_fancy2(l(mm), singular, plural); } static public int l(Object[] a) { return a == null ? 0 : a.length; } static public int l(boolean[] a) { return a == null ? 0 : a.length; } static public int l(byte[] a) { return a == null ? 0 : a.length; } static public int l(short[] a) { return a == null ? 0 : a.length; } static public int l(long[] a) { return a == null ? 0 : a.length; } static public int l(int[] a) { return a == null ? 0 : a.length; } static public int l(float[] a) { return a == null ? 0 : a.length; } static public int l(double[] a) { return a == null ? 0 : a.length; } static public int l(char[] a) { return a == null ? 0 : a.length; } static public int l(Collection c) { return c == null ? 0 : c.size(); } static public int l(Iterator i) { return iteratorCount_int_close(i); } static public int l(Map m) { return m == null ? 0 : m.size(); } static public int l(CharSequence s) { return s == null ? 0 : s.length(); } static public long l(File f) { return f == null ? 0 : f.length(); } static public int l(MultiSet ms) { return ms == null ? 0 : ms.size(); } static public int l(IMultiMap mm) { return mm == null ? 0 : mm.size(); } static public int l(IntRange r) { return r == null ? 0 : r.length(); } static public double l(DoubleRange r) { return r == null ? 0 : r.length(); } static public int l(AppendableChain a) { return a == null ? 0 : a.size; } static public int l(IntSize o) { return o == null ? 0 : o.size(); } 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 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 JTextArea showTextWordWrapped(final String title, final String text) { return showWrappedText(title, text); } static public JTextArea showTextWordWrapped(Object text) { return showWrappedText(text); } static public String renderStackTrace(StackTraceElement[] st) { return stackTraceToString(st); } static public String renderStackTrace(Throwable e) { return stackTraceToString(e); } static public String renderStackTrace(String msg) { return renderStackTrace(new Throwable(msg)); } 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 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 == null || 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 : getDeclaredConstructors_cached(c)) { 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 void setMetaAndVerify(Object o, Object key, Object value) { setMeta(o, key, value); assertSame(() -> "setMeta failed (class: " + className(o) + ", key: " + key + ")", value, metaGet(o, key)); } static public void setMetaAndVerify(IMeta o, Object key, Object value) { setMeta(o, key, value); assertSame(() -> "setMeta failed (class: " + className(o) + ", key: " + key + ")", value, metaGet(o, key)); } 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 Field getOpt_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); return null; } 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 Object getOptDynOnly(DynamicObject o, String field) { if (o == null || o.fieldValues == null) return null; return o.fieldValues.get(field); } static public RuntimeException asRuntimeException(Throwable t) { if (t instanceof Error) _handleError((Error) t); return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static public A jtransparent(final A a) { { swing(() -> { a.setOpaque(false); }); } return a; } static public JPanel borderLayoutPanel() { return jpanel(new BorderLayout()); } static public JButton jbutton(String text, Runnable action) { return newButton(text, action); } 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 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(IMultiMap mm) { return mm == null || mm.size() == 0; } static public boolean empty(File f) { return getFileSize(f) == 0; } static public boolean empty(IntRange r) { return r == null || r.empty(); } static public boolean empty(DoubleRange r) { return r == null || r.isEmpty(); } static public boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); } static public boolean empty(Chain c) { return c == null; } static public boolean empty(AppendableChain c) { return c == null; } 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 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 getPreferredWidth(Component c) { return preferredWidth(c); } 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 == null) return null; 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 str_nullIfEmpty(Object o) { return nullIfEmpty(strOrNull(o)); } 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 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 MouseListener findComponentPopupMenuListener_gen(final JComponent c) { return c == null ? null : swing(() -> firstWithClassShortNamed("componentPopupMenu_Adapter", c.getMouseListeners())); } static public boolean internalFrameActive(Component c) { final JInternalFrame f = getInternalFrame(c); return f != null && swing(new F0() { public Boolean get() { try { return f.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return f.isSelected();"; } }); } static public AutoCloseable tempSetTL(ThreadLocal tl, A a) { return tempSetThreadLocal(tl, a); } static public AutoCloseable tempSetTL(BetterThreadLocal tl, A a) { return tempSetThreadLocalIfNecessary(tl, a); } 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 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 A bindHasChangeListenersToComponent(A component, IHasChangeListeners hcl, Runnable listener) { if (hcl != null) bindToComponent(component, () -> hcl.onChangeAndNow(listener), () -> hcl.removeChangeListener(listener)); return component; } static public A setTextKeepCaret(final String text, final A c) { if (c != null) { swing(() -> { int caret = c.getCaretPosition(); setText(c, text); setCaretPosition(c, caret); }); } return c; } static public A setTextKeepCaret(A c, String text) { return setTextKeepCaret(text, c); } 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 void onChange(JTextComponent tc, Runnable 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, Runnable r) { addActionListener(cb, r); return cb; } 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 A onChange(Runnable r, A cc) { if (cc != null && r != null) { swing(() -> { cc.getSelectionModel().addChangeListener(changeListener(r)); }); } return cc; } static public void onChange(IHasChangeListeners a, ChangeTriggerable b) { if (a != null && b != null) a.onChange(new ChangeTrigger(b)); } 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 "return 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 "return 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 "return 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 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 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(A textcomp) { { swing(() -> { UndoManager undo = new UndoManager(); vm_generalWeakSet("Undo Managers").add(undo); setMeta(textcomp, "UndoManager", 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 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 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 > A max(Iterable l) { A max = null; var it = iterator(l); if (it.hasNext()) { max = it.next(); while (it.hasNext()) { A a = it.next(); if (cmp(a, max) > 0) max = a; } } return max; } 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 A jPreferHeight(int h, A c) { Dimension size = c.getPreferredSize(); c.setPreferredSize(new Dimension(size.width, max(h, size.height))); return c; } static public Object pcallFunction(Object f, Object... args) { try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace(__e); } return null; } 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 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 A printHidingCredentials(A o) { print(hideCredentials(str(o))); return o; } 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 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 Boolean isHeadless_cache; static public boolean isHeadless() { if (isHeadless_cache != null) return isHeadless_cache; if (isAndroid()) return isHeadless_cache = true; if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; try { SwingUtilities.isEventDispatchThread(); return isHeadless_cache = false; } catch (Throwable e) { return isHeadless_cache = true; } } 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 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 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 getClassName(Object o) { return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName(); } static public Object callOpt_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.findMethod(method, args); if (me == null) { return null; } if ((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(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); } return null; } } catch (Exception __e) { throw rethrow(__e); } } static public JButton jimageButtonScaledToWidth(int w, String imageID, Runnable action) { return jimageButtonScaledToWidth(w, imageID, "", action); } static public JButton jimageButtonScaledToWidth(int w, String imageID, String toolTip, Runnable action) { return jimageButton(scaleImageToWidth(w, imageID), toolTip, action); } static public String errorIconID() { return "#1101390"; } static public JLabel jlabel_noAutoToolTip() { return jlabel_noAutoToolTip(" "); } static public JLabel jlabel_noAutoToolTip(String text) { var lbl = swingConstruct(BetterLabel.class, text); lbl.autoToolTip = false; return lbl; } static public String exceptionType(Throwable e) { e = getInnerException(e); return shortClassName(e); } static public boolean endsWithLetterOrDigit(String s) { return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length() - 1)); } 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(PingSource pingSource) { return ping(); } 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 Object getOpt(Object o, String field) { return getOpt_cached(o, field); } static public Object getOpt(String field, Object o) { return getOpt_cached(o, field); } static public Object getOpt_raw(Object o, String field) { try { Field f = getOpt_findField(o.getClass(), field); if (f == null) return null; makeAccessible(f); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } static public Object getOpt(Class c, String field) { try { if (c == null) return null; Field f = getOpt_findStaticField(c, field); if (f == null) return null; makeAccessible(f); return f.get(null); } catch (Exception __e) { throw rethrow(__e); } } static public Field getOpt_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); return null; } static public Map newDangerousWeakHashMap() { return _registerDangerousWeakMap(synchroMap(new WeakHashMap())); } static public Map newDangerousWeakHashMap(Object initFunction) { return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction); } 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 call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != l(args)) { 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 volatile public PersistableThrowable lastException_lastException; static public PersistableThrowable lastException() { return lastException_lastException; } static public void lastException(Throwable e) { lastException_lastException = persistableThrowable(e); } static public int indexOf(List l, A a, int startIndex) { if (l == null) return -1; int n = l(l); for (int i = startIndex; i < n; i++) if (eq(l.get(i), a)) return i; return -1; } static public int indexOf(List l, int startIndex, A a) { return indexOf(l, a, startIndex); } static public int indexOf(List l, A a) { if (l == null) return -1; return l.indexOf(a); } static public int indexOf(String a, String b) { return a == null || b == null ? -1 : a.indexOf(b); } static public int indexOf(String a, String b, int i) { return a == null || b == null ? -1 : a.indexOf(b, i); } static public int indexOf(String a, char b) { return a == null ? -1 : a.indexOf(b); } static public int indexOf(String a, int i, char b) { return indexOf(a, b, i); } static public int indexOf(String a, char b, int i) { return a == null ? -1 : a.indexOf(b, i); } static public int indexOf(String a, int i, String b) { return a == null || b == null ? -1 : a.indexOf(b, i); } static public int indexOf(A[] x, A a) { int n = l(x); for (int i = 0; i < n; i++) if (eq(x[i], a)) return i; return -1; } static public int indexOf(Iterable l, A a) { if (l == null) return -1; int i = 0; for (A x : l) { if (eq(x, a)) return i; i++; } return -1; } 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 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 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 boolean containsNewLines(String s) { return containsNewLine(s); } static public String jlabel_textAsHTML_center(String text) { return "
" + replace(htmlencode2(text), "\n", "
") + "
"; } static public Object call_withVarargs(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.findStaticMethod(methodName, args); if (me != null) return invokeMethod(me, null, args); List methods = cache.cache.get(methodName); 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() + "." + methodName + "(" + joinWithComma(classNames(args)) + ") not found"); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(methodName, args); if (me != null) return invokeMethod(me, o, args); List methods = cache.cache.get(methodName); 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() + "." + methodName + "(" + joinWithComma(classNames(args)) + ") not found"); } } catch (Exception __e) { throw rethrow(__e); } } 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
int iteratorCount_int_close(Iterator i) { try { int n = 0; if (i != null) while (i.hasNext()) { i.next(); ++n; } if (i instanceof AutoCloseable) ((AutoCloseable) i).close(); return n; } catch (Exception __e) { throw rethrow(__e); } } 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 public JTextArea showWrappedText(final String title, final String text) { return (JTextArea) swingAndWait(new F0() { public Object get() { try { JTextArea textArea = wrappedTextArea(text); caretToHome(textArea); textArea.setFont(typeWriterFont()); makeFrame(title, new JScrollPane(textArea)); return textArea; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JTextArea textArea = wrappedTextArea(text);\r\n caretToHome(textArea);\r\n ..."; } }); } static public JTextArea showWrappedText(Object text) { return showWrappedText(autoFrameTitle(), str(text)); } static public String stackTraceToString(StackTraceElement[] st) { return lines(st); } static public String stackTraceToString(Throwable e) { return getStackTrace_noRecord(e); } 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 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 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 : getDeclaredConstructors_cached(c)) if (empty(m.getParameterTypes())) { makeAccessible(m); return m; } throw fail("No default constructor found in " + c.getName()); } static public Map getDeclaredConstructors_cached_cache = newDangerousWeakHashMap(); static public Constructor[] getDeclaredConstructors_cached(Class c) { Constructor[] ctors; synchronized (getDeclaredConstructors_cached_cache) { ctors = getDeclaredConstructors_cached_cache.get(c); if (ctors == null) { getDeclaredConstructors_cached_cache.put(c, ctors = c.getDeclaredConstructors()); for (var ctor : ctors) makeAccessible(ctor); } } return ctors; } 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 void setMeta(IMeta o, Object key, Object value) { metaMapPut(o, key, value); } static public void setMeta(Object o, Object key, Object value) { metaMapPut(o, key, value); } static public void assertSame(Object a, Object b) { assertSame("", a, b); } static public void assertSame(String msg, Object a, Object b) { if (a != b) throw fail(joinNemptiesWithColon(msg, a + " != " + b + " (" + identityHash(a) + "/" + identityHash(b) + ")")); } static public void assertSame(IF0 msg, Object a, Object b) { if (a != b) throw fail(joinNemptiesWithColon(msg.get(), a + " != " + b + " (" + identityHash(a) + "/" + identityHash(b) + ")")); } static public String className(Object o) { return getClassName(o); } static public Object metaGet(IMeta o, Object key) { return metaMapGet(o, key); } static public Object metaGet(Object o, Object key) { return metaMapGet(o, key); } static public Object metaGet(String key, IMeta o) { return metaMapGet(o, key); } static public Object metaGet(String key, Object o) { return metaMapGet(o, key); } 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 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 JPanel jpanel(LayoutManager layout, Object... components) { return jpanel(layout, asList(components)); } static public JPanel jpanel(LayoutManager layout, List components) { return smartAdd(jpanel(layout), components); } static public JPanel jpanel(LayoutManager layout) { return swing(() -> new JPanel(layout)); } static public JPanel jpanel() { return swing(() -> new JPanel()); } 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); JButton btn = basicJButton(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 JButton btn = basicJButton(te..."; } }); } static public A swingNu(final Class c, final Object... args) { return swingConstruct(c, args); } 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 String charToString(char c) { return String.valueOf(c); } static public String charToString(int c) { return String.valueOf((char) c); } 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, IHasChangeListeners lv, Runnable listener) { return bindHasChangeListenersToComponent(component, lv, listener); } static public boolean isCurlyBracketed(String s) { return isCurlyBraced(s); } 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 void setEnabled(boolean enable, JComponent... l) { for (var c : unnullForIteration(l)) setEnabled(c, enable); } static public String unCurlyBracket(String s) { return tok_unCurlyBracket(s); } 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 HashSet lithashset(A... items) { HashSet set = new HashSet(); for (A a : items) set.add(a); return set; } 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 String programID() { return getProgramID(); } static public String programID(Object o) { return getProgramID(o); } static public Object dm_current_generic() { return getWeakRef(dm_current_generic_tl().get()); } static public Object rcall(String method, Object o, Object... args) { return call_withVarargs(o, method, args); } static public Runnable _topLevelErrorHandling(Runnable r) { if (r == null) return null; Object info = _threadInfo(); Object mod = dm_current_generic(); Runnable r2 = r; if (info != null || mod == null) r2 = 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 ..."; } }; r2 = rPcall(r2); return r2; } static public Map newWeakHashMap() { return _registerWeakMap(synchroMap(new WeakHashMap())); } static public Map vm_generalWeakSubMap(Object name) { synchronized (vm_generalMap()) { Map map = (Map) (vm_generalMap_get(name)); if (map == null) vm_generalMap_put(name, map = newWeakMap()); return map; } } static public WeakReference weakRef(A a) { return newWeakReference(a); } 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 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 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 A firstWithClassShortNamed(String shortName, Iterable l) { if (l != null) for (A o : l) if (eq(shortClassName(o), shortName)) return o; return null; } static public A firstWithClassShortNamed(String shortName, A[] l) { if (l != null) for (A o : l) if (eq(shortClassName(o), shortName)) return o; return null; } 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 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 AutoCloseable tempSetThreadLocalIfNecessary(BetterThreadLocal 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 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 String dropPrefix(String prefix, String s) { return s == null ? null : s.startsWith(prefix) ? s.substring(l(prefix)) : s; } 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 JMenuItem disableMenuItem(final JMenuItem mi) { if (mi != null) { swing(() -> { mi.setEnabled(false); }); } return mi; } 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 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 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 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 A bindToComponent(A component, Runnable onShow, Runnable onUnShow) { { swing(() -> { final Var flag = new Var<>(false); component.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { if (flag.get()) print("Warning: bindToComponent logic failure"); flag.set(true); pcallF(onShow); } public void ancestorRemoved(AncestorEvent event) { if (!flag.get()) print("Warning: bindToComponent logic failure"); flag.set(false); pcallF(onUnShow); } public void ancestorMoved(AncestorEvent event) { } }); if (component.isShowing()) { flag.set(true); pcallF(onShow); } }); } return component; } static public A bindToComponent(A component, Runnable onShow) { return bindToComponent(component, onShow, null); } static public A bindToComponent(A component, IF0 onShow, IVF1 onUnShow) { Var b = new Var(); return bindToComponent(component, () -> b.set(onShow.get()), () -> { try { onUnShow.get(b.get()); } finally { b.set(null); } }); } static public void setCaretPosition(final JTextComponent c, final int pos) { if (c != null) { swing(() -> { try { int _pos = max(0, min(l(c.getText()), pos)); c.setCaretPosition(_pos); } catch (Throwable __e) { printStackTrace(__e); } }); } } 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(JTextComponent c, IVF1 r) { if (c == null || r == null) return; c.getDocument().addDocumentListener(runnableToDocumentListener(() -> r.get(c.getText()))); } static public void onUpdate(JComponent c, Object r) { if (c instanceof JTextComponent) ((JTextComponent) c).getDocument().addDocumentListener(runnableToDocumentListener(toRunnable(r))); else if (c instanceof ItemSelectable) ((ItemSelectable) c).addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { pcallF(r); } }); else if (c instanceof JSpinner) onChange(((JSpinner) c), 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 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 A getSelectedItem_typed(JList l) { return swing(() -> l.getSelectedValue()); } static public A getSelectedItem_typed(JComboBox cb) { return swing(() -> (A) cb.getSelectedItem()); } 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 "return cb.isEditable();"; } }); } 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 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 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 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 AbstractAction abstractAction(String name, final Object runnable) { return new AbstractAction(name) { public void actionPerformed(ActionEvent evt) { pcallF(runnable); } }; } 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(Producer p) { ArrayList l = new ArrayList(); A a; if (p != null) while ((a = p.next()) != null) 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 ArrayList asList(ReverseChain c) { return c == null ? emptyList() : c.toList(); } static public List asList(Pair p) { return p == null ? null : ll(p.a, p.b); } static public Iterator iterator(Iterable c) { return c == null ? emptyIterator() : c.iterator(); } 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 Object callFunction(Object f, Object... args) { return callF(f, args); } static public double parseDouble(String s) { return empty(s) ? 0.0 : Double.parseDouble(s); } 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 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 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 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 int isAndroid_flag; static public boolean isAndroid() { if (isAndroid_flag == 0) isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; return isAndroid_flag > 0; } 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(A c, IVF1 runnable) { return onClick(c, (Object) runnable); } static public A onClick(A c, 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, Object runnable) { onEnter(btn, runnable); } 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 Font typeWriterFont() { return typeWriterFont(iround(14 * getSwingFontScale())); } static public Font typeWriterFont(int size) { return new Font("Courier", Font.PLAIN, size); } 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 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 Rect preferredScreenBounds() { return screenBounds_safe(preferredScreen()); } static public boolean vmBus_anyFalse(String msg, Object... args) { return contains(vmBus_queryAll(msg, args), false); } 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 int toMS_int(double seconds) { return toInt_checked((long) (seconds * 1000)); } 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 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[] massageArgsForVarArgsCall(Executable m, Object[] args) { Class[] types = m.getParameterTypes(); int n = types.length - 1, nArgs = l(args); 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); int nVarArgs = nArgs - n; Object varArgs = Array.newInstance(varArgType, nVarArgs); for (int i = 0; i < nVarArgs; i++) Array.set(varArgs, i, args[n + i]); newArgs[n] = varArgs; return newArgs; } static public JButton jimageButton(String imageID, Object action) { JButton btn = jbutton("", action); btn.setIcon(imageIcon(imageID)); return btn; } static public JButton jimageButton(String imageID) { return jimageButton(imageID, null); } static public JButton jimageButton(Image img) { return jimageButton(img, null, null); } static public JButton jimageButton(String imageID, String toolTip, Runnable action) { return jimageButton(imageIcon(imageID), toolTip, action); } static public JButton jimageButton(Image img, String toolTip, Runnable action) { var btn = jbutton("", action); setButtonImage(btn, img); return setToolTip(toolTip, btn); } static public JButton jimageButton(ImageIcon img, String toolTip, Runnable action) { var btn = jbutton("", action); setButtonImage(btn, img); return setToolTip(toolTip, btn); } static public BufferedImage scaleImageToWidth(BufferedImage img, int newW) { return resizeImage(img, newW); } static public BufferedImage scaleImageToWidth(int newW, BufferedImage img) { return scaleImageToWidth(img, newW); } static public BufferedImage scaleImageToWidth(int newW, String imageID) { return scaleImageToWidth(newW, loadImage2(imageID)); } 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 void newPing() { var tl = newPing_actionTL(); Runnable action = tl == null ? null : tl.get(); { if (action != null) action.run(); } } static public boolean isTrue(Object o) { if (o instanceof Boolean) return ((Boolean) o).booleanValue(); if (o == null) return false; if (o instanceof ThreadLocal) return isTrue(((ThreadLocal) o).get()); throw fail(getClassName(o)); } static public boolean isTrue(Boolean b) { return b != null && b.booleanValue(); } static public void failIfUnlicensed() { assertTrue("license off", licensed()); } static public Thread currentThread() { return Thread.currentThread(); } 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 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 Map synchroMap() { return synchroHashMap(); } static public Map synchroMap(Map map) { return Collections.synchronizedMap(map); } 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(Object... c) { return join(" ", c); } static public List classNames(Collection l) { return getClassNames(l); } static public List classNames(Object[] l) { return getClassNames(asList(l)); } static public PersistableThrowable persistableThrowable(Throwable e) { return e == null ? null : new PersistableThrowable(e); } 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 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 Set vm_generalIdentityHashSet(Object name) { synchronized (vm_generalMap()) { Set set = (Set) (vm_generalMap_get(name)); if (set == null) vm_generalMap_put(name, set = syncIdentityHashSet()); return set; } } static public Map vm_generalHashMap(Object name) { synchronized (vm_generalMap()) { Map m = (Map) (vm_generalMap_get(name)); if (m == null) vm_generalMap_put(name, m = syncHashMap()); return m; } } static public boolean startsWithIgnoreCase(String a, String b) { return regionMatchesIC(a, 0, b, 0, b.length()); } 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, IntRange r) { return r == null ? null : substring(s, r.start, r.end); } static public String substring(String s, CharSequence l) { return substring(s, lCharSequence(l)); } 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 boolean containsNewLine(String s) { return contains(s, '\n'); } 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 String htmlencode2(String s) { return htmlencode_noQuotes(s); } static public boolean isStaticMethod(Method m) { return methodIsStatic(m); } 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 String formatWithThousandsSeparator(long l) { return NumberFormat.getInstance(new Locale("en_US")).format(l); } 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 void caretToHome(JTextComponent c) { setCaret(c, 0); } 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 String autoFrameTitle_value; static public String autoFrameTitle() { return autoFrameTitle_value != null ? autoFrameTitle_value : getProgramTitle(); } static public void autoFrameTitle(Component c) { setFrameTitle(getFrame(c), autoFrameTitle()); } 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 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 "return keysList(myFrames_list);"; } }); } 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 A setThreadLocal(ThreadLocal tl, A value) { if (tl == null) return null; A old = tl.get(); tl.set(value); return old; } static public Map synchroHashMap() { return synchronizedMap(new HashMap()); } 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 void metaMapPut(IMeta o, Object key, Object value) { { if (o != null) o.metaPut(key, value); } } static public void metaMapPut(Object o, Object key, Object value) { var meta = initIMeta(o); { if (meta != null) meta.metaPut(key, value); } } static public String joinNemptiesWithColon(String... strings) { return joinNempties(": ", strings); } static public String joinNemptiesWithColon(Collection strings) { return joinNempties(": ", strings); } static public int identityHash(Object o) { return identityHashCode(o); } static public Object metaMapGet(IMeta o, Object key) { return o == null ? null : o.metaGet(key); } static public Object metaMapGet(Object o, Object key) { return metaMapGet(toIMeta(o), key); } static public List> _threadInfo_makers = synchroList(); static public Object _threadInfo() { if (empty(_threadInfo_makers)) return null; HashMap map = new HashMap(); pcallFAll(_threadInfo_makers, map); return map; } static public Runnable asRunnable(Object o) { return toRunnable(o); } static public void _inheritThreadInfo(Object info) { _threadInheritInfo(info); } static public JPanel smartAdd(JPanel panel, List parts) { for (Object o : parts) addToContainer(panel, wrapForSmartAdd(o)); return panel; } static public JPanel smartAdd(JPanel panel, Object... parts) { return smartAdd(panel, asList(parts)); } static public JButton basicJButton(String text) { return swing(() -> new JButton(text)); } static public boolean eqOneOf(Object o, Object... l) { if (l != null) for (Object x : l) if (eq(o, x)) return true; return false; } static public boolean hasMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args) != null; } static public boolean isCurlyBraced(String s) { List tok = tok_combineCurlyBrackets_keep(javaTok(s)); return l(tok) == 3 && startsWithAndEndsWith(tok.get(1), "{", "}"); } 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 String tok_unCurlyBracket(String s) { return isCurlyBraced(s) ? join(dropFirstThreeAndLastThree(javaTok(s))) : s; } 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 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 "return c.getPreferredSize();"; } }); } static public String programID; 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 A getWeakRef(Reference ref) { return ref == null ? null : ref.get(); } static public x30_pkg.x30_util.BetterThreadLocal dm_current_generic_tl; static public x30_pkg.x30_util.BetterThreadLocal dm_current_generic_tl() { if (dm_current_generic_tl == null) dm_current_generic_tl = vm_generalMap_getOrCreate("currentModule", () -> new x30_pkg.x30_util.BetterThreadLocal()); return dm_current_generic_tl; } static public List> _threadInheritInfo_retrievers = synchroList(); static public void _threadInheritInfo(Object info) { if (info == null) return; pcallFAll(_threadInheritInfo_retrievers, (Map) info); } static public Runnable rPcall(Runnable r) { return r == null ? null : () -> { try { r.run(); } catch (Throwable __e) { printStackTrace(__e); } }; } static public List _registerWeakMap_preList; static public A _registerWeakMap(A map) { if (javax() == null) { if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList(); _registerWeakMap_preList.add(map); return map; } try { call(javax(), "_registerWeakMap", map); } catch (Throwable e) { printException(e); print("Upgrade JavaX!!"); } return map; } static public void _onLoad_registerWeakMap() { assertNotNull(javax()); if (_registerWeakMap_preList == null) return; for (Object o : _registerWeakMap_preList) _registerWeakMap(o); _registerWeakMap_preList = null; } static public Map newWeakMap() { return newWeakHashMap(); } static public WeakReference newWeakReference(A a) { return a == null ? null : new WeakReference(a); } 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 boolean isEmpty(DoubleRange r) { return r == null || r.isEmpty(); } static public boolean isEmpty(AppendableChain c) { return c == null; } static public Class javax() { return getJavaX(); } 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 A first(T3 t) { return t == null ? null : t.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 first(AppendableChain a) { return a == null ? null : a.element; } static public List buttonsInGroup(ButtonGroup g) { if (g == null) return ll(); return asList(g.getElements()); } static public boolean isLetterOrDigit(char c) { return Character.isLetterOrDigit(c); } 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 boolean nemptyString(String s) { return s != null && s.length() > 0; } static public int strL(String s) { return s == null ? 0 : s.length(); } static public int listL(Collection l) { return l == null ? 0 : l.size(); } static public void messageBox(final String msg) { print(msg); { swing(() -> { JOptionPane.showMessageDialog(null, msg, "JavaX", JOptionPane.INFORMATION_MESSAGE); }); } } static public void messageBox(Throwable e) { printStackTrace(e); messageBox(hideCredentials(innerException2(e))); } static public RootPaneContainer getPossiblyInternalFrame(Component c) { JInternalFrame f = getInternalFrame(c); if (f != null) return f; return optCast(RootPaneContainer.class, getWindow(c)); } 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 DocumentListener runnableToDocumentListener(Runnable r) { return new DocumentListener() { public void insertUpdate(DocumentEvent e) { pcallF(r); } public void removeUpdate(DocumentEvent e) { pcallF(r); } public void changedUpdate(DocumentEvent e) { pcallF(r); } }; } static public JTextField onEnter(JTextField tf, JButton btn) { if (btn != null) onEnter(tf, new Runnable() { public void run() { try { clickButton(btn); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "clickButton(btn)"; } }); return tf; } static public JTextField onEnter(JTextField tf, 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, Runnable 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(Runnable action, JTextField tf) { return onEnter(tf, action); } static public String selectedItem(JList l) { return getSelectedItem(l); } static public String selectedItem(JComboBox cb) { return getSelectedItem(cb); } 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 Set newWeakHashSet() { return synchroWeakHashSet(); } 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 Iterator emptyIterator() { return Collections.emptyIterator(); } static public boolean domainIsUnder(String domain, String mainDomain) { return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain); } static public String theAGIBlueDomain() { return "agi.blue"; } 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 long now_virtualTime; static public long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } 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 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 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 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 boolean contains(Producer p, A a) { if (p != null && a != null) while (true) { A x = p.next(); if (x == null) break; if (eq(x, a)) return true; } return false; } static public boolean contains(Rect r, Pt p) { return rectContains(r, p); } 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 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 int toInt_checked(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static public Throwable getException(Runnable r) { try { callF(r); return null; } catch (Throwable e) { return e; } } 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 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 img == null ? null : new ImageIcon(img); } static public ImageIcon imageIcon(RGBImage img) { return imageIcon(img.getBufferedImage()); } static public JButton setButtonImage(Icon img, JButton btn) { btn.setIcon(img); return btn; } static public JButton setButtonImage(Image img, JButton btn) { btn.setIcon(imageIcon(img)); return btn; } static public A setButtonImage(Image img, A btn) { btn.setIcon(imageIcon(img)); return btn; } static public A setButtonImage(A btn, Image img) { return setButtonImage(img, btn); } static public A setButtonImage(A btn, String imageID) { btn.setIcon(imageIcon(imageID)); return btn; } static public JButton setButtonImage(JButton btn, Image img) { return setButtonImage(img, btn); } static public JButton setButtonImage(JButton btn, Icon img) { return setButtonImage(img, btn); } static public A setToolTip(A c, Object toolTip) { return setToolTipText(c, toolTip); } static public A setToolTip(Object toolTip, A c) { return setToolTipText(c, toolTip); } static public void setToolTip(TrayIcon trayIcon, String toolTip) { setTrayIconToolTip(trayIcon, toolTip); } static public BufferedImage resizeImage(BufferedImage img, int newW, int newH) { return resizeImage(img, newW, newH, Image.SCALE_SMOOTH); } static public BufferedImage resizeImage(BufferedImage img, int newW, int newH, int scaleType) { if (newW == img.getWidth() && newH == img.getHeight()) return img; Image tmp = img.getScaledInstance(newW, newH, scaleType); BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = dimg.createGraphics(); g2d.drawImage(tmp, 0, 0, null); g2d.dispose(); return dimg; } static public BufferedImage resizeImage(BufferedImage img, int newW) { int newH = iround(img.getHeight() * (double) newW / img.getWidth()); return resizeImage(img, newW, newH); } static public BufferedImage resizeImage(int newW, BufferedImage img) { return resizeImage(img, newW); } static public BufferedImage loadImage2(String snippetIDOrURL) { return loadBufferedImage(snippetIDOrURL); } static public BufferedImage loadImage2(File file) { return loadBufferedImage(file); } 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 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; } static public void assertTrue(Object o) { if (!(eq(o, true))) throw fail(str(o)); } static public boolean assertTrue(String msg, boolean b) { if (!b) throw fail(msg); return b; } static public boolean assertTrue(boolean b) { if (!b) throw fail("oops"); return b; } 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 void clear(Collection c) { if (c != null) c.clear(); } static public void clear(Map map) { if (map != null) map.clear(); } 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 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 HashMap> callMC_cache = new HashMap(); static public String callMC_key; static public Method callMC_value; static public Object callMC(String method, String[] arg) { return callMC(method, new Object[] { arg }); } static public Object callMC(String method, Object... args) { try { Method me; if (callMC_cache == null) callMC_cache = new HashMap(); synchronized (callMC_cache) { me = method == callMC_key ? callMC_value : null; } if (me != null) try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } List m; synchronized (callMC_cache) { m = callMC_cache.get(method); } if (m == null) { if (callMC_cache.isEmpty()) { callMC_makeCache(); m = callMC_cache.get(method); } if (m == null) throw fail("Method named " + method + " not found in main"); } int n = m.size(); if (n == 1) { me = m.get(0); synchronized (callMC_cache) { callMC_key = method; callMC_value = me; } try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } } for (int i = 0; i < n; i++) { me = m.get(i); if (call_checkArgs(me, args, false)) return invokeMethod(me, null, args); } throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main"); } catch (Exception __e) { throw rethrow(__e); } } static public void callMC_makeCache() { synchronized (callMC_cache) { callMC_cache.clear(); Class _c = (Class) mc(), c = _c; while (c != null) { for (Method m : c.getDeclaredMethods()) if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) { makeAccessible(m); multiMapPut(callMC_cache, m.getName(), m); } c = c.getSuperclass(); } } } static public List synchroList() { return synchroList(new ArrayList()); } static public List synchroList(List l) { return Collections.synchronizedList(l); } 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; } 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 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 collectionMutex(List l) { return l; } static public Object collectionMutex(Object o) { if (o instanceof List) return o; String c = className(o); return o; } static public Throwable _storeException_value; static public void _storeException(Throwable e) { _storeException_value = e; } static public Set syncIdentityHashSet() { return (Set) synchronizedSet(identityHashSet()); } static public Map syncHashMap() { return synchroHashMap(); } 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 int lCharSequence(CharSequence s) { return s == null ? 0 : s.length(); } 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 boolean methodIsStatic(Method m) { return (m.getModifiers() & Modifier.STATIC) != 0; } static public void setCaret(final JTextComponent c, final int pos) { if (c != null) { swing(() -> { c.setCaretPosition(pos); }); } } static public String programTitle() { return getProgramName(); } 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 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 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 String getProgramTitle() { return getProgramName(); } 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 Map weakHashMap() { return newWeakHashMap(); } 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 A popLast(List l) { return liftLast(l); } static public List popLast(int n, List l) { return liftLast(n, l); } static public Map synchronizedMap() { return synchroMap(); } static public Map synchronizedMap(Map map) { return synchroMap(map); } 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 IMeta initIMeta(Object o) { if (o == null) return null; if (o instanceof IMeta) return ((IMeta) o); if (o instanceof JComponent) return initMetaOfJComponent((JComponent) o); if (o instanceof BufferedImage) return optCast(IMeta.class, ((BufferedImage) o).getProperty("meta")); return null; } 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 int identityHashCode(Object o) { return System.identityHashCode(o); } static public IMeta toIMeta(Object o) { return initIMeta(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 addToContainer(Container a, Component... b) { if (a == null) return; { swing(() -> { for (Component c : unnullForIteration(b)) if (c != null) a.add(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 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 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 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 boolean startsWithAndEndsWith(String s, String prefix, String suffix) { return startsWith(s, prefix) && endsWith(s, suffix); } 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 List dropFirstThreeAndLastThree(List l) { return dropFirstAndLast(3, l); } 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(IMultiMap mm) { return mm != null && mm.size() != 0; } static public boolean nempty(Object o) { return !empty(o); } static public boolean nempty(IntRange r) { return !empty(r); } 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 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 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 printException(A e) { printStackTrace(e); return e; } 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 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 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 Throwable innerException2(Throwable e) { if (e == null) return null; while (empty(e.getMessage()) && e.getCause() != null) e = e.getCause(); return e; } static public A optCast(Class c, Object o) { return isInstance(c, o) ? (A) o : null; } static public void clickButton(final JButton b) { if (b != null) { swing(() -> { if (b.isEnabled()) b.doClick(); }); } } 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 String getSelectedItem(JList l) { return (String) l.getSelectedValue(); } static public String getSelectedItem(JComboBox cb) { return strOrNull(cb.getSelectedItem()); } static public Set synchroWeakHashSet() { return Collections.newSetFromMap((Map) newWeakHashMap()); } 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 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 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 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 File userDir() { return new File(userHome()); } static public File userDir(String path) { return new File(userHome(), path); } 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 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 boolean rectContains(Rect a, Pt p) { return a != null && p != null && a.contains(p); } 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 int parseInt(String s) { return emptyString(s) ? 0 : Integer.parseInt(s); } static public int parseInt(char c) { return Integer.parseInt(str(c)); } static public int boolToInt(boolean b) { return b ? 1 : 0; } 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 String fsI(String id) { return formatSnippetID(id); } static public String fsI(long id) { return formatSnippetID(id); } 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 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 void setTrayIconToolTip(TrayIcon trayIcon, String toolTip) { if (trayIcon != null) trayIcon.setToolTip(toolTip); } 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 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 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(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 litset(A... items) { return lithashset(items); } 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 synchronizedSet() { return synchroHashSet(); } static public Set synchronizedSet(Set set) { return Collections.synchronizedSet(set); } static public Set identityHashSet() { return Collections.newSetFromMap(new IdentityHashMap()); } 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 String intToHex_flexLength(int i) { return Integer.toHexString(i); } 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 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 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 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 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 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 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 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 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(IMultiMap mm) { return mm.keySet(); } 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(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(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(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(Map map, IF2 f) { List x = new ArrayList(); if (map != null) for (Map.Entry e : map.entrySet()) { ping(); x.add(f.get(e.getKey(), e.getValue())); } return x; } 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 ArrayList cloneListSynchronizingOn(Collection l, Object mutex) { if (l == null) return new ArrayList(); synchronized (mutex) { return new ArrayList(l); } } 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 IMeta initMetaOfJComponent(JComponent c) { if (c == null) return null; IMeta meta = (IMeta) (c.getClientProperty(IMeta.class)); if (meta == null) c.putClientProperty(IMeta.class, meta = new Meta()); return meta; } 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 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 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 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 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 joinSubList(List l, IntRange r) { return r == null ? null : joinSubList(l, r.start, r.end); } 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 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 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); } public static boolean isSnippetID(String s) { try { parseSnippetID(s); return true; } catch (RuntimeException e) { return false; } } 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 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 IF0 f0ToIF0(F0 f) { return f == null ? null : () -> f.get(); } static public void _onJavaXSet() { } static public Set> _entrySet(Map map) { return map == null ? Collections.EMPTY_SET : map.entrySet(); } static public boolean isInstance(Class type, Object arg) { return type.isInstance(arg); } static public String asString(Object o) { return o == null ? null : o.toString(); } static public File getProgramDir() { return programDir(); } static public File getProgramDir(String snippetID) { return programDir(snippetID); } 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 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 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 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 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 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 boolean emptyString(String s) { return s == null || s.length() == 0; } 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); } static public IResourceLoader vm_getResourceLoader() { return proxy(IResourceLoader.class, vm_generalMap_get("_officialResourceLoader")); } static public boolean isImageServerSnippet(long id) { return id >= 1100000 && id < 1200000; } 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 File DiskSnippetCache_getLibrary(String snippetID) { try { return DiskSnippetCache_getLibrary(psI(snippetID)); } catch (Exception __e) { throw rethrow(__e); } } 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 long fileSize(String path) { return getFileSize(path); } static public long fileSize(File f) { return getFileSize(f); } 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 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 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 isURL(String s) { return startsWithOneOf(s, "http://", "https://", "file:"); } 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 Set synchroHashSet() { return synchronizedSet(new HashSet()); } 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 List newSubListOrSame(List l, IntRange r) { return newSubListOrSame(l, r.start, r.end); } 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 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 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 int random(int n) { return random(n, defaultRandomGenerator()); } 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 defaultRandomGenerator().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 int random(IntRange r) { return random(r.start, r.end); } static public Pair random(Map map) { return entryToPair(random(entries(map))); } static public Integer rectCenterY(Rect r) { return r == null ? null : r.y + r.h / 2; } 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 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 "return 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 GZIPInputStream newGZIPInputStream(File f) { return gzInputStream(f); } static public GZIPInputStream newGZIPInputStream(InputStream in) { return gzInputStream(in); } 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 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 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 List subList(List l, IntRange r) { return subList(l, r.start, r.end); } 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 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 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 void _registerIO(Object object, String path, boolean opened) { } 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 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 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/"); } 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); } } 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 long psI(String snippetID) { return parseSnippetID(snippetID); } 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 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 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 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 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 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 replacePrefix(String prefix, String replacement, String s) { if (!startsWith(s, prefix)) return s; return replacement + substring(s, l(prefix)); } 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 boolean isFile(File f) { return f != null && f.isFile(); } static public boolean isFile(String path) { return isFile(newFile(path)); } 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 int[] subIntArray(int[] a, IntRange r) { return r == null ? null : subIntArray(a, r.start, r.end); } 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 byte[] subByteArray(byte[] b, IntRange r) { return r == null ? null : subByteArray(b, r.start, r.end); } 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 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 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 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 "return 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 "return mi.isSelected();"; } }); } static public boolean isChecked(JRadioButton rb) { return rb != null && (boolean) swing(() -> rb.isSelected()); } static public Random defaultRandomGenerator() { { Random r = customRandomizerForThisThread(); if (r != null) return r; } return ThreadLocalRandom.current(); } static public Random getRandomizer(Random r) { return r != null ? r : defaultRandomGenerator(); } static public A oneOf(List l) { if (empty(l)) return null; int n = l.size(); return n == 1 ? first(l) : l.get(defaultRandomizer().nextInt(n)); } static public char oneOf(String s) { return empty(s) ? '?' : s.charAt(random(l(s))); } static public A oneOf(A... 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 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 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); } } 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 A[] arrayOfSameType(A[] a, int n) { return newObjectArrayOfSameType(a, n); } 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 boolean sameSnippetID(String a, String b) { if (!isSnippetID(a) || !isSnippetID(b)) return false; return parseSnippetID(a) == parseSnippetID(b); } static volatile public String caseID_caseID; static public String caseID() { return caseID_caseID; } static public void caseID(String id) { caseID_caseID = id; } 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 A addAll(A c, Collection components) { return addComponents(c, components); } static public A addAll(A c, Component... components) { return addComponents(c, components); } 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 A println(A a) { return print(a); } static public String imageServerURL() { return or2(trim(loadTextFile(javaxDataDir("image-server-url.txt"))), "http://botcompany.de/images/raw/"); } static volatile public boolean muricaPassword_pretendNotAuthed = false; static public String muricaPassword() { if (muricaPassword_pretendNotAuthed) return null; return trim(loadTextFile(muricaPasswordFile())); } static public String fileServerURL() { return "https://botcompany.de/files"; } 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); } 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 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 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 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 String getLookAndFeel() { return getClassName(UIManager.getLookAndFeel()); } static public JComponent getInternalFrameTitlePaneComponent(JInternalFrame f) { return (JComponent) childWithClassNameEndingWith(f, "InternalFrameTitlePane"); } static public Class hotwireOnce(String programID) { return hotwireCached(programID, false); } 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 boolean isQuoted(String s) { if (isNormalQuoted(s)) return true; return isMultilineQuoted(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 Random customRandomizerForThisThread() { return customRandomizerForThisThread_tl().get(); } static public A listGet(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } 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 String dropSuffix(String suffix, String s) { return nempty(suffix) && endsWith(s, suffix) ? s.substring(0, l(s) - l(suffix)) : s; } static public A addComponents(A c, Collection components) { if (nempty(components)) { swing(() -> { for (Component comp : components) if (comp != null) c.add(comp); revalidate(c); }); } return c; } static public A addComponents(A c, Component... components) { return addComponents(c, asList(components)); } static public boolean networkAllowanceTest(String url) { return isAllowed("networkAllowanceTest", url); } static public void sleepSeconds(double s) { if (s > 0) sleep(round(s * 1000)); } 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 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 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); } } return unquoteSingleOrDoubleQuotes(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 Matcher regexpMatcher(java.util.regex.Pattern pat, String s) { return pat.matcher(unnull(s)); } 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 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 File muricaPasswordFile() { return new File(javaxSecretDir(), "murica/muricaPasswordFile"); } static public ThreadLocal> checkFileNotTooBigToRead_tl = new ThreadLocal(); static public void checkFileNotTooBigToRead(File f) { callF(checkFileNotTooBigToRead_tl.get(), f); } 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 boolean possibleMD5(String s) { return isMD5(s); } 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 String htmlQuery(Map params) { return empty(params) ? "" : "?" + makePostData(params); } static public String htmlQuery(Object... data) { return empty(data) ? "" : "?" + makePostData(data); } 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 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 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 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, n = s.length(); while (i < n && s.charAt(i) == '=') ++i; return i < n && s.charAt(i) == '['; } static public ThreadLocal customRandomizerForThisThread_tl = new ThreadLocal(); static public ThreadLocal customRandomizerForThisThread_tl() { return customRandomizerForThisThread_tl; } 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 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 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 String hmsWithColons() { return hmsWithColons(now()); } static public String hmsWithColons(long time) { return new SimpleDateFormat("HH:mm:ss").format(time); } static public String unquoteSingleOrDoubleQuotes(String s) { if (s == null) return null; 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; } 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 byte[] toUtf8(String s) { try { return s.getBytes(utf8charset()); } catch (Exception __e) { throw rethrow(__e); } } 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 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 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 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 isMD5(String s) { return l(s) == 32 && isLowerHexString(s); } 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 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 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 String urlencode(String x) { try { return URLEncoder.encode(unnull(x), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } static public File saveTextFile(String fileName, String contents) throws IOException { 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()); try { OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); PrintWriter printWriter = new PrintWriter(outputStreamWriter); printWriter.print(contents); printWriter.close(); } finally { _close(fileOutputStream); } } 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; } static public File saveTextFile(File fileName, String contents) { try { saveTextFile(fileName.getPath(), contents); return fileName; } catch (Exception __e) { throw rethrow(__e); } } 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 "return ((Container) c).getComponents();"; } })); } 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 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 String roundBracket(String s) { return "(" + s + ")"; } static public String roundBracket(Object s) { return roundBracket(str(s)); } 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 Map syncMRUCache(int size) { return synchroMap(new MRUCache(size)); } static public File computerIDFile() { return javaxDataDir("Basic Info/computer-id.txt"); } 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 char stringToChar(String s) { if (l(s) != 1) throw fail("bad stringToChar: " + s); return firstChar(s); } 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 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 Map castMapToMapO(Map map) { return map; } 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 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 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 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 Field setOpt_findField(Class c, String field) { HashMap map; synchronized (getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } return map.get(field); } static public void setOpt(Object o, String field, Object value) { try { if (o == null) return; Class c = o.getClass(); HashMap map; if (getOpt_cache == null) map = getOpt_makeCache(c); else synchronized (getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } if (map == getOpt_special) { if (o instanceof Class) { setOpt((Class) o, field, value); return; } setOpt_raw(o, field, value); return; } Field f = map.get(field); if (f != null) { smartSet(f, o, value); return; } if (o instanceof DynamicObject) { setDyn(((DynamicObject) o), field, value); return; } if (o instanceof IMeta) setDyn(((IMeta) o), field, value); } catch (Exception __e) { throw rethrow(__e); } } static public void setOpt(Class c, String field, Object value) { if (c == null) return; try { Field f = setOpt_findStaticField(c, field); if (f != null) smartSet(f, null, value); } catch (Exception e) { throw new RuntimeException(e); } } static public Field setOpt_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) { makeAccessible(f); return f; } _c = _c.getSuperclass(); } while (_c != null); return null; } static public List> hotwire_classes = synchroList(); static public Class hotwireDependent(String src) { Class c = hotwire(src); makeDependent(c); return c; } static public char firstChar(String s) { return s.charAt(0); } 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 boolean fileExists(String path) { return path != null && new File(path).exists(); } static public boolean fileExists(File f) { return f != null && f.exists(); } 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 void setOptIfNotNull(Object o, String field, Object value) { if (value != null) setOpt(o, field, value); } static public Object mainBot; static public Object getMainBot() { return mainBot; } 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 void setOpt_raw(Object o, String field, Object value) { try { if (o == null) return; if (o instanceof Class) setOpt_raw((Class) o, field, value); else { Field f = setOpt_raw_findField(o.getClass(), field); if (f != null) { makeAccessible(f); smartSet(f, o, value); } } } catch (Exception __e) { throw rethrow(__e); } } static public void setOpt_raw(Class c, String field, Object value) { try { if (c == null) return; Field f = setOpt_raw_findStaticField(c, field); if (f != null) { makeAccessible(f); smartSet(f, null, value); } } catch (Exception __e) { throw rethrow(__e); } } static public Field setOpt_raw_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); return null; } static public Field setOpt_raw_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); return null; } 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 A setDyn(A o, String key, Object value) { setDynObjectValue(o, key, value); return o; } static public void setDyn(IMeta o, String key, Object value) { metaMapPut(o, key, value); } 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 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 void setDynObjectValue(DynamicObject o, String field, Object value) { dynamicObject_setRawFieldValue(o, field, value); } static public String addPrefixIfNotEmpty2(String prefix, String s) { return empty(s) ? "" : addPrefix(prefix, 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 boolean eqicOneOf(String s, String... l) { for (String x : l) if (eqic(s, x)) return true; return false; } 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 void dynamicObject_setRawFieldValue(DynamicObject o, Object key, Object value) { if (o == null) return; synchronized (o) { o.fieldValues = syncMapPut2_createLinkedHashMap((LinkedHashMap) o.fieldValues, key, value); } } static public String addPrefix(String prefix, String s) { return s.startsWith(prefix) ? s : prefix + s; } static public ArrayList litlist(A... a) { ArrayList l = new ArrayList(a.length); for (A x : a) l.add(x); return l; } 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(__30 -> isLetterOrDigit(__30), s); else return "" + first(s); } static public LinkedHashMap syncMapPut2_createLinkedHashMap(LinkedHashMap map, A key, B value) { if (key != null) if (value != null) { if (map == null) map = new LinkedHashMap(); synchronized (collectionMutex(map)) { map.put(key, value); } } else if (map != null) synchronized (collectionMutex(map)) { map.remove(key); } return map; } 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 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 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); } public interface IVarWithNotify extends IVar, IF0WithChangeListeners { default public IVarWithNotify onChange(IVF1 r) { if (r == null) return this; onChange(() -> r.get(get())); return this; } default public IVarWithNotify onChangeAndNow(IVF1 r) { if (r == null) return this; onChangeAndNow(() -> r.get(get())); return this; } } static abstract public class VF1 implements IVF1 { public abstract void get(A a); } static public class Meta implements IMeta { volatile public Object meta; public void _setMeta(Object meta) { this.meta = meta; } public Object _getMeta() { return meta; } final public boolean scaffolding() { return scaffoldingEnabled(); } public boolean scaffoldingEnabled() { return main.scaffoldingEnabled(this); } public boolean scaffoldingEnabled(Object o) { return main.scaffoldingEnabled(o); } } static public class ComponentResizeDragger extends MouseAdapter { public Component component; public int cornerSize = 10; final public ComponentResizeDragger setDebug(boolean debug) { return debug(debug); } public ComponentResizeDragger debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug() { return debug(); } public boolean debug() { return debug; } public boolean debug = false; public MouseEvent mouseDownEvent; public JComponent src; public Rect originalPosition, srcBounds; public int dragX, dragY; public Cursor originalCursor, ourCursor; public ComponentResizeDragger(Component component, JComponent src) { this.src = src; this.component = component; addMouseAndMotionListener(src, this); } public boolean engaged() { return mouseDownEvent != null; } public void start(MouseEvent e) { this.mouseDownEvent = e; originalPosition = toRect(getBounds(component)); cursorCalc(e, true); } public void cursorCalc(MouseEvent e, boolean inside) { srcBounds = toRect(boundsOnScreen(src)); Pt mouse = pt(e.getXOnScreen(), e.getYOnScreen()); if (distance(mouse.y, srcBounds.y2()) <= cornerSize) dragY = 1; else if (distance(mouse.y, srcBounds.y1()) <= cornerSize) dragY = -1; else dragY = 0; if (distance(mouse.x, srcBounds.x2()) <= cornerSize) dragX = 1; else if (distance(mouse.x, srcBounds.x1()) <= cornerSize) dragX = -1; else dragX = 0; originalCursor = src.getCursor(); int iCursor = dragY * 3 + dragX + 4; int cursor = new int[] { Cursor.NW_RESIZE_CURSOR, Cursor.N_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, Cursor.W_RESIZE_CURSOR, -1, Cursor.E_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.S_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR }[iCursor]; Cursor newCursor = cursor >= 0 && inside ? Cursor.getPredefinedCursor(cursor) : null; if (newCursor != ourCursor) { ourCursor = newCursor; src.setCursor(newCursor); } } @Override public void mouseEntered(MouseEvent e) { if (debug) print("mouseEntered"); if (!engaged()) cursorCalc(e, true); } @Override public void mouseExited(MouseEvent e) { if (debug) print("mouseExited"); if (!engaged()) cursorCalc(e, false); } public void mousePressed(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1) return; if (engaged()) return; if (!mouseEventIsInBorder(e)) return; start(e); } public void mouseDragged(MouseEvent e) { if (!engaged()) return; updatePosition(e); } public void mouseMoved(MouseEvent e) { cursorCalc(e, true); } public void mouseReleased(MouseEvent e) { if (mouseDownEvent == null) return; if (e.getButton() != mouseDownEvent.getButton()) return; updatePosition(e); if (debug) print("drag done"); if (src.getCursor() == ourCursor) src.setCursor(originalCursor); mouseDownEvent = null; dragDone(); } public void updatePosition(MouseEvent e) { Rect w = toRect(component.getBounds()); Pt a = topLeftCorner(w), b = bottomRightCorner(w); Pt mouse = pt(e.getXOnScreen(), e.getYOnScreen()); Pt minSize = toPt(component.getMinimumSize()); if (dragX < 0) a.x = max(0, min(b.x - minSize.x, mouse.x + originalPosition.x - mouseDownEvent.getXOnScreen())); else if (dragX > 0) b.x = max(a.x + minSize.x, mouse.x + originalPosition.x2() - mouseDownEvent.getXOnScreen()); if (dragY < 0) a.y = max(0, min(b.y - minSize.y, mouse.y + originalPosition.y - mouseDownEvent.getYOnScreen())); else if (dragY > 0) b.y = max(a.y + minSize.y, mouse.y + originalPosition.y2() - mouseDownEvent.getYOnScreen()); Rect r = rectFromPoints(a, b); if (debug) printVars("ComponentResizeDragger.updatePosition", "w", w, "mouse", mouse, "a", a, "b", b, "dragX", dragX, "dragY", dragY); component.setBounds(toRectangle(r)); } public void dragDone() { } } 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 class CollapsibleLeftPanel extends MetaWithChangeListeners implements Swingable { public transient FieldVar varSidePanelName_cache; public FieldVar varSidePanelName() { if (varSidePanelName_cache == null) varSidePanelName_cache = varSidePanelName_load(); return varSidePanelName_cache; } public FieldVar varSidePanelName_load() { return new FieldVar(this, "sidePanelName", () -> sidePanelName(), sidePanelName -> sidePanelName(sidePanelName)); } final public CollapsibleLeftPanel setSidePanelName(String sidePanelName) { return sidePanelName(sidePanelName); } public CollapsibleLeftPanel sidePanelName(String sidePanelName) { if (!eq(this.sidePanelName, sidePanelName)) { this.sidePanelName = sidePanelName; change(); } return this; } final public String getSidePanelName() { return sidePanelName(); } public String sidePanelName() { return sidePanelName; } volatile public String sidePanelName; public JComponent sideComponent, mainComponent; public JSplitPane splitPane; public transient FieldVar varExpanded_cache; public FieldVar varExpanded() { if (varExpanded_cache == null) varExpanded_cache = varExpanded_load(); return varExpanded_cache; } public FieldVar varExpanded_load() { return new FieldVar(this, "expanded", () -> expanded(), expanded -> expanded(expanded)); } final public CollapsibleLeftPanel setExpanded(boolean expanded) { return expanded(expanded); } public CollapsibleLeftPanel expanded(boolean expanded) { if (!eq(this.expanded, expanded)) { this.expanded = expanded; change(); } return this; } final public boolean getExpanded() { return expanded(); } public boolean expanded() { return expanded; } volatile public boolean expanded = false; public SingleComponentPanel scp = singleComponentPanel(); public CollapsibleLeftPanel(boolean expanded, String sidePanelName, JComponent sideComponent, JComponent mainComponent) { this.mainComponent = mainComponent; this.sideComponent = sideComponent; this.sidePanelName = sidePanelName; this.expanded = expanded; } public void expand() { if (scaffolding()) print("CollapsibleLeftPanel.expand"); setExpanded(true); } public void collapse() { setExpanded(false); } public void updateScp() { swing(() -> { if (metaGet("scaffolding") != null) scaffoldCalled(this, "updateScp"); if (expanded) { splitPane().setRightComponent(mainComponent); scp.set(splitPane()); } else { splitPane().setRightComponent(jpanel()); scp.set(westAndCenterWithMargin(sidePanelMargins(vstack(expandButton())), mainComponent)); } }); } public JComponent expandButton() { return jClickableImage_instantToolTip("#1103075", "Expand " + sidePanelName, new Runnable() { public void run() { try { expand(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "expand();"; } }); } public JComponent collapseButton() { return jClickableImage_instantToolTip("#1103076", "Collapse " + sidePanelName, new Runnable() { public void run() { try { collapse(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "collapse();"; } }); } public JComponent wrappedSideComponent() { return sidePanelMargins(northAndCenterWithMargin(westAndCenterWithMargin(collapseButton(), liveValueLabel(varSidePanelName())), sideComponent)); } public JSplitPane splitPane() { if (scaffolding()) print("splitPane " + splitPane); if (splitPane == null) { splitPane = jhsplit(0.25, wrappedSideComponent(), null); varExpanded().onChangeAndNow(new Runnable() { public void run() { try { updateScp(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateScp();"; } }); } return splitPane; } transient public IF1 sidePanelMargins; public JComponent sidePanelMargins(JComponent c) { return sidePanelMargins != null ? sidePanelMargins.get(c) : sidePanelMargins_base(c); } final public JComponent sidePanelMargins_fallback(IF1 _f, JComponent c) { return _f != null ? _f.get(c) : sidePanelMargins_base(c); } public JComponent sidePanelMargins_base(JComponent c) { return c; } public JComponent visualize() { splitPane(); return scp; } } static public class G22NetworkElement extends MetaWithChangeListeners { public G22NetworkElement() { } final public G22NetworkElement setNetwork(G22Network network) { return network(network); } public G22NetworkElement network(G22Network network) { this.network = network; return this; } final public G22Network getNetwork() { return network(); } public G22Network network() { return network; } public G22Network network; final public G22NetworkElement setBounds(Rect bounds) { return bounds(bounds); } public G22NetworkElement bounds(Rect bounds) { this.bounds = bounds; return this; } final public Rect getBounds() { return bounds(); } public Rect bounds() { return bounds; } public Rect bounds; public transient FieldVar varIdentifier_cache; public FieldVar varIdentifier() { if (varIdentifier_cache == null) varIdentifier_cache = varIdentifier_load(); return varIdentifier_cache; } public FieldVar varIdentifier_load() { return new FieldVar(this, "identifier", () -> identifier(), identifier -> identifier(identifier)); } final public G22NetworkElement setIdentifier(String identifier) { return identifier(identifier); } public G22NetworkElement identifier(String identifier) { if (!eq(this.identifier, identifier)) { this.identifier = identifier; change(); } return this; } final public String getIdentifier() { return identifier(); } public String identifier() { return identifier; } public String identifier; public transient FieldVar varCode_cache; public FieldVar varCode() { if (varCode_cache == null) varCode_cache = varCode_load(); return varCode_cache; } public FieldVar varCode_load() { return new FieldVar(this, "code", () -> code(), code -> code(code)); } final public G22NetworkElement setCode(String code) { return code(code); } public G22NetworkElement code(String code) { if (!eq(this.code, code)) { this.code = code; change(); } return this; } final public String getCode() { return code(); } public String code() { return code; } public String code; public Map properties = syncMap(); public transient FieldVar varCodeVisible_cache; public FieldVar varCodeVisible() { if (varCodeVisible_cache == null) varCodeVisible_cache = varCodeVisible_load(); return varCodeVisible_cache; } public FieldVar varCodeVisible_load() { return new FieldVar(this, "codeVisible", () -> codeVisible(), codeVisible -> codeVisible(codeVisible)); } final public G22NetworkElement setCodeVisible(boolean codeVisible) { return codeVisible(codeVisible); } public G22NetworkElement codeVisible(boolean codeVisible) { if (!eq(this.codeVisible, codeVisible)) { this.codeVisible = codeVisible; change(); } return this; } final public boolean getCodeVisible() { return codeVisible(); } public boolean codeVisible() { return codeVisible; } public boolean codeVisible = true; { onChange(() -> { { if (network != null) network.change(); } }); } public class Port extends MetaWithChangeListeners implements IUnstructured { public transient FieldVar varPosition_cache; public FieldVar varPosition() { if (varPosition_cache == null) varPosition_cache = varPosition_load(); return varPosition_cache; } public FieldVar varPosition_load() { return new FieldVar(this, "position", () -> position(), position -> position(position)); } final public Port setPosition(DoublePt position) { return position(position); } public Port position(DoublePt position) { if (!eq(this.position, position)) { this.position = position; change(); } return this; } final public DoublePt getPosition() { return position(); } public DoublePt position() { return position; } public DoublePt position; public transient FieldVar varName_cache; public FieldVar varName() { if (varName_cache == null) varName_cache = varName_load(); return varName_cache; } public FieldVar varName_load() { return new FieldVar(this, "name", () -> name(), name -> name(name)); } final public Port setName(String name) { return name(name); } public Port name(String name) { if (!eq(this.name, name)) { this.name = name; change(); } return this; } final public String getName() { return name(); } public String name() { return name; } public String name; public transient FieldVar varCable_cache; public FieldVar varCable() { if (varCable_cache == null) varCable_cache = varCable_load(); return varCable_cache; } public FieldVar varCable_load() { return new FieldVar(this, "cable", () -> cable(), cable -> cable(cable)); } final public Port setCable(G22NetworkCable cable) { return cable(cable); } public Port cable(G22NetworkCable cable) { if (!eq(this.cable, cable)) { this.cable = cable; change(); } return this; } final public G22NetworkCable getCable() { return cable(); } public G22NetworkCable cable() { return cable; } public G22NetworkCable cable; public transient FieldVar varIsOutput_cache; public FieldVar varIsOutput() { if (varIsOutput_cache == null) varIsOutput_cache = varIsOutput_load(); return varIsOutput_cache; } public FieldVar varIsOutput_load() { return new FieldVar(this, "isOutput", () -> isOutput(), isOutput -> isOutput(isOutput)); } final public Port setIsOutput(boolean isOutput) { return isOutput(isOutput); } public Port isOutput(boolean isOutput) { if (!eq(this.isOutput, isOutput)) { this.isOutput = isOutput; change(); } return this; } final public boolean getIsOutput() { return isOutput(); } public boolean isOutput() { return isOutput; } public boolean isOutput = false; public transient FieldVar varDataType_cache; public FieldVar varDataType() { if (varDataType_cache == null) varDataType_cache = varDataType_load(); return varDataType_cache; } public FieldVar varDataType_load() { return new FieldVar(this, "dataType", () -> dataType(), dataType -> dataType(dataType)); } final public Port setDataType(Class dataType) { return dataType(dataType); } public Port dataType(Class dataType) { if (!eq(this.dataType, dataType)) { this.dataType = dataType; change(); } return this; } final public Class getDataType() { return dataType(); } public Class dataType() { return dataType; } public Class dataType; public G22NetworkElement element() { return G22NetworkElement.this; } public String toString() { return (isOutput ? "Output" : "Input") + " port" + " " + quote(name) + " of type " + shortClassName(dataType); } public Rect bounds() { int size = 10; Rect r = element().bounds; if (r == null) return null; r = growRectTopAndLeft(r, size); return rect(r.x + iround(position.x * r.w), r.y + iround(position.y * r.h), size, size); } public void delete() { disconnect(); ports.remove(this); change(); } public void disconnect() { { if (cable != null) cable.remove(); } } public boolean isConnected() { return cable != null; } public void _doneLoading() { onChange(() -> element().change()); } } public List ports = syncL(); public LASCompileResult newCompileResult() { return new LASCompileResult(); } transient public LASCompileResult compileResult; public LASCompileResult compile(G22Utils g22utils) { String code = unnull(this.code); var cr = compileResult; if (cr != null && eq(cr.script, code)) return cr; cr = newCompileResult(); var parser = g22utils.leftArrowParser(); configureParser(parser); cr.script(code).parser(parser).compile(); return compileResult = cr; } public void configureParser(GazelleV_LeftArrowScriptParser parser) { parser.addVar("blueprint"); parser.addVar("instance"); } public GazelleV_LeftArrowScript.Script compileScript(G22Utils g22utils) { var compiled = compile(g22utils); if (compiled == null) return null; if (!compiled.runnable()) return null; return compiled.get(); } public void configureBlueprint(G22Utils g22utils) { var script = compileScript(g22utils); if (script == null) return; FlexibleVarContext ctx = new FlexibleVarContext(); var f = script.getFunction("configure"); if (f != null) f.call(ctx, this); } public Object makeInstance(G22Utils g22utils, G22NetworkInstance networkInstance) { var script = compileScript(g22utils); if (script == null) return null; FlexibleVarContext ctx = new FlexibleVarContext(); for (var port : ports) if (!port.isOutput() && port.cable != null) { var outputPort = port.cable.from; if (outputPort != null) ctx.set(port.name, networkInstance.getObjectForBlueprint(outputPort.element())); } return script.get(ctx); } public Set upstreamNodes() { Set set = new HashSet(); for (var port : ports) if (!port.isOutput() && port.cable != null) { var outputPort = port.cable.from; if (outputPort != null) set.add(outputPort.element()); } return set; } public Set downstreamNodes() { Set set = new HashSet(); for (var port : ports) if (port.isOutput() && port.cable != null) { var outputPort = port.cable.to; if (outputPort != null) set.add(outputPort.element()); } return set; } public String toString() { return or2(identifier(), "Unnamed element"); } public Port getPort(String name) { return firstThat(ports, p -> eq(p.name, name)); } public void addPort(Port port) { port.onChange(() -> change()); ports.add(port); } final public void addSlot(String name, double position_x, double position_y) { addSlot(name, doublePt(position_x, position_y)); } final public void addSlot(String name, DoublePt position) { addPort(name, position); } public void addPort(String name, double position_x, double position_y) { addPort(name, doublePt(position_x, position_y)); } public void addPort(String name, DoublePt position) { printFunctionCall("addPort", "name", name, "position", position); Port p = getPort(name); if (p != null) return; addPort(new Port().name(name).position(position)); change(); } public void addInputPort(String name, double position_x, double position_y, Class type) { addInputPort(name, doublePt(position_x, position_y), type); } public void addInputPort(String name, DoublePt position, Class type) { Port p = getPort(name); if (p != null) return; addPort(new Port().name(name).position(position).isOutput(false).dataType(type)); change(); } public void addOutputPort(String name, double position_x, double position_y, Class type) { addOutputPort(name, doublePt(position_x, position_y), type); } public void addOutputPort(String name, DoublePt position, Class type) { Port p = getPort(name); if (p != null) return; p = new Port().name(name).position(position).isOutput(true).dataType(type); addPort(p); print("Made port " + p); change(); } final public void deletePorts() { removePorts(); } final public void removeSlots() { removePorts(); } final public void deleteSlots() { removePorts(); } public void removePorts() { while (nempty(ports)) last(ports).delete(); } public void removeOutputPorts() { for (var p : filter(ports, p -> p.isOutput())) p.delete(); } public void removeInputPorts() { for (var p : antiFilter(ports, p -> p.isOutput())) p.delete(); } public List ports() { return cloneList(ports); } public void setProperty(Object key, Object value) { properties.put(key, value); change(); } public Object getProperty(Object key) { return properties.get(key); } public void autoCreateOutputPort(G22NetworkInstance.Value myValue) { if (myValue == null) return; removeOutputPorts(); Object o = myValue.object(); Class type = or(_getClass(o), Object.class); addOutputPort("output", 1, 0.5, type); } public void autoCreateInputPorts(G22Utils g22utils) { removeInputPorts(); var script = compile(g22utils).get(); int n = l(script.params); int i = 0; for (var __1 : _entrySet(unnullForIteration(script.params))) { var name = __1.getKey(); var valueDescriptor = __1.getValue(); double y = doubleRatio(++i, (n + 1)); addInputPort(name, 0, y, or(valueDescriptor.javaClass(), Object.class)); } } public G22NetworkElement defaultName(String name) { if (empty(identifier())) identifier(name); return this; } } static public class G22Utils_Base { transient public Set> onProjectFileChanged; public G22Utils_Base onProjectFileChanged(IVF1 f) { onProjectFileChanged = createOrAddToSyncLinkedHashSet(onProjectFileChanged, f); return this; } public G22Utils_Base removeProjectFileChangedListener(IVF1 f) { main.remove(onProjectFileChanged, f); return this; } public void projectFileChanged(File file) { if (onProjectFileChanged != null) for (var listener : onProjectFileChanged) pcallF_typed(listener, file); } } static public class G22Utils extends G22Utils_Base implements AutoCloseable, TransientObject { final public G22Utils setBackgroundProcessesUI(IBackgroundProcesses backgroundProcessesUI) { return backgroundProcessesUI(backgroundProcessesUI); } public G22Utils backgroundProcessesUI(IBackgroundProcesses backgroundProcessesUI) { this.backgroundProcessesUI = backgroundProcessesUI; return this; } final public IBackgroundProcesses getBackgroundProcessesUI() { return backgroundProcessesUI(); } public IBackgroundProcesses backgroundProcessesUI() { return backgroundProcessesUI; } public IBackgroundProcesses backgroundProcessesUI; final public G22Utils setModule(Enterable module) { return module(module); } public G22Utils module(Enterable module) { this.module = module; return this; } final public Enterable getModule() { return module(); } public Enterable module() { return module; } public Enterable module; final public G22Utils setMasterStuff(G22MasterStuff masterStuff) { return masterStuff(masterStuff); } public G22Utils masterStuff(G22MasterStuff masterStuff) { this.masterStuff = masterStuff; return this; } final public G22MasterStuff getMasterStuff() { return masterStuff(); } public G22MasterStuff masterStuff() { return masterStuff; } public G22MasterStuff masterStuff; final public G22Utils setConcepts(Concepts concepts) { return concepts(concepts); } public G22Utils concepts(Concepts concepts) { this.concepts = concepts; return this; } final public Concepts getConcepts() { return concepts(); } public Concepts concepts() { return concepts; } public Concepts concepts; final public G22Utils setProjectActions(G22ProjectActions projectActions) { return projectActions(projectActions); } public G22Utils projectActions(G22ProjectActions projectActions) { this.projectActions = projectActions; return this; } final public G22ProjectActions getProjectActions() { return projectActions(); } public G22ProjectActions projectActions() { return projectActions; } public G22ProjectActions projectActions; final public G22AutoStarter getAutoStarter() { return autoStarter(); } public G22AutoStarter autoStarter() { return autoStarter; } public G22AutoStarter autoStarter = new G22AutoStarter(this); final public G22Utils setFunctionTimings(FunctionTimings functionTimings) { return functionTimings(functionTimings); } public G22Utils functionTimings(FunctionTimings functionTimings) { this.functionTimings = functionTimings; return this; } final public FunctionTimings getFunctionTimings() { return functionTimings(); } public FunctionTimings functionTimings() { return functionTimings; } public FunctionTimings functionTimings = new FunctionTimings(); public FileWatchService fileWatcher; public boolean projectFileListenerInitiated = false; final public CombinedStringifier getStringifier() { return stringifier(); } public CombinedStringifier stringifier() { return stringifier; } public CombinedStringifier stringifier = new CombinedStringifier(o -> o instanceof BufferedImage ? "Image (" + ((BufferedImage) o).getWidth() + "*" + ((BufferedImage) o).getHeight() + " px)" : null); public ILASClassLoader lasClassLoader() { return masterStuff == null ? null : masterStuff.lasClassLoader(); } public ImageSurface stdImageSurface() { var is = pixelatedImageSurface().setAutoZoomToDisplay(true).repaintInThread(false); is.defaultImageDir = () -> dbDir(); is.specialPurposed = true; new ImageSurface_PositionToolTip(is); return is; } public ImageSurface stdImageSurface(MakesBufferedImage img) { return stdImageSurface(toBufferedImage(img)); } public ImageSurface stdImageSurface(BufferedImage img) { var is = stdImageSurface(); is.setImage(img); return is; } public ImageSurface stdImageSurfaceWithSelection(MakesBufferedImage img, Rect selection) { return stdImageSurfaceWithSelection(toBufferedImage(img), selection); } public ImageSurface stdImageSurfaceWithSelection(BufferedImage img, Rect selection) { var is = stdImageSurface(img); is.setSelection(selection); return is; } public String stringify(Object o) { return stringifier.toString(o); } transient public Set> onSettingUpParser; public G22Utils onSettingUpParser(IVF1 f) { onSettingUpParser = createOrAddToSyncLinkedHashSet(onSettingUpParser, f); return this; } public G22Utils removeSettingUpParserListener(IVF1 f) { main.remove(onSettingUpParser, f); return this; } public void settingUpParser(GazelleV_LeftArrowScriptParser parser) { if (onSettingUpParser != null) for (var listener : onSettingUpParser) pcallF_typed(listener, parser); } transient public Set> onSettingUpScriptIDE; public G22Utils onSettingUpScriptIDE(IVF1 f) { onSettingUpScriptIDE = createOrAddToSyncLinkedHashSet(onSettingUpScriptIDE, f); return this; } public G22Utils removeSettingUpScriptIDEListener(IVF1 f) { main.remove(onSettingUpScriptIDE, f); return this; } public void settingUpScriptIDE(JLeftArrowScriptIDE ide) { if (onSettingUpScriptIDE != null) for (var listener : onSettingUpScriptIDE) pcallF_typed(listener, ide); } public GazelleV_LeftArrowScriptParser leftArrowParser() { GazelleV_LeftArrowScriptParser parser = new GazelleV_LeftArrowScriptParser(); parser.classNameResolver(classNameResolver()); parser.lasClassLoader(lasClassLoader()); settingUpParser(parser); parser.addClassAlias("Freq", "Frequency"); return parser; } public void basicParserTest() { var parser = leftArrowParser(); print("classContainerPrefixes", parser.classContainerPrefixes()); assertEquals(pair(1, 2), parser.parse("new Pair 1 2").get()); } public JLeftArrowScriptIDE leftArrowIDE() { JLeftArrowScriptIDE ide = new JLeftArrowScriptIDE(); ide.g22utils(this); ide.scriptTimeout(projectWideScriptTimeout()); settingUpScriptIDE(ide); return ide; } public File byteCodePath() { return assertNotNull(getBytecodePathForClass(this)); } public ClassNameResolver classNameResolver_cache; public ClassNameResolver classNameResolver() { if (classNameResolver_cache == null) classNameResolver_cache = classNameResolver_load(); return classNameResolver_cache; } public ClassNameResolver classNameResolver_load() { return new ClassNameResolver().byteCodePath(byteCodePath()).init(); } public File databasesMotherDir() { return masterStuff.databasesMotherDir(); } public File dirOfProjectNamed(String name) { assertNempty(name); return newFile(databasesMotherDir(), name); } public AutoCloseable enter() { return module == null ? null : module.enter(); } public String defaultDBName() { return "Default"; } public File lastOpenedDBsFile() { return newFile(databasesMotherDir(), "Last Opened"); } public File autoUpdateFile() { return newFile(databasesMotherDir(), "Auto-Update"); } public boolean autoUpdateEnabled() { return fileExists(autoUpdateFile()); } public void setAutoUpdate(boolean b) { createOrRemoveFile(autoUpdateFile(), b); } public List dbsToOpen() { List dbNames = new ArrayList(); for (String name : tlft(loadTextFile(lastOpenedDBsFile()))) { String name2 = dropPrefix("*", name); if (fileExists(newFile(databasesMotherDir(), name2))) dbNames.add(name); } if (empty(dbNames)) dbNames.add(defaultDBName()); return dbNames; } public void setOpenDBs(Collection dbs) { List dbNames = new ArrayList(); for (var db : dbs) { var dbDir = conceptsDir(db.concepts()); if (sameFile(databasesMotherDir(), dirOfFile(dbDir))) dbNames.add((db.hidden() ? "*" : "") + fileName(dbDir)); } saveTextFile(lastOpenedDBsFile(), lines(dbNames)); } public Map scriptToMap(G22LeftArrowScript c) { return scriptToMap(c, false); } public Map scriptToMap(G22LeftArrowScript c, boolean allowRunOnProjectOpen) { return litorderedmap("Description", str(c), "Status", renderScriptStatus(c), "LoC", renderScriptLoC(c), "Import note", c.importNote, "Run on project open", c.renderRunOnProjectOpenStatus()); } public String renderScriptStatus(G22LeftArrowScript c) { return or2_rev("Empty", joinNemptiesWithSpacedPlus(c.isClearForAutoRun() ? "Clear for auto-run" : null, c.isSavedDistinctFromAutoRunVersion() ? "Saved (not cleared)" : null, c.isEditing() ? "Editing" : null)); } public String renderScriptLoC(G22LeftArrowScript c) { return n2(intMax(mapLL(__70 -> linesOfCode_javaTok(__70), c.editingText, c.text, c.codeForAutoRun()))); } public List labelsForFile(File file) { if (file == null) return null; File labelsFile = appendToFileName(file, ".labels"); List labels = tlft(loadTextFile(labelsFile)); return map(__31 -> getLabel(__31), labels); } public File labelsFile(File file) { if (file == null) return null; return appendToFileName(file, ".labels"); } public void setLabelsForFile(File file, List labels) { List list = map(labels, label -> label.name); File f = labelsFile(file); saveTextFile(f, lines(list)); print("Saved " + nLabels(list) + " (" + joinWithComma(list) + ") to " + f); } public G22Label getLabel(String name) { if (empty(name)) return null; if (containsNewLine(name)) throw fail("No newlines in label names allowed: " + name); return uniqCI(concepts, G22Label.class, "name", name); } final public File projectDir() { return dbDir(); } public File dbDir() { return conceptsDir(concepts); } final public File projectFile(String name) { return fileInDbDir(name); } public File fileInDbDir(String name) { return newFile(dbDir(), name); } public class GazelleDB implements IFieldsToList { public String name; public File dir; public GazelleDB() { } public GazelleDB(String name, File dir) { this.dir = dir; this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + dir + ")"; } public boolean equals(Object o) { if (!(o instanceof GazelleDB)) return false; GazelleDB __0 = (GazelleDB) o; return eq(name, __0.name) && eq(dir, __0.dir); } public int hashCode() { int h = 1669530526; h = boostHashCombine(h, _hashCode(name)); h = boostHashCombine(h, _hashCode(dir)); return h; } public Object[] _fieldsToList() { return new Object[] { name, dir }; } public String name() { return name; } public File dir() { return dir; } public boolean loaded() { return loadedDB() != null; } public IG22LoadedDB loadedDB_cache; public IG22LoadedDB loadedDB() { if (loadedDB_cache == null) loadedDB_cache = loadedDB_load(); return loadedDB_cache; } public IG22LoadedDB loadedDB_load() { return masterStuff.getLoadedDBForConceptDir(dir); } public File conceptsFile() { return conceptsFileIn(dir); } } public List gazelleDBs() { List dbs = new ArrayList(); for (File dir : listDirsContainingFileNamed(databasesMotherDir(), "concepts.structure.gz")) dbs.add(new GazelleDB(fileName(dir), dir)); return dbs; } public RSyntaxTextAreaWithSearch newSyntaxTextArea() { return newSyntaxTextArea((IF1) null); } public RSyntaxTextAreaWithSearch newSyntaxTextArea(IF1 wrapStatusLabel) { RSyntaxTextAreaWithSearch ta = new RSyntaxTextAreaWithSearch(wrapStatusLabel); ta.textArea().setHighlightCurrentLine(false); ta.menuLessOperation(); return ta; } public RSyntaxTextAreaWithSearch newSyntaxTextArea(String text) { var ta = newSyntaxTextArea(); ta.setText(text); return ta; } public File projectStoryTextFile() { return newFile(dbDir(), "story.txt"); } public String projectName() { return fileName(dbDir()); } public void close() { try { autoStarter.close(); { cleanUp(fileWatcher); fileWatcher = null; } } catch (Exception __e) { throw rethrow(__e); } } public G22Variable findProjectVar(String name) { return conceptWhere(concepts, G22Variable.class, "name", name); } public Object getProjectVar(String name) { G22Variable var = findProjectVar(name); return var == null ? null : var.value; } public Object waitForProjectVar(String name) { G22Variable var = optimizedUniq(concepts, G22Variable.class, "name", name); Object o = var.value; { var __2 = o; if (__2 != null) return __2; } return waitUntilNotNull(var.varValue()); } public void setProjectVar(boolean persistent, String name, Object value) { G22Variable var = optimizedUniq(concepts, G22Variable.class, "name", name); if (!persistent) var.persistent(persistent); var.value(value); if (persistent) var.persistent(persistent); } public void setTransientProjectVar(String name, Object value) { G22Variable var = optimizedUniq(concepts, G22Variable.class, "name", name); var.persistent(false).value(value); } public void deleteProjectVar(String name) { deleteConcept(findProjectVar(name)); } public IVarWithNotify liveProjectVar(String name) { return liveProjectVar(name, null); } public IVarWithNotify liveProjectVar(String name, Object defaultValue) { G22Variable var = optimizedUniq(concepts, G22Variable.class, "name", name); var.persistent(true); var.setValueIfNull(defaultValue); return var.varValue(); } public IVarWithNotify liveTransientProjectVar(String name) { return liveTransientProjectVar(name, null); } public IVarWithNotify liveTransientProjectVar(String name, Object defaultValue) { G22Variable var = optimizedUniq(concepts, G22Variable.class, "name", name); var.persistent(false); var.setValueIfNull(defaultValue); return var.varValue(); } public void replaceCloseableProjectVar(String name, IF0 calc) { Object value = getProjectVar(name); if (value instanceof AutoCloseable) { main.close((AutoCloseable) value); deleteProjectVar(name); } setTransientProjectVar(name, calc == null ? null : calc.get()); } public double defaultScriptTimeout() { return 10.0; } public double projectWideScriptTimeout() { return or(toDoubleOrNull(getProjectVar("!Script Timeout")), defaultScriptTimeout()); } public G22Analyzer getAnalyzer(long id) { var a = getConcept(concepts, G22Analyzer.class, id); if (a == null) throw fail("Analyzer not found: " + id); return a; } public G22LeftArrowScript getScript(long id) { var a = getConcept(concepts, G22LeftArrowScript.class, id); if (a == null) throw fail("Script not found: " + id); return a; } public Object callScript(long id) { var script = getScript(id); return script.evaluateWithoutTimeout(); } public Object callAutoRunnableScript(long id) { var script = getScript(id); return script.evaluateAutoRunWithoutTimeout(); } public double defaultTimeout() { return infinity(); } public A evalRegisteredCode(String processName, IF0 code) { return evalRegisteredCode(defaultTimeout(), processName, code); } public A evalRegisteredCode(double timeoutSeconds, String processName, IF0 code) { if (code == null) return null; return evalWithTimeoutOrTypedException(timeoutSeconds, () -> { AutoCloseable __3 = enter(); try { var process = backgroundProcessesUI.tempAdd(processName); try { Thread myThread = currentThread(); process.setInterruptAction(new Runnable() { public void run() { try { cancelThread(myThread); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cancelThread(myThread)"; } }); return code.get(); } finally { _close(process); } } finally { _close(__3); } }); } public Object host() { AutoCloseable __4 = enter(); try { return dm_os(); } finally { _close(__4); } } public A timeFunction(String name, IF0 f) { return functionTimings.get(name, f); } public boolean isConceptsDir(File dir) { return isSameFile(conceptsDir(concepts), dir); } synchronized public FileWatchService fileWatcher() { { if (fileWatcher == null) fileWatcher = new FileWatchService(); return fileWatcher; } } synchronized public G22Utils onProjectFileChanged(IVF1 listener) { super.onProjectFileChanged(listener); if (!projectFileListenerInitiated) { projectFileListenerInitiated = true; fileWatcher().addRecursiveListener(dbDir(), __5 -> projectFileChanged(__5)); } return this; } public G22ProjectInfo projectInfo_cache; public G22ProjectInfo projectInfo() { if (projectInfo_cache == null) projectInfo_cache = projectInfo_load(); return projectInfo_cache; } public G22ProjectInfo projectInfo_load() { return optimizedUniq(concepts, G22ProjectInfo.class); } public RunnablesReferenceQueue runnablesReferenceQueue() { return masterStuff.runnablesReferenceQueue(); } public EphemeralObjectIDs ephemeralObjectIDs() { return masterStuff.ephemeralObjectIDs(); } public Object eph(long id) { return ephemeralObjectIDs().get(id); } public void openInBrowser(String url) { if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) main.openInBrowser(url); else { String cmd; if (projectInfo().useFirefox() && isOnPATH("firefox")) cmd = "firefox"; else { cmd = chromeCmd(); if (isRoot()) cmd += " -no-sandbox"; } cmd += " " + platformQuote(url); nohup(cmd); } } public String compilationDate() { return or2(compilationDateFromClassPath(this), "unknown"); } public String projectID() { return projectInfo().projectID(); } public IG22LoadedDB getLoadedDB() { return masterStuff.getLoadedDB(concepts); } public ConceptsComboBox galleryImagesComboBox() { return swing(() -> new ConceptsComboBox(concepts, G22GalleryImage.class)); } public IBackgroundProcess tempAddBackgroundProcess(String name) { return backgroundProcessesUI == null ? null : backgroundProcessesUI.tempAdd(name); } } static public class PingSource { final public PingSource setAction(IF0 action) { return action(action); } public PingSource action(IF0 action) { this.action = action; return this; } final public IF0 getAction() { return action(); } public IF0 action() { return action; } volatile public IF0 action; public String text; public ThreadPool threadPool; public PingSource() { } public PingSource(ThreadPool threadPool) { this.threadPool = threadPool; } public PingSource(ThreadPool threadPool, String text) { this.text = text; this.threadPool = threadPool; } public PingSource(IF0 action) { this.action = action; } final public boolean get() { var a = action; return a != null && a.get(); } final public void ping() { var a = action; if (a != null) a.get(); } public void cancel() { action = new Cancelled(); } public class Cancelled implements IF0 { public Boolean get() { throw new PingSourceCancelledException(PingSource.this); } } public class Encapsulated implements Runnable, IFieldsToList { public Runnable r; public Encapsulated() { } public Encapsulated(Runnable r) { this.r = r; } public Object[] _fieldsToList() { return new Object[] { r }; } public void run() { try { try { pingSource_tl().set(PingSource.this); ping(); r.run(); } finally { pingSource_tl().set(null); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return PingSource.this + ": " + r; } } public void dO(Runnable r) { if (r == null) return; threadPool.acquireThreadOrQueue(new Encapsulated(r)); } public String toString() { String t = text; return nempty(t) ? t : super.toString(); } public ISleeper_v2 sleeper() { return threadPool.sleeper(); } } static public class PopupMenuMaker { final public PopupMenuMaker setAllowScrolling(boolean allowScrolling) { return allowScrolling(allowScrolling); } public PopupMenuMaker allowScrolling(boolean allowScrolling) { this.allowScrolling = allowScrolling; return this; } final public boolean getAllowScrolling() { return allowScrolling(); } public boolean allowScrolling() { return allowScrolling; } public boolean allowScrolling = true; final public PopupMenuMaker setEvent(MouseEvent event) { return event(event); } public PopupMenuMaker event(MouseEvent event) { this.event = event; return this; } final public MouseEvent getEvent() { return event(); } public MouseEvent event() { return event; } public MouseEvent event; final public PopupMenuMaker setPtInComponent(PtInComponent ptInComponent) { return ptInComponent(ptInComponent); } public PopupMenuMaker ptInComponent(PtInComponent ptInComponent) { this.ptInComponent = ptInComponent; return this; } final public PtInComponent getPtInComponent() { return ptInComponent(); } public PtInComponent ptInComponent() { return ptInComponent; } public PtInComponent ptInComponent; final public PopupMenuMaker setFillMenu(IVF1 fillMenu) { return fillMenu(fillMenu); } public PopupMenuMaker fillMenu(IVF1 fillMenu) { this.fillMenu = fillMenu; return this; } final public IVF1 getFillMenu() { return fillMenu(); } public IVF1 fillMenu() { return fillMenu; } public IVF1 fillMenu; final public PopupMenuMaker setExistingMenu(JPopupMenu existingMenu) { return existingMenu(existingMenu); } public PopupMenuMaker existingMenu(JPopupMenu existingMenu) { this.existingMenu = existingMenu; return this; } final public JPopupMenu getExistingMenu() { return existingMenu(); } public JPopupMenu existingMenu() { return existingMenu; } public JPopupMenu existingMenu; final public PopupMenuMaker setAddSeparator(boolean addSeparator) { return addSeparator(addSeparator); } public PopupMenuMaker addSeparator(boolean addSeparator) { this.addSeparator = addSeparator; return this; } final public boolean getAddSeparator() { return addSeparator(); } public boolean addSeparator() { return addSeparator; } public boolean addSeparator = true; public JPopupMenu menu; public PopupMenuMaker() { } public PopupMenuMaker(MouseEvent event, IVF1 fillMenu) { this.fillMenu = fillMenu; this.event = event; } public void run() { swing(() -> { if (existingMenu != null) { var menu = existingMenu; int emptyCount = menu.getComponentCount(); if (addSeparator) menu.addSeparator(); int emptyCount2 = menu.getComponentCount(); { if (fillMenu != null) fillMenu.get(menu); } if (menu.getComponentCount() == emptyCount2) truncateContainer(menu, emptyCount); packWindow(menu); } else { JPopupMenu menu = new JPopupMenu(); int emptyCount = menu.getComponentCount(); { if (fillMenu != null) fillMenu.get(menu); } if (menu.getComponentCount() == emptyCount) return; if (allowScrolling) { menu = new JPopupMenu(); JMenuScroller scroller = JMenuScroller.setScrollerFor(menu); scroller.fillMenu = toVF1(fillMenu); } if (ptInComponent == null) ptInComponent = ptInComponentFromEvent(event); if (hasParentOfType(JPopupMenu.class, ptInComponent.component)) { menu.setInvoker(ptInComponent.component); menu.setVisible(true); } else menu.show(ptInComponent.component, ptInComponent.p.x, ptInComponent.p.y); } }); } } static public class RunResultWithTimestamps extends OKOrError { final public RunResultWithTimestamps setStarted(Timestamp started) { return started(started); } public RunResultWithTimestamps started(Timestamp started) { this.started = started; return this; } final public Timestamp getStarted() { return started(); } public Timestamp started() { return started; } public Timestamp started; final public RunResultWithTimestamps setEnded(Timestamp ended) { return ended(ended); } public RunResultWithTimestamps ended(Timestamp ended) { this.ended = ended; return this; } final public Timestamp getEnded() { return ended(); } public Timestamp ended() { return ended; } public Timestamp ended; final public RunResultWithTimestamps setPrintOutput(CharSequence printOutput) { return printOutput(printOutput); } public RunResultWithTimestamps printOutput(CharSequence printOutput) { this.printOutput = printOutput; return this; } final public CharSequence getPrintOutput() { return printOutput(); } public CharSequence printOutput() { return printOutput; } public CharSequence printOutput; public RunResultWithTimestamps run(IF0 f) { return run(f, true); } public RunResultWithTimestamps run(IF0 f, boolean printStackTrace) { return setPrintOutput(hijackPrint_tee(new Runnable() { public void run() { try { started(tsNow()); copyFrom(okOrError(f, printStackTrace)); ended(tsNow()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "started(tsNow());\r\n copyFrom(okOrError(f, printStackTrace));\r\n ende..."; } })); } public boolean hasRun() { return ended != null; } public OKOrError result() { return this; } public Duration duration() { return ended.minusAsDuration(started); } public String renderDuration() { return formatElapsedTimeWithAppropriateUnit(nanosToSeconds(duration().toNanos())); } } static public class SingleComponentPanel extends JPanel { public SingleComponentPanel() { super(new BorderLayout()); } public SingleComponentPanel(Component component) { this(); if (component != null) setComponent(component); } public void set(Swingable component) { set(wrap(component)); } final public void set(Component component) { setComponent(component); } public void setComponent(Component component) { { swing(() -> { if (getComponent() == component) return; removeAll(); if (component != null) add(BorderLayout.CENTER, wrap(component)); _revalidate(SingleComponentPanel.this); }); } } public void setComponentAndRevalidateParent(Component component) { setComponent(component); _revalidate(_getParent(this)); } final public void clear() { noComponent(); } public void noComponent() { setComponent(null); } final public Component get() { return getComponent(); } public Component getComponent() { return swing(() -> getComponentCount() == 0 ? null : getComponent(0)); } public boolean isEmpty() { return getComponent() == null; } public boolean hasComponent() { return getComponent() != null; } } 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 BoolVarWithNotify extends BoolVar { transient public Set onChange; public BoolVarWithNotify onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public BoolVarWithNotify removeChangeListener(Runnable r) { main.remove(onChange, r); return this; } public void fireChange() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public BoolVarWithNotify() { } public BoolVarWithNotify(boolean value) { super(value); } @Override public synchronized void set(boolean a) { if (get() != a) { super.set(a); fireChange(); } } public BoolVarWithNotify onChangeAndNow(Runnable r) { onChange(r); r.run(); return this; } } static public class Rect implements WidthAndHeight, IFieldsToList { static final public String _fieldOrder = "x y w h"; public int x; public int y; public int w; public int h; public Rect() { } public Rect(int x, int y, int w, int h) { this.h = h; this.w = w; this.y = y; this.x = x; } public boolean equals(Object o) { if (!(o instanceof Rect)) return false; Rect __1 = (Rect) o; return x == __1.x && y == __1.y && w == __1.w && h == __1.h; } public int hashCode() { int h = 2543108; h = boostHashCombine(h, _hashCode(x)); h = boostHashCombine(h, _hashCode(y)); h = boostHashCombine(h, _hashCode(w)); h = boostHashCombine(h, _hashCode(h)); return h; } public Object[] _fieldsToList() { return new Object[] { x, y, w, h }; } public Rect(Rectangle r) { x = r.x; y = r.y; w = r.width; h = r.height; } public Rect(Pt p, int w, int h) { this.h = h; this.w = w; x = p.x; y = p.y; } public Rect(Rect r) { x = r.x; y = r.y; w = r.w; h = r.h; } final public Rectangle getRectangle() { return new Rectangle(x, y, w, h); } public String toString() { return x + "," + y + " / " + w + "," + h; } final public int x1() { return x; } final public int y1() { return y; } final public int x2() { return x + w; } final public int y2() { return y + h; } final public boolean contains(Pt p) { return contains(p.x, p.y); } final public boolean contains(int _x, int _y) { return _x >= x && _y >= y && _x < x + w && _y < y + h; } final public boolean contains(Rectangle r) { return rectContains(this, r); } final public boolean empty() { return w <= 0 || h <= 0; } final public int getWidth() { return w; } final public int getHeight() { return h; } final public int area() { return w * h; } public WidthAndHeight widthAndHeight() { return main.widthAndHeight(w, h); } } static public class Pt implements Comparable, IDoublePt { public int x, y; public Pt() { } public Pt(Point p) { x = p.x; y = p.y; } public Pt(int x, int y) { this.y = y; this.x = x; } public Point getPoint() { return new Point(x, y); } public boolean equals(Object o) { return o instanceof Pt && x == ((Pt) o).x && y == ((Pt) o).y; } public int hashCode() { return boostHashCombine(x, y); } public int compareTo(Pt p) { if (y != p.y) return cmp(y, p.y); return cmp(x, p.x); } public String toString() { return x + ", " + y; } public double length() { return sqrt(x * x + y * y); } public Pt minus(Pt p) { return ptMinus(this, p); } public double x_double() { return x; } public double y_double() { return y; } } static abstract public class F0 { abstract public A get(); } static public class LeftAlignedLine extends JPanel { public LeftAlignedLine(int spacing, Component... components) { this(components); setSpacing(spacing); } public LeftAlignedLine(Component... components) { setLayout(LetterLayout.leftAlignedRow()); addAll(this, components); } public void setSpacing(int spacing) { ((LetterLayout) getLayout()).setSpacing(spacing, spacing); } public void add(String text) { add(new JLabel(text)); } } static abstract public class F1 { abstract public B get(A a); } static abstract public class IterableIterator implements Iterator, Iterable { public Iterator iterator() { return this; } public void remove() { unsupportedOperation(); } } static public class BoolVar { public boolean a = false; public BoolVar() { } public BoolVar(boolean a) { this.a = a; } public synchronized void set() { set(true); } public synchronized void set(boolean v) { if (v != a) { a = v; notifyAll(); } } public synchronized boolean get() { return a; } final public void unset() { clear(); } public void clear() { set(false); } public boolean waitUntilTrue() { return waitForValue(true); } public boolean waitUntilFalse() { return waitForValue(false); } synchronized public boolean waitForValue(boolean wantedValue) { try { while (a != wantedValue) wait(); return a; } catch (Exception __e) { throw rethrow(__e); } } } static public class JLeftArrowScriptIDE extends MetaWithChangeListeners implements Swingable { final public JLeftArrowScriptIDE setLvScript(IVarWithNotify lvScript) { return lvScript(lvScript); } public JLeftArrowScriptIDE lvScript(IVarWithNotify lvScript) { this.lvScript = lvScript; return this; } final public IVarWithNotify getLvScript() { return lvScript(); } public IVarWithNotify lvScript() { return lvScript; } public IVarWithNotify lvScript = stringLiveValue(); final public JLeftArrowScriptIDE setSectionTitle(String sectionTitle) { return sectionTitle(sectionTitle); } public JLeftArrowScriptIDE sectionTitle(String sectionTitle) { this.sectionTitle = sectionTitle; return this; } final public String getSectionTitle() { return sectionTitle(); } public String sectionTitle() { return sectionTitle; } public String sectionTitle = "Left arrow script"; final public JLeftArrowScriptIDE setWithResultPanel(boolean withResultPanel) { return withResultPanel(withResultPanel); } public JLeftArrowScriptIDE withResultPanel(boolean withResultPanel) { this.withResultPanel = withResultPanel; return this; } final public boolean getWithResultPanel() { return withResultPanel(); } public boolean withResultPanel() { return withResultPanel; } public boolean withResultPanel = true; final public JLeftArrowScriptIDE setCompileDelay(double compileDelay) { return compileDelay(compileDelay); } public JLeftArrowScriptIDE compileDelay(double compileDelay) { this.compileDelay = compileDelay; return this; } final public double getCompileDelay() { return compileDelay(); } public double compileDelay() { return compileDelay; } public double compileDelay = 0.1; static public String helpText = "Gazelle 22 \"Left Arrow Script\"\r\n------------------------------\r\n\r\n\"Left arrow script\" is one of Gazelle 22's two scripting languages. It is the powerful one of the two. It can do anything Java can do except for defining classes or lambdas.\r\n\r\n-Usually, you write one command per line\r\n-Each command contains at most one action and at most one assignment\r\n-The language is case-sensitive\r\n-You can add comments like in Java with /* */ or //\r\n-You can write multiple commands in one line by separating them with a semicolon\r\n-Arguments to functions are separated by spaces\r\n-You can use integer and string literals like in Java\r\n-You can use true, false and null\r\n\r\nIt's called \"left arrow script\" because the left arrow (variable assignment) is its only actual operator (not counting ; and {}).\r\n\r\n\r\nOperations\r\n----------\r\n\r\nYou can call any global function defined in Gazelle. Example:\r\n\r\n infoBox \"hello\" // show a popup with the text \"hello\"\r\n \r\nYou can assign the result of a function call to a variable:\r\n\r\n time <- tsNow // get current time as a Timestamp object\r\n infoBox time // show as popup\r\n \r\nNote that this script requires 2 lines because only one operation is allowed per command.\r\n \r\nVariables can be overwritten and don't have to be declared.\r\n\r\n\r\nCreating objects\r\n----------------\r\n\r\nYou can create an instance of any Java class and call methods on the object:\r\n\r\n list <- new ArrayList\r\n list add \"hello\"\r\n list add \"world\"\r\n infoBox list // shows [hello, world]\r\n \r\n(Currently you can also say \"list <- ArrayList\", but this is ambiguous and may be removed in a future version.)\r\n \r\nYou can pass parameters to the constructor:\r\n\r\n pair <- new Pair \"hello\" \"world\"\r\n infoBox pair // shows \r\n \r\n\r\nJava operators (+, * etc)\r\n-------------------------\r\n \r\nJava operators can't be used directly but we have functions that do the same thing (if we don't, we'll add them):\r\n\r\n x <- plus 1 2\r\n infoBox x\r\n\r\n\r\nFunction definitions\r\n--------------------\r\n\r\nYou can define functions in your script, with arguments. The function can return a value (which is the result of the last command in the function).\r\n\r\n def doubleMe x { mul x 2 }\r\n\r\n x <- doubleMe 5\r\n infoBox x // shows 10\r\n"; public transient FieldVar varCompileResult_cache; public FieldVar varCompileResult() { if (varCompileResult_cache == null) varCompileResult_cache = varCompileResult_load(); return varCompileResult_cache; } public FieldVar varCompileResult_load() { return new FieldVar(this, "compileResult", () -> compileResult(), compileResult -> compileResult(compileResult)); } final public JLeftArrowScriptIDE setCompileResult(LASCompileResult compileResult) { return compileResult(compileResult); } public JLeftArrowScriptIDE compileResult(LASCompileResult compileResult) { if (!eq(this.compileResult, compileResult)) { this.compileResult = compileResult; change(); } return this; } final public LASCompileResult getCompileResult() { return compileResult(); } public LASCompileResult compileResult() { return compileResult; } transient public LASCompileResult compileResult; transient public RSyntaxTextAreaWithSearch taScript; transient public RSTADummyParser dummyParser = new RSTADummyParser(); transient public Q compileQ = new Q(); final public JPanel getButtons() { return buttons(); } public JPanel buttons() { return buttons; } transient public JPanel buttons = jline(); transient public JButton btnRun; transient public CollapsibleLeftPanel collapsibleResultPanel; transient public G22ScriptResultPanel resultPanel; transient public JPopDownButton popDownButton; transient public LeftArrowCompletionProvider completionProvider; final public JLeftArrowScriptIDE setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public JLeftArrowScriptIDE g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; final public JLeftArrowScriptIDE setScriptTimeout(double scriptTimeout) { return scriptTimeout(scriptTimeout); } public JLeftArrowScriptIDE scriptTimeout(double scriptTimeout) { this.scriptTimeout = scriptTimeout; return this; } final public double getScriptTimeout() { return scriptTimeout(); } public double scriptTimeout() { return scriptTimeout; } public double scriptTimeout = 10.0; final public JLeftArrowScriptIDE setShowTitle(boolean showTitle) { return showTitle(showTitle); } public JLeftArrowScriptIDE showTitle(boolean showTitle) { this.showTitle = showTitle; return this; } final public boolean getShowTitle() { return showTitle(); } public boolean showTitle() { return showTitle; } transient public boolean showTitle = true; transient public IF0 makeParser; public GazelleV_LeftArrowScriptParser makeParser() { return makeParser != null ? makeParser.get() : makeParser_base(); } final public GazelleV_LeftArrowScriptParser makeParser_fallback(IF0 _f) { return _f != null ? _f.get() : makeParser_base(); } public GazelleV_LeftArrowScriptParser makeParser_base() { return g22utils.leftArrowParser(); } public class LeftArrowCompletionProvider extends DefaultCompletionProvider { @Override public List getCompletionsImpl(JTextComponent comp) { try { String text = getText(comp); GazelleV_LeftArrowScriptParser parser = makeParser2(); LeftArrowScriptAutoCompleter completer = new LeftArrowScriptAutoCompleter(g22utils, parser); enableScaffolding(completer); completer.seek(text, getCaretPosition(comp)); return map(completer.searcher().withScores(), completion -> { BasicCompletion c = new BasicCompletion(this, completion.get()); c.setRelevance((int) completion.score()); return c; }); } catch (Throwable e) { printStackTrace(e); return ll(); } } } public JComponent wrapStatusLabel(JComponent lbl) { onLeftClick(lbl, () -> { LineAndColumn lineAndCol = compileResult == null ? null : compileResult.errorLineAndCol(); if (lineAndCol != null) { moveCaretToLineAndCol(textArea(), lineAndCol); focus(textArea()); } }); popDownButton = swing(() -> new JPopDownButton("Help")); popDownButton.onFillingMenu(menu -> addMenuItems(menu, "Show Scripting Help", runnableThread(new Runnable() { public void run() { try { showTextWordWrapped("Gazelle 'Left arrow script' Help", helpText); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showTextWordWrapped(\"Gazelle 'Left arrow script' Help\", helpText)"; } }), "Show Global Class Names", runnableThread(new Runnable() { public void run() { try { showGlobalClassNames(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showGlobalClassNames();"; } }), "Convert to Java", runnableThread(new Runnable() { public void run() { try { convertToJava(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "convertToJava();"; } }))); return centerAndEastWithMargin(jBorderlessHigherScrollPane(lbl), jfullcenter(buttons)); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return swing(() -> { taScript = g22utils.newSyntaxTextArea(__2 -> wrapStatusLabel(__2)); bindTextComponentToVarWithNotify_noInitialUndo(textArea(), lvScript); dummyParser.install(textArea()); addKeyListener(textArea(), functionKeyListener(5, runnableThread(new Runnable() { public void run() { try { runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "runScript();"; } }))); addKeyListener(textArea(), ctrlLetterKeyListener('b', runnableThread(new Runnable() { public void run() { try { goToDefinition(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "goToDefinition();"; } }))); awtCalcEvery(textArea(), compileDelay, () -> compileQ.add(new Runnable() { public void run() { try { compile(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "compile();"; } })); installCompletionProvider(completionProvider = new LeftArrowCompletionProvider(), textArea()); JComponent vis = taScript.visualize(); if (showTitle) vis = jCenteredSection(sectionTitle, vis); vis = wrapSection(vis); addAll(buttons, btnRun = toolTip("Run script (F5)", jbutton("Run", runnableThread(new Runnable() { public void run() { try { runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "runScript();"; } }))), popDownButton); if (withResultPanel) { resultPanel = new G22ScriptResultPanel(); collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), vis); collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c); return collapsibleResultPanel.visualize(); } else return vis; }); } transient public IF1 wrapSection; public JComponent wrapSection(JComponent c) { return wrapSection != null ? wrapSection.get(c) : wrapSection_base(c); } final public JComponent wrapSection_fallback(IF1 _f, JComponent c) { return _f != null ? _f.get(c) : wrapSection_base(c); } public JComponent wrapSection_base(JComponent c) { return c; } public RSyntaxTextArea textArea() { if (taScript == null) visualize(); return taScript.textArea(); } public void setText(String text) { main.setText(textArea(), text); } public boolean visible() { return isShowing(textArea()); } public void compile() { var script = lvScript.get(); var result = compileResult; if (result == null || !eq(result.script, script)) { result = newCompileResult(); result.script = script; result.makeParser = () -> makeParser(); result.compile(); compileResult(result); showStatus(str(compileResult)); updateRunButtonState(); List errors = new ArrayList(); if (result.compileError != null) { LineAndColumn lineAndCol = result.errorLineAndCol(); if (lineAndCol != null) errors.add(new RSTADummyParser.Error().msg(result.errorToString()).start(lineAndCol).end(new LineAndColumn(lineAndCol.line + 1, 1))); } dummyParser.setErrors(result.script, errors, textArea()); } } public void updateRunButtonState() { setEnabled(btnRun, runButtonShouldBeEnabled()); } transient public IF0 runButtonShouldBeEnabled; public boolean runButtonShouldBeEnabled() { return runButtonShouldBeEnabled != null ? runButtonShouldBeEnabled.get() : runButtonShouldBeEnabled_base(); } final public boolean runButtonShouldBeEnabled_fallback(IF0 _f) { return _f != null ? _f.get() : runButtonShouldBeEnabled_base(); } public boolean runButtonShouldBeEnabled_base() { return compileResult != null && compileResult.runnable(); } public LASCompileResult freshCompileResult() { runInQAndWait(compileQ, new Runnable() { public void run() { try { compile(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "compile();"; } }); return compileResult; } public GazelleV_LeftArrowScript.Script parsedScript() { return freshCompileResult().parsedScript; } transient public Runnable runScript; public void runScript() { if (runScript != null) runScript.run(); else runScript_base(); } final public void runScript_fallback(Runnable _f) { if (_f != null) _f.run(); else runScript_base(); } public void runScript_base() { var result = freshCompileResult(); if (result.parsedScript != null) { var value = runResultWithTimestamps(() -> callCompiledObjectWithTimeout(result.parsedScript)); showScriptResult(value); } } public void showScriptResult(OKOrError result) { if (result instanceof RunResultWithTimestamps) { if (resultPanel != null) resultPanel.logView.setText(str(((RunResultWithTimestamps) result).printOutput())); } if (result.isOK()) { setStatus(shorten(g22utils.stringify(result.get()))); var objVisualizer = new G22JavaObjectVisualizer(g22utils, result.get()); if (result instanceof RunResultWithTimestamps) { var duration = ((RunResultWithTimestamps) result).duration(); print("duration", duration); if (duration != null) { long nanos = ((RunResultWithTimestamps) result).duration().toNanos(); printVars("nanos", nanos, "objVisualizer", objVisualizer); objVisualizer.nanos(nanos); } } if (collapsibleResultPanel != null) objVisualizer.withTypeAndTime(false); { if (resultPanel != null) resultPanel.scpResult.set(objVisualizer); } if (collapsibleResultPanel != null) collapsibleResultPanel.sidePanelName("Output" + appendBracketed(objVisualizer.objectInfos())); } else { setStatus(exceptionToStringShorter_dontDropOuterExceptions(result.error())); { if (resultPanel != null) resultPanel.scpResult.set(jErrorView(result.getError())); } } { if (collapsibleResultPanel != null) collapsibleResultPanel.expand(); } } final public void showStatus(String status) { setStatus(status); } public void setStatus(String status) { { if (taScript != null) taScript.setStatus(" " + unnull(status)); } } public void showRuntimeError(Throwable e) { showStatus(exceptionToStringShorter(e)); } transient public IF0 makeVarContextForExecution; public VarContext makeVarContextForExecution() { return makeVarContextForExecution != null ? makeVarContextForExecution.get() : makeVarContextForExecution_base(); } final public VarContext makeVarContextForExecution_fallback(IF0 _f) { return _f != null ? _f.get() : makeVarContextForExecution_base(); } public VarContext makeVarContextForExecution_base() { return new FlexibleVarContext(); } public Object callCompiledObjectWithTimeout(GazelleV_LeftArrowScript.Script script) { return callCompiledObjectWithTimeout(scriptTimeout, script); } public Object callCompiledObjectWithTimeout(double timeoutSeconds, GazelleV_LeftArrowScript.Script script) { return callCompiledObjectWithTimeout(timeoutSeconds, script, makeVarContextForExecution()); } public Object callCompiledObjectWithTimeout(GazelleV_LeftArrowScript.Script script, VarContext ctx) { return callCompiledObjectWithTimeout(scriptTimeout, script, ctx); } public Object callCompiledObjectWithTimeout(double timeoutSeconds, GazelleV_LeftArrowScript.Script script, VarContext ctx) { return g22utils.evalRegisteredCode(timeoutSeconds, str(script), () -> script.get(ctx)); } public GazelleV_LeftArrowScriptParser makeParser2() { var parser = makeParser(); print("Function containers: " + parser.functionContainers); return parser; } public void showGlobalClassNames() { showText("Global Class Names", pnlToString(toCIMap(makeParser().globalClassNames()))); } public void setEditable(boolean b) { main.setEditable(textArea(), b); } transient public IF0 newCompileResult; public LASCompileResult newCompileResult() { return newCompileResult != null ? newCompileResult.get() : newCompileResult_base(); } final public LASCompileResult newCompileResult_fallback(IF0 _f) { return _f != null ? _f.get() : newCompileResult_base(); } public LASCompileResult newCompileResult_base() { return new LASCompileResult(); } public void convertToJava() { try { ConvertLASToJava converter = new ConvertLASToJava(); enableScaffolding(converter); showText("Java conversion - " + sectionTitle(), strOrNull(converter.get(parsedScript(), true))); } catch (Throwable __e) { infoBox(__e); } } public void goToDefinition() { String text; int iChar; Pair __1 = textAndCaretPosition(textArea()); text = __1.a; iChar = __1.b; List tok = lasTok(text); int iTok = charToTokenIndex_left(tok, iChar); String token = lastIdentifier(subList(tok, iTok - 2, iTok + 1)); printVars("goToDefinition", "iTok", iTok, "token", quote(token)); if (token != null) { String name = lookupStandardFunctionOrClassNameIC(token); if (name != null) { String snippetID = sfOrSCSnippet(token); if (snippetID != null) { infoBox("Opening " + quote(name)); g22utils.openInBrowser(snippetURL(snippetID)); return; } } flatInfoBox("No information found for " + token); } } } public static interface IF0 { public A get(); } static public interface Hasher { public int hashCode(A a); public boolean equals(A a, A b); } 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 interface IF1 { public B get(A a); } static public interface IVF1 { public void get(A a); } static public class GazelleV_LeftArrowScript { abstract static public class Base extends HasTokenRangeWithSrc { public RuntimeException rethrowWithSrc(Throwable e) { return rethrowWithSrc("", e); } public RuntimeException rethrowWithSrc(String msg, Throwable e) { if (src != null) throw rethrowAndAppendToMessage(e, squareBracketed(joinNemptiesWithComma(msg, src))); else throw rethrow(e); } } public interface Evaluable extends IF0, IHasTokenRangeWithSrc { public default Object get() { return get(new FlexibleVarContext()); } public Object get(VarContext ctx); public default LASValueDescriptor returnType() { return null; } public default Evaluable optimize() { return this; } public default Evaluable optimizeForReturnValueNotNeeded() { return this; } } abstract static public class EvaluableBase extends Base implements Evaluable { final public EvaluableBase setReturnType(LASValueDescriptor returnType) { return returnType(returnType); } public EvaluableBase returnType(LASValueDescriptor returnType) { this.returnType = returnType; return this; } final public LASValueDescriptor getReturnType() { return returnType(); } public LASValueDescriptor returnType() { return returnType; } public LASValueDescriptor returnType; public boolean returnValueNeeded = true; public Evaluable optimizeForReturnValueNotNeeded() { returnValueNeeded = false; return optimize(); } } static public AtomicLong scriptIDCounter = new AtomicLong(); static public long scriptID() { return incAtomicLong(scriptIDCounter); } static public class Script extends EvaluableBase { transient public long id = scriptID(); public Map functionDefs; public Evaluable[] steps; final public Script setScope(LASScope scope) { return scope(scope); } public Script scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public Map params; public Object get(VarContext ctx) { Object result = null; var pingSource = pingSource(); for (var step : steps) { ping(pingSource); result = step.get(ctx); var exiting = ctx.exitFromScript; if (exiting != null) { if (exiting == this) { ctx.exitFromScript = null; result = ctx.returnValue; ctx.returnValue(null); return result; } return null; } } return result; } public String toStringLong() { return pnlToLines(steps); } public String toString() { return "Script " + n2(id); } public FunctionDef getFunction(String name) { return mapGet(functionDefs, name); } final public Script optimize() { return optimizeScript(); } public Script optimizeScript() { int n = returnValueNeeded ? steps.length - 1 : steps.length; for (int i = 0; i < n; i++) steps[i] = steps[i].optimizeForReturnValueNotNeeded(); for (var f : values(functionDefs)) f.optimize(); return this; } } static public class FunctionDef extends Base implements IFieldsToList { public String name; public String[] args; public Script body; public FunctionDef() { } public FunctionDef(String name, String[] args, Script body) { this.body = body; this.args = args; this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + args + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { name, args, body }; } final public FunctionDef setScope(LASScope scope) { return scope(scope); } public FunctionDef scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; final public FunctionDef setReturnType(Type returnType) { return returnType(returnType); } public FunctionDef returnType(Type returnType) { this.returnType = returnType; return this; } final public Type getReturnType() { return returnType(); } public Type returnType() { return returnType; } public Type returnType = Object.class; public FunctionDef(String name, List args, Script body) { this.args = toStringArray(args); this.body = body; this.name = name; } public Object call(VarContext ctx, Object... args) { VarContext ctx2 = scope != null && scope.useFixedVars ? new FixedVarContext(ctx, scope.names) : new FlexibleVarContext(ctx); int n = min(l(args), l(this.args)); for (int i = 0; i < n; i++) ctx2.put(this.args[i], args[i]); return body.get(ctx2); } public void optimize() { body = body.optimize(); } } static public class Assignment extends EvaluableBase implements IFieldsToList { public String var; public Evaluable expression; public Assignment() { } public Assignment(String var, Evaluable expression) { this.expression = expression; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, expression }; } public Object get(VarContext ctx) { Object o = expression.get(ctx); ctx.set(var, o); return o; } public String toString() { return var + " <- " + expression; } } abstract static public class FixedVarBase extends EvaluableBase { final public FixedVarBase setScope(LASScope scope) { return scope(scope); } public FixedVarBase scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public String var; public int varIdx; public String varToStr() { return var + " [" + varIdx + "]"; } public void assertResolved() { if (varIdx < 0) throw fail("Unresolved variable access: " + var); } public void resolve() { varIdx = scope.resolveVar(var); } } static public class FixedVarAssignment extends FixedVarBase { public FixedVarAssignment() { } public Evaluable expression; public FixedVarAssignment(LASScope scope, String var, Evaluable expression) { this.expression = expression; this.var = var; this.scope = scope; } public Object get(VarContext ctx) { Object o = expression.get(ctx); ((FixedVarContext) ctx).set(varIdx, o); return o; } public String toString() { return varToStr() + " <- " + expression; } } static public class VarDeclaration extends EvaluableBase implements IFieldsToList { public String var; public Class type; public Evaluable expression; public VarDeclaration() { } public VarDeclaration(String var, Class type, Evaluable expression) { this.expression = expression; this.type = type; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, type, expression }; } public Object get(VarContext ctx) { Object o = expression == null ? null : expression.get(ctx); ctx.set(var, o); return o; } public String toString() { return "var " + var + " <- " + expression; } } static public class AssignmentToOuterVar extends EvaluableBase implements IFieldsToList { public String var; public Evaluable expression; public AssignmentToOuterVar() { } public AssignmentToOuterVar(String var, Evaluable expression) { this.expression = expression; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, expression }; } public Object get(VarContext ctx) { var parent = ctx.parent(); assertNotNull("No outer variable context", parent); Object o = expression.get(ctx); parent.set(var, o); return o; } public String toString() { return "outer " + var + " <- " + expression; } } static public class NewObject extends EvaluableBase { public NewObject() { } public Class c; public Evaluable[] args; public NewObject(Class c) { this.c = c; } public NewObject(Class c, Evaluable[] args) { this.args = args; this.c = c; } public Object get(VarContext ctx) { try { return preciseNuObject(c, mapToArrayOrNull(args, arg -> arg.get(ctx))); } catch (Throwable e) { throw rethrowWithSrc(e); } } public String toString() { return "new " + formatFunctionCall(className(c), args); } } static public class NewObject_LASClass extends NewObject { public NewObject_LASClass() { } public ResolvableLASClass lasClass; public NewObject_LASClass(ResolvableLASClass lasClass) { this.lasClass = lasClass; } public NewObject_LASClass(ResolvableLASClass lasClass, Evaluable[] args) { this.args = args; this.lasClass = lasClass; } public void resolve() { if (c == null) c = lasClass.get(); } public Object get(VarContext ctx) { resolve(); return super.get(ctx); } public String toString() { return "new " + formatFunctionCall(str(lasClass), args); } } static public class NewObject_UnknownClass extends NewObject implements IFieldsToList { public Evaluable classExpr; public Evaluable[] args; public NewObject_UnknownClass() { } public NewObject_UnknownClass(Evaluable classExpr, Evaluable[] args) { this.args = args; this.classExpr = classExpr; } public Object[] _fieldsToList() { return new Object[] { classExpr, args }; } public Object get(VarContext ctx) { try { Class c = (Class) (classExpr.get(ctx)); return preciseNuObject(c, mapToArrayOrNull(args, arg -> arg.get(ctx))); } catch (Throwable e) { throw rethrowWithSrc(e); } } public String toString() { return "new " + formatFunctionCall(classExpr, args); } } static public class CallFunction extends EvaluableBase implements IFieldsToList { public FunctionDef f; public Evaluable[] args; public CallFunction() { } public CallFunction(FunctionDef f, Evaluable[] args) { this.args = args; this.f = f; } public Object[] _fieldsToList() { return new Object[] { f, args }; } public Object get(VarContext ctx) { var evaledArgs = mapToArrayOrNull(args, a -> a.get(ctx)); if (ctx.exiting()) return null; return f.call(ctx, evaledArgs); } public String toString() { return formatFunctionCall(f.name, args); } } static public class GetVar extends EvaluableBase implements IFieldsToList { public String var; public GetVar() { } public GetVar(String var) { this.var = var; } public Object[] _fieldsToList() { return new Object[] { var }; } public Object get(VarContext ctx) { return ctx.get(var); } public String toString() { return var; } } static public class GetFixedVar extends FixedVarBase { public GetFixedVar() { } public GetFixedVar(LASScope scope, String var) { this.var = var; this.scope = scope; } public Object get(VarContext ctx) { assertResolved(); try { return ((FixedVarContext) ctx).get(varIdx); } catch (ArrayIndexOutOfBoundsException e) { assertResolved(); throw e; } } public String toString() { return var + " [" + varIdx + "]"; } } static public class Const extends EvaluableBase implements IFieldsToList { public Object value; public Const() { } public Const(Object value) { this.value = value; } public Object[] _fieldsToList() { return new Object[] { value }; } public Object get(VarContext ctx) { return value; } public String toString() { return strOrClassName(value); } public LASValueDescriptor returnType() { return new LASValueDescriptor.KnownValue(value); } public Object _serialize() { boolean ok = isUnproblematicValue(value); return ok ? this : toStringWithClass(value); } } static public class GetStaticField extends EvaluableBase implements IFieldsToList { public Field field; public GetStaticField() { } public GetStaticField(Field field) { this.field = field; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + field + ")"; } public Object[] _fieldsToList() { return new Object[] { field }; } public Object get(VarContext ctx) { try { return field.get(null); } catch (Exception __e) { throw rethrow(__e); } } public String _serialize() { return str(field); } } static public class CallMethodOrGetField extends EvaluableBase implements IFieldsToList { public Evaluable target; public String name; public CallMethodOrGetField() { } public CallMethodOrGetField(Evaluable target, String name) { this.name = name; this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ", " + name + ")"; } public Object[] _fieldsToList() { return new Object[] { target, name }; } final public CallMethodOrGetField setAllowNullReference(boolean allowNullReference) { return allowNullReference(allowNullReference); } public CallMethodOrGetField allowNullReference(boolean allowNullReference) { this.allowNullReference = allowNullReference; return this; } final public boolean getAllowNullReference() { return allowNullReference(); } public boolean allowNullReference() { return allowNullReference; } public boolean allowNullReference = false; public Object handleNullReference() { if (allowNullReference) return null; else throw new NullPointerException(); } public Object get(VarContext ctx) { try { Object object = target.get(ctx); if (object == null) return handleNullReference(); return preciseGetOrCallMethod(object, name); } catch (Throwable e) { throw rethrowWithSrc("Was getting " + name, e); } } } static public class GetVarContext extends EvaluableBase { public Object get(VarContext ctx) { return ctx; } } static public class ThrowMethodNotFoundException extends EvaluableBase implements IFieldsToList { public CallMethod instruction; public ThrowMethodNotFoundException() { } public ThrowMethodNotFoundException(CallMethod instruction) { this.instruction = instruction; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + instruction + ")"; } public Object[] _fieldsToList() { return new Object[] { instruction }; } public Object get(VarContext ctx) { throw fail("Method not found: " + instruction); } } static public class ThrowNullPointerException extends EvaluableBase implements IFieldsToList { public CallMethod instruction; public ThrowNullPointerException() { } public ThrowNullPointerException(CallMethod instruction) { this.instruction = instruction; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + instruction + ")"; } public Object[] _fieldsToList() { return new Object[] { instruction }; } public Object get(VarContext ctx) { throw fail("Null pointer exception: " + instruction); } } static public class CallMethod extends EvaluableBase implements IFieldsToList { public Evaluable target; public String methodName; public Evaluable[] args; public CallMethod() { } public CallMethod(Evaluable target, String methodName, Evaluable[] args) { this.args = args; this.methodName = methodName; this.target = target; } public Object[] _fieldsToList() { return new Object[] { target, methodName, args }; } public Object get(VarContext ctx) { return newPreciseCall(target.get(ctx), methodName, mapToArrayOrNull(args, arg -> arg.get(ctx))); } public String toString() { return target + "." + formatFunctionCall(methodName, args); } public Evaluable optimize() { var targetType = target.returnType(); if (targetType != null && targetType.knownValue()) { Object o = targetType.value(); if (o == null) return new ThrowNullPointerException(this); Class[] argTypes = new Class[l(args)]; for (int i = 0; i < l(args); i++) { var type = args[i].returnType(); if (type == null || !type.javaClassIsExact()) return this; argTypes[i] = type.javaClass(); } List methods = findMethodsNamed_cached(o, methodName); if (any(methods, m -> m.isVarArgs())) return this; var __4 = findMethod_withPrimitiveWidening_onTypes(o, methodName, argTypes); var method = __4.a; var widening = __4.b; if (method == null) return new ThrowMethodNotFoundException(this); return new DirectMethodCallOnKnownTarget(widening, o instanceof Class ? null : o, method, args); } return this; } } static public class LambdaDef extends EvaluableBase implements IFieldsToList { public Class intrface; public String[] args; public Evaluable body; public LambdaDef() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ", " + args + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface, args, body }; } public Method implementedMethod; public LambdaDef(Class intrface, String[] args, Evaluable body) { this.body = body; this.args = args; this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); if (implementedMethod.getParameterCount() != l(args)) throw fail("Bad parameter count for lambda: " + implementedMethod + " vs: " + joinWithComma(args)); } public Object get(VarContext ctx) { return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { ping(); if (method.getDeclaringClass() == intrface) { var ctx2 = new FlexibleVarContext(ctx); var argNames = args; for (int i = 0; i < l(args); i++) ctx2.put(argNames[i], actualArgs[i]); return body.get(ctx2); } else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); }); } } abstract static public class CurriedLambdaBase extends EvaluableBase implements IFieldsToList { public Class intrface; public Evaluable[] curriedArgs; public CurriedLambdaBase() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ", " + curriedArgs + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface, curriedArgs }; } public Method implementedMethod; public CurriedLambdaBase(Class intrface, Evaluable[] curriedArgs) { this.curriedArgs = curriedArgs; this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); } public Object get(VarContext ctx) { Object[] curriedArguments = mapToArrayOrNull(curriedArgs, arg -> arg.get(ctx)); return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { if (method.getDeclaringClass() == intrface) return forwardCall(ctx, concatMethodArgs(curriedArguments, actualArgs)); else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); }); } abstract public Object forwardCall(VarContext ctx, Object[] args); } static public class CurriedMethodLambda extends CurriedLambdaBase { public Object target; public String targetMethod; public CurriedMethodLambda(Class intrface, Object target, String targetMethod, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.targetMethod = targetMethod; this.target = target; } public Object forwardCall(VarContext ctx, Object[] args) { return call(target, targetMethod, args); } } static public class CurriedScriptFunctionLambda extends CurriedLambdaBase { public FunctionDef f; public CurriedScriptFunctionLambda(Class intrface, FunctionDef f, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.f = f; } public Object forwardCall(VarContext ctx, Object[] args) { return f.call(ctx, args); } } static public class CurriedConstructorLambda extends CurriedLambdaBase { public Constructor[] ctors; public CurriedConstructorLambda(Class intrface, Constructor[] ctors, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.ctors = ctors; } public Object forwardCall(VarContext ctx, Object[] args) { return preciseNuObject(ctors, args); } } static public class DirectMethodCallOnKnownTarget extends EvaluableBase implements IFieldsToList { public boolean widening = false; public Object target; public Method method; public Evaluable[] args; public DirectMethodCallOnKnownTarget() { } public DirectMethodCallOnKnownTarget(boolean widening, Object target, Method method, Evaluable[] args) { this.args = args; this.method = method; this.target = target; this.widening = widening; } public Object[] _fieldsToList() { return new Object[] { widening, target, method, args }; } public Object get(VarContext ctx) { var evaluatedArgs = mapToArrayOrNull(args, arg -> arg.get(ctx)); return widening ? invokeMethodWithWidening(method, target, evaluatedArgs) : invokeMethod(method, target, evaluatedArgs); } public String toString() { return (target == null ? "" : target + ".") + formatFunctionCall(str(method), args); } public LASValueDescriptor returnType() { return LASValueDescriptor.fromClass(method.getReturnType()); } } static public class While extends EvaluableBase implements IFieldsToList { public Evaluable condition; public Evaluable body; public While() { } public While(Evaluable condition, Evaluable body) { this.body = body; this.condition = condition; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + condition + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { condition, body }; } public Object get(VarContext ctx) { while (!ctx.exiting() && (Boolean) condition.get(ctx)) { body.get(ctx); } return null; } } abstract static public class ForEachBase extends EvaluableBase implements IFieldsToList { public Evaluable collection; public Evaluable body; public ForEachBase() { } public ForEachBase(Evaluable collection, Evaluable body) { this.body = body; this.collection = collection; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + collection + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { collection, body }; } public Object get(VarContext ctx) { var coll = collection.get(ctx); Iterator iterator; List out; try { if (coll instanceof Object[]) { out = emptyList(((Object[]) coll).length); for (var element : ((Object[]) coll)) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof Iterable) { out = emptyList((Iterable) coll); for (var element : ((Iterable) coll)) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll == null) out = new ArrayList(); else throw fail("Not iterable: " + className(coll)); } finally { loopDone(ctx); } return out; } abstract public void processElement(VarContext ctx, List out, Object o); abstract public void loopDone(VarContext ctx); } static public class ForEach extends ForEachBase { public ForEach() { } public String var; public ForEach(Evaluable collection, String var, Evaluable body) { this.body = body; this.var = var; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { ctx.set(var, o); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(var); } } static public class ForIterator extends EvaluableBase implements IFieldsToList { static final public String _fieldOrder = "iterable var body"; public Evaluable iterable; public String var; public Evaluable body; public ForIterator() { } public ForIterator(Evaluable iterable, String var, Evaluable body) { this.body = body; this.var = var; this.iterable = iterable; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + iterable + ", " + var + ", " + body + ")"; } public boolean equals(Object o) { if (!(o instanceof ForIterator)) return false; ForIterator __5 = (ForIterator) o; return eq(iterable, __5.iterable) && eq(var, __5.var) && eq(body, __5.body); } public int hashCode() { int h = -214906825; h = boostHashCombine(h, _hashCode(iterable)); h = boostHashCombine(h, _hashCode(var)); h = boostHashCombine(h, _hashCode(body)); return h; } public Object[] _fieldsToList() { return new Object[] { iterable, var, body }; } public Object get(VarContext ctx) { VarContext subContext = new FlexibleVarContext(ctx); var iterable = this.iterable.get(ctx); Iterator iterator = iterator_gen(iterable); return mapI(iterator, value -> { subContext.set(var, value); return body.get(subContext); }); } } static public class ForNested extends EvaluableBase implements IFieldsToList { static final public String _fieldOrder = "iterable var body"; public Evaluable iterable; public String var; public Evaluable body; public ForNested() { } public ForNested(Evaluable iterable, String var, Evaluable body) { this.body = body; this.var = var; this.iterable = iterable; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + iterable + ", " + var + ", " + body + ")"; } public boolean equals(Object o) { if (!(o instanceof ForNested)) return false; ForNested __6 = (ForNested) o; return eq(iterable, __6.iterable) && eq(var, __6.var) && eq(body, __6.body); } public int hashCode() { int h = -1363247360; h = boostHashCombine(h, _hashCode(iterable)); h = boostHashCombine(h, _hashCode(var)); h = boostHashCombine(h, _hashCode(body)); return h; } public Object[] _fieldsToList() { return new Object[] { iterable, var, body }; } public Object get(VarContext ctx) { VarContext subContext = new FlexibleVarContext(ctx); var iterable = this.iterable.get(ctx); Iterator iterator = iterator_gen(iterable); return nestedIterator(iterator, value -> { subContext.set(var, value); return iterator_gen(body.get(subContext)); }); } } static public class ForPairs extends ForEachBase { public ForPairs() { } public String varA, varB; public ForPairs(Evaluable collection, Evaluable body, String varA, String varB) { this.varB = varB; this.varA = varA; this.body = body; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { Pair p = (Pair) o; ctx.set(varA, p.a); ctx.set(varB, p.b); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(varA); ctx.unset(varB); } } static public class ForKeyValue extends EvaluableBase implements IFieldsToList { public Evaluable map; public Evaluable body; public String varA; public String varB; public ForKeyValue() { } public ForKeyValue(Evaluable map, Evaluable body, String varA, String varB) { this.varB = varB; this.varA = varA; this.body = body; this.map = map; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + map + ", " + body + ", " + varA + ", " + varB + ")"; } public Object[] _fieldsToList() { return new Object[] { map, body, varA, varB }; } public Object get(VarContext ctx) { Map theMap = (Map) map.get(ctx); List out; try { if (theMap != null) { out = emptyList(theMap.size()); for (var entry : theMap.entrySet()) { if (ctx.exiting()) return null; ctx.set(varA, entry.getKey()); ctx.set(varB, entry.getValue()); out.add(body.get(ctx)); } } else out = new ArrayList(); } finally { ctx.unset(varA); ctx.unset(varB); } return out; } } static public class ForIntTo extends EvaluableBase implements IFieldsToList { public Evaluable endValue; public String var; public Evaluable body; public ForIntTo() { } public ForIntTo(Evaluable endValue, String var, Evaluable body) { this.body = body; this.var = var; this.endValue = endValue; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + endValue + ", " + var + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { endValue, var, body }; } public Evaluable optimize() { if (!returnValueNeeded) body = body.optimizeForReturnValueNotNeeded(); return this; } public Object get(VarContext ctx) { int n = (Integer) endValue.get(ctx), i = 0; List out = returnValueNeeded ? new ArrayList() : null; try { ctx.put(var, i); while (i < n) { if (ctx.exiting()) return null; Object o = body.get(ctx); { if (out != null) out.add(o); } ctx.set(var, i = (Integer) ctx.get(var) + 1); } } finally { ctx.unset(var); } return out; } } static public class ForIndex extends EvaluableBase { public ForIndex() { } public Evaluable collection, body; public String varIndex, varElement; public ForIndex(Evaluable collection, Evaluable body, String varIndex, String varElement) { this.varElement = varElement; this.varIndex = varIndex; this.body = body; this.collection = collection; } public Object get(VarContext ctx) { return new ForIndex_instance(collection, body, varIndex, varElement).get(ctx); } } static public class ForIndex_instance extends ForEachBase { public String varIndex, varElement; public int index; public ForIndex_instance(Evaluable collection, Evaluable body, String varIndex, String varElement) { this.varElement = varElement; this.varIndex = varIndex; this.body = body; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { ctx.set(varIndex, index++); ctx.set(varElement, o); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(varIndex); ctx.unset(varElement); } } static public class IfThen extends EvaluableBase implements IFieldsToList { public Evaluable condition; public Evaluable body; public Evaluable elseBranch; public IfThen() { } public IfThen(Evaluable condition, Evaluable body, Evaluable elseBranch) { this.elseBranch = elseBranch; this.body = body; this.condition = condition; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + condition + ", " + body + ", " + elseBranch + ")"; } public Object[] _fieldsToList() { return new Object[] { condition, body, elseBranch }; } public IfThen(Evaluable condition, Evaluable body) { this.condition = condition; this.body = body; } public Object get(VarContext ctx) { if ((Boolean) condition.get(ctx)) return body.get(ctx); else if (elseBranch != null) return elseBranch.get(ctx); else return null; } } static public class ReturnFromScript extends EvaluableBase implements IFieldsToList { public Script script; public Evaluable value; public ReturnFromScript() { } public ReturnFromScript(Script script, Evaluable value) { this.value = value; this.script = script; } public Object[] _fieldsToList() { return new Object[] { script, value }; } public Object get(VarContext ctx) { Object result = value.get(ctx); ctx.exitFromScript(script); ctx.returnValue(result); return null; } public String toString() { return formatFunctionCall("ReturnFromScript", script, value); } } static public class Continue extends EvaluableBase implements IFieldsToList { public Script loopBody; public Continue() { } public Continue(Script loopBody) { this.loopBody = loopBody; } public Object[] _fieldsToList() { return new Object[] { loopBody }; } public Object get(VarContext ctx) { ctx.exitFromScript(loopBody); ctx.returnValue(null); return null; } public String toString() { return formatFunctionCall("Continue", loopBody); } } static public class RepeatN extends EvaluableBase implements IFieldsToList { public Evaluable n; public Evaluable body; public RepeatN() { } public RepeatN(Evaluable n, Evaluable body) { this.body = body; this.n = n; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + n + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { n, body }; } public Object get(VarContext ctx) { long count = ((Number) n.get(ctx)).longValue(); for (int _repeat_0 = 0; _repeat_0 < count; _repeat_0++) { if (ctx.exiting()) return null; body.get(ctx); } return null; } } static public class BoolAnd extends EvaluableBase implements IFieldsToList { public Evaluable a; public Evaluable b; public BoolAnd() { } public BoolAnd(Evaluable a, Evaluable b) { this.b = b; this.a = a; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + a + ", " + b + ")"; } public boolean equals(Object o) { if (!(o instanceof BoolAnd)) return false; BoolAnd __7 = (BoolAnd) o; return eq(a, __7.a) && eq(b, __7.b); } public int hashCode() { int h = 1729330797; h = boostHashCombine(h, _hashCode(a)); h = boostHashCombine(h, _hashCode(b)); return h; } public Object[] _fieldsToList() { return new Object[] { a, b }; } public Object get(VarContext ctx) { if (!((Boolean) a.get(ctx))) return false; return b.get(ctx); } } static public class BoolOr extends EvaluableBase implements IFieldsToList { public Evaluable a; public Evaluable b; public BoolOr() { } public BoolOr(Evaluable a, Evaluable b) { this.b = b; this.a = a; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + a + ", " + b + ")"; } public boolean equals(Object o) { if (!(o instanceof BoolOr)) return false; BoolOr __8 = (BoolOr) o; return eq(a, __8.a) && eq(b, __8.b); } public int hashCode() { int h = 1995447949; h = boostHashCombine(h, _hashCode(a)); h = boostHashCombine(h, _hashCode(b)); return h; } public Object[] _fieldsToList() { return new Object[] { a, b }; } public Object get(VarContext ctx) { if (((Boolean) a.get(ctx))) return true; return b.get(ctx); } } static public class TempBlock extends EvaluableBase implements IFieldsToList { public Evaluable tempExpr; public Evaluable body; public TempBlock() { } public TempBlock(Evaluable tempExpr, Evaluable body) { this.body = body; this.tempExpr = tempExpr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + tempExpr + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { tempExpr, body }; } public Object get(VarContext ctx) { AutoCloseable __2 = (AutoCloseable) (tempExpr.get(ctx)); try { return body.get(ctx); } finally { _close(__2); } } } static public class ClassDef extends EvaluableBase implements IFieldsToList { public ResolvableLASClass lasClass; public ClassDef() { } public ClassDef(ResolvableLASClass lasClass) { this.lasClass = lasClass; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + lasClass + ")"; } public boolean equals(Object o) { if (!(o instanceof ClassDef)) return false; ClassDef __9 = (ClassDef) o; return eq(lasClass, __9.lasClass); } public int hashCode() { int h = 757052301; h = boostHashCombine(h, _hashCode(lasClass)); return h; } public Object[] _fieldsToList() { return new Object[] { lasClass }; } public Object get(VarContext ctx) { return lasClass.get(); } } static public class SetField extends EvaluableBase implements IFieldsToList { public Evaluable target; public String name; public Evaluable expr; public SetField() { } public SetField(Evaluable target, String name, Evaluable expr) { this.expr = expr; this.name = name; this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ", " + name + ", " + expr + ")"; } public Object[] _fieldsToList() { return new Object[] { target, name, expr }; } final public SetField setAllowNullReference(boolean allowNullReference) { return allowNullReference(allowNullReference); } public SetField allowNullReference(boolean allowNullReference) { this.allowNullReference = allowNullReference; return this; } final public boolean getAllowNullReference() { return allowNullReference(); } public boolean allowNullReference() { return allowNullReference; } public boolean allowNullReference = false; public Object handleNullReference() { if (allowNullReference) return null; else throw new NullPointerException(); } public Object get(VarContext ctx) { try { Object value = expr.get(ctx); Object object = target.get(ctx); if (object == null) handleNullReference(); else set(object, name, value); return value; } catch (Throwable e) { throw rethrowWithSrc(e); } } } static public class Throw extends EvaluableBase implements IFieldsToList { public Evaluable expr; public Throw() { } public Throw(Evaluable expr) { this.expr = expr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + expr + ")"; } public Object[] _fieldsToList() { return new Object[] { expr }; } public Object get(VarContext ctx) { throw asRuntimeException((Throwable) expr.get(ctx)); } } static public class TryCatch extends EvaluableBase implements IFieldsToList { public Evaluable body; public String var; public Evaluable catchBlock; public TryCatch() { } public TryCatch(Evaluable body, String var, Evaluable catchBlock) { this.catchBlock = catchBlock; this.var = var; this.body = body; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + body + ", " + var + ", " + catchBlock + ")"; } public Object[] _fieldsToList() { return new Object[] { body, var, catchBlock }; } public Object get(VarContext ctx) { try { return body.get(ctx); } catch (Throwable e) { AutoCloseable __3 = ctx.tempPut(var, e); try { return catchBlock.get(ctx); } finally { _close(__3); } } } } static public class TryFinally extends EvaluableBase implements IFieldsToList { public Evaluable body; public Evaluable finallyBlock; public TryFinally() { } public TryFinally(Evaluable body, Evaluable finallyBlock) { this.finallyBlock = finallyBlock; this.body = body; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + body + ", " + finallyBlock + ")"; } public Object[] _fieldsToList() { return new Object[] { body, finallyBlock }; } public Object get(VarContext ctx) { try { return body.get(ctx); } finally { finallyBlock.get(ctx); } } } static public structure_Data structureDataForLAS() { structure_Data d = new structure_Data(); d.skipDefaultValues(true); d.shouldIncludeField = field -> { String c = shortClassName(field.getDeclaringClass()); String f = field.getName(); boolean shouldInclude = !(eq(c, "HasTokenRangeWithSrc") && eq(f, "src")); return shouldInclude; }; return d; } static public boolean isUnproblematicValue(Object o) { return o == null || o instanceof Number || o instanceof String || o instanceof Boolean || o instanceof Class; } static public String scriptStruct(Object o) { String s = struct(o, structureDataForLAS()); List tok = structTok(s); String prefix = shortName(GazelleV_LeftArrowScript.class) + "$"; for (int i = 1; i < l(tok); i += 2) tok.set(i, replacePrefix(prefix, "$", tok.get(i))); return join(tok); } static public String indentedScriptStruct(Object o) { return indentStructureString(scriptStruct(o)); } } static public interface IVar extends IF0 { public void set(A a); public A get(); default public Class getType() { return null; } default public boolean has() { return get() != null; } default public void clear() { set(null); } } 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; java.lang.Module myModule = getClass().getModule(); boolean anyHiddenClasses = false; while (_c != null) { boolean exported = classIsExportedTo(_c, myModule); if (!exported) anyHiddenClasses = true; else for (Method m : _c.getDeclaredMethods()) if ((anyHiddenClasses || !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 ((anyHiddenClasses || 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 public class FlexibleVarContext extends VarContext { public Map vars; public FlexibleVarContext() { } public FlexibleVarContext(VarContext parent) { super(parent); } public Object get(String name) { if (containsKey(vars, name)) return mapGet(vars, name); if (parent != null) return parent.get(name); return null; } public void set(String name, Object value) { vars = putOrCreateSyncMap(vars, name, value); } public AutoCloseable tempSet(String name, Object value) { initMap(); return main.tempPut(vars, name, value); } public void unset(String name) { remove(vars, name); } public Map varMap() { return vars; } final public void initMap() { makeThreadSafe(); } public void makeThreadSafe() { if (vars == null) vars = syncHashMap(); } } static public class Matches { public String[] m; public Matches() { } public Matches(String... m) { this.m = m; } public String get(int i) { return i < m.length ? m[i] : null; } public String unq(int i) { return unquote(get(i)); } public String tlc(int i) { return unq(i).toLowerCase(); } public boolean bool(int i) { return "true".equals(unq(i)); } public String rest() { return m[m.length - 1]; } public int psi(int i) { return Integer.parseInt(unq(i)); } public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; } public int hashCode() { return _hashCode(toList(m)); } public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); } } 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 IMeta { public void _setMeta(Object meta); public Object _getMeta(); default public IAutoCloseableF0 _tempMetaMutex() { return new IAutoCloseableF0() { public Object get() { return IMeta.this; } public void close() { } }; } default public Object getMeta(Object obj, Object key) { return metaGet(obj, key); } default public Object metaGet(Object obj, Object key) { return metaMapGet(obj, key); } default public Object metaGet(String key, Object obj) { return metaMapGet(obj, key); } default public Object getMeta(Object key) { return metaGet(key); } default public Object metaGet(Object key) { if (key == null) return null; Object meta = _getMeta(); if (meta instanceof Map) return ((Map) meta).get(key); return null; } default public void metaSet(IMeta obj, Object key, Object value) { metaPut(obj, key, value); } default public void metaPut(IMeta obj, Object key, Object value) { metaMapPut(obj, key, value); } default public void metaSet(Object key, Object value) { metaPut(key, value); } default public void metaPut(Object key, Object value) { if (key == null) return; Map map = convertObjectMetaToMap(this); syncMapPutOrRemove(map, key, value); } } 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 G22NetworkInstance implements IFieldsToList { public boolean _isTransient() { return true; } public G22Network network; public G22NetworkInstance() { } public G22NetworkInstance(G22Network network) { this.network = network; } public Object[] _fieldsToList() { return new Object[] { network }; } public Map valuesByIdentifier = new HashMap(); public Map valuesByBlueprint = new HashMap(); transient public Set onDirtyStatesChanged; public G22NetworkInstance onDirtyStatesChanged(Runnable r) { onDirtyStatesChanged = createOrAddToSyncLinkedHashSet(onDirtyStatesChanged, r); return this; } public G22NetworkInstance removeDirtyStatesChangedListener(Runnable r) { main.remove(onDirtyStatesChanged, r); return this; } public void dirtyStatesChanged() { if (onDirtyStatesChanged != null) for (var listener : onDirtyStatesChanged) pcallF_typed(listener); } static public class Value { final public Value setObject(Object object) { return object(object); } public Value object(Object object) { this.object = object; return this; } final public Object getObject() { return object(); } public Object object() { return object; } public Object object; final public Value setCalculatedWhen(Timestamp calculatedWhen) { return calculatedWhen(calculatedWhen); } public Value calculatedWhen(Timestamp calculatedWhen) { this.calculatedWhen = calculatedWhen; return this; } final public Timestamp getCalculatedWhen() { return calculatedWhen(); } public Timestamp calculatedWhen() { return calculatedWhen; } public Timestamp calculatedWhen; final public Value setDirty(boolean dirty) { return dirty(dirty); } public Value dirty(boolean dirty) { this.dirty = dirty; return this; } final public boolean getDirty() { return dirty(); } public boolean dirty() { return dirty; } volatile public boolean dirty = false; final public Value setCalculating(boolean calculating) { return calculating(calculating); } public Value calculating(boolean calculating) { this.calculating = calculating; return this; } final public boolean getCalculating() { return calculating(); } public boolean calculating() { return calculating; } volatile public boolean calculating = false; final public Value setError(Throwable error) { return error(error); } public Value error(Throwable error) { this.error = error; return this; } final public Throwable getError() { return error(); } public Throwable error() { return error; } volatile public Throwable error; public Object get() { return object; } public String toString() { return classNameWithIdentity(this) + ": " + object; } public boolean hasError() { return error != null; } } public void calculateNode(G22Utils g22utils, G22NetworkElement e) { if (e == null) return; Value value = valueForBlueprint(e); value.calculating(true); try { dirtyStatesChanged(); Object instance = e.makeInstance(g22utils, this); print("Calculated: " + instance); value.error(null); setObject(e, value, instance); } catch (Throwable exception) { printStackTrace(exception); value.error(exception); value.dirty(false); } finally { value.calculating(false); dirtyStatesChanged(); } } public void setObject(G22NetworkElement e, Value value, Object instance) { value.object(instance).calculatedWhen(tsNow()); if (value.dirty()) { value.dirty(false); dirtyStatesChanged(); } invalidateDependentNodes(e); } public void init(G22Utils g22utils) { for (var e : network.elements) { Value value = new Value(); value.dirty(true); dirtyStatesChanged(); valuesByBlueprint.put(e, value); mapPut(valuesByIdentifier, e.identifier(), value); } } public Object getObjectForBlueprint(G22NetworkElement element) { var value = valueForBlueprint(element); Object object = value.get(); printVars("getObjectForBlueprint", "element", element, "value", value, "object", object); return object; } public void invalidateDependentNodes(G22NetworkElement element) { if (element == null) return; print("invalidateDependentNodes", element); for (var e : element.downstreamNodes()) invalidateNode(e); } public boolean isCalculable(G22NetworkElement element) { return all(element.upstreamNodes(), e -> !isDirty(e)); } public Value valueForBlueprint(G22NetworkElement element) { return syncGetOrCreate(valuesByBlueprint, element, () -> new Value()); } public boolean isDirty(G22NetworkElement element) { return valueForBlueprint(element).dirty(); } public void invalidateNode(G22NetworkElement element) { print("invalidateNode", element); var value = valueForBlueprint(element); if (value.dirty()) return; value.dirty(true); dirtyStatesChanged(); invalidateDependentNodes(element); } public G22NetworkElement calculateOneNode(G22Utils g22utils) { var calculableElements = filter(e -> isDirty(e) && isCalculable(e), keys(valuesByBlueprint)); var e = random(calculableElements); calculateNode(g22utils, e); return e; } } static public class MultiMap implements IMultiMap { 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); } } } final public Set keys() { return keySet(); } public Set keySet() { 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); } } public interface IHasChangeListeners { public IHasChangeListeners onChange(Runnable r); public IHasChangeListeners removeChangeListener(Runnable r); default public IHasChangeListeners onChangeAndNow(Runnable l) { onChange(l); callF(l); return this; } } 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 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(); } } 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 public class JG22Network implements Swingable { public G22Utils g22utils; public MainPanel mainPanel = new MainPanel(); public G22Network network = new G22Network(); public Map elementToComponent = syncMap(); public ReliableSingleThread rstUpdate = rstWithPreDelay(0.25, () -> updateImpl()); public JCheckBox cbAutoCalculate; final public JG22Network setMaxMagneticDistance(int maxMagneticDistance) { return maxMagneticDistance(maxMagneticDistance); } public JG22Network maxMagneticDistance(int maxMagneticDistance) { this.maxMagneticDistance = maxMagneticDistance; return this; } final public int getMaxMagneticDistance() { return maxMagneticDistance(); } public int maxMagneticDistance() { return maxMagneticDistance; } public int maxMagneticDistance = 100; final public JG22Network setAutoCalcInterval(double autoCalcInterval) { return autoCalcInterval(autoCalcInterval); } public JG22Network autoCalcInterval(double autoCalcInterval) { this.autoCalcInterval = autoCalcInterval; return this; } final public double getAutoCalcInterval() { return autoCalcInterval(); } public double autoCalcInterval() { return autoCalcInterval; } public double autoCalcInterval = 0.1; final public JG22Network setNetworkInstance(G22NetworkInstance networkInstance) { return networkInstance(networkInstance); } public JG22Network networkInstance(G22NetworkInstance networkInstance) { this.networkInstance = networkInstance; return this; } final public G22NetworkInstance getNetworkInstance() { return networkInstance(); } public G22NetworkInstance networkInstance() { return networkInstance; } volatile public G22NetworkInstance networkInstance; transient public int margin = 50; public class MainPanel extends JPanel { public MainPanel() { super(null); } public boolean isOptimizedDrawingEnabled() { return false; } public Dimension getPreferredSize() { Rect r = combinedChildBounds(this); if (r == null) r = rect(0, 0, 0, 0); return new Dimension(r.x2() + margin, r.y2() + margin); } public void revalidateMe() { revalidateIncludingFullCenterContainer(this); repaint(); } public void paintComponent(Graphics g) { fillRect(((Graphics2D) g), 0, 0, getWidth(), getHeight(), Color.white); for (var cable : network.allCables()) { Rect r1 = cable.from.bounds(); Rect r2 = cable.to.bounds(); drawLine(((Graphics2D) g), center(r1), center(r2), Color.black); } } } public JG22Network(G22Utils g22utils, G22Network network) { this.network = network; this.g22utils = g22utils; network.onChangeAndNow(() -> networkChanged()); for (var element : network.elements) visualizeElement(element); } public void networkChanged() { rstUpdate.trigger(); } public void updateImpl() { if (networkInstance == null) makeInstance(); visualizePorts(); } public void visualizePorts() { swingLater(new Runnable() { public void run() { try { Map visualizations = new HashMap(); for (var port : directChildrenOfType(mainPanel, JG22NetworkPort.class)) visualizations.put(port.port, port); for (var e : network.elements) { var c = elementToComponent.get(e); if (c == null) print("No component for " + e); else for (var port : e.ports) { var p = visualizations.get(port); if (p != null) { p.update(); visualizations.remove(port); } else { p = new JG22NetworkPort(g22utils, c, port); p.init(); mainPanel.add(p); } } } for (var port : values(visualizations)) removeFromParent(port); mainPanel.repaint(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Map visualizations = new Map;\r\n f..."; } }); } public void makeInstance() { var networkInstance = new G22NetworkInstance(network); networkInstance.onDirtyStatesChanged(() -> dirtyStatesChanged()); networkInstance.init(g22utils); networkInstance(networkInstance); dirtyStatesChanged(); print("Network instance made"); } public void dirtyStatesChanged() { for (var component : values(elementToComponent)) component.updateDirtyFlag(); } public void visualizeElement(G22NetworkElement element) { swing(() -> { var c = new JG22NetworkElement(g22utils, this, element); elementToComponent.put(element, c); var component = c.visualize(); mainPanel.add(component); mainPanel.revalidateMe(); componentToFront(component); }); } public void newInstance() { networkInstance = null; rstUpdate.trigger(); } public void newElement() { G22NetworkElement element = new G22NetworkElement(); element.network(network); network.elements.add(element); network.change(); visualizeElement(element); } public void deleteElement(JG22NetworkElement element) { network.elements.remove(element.element); network.change(); mainPanel.remove(element.visualize()); mainPanel.repaint(); } public void doMagneticConnections() { var newCables = network.doMagneticConnections(); for (var cable : unnullForIteration(newCables)) networkInstance.invalidateNode(cable.to().element()); mainPanel.repaint(); } public void configureNodes() { for (var element : network.elements) element.configureBlueprint(g22utils); } public void calculationStep() { var node = networkInstance == null ? null : networkInstance.calculateOneNode(g22utils); if (node == null) return; elementToComponent.get(node).visualizeNode(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { cbAutoCalculate = jVarCheckBox("Auto-calculate", network.varAutoCalculate()); awtCalcEvery(mainPanel, autoCalcInterval, () -> { if (isChecked(cbAutoCalculate)) calculationStep(); }); var magneticDistanceSlider = jLiveValueSlider_int_bothWays(0, maxMagneticDistance, network.varMagneticDistance()); return withRightAlignedButtons(jscroll(mainPanel), cbAutoCalculate, withLabel("Magnetic auto-connect distance:", jMinWidth(maxMagneticDistance, magneticDistanceSlider)), "Do magnetic connections", runnableThread(new Runnable() { public void run() { try { doMagneticConnections(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "doMagneticConnections();"; } }), "Configure nodes", runnableThread(new Runnable() { public void run() { try { configureNodes(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "configureNodes();"; } }), "New instance", runnableThread(new Runnable() { public void run() { try { newInstance(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newInstance();"; } }), "New node", runnableThread(new Runnable() { public void run() { try { newElement(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newElement();"; } })); } } static public class ChangeTrigger implements Runnable, IFieldsToList { public ChangeTriggerable target; public ChangeTrigger() { } public ChangeTrigger(ChangeTriggerable target) { this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ")"; } public boolean equals(Object o) { if (!(o instanceof ChangeTrigger)) return false; ChangeTrigger __1 = (ChangeTrigger) o; return eq(target, __1.target); } public int hashCode() { int h = -1239972920; h = boostHashCombine(h, _hashCode(target)); return h; } public Object[] _fieldsToList() { return new Object[] { target }; } public void run() { try { { if (target != null) target.change(); } } catch (Exception __e) { throw rethrow(__e); } } } static public class Pair implements Comparable> { final public Pair setA(A a) { return a(a); } public Pair a(A a) { this.a = a; return this; } final public A getA() { return a(); } public A a() { return a; } public A a; final public Pair setB(B b) { return b(b); } public Pair b(B b) { this.b = b; return this; } final public B getB() { return b(); } public B b() { return b; } 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 interface IResourceHolder { public A add(A a); public Collection takeAll(); } static public interface Swingable { public JComponent visualize(); } public interface ChangeTriggerable { public void change(); } static public class BetterLabel extends JLabel { public boolean autoToolTip = true; public BetterLabel() { final WeakReference me = new WeakReference<>(this); componentPopupMenu(this, BetterLabel_menuItems(me)); } public BetterLabel(String text) { this(); this.setText(text); } public void setText(String text) { super.setText(text); if (autoToolTip) if (!swic(text, "")) setToolTipText(nullIfEmpty(text)); } } static public VF1 BetterLabel_menuItems(final WeakReference me) { return new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, "Copy text to clipboard", new Runnable() { public void run() { try { copyTextToClipboard(me.get().getText()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyTextToClipboard(me.get().getText());"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, \"Copy text to clipboard\", r {\r\n copyTextToClipboard(me..."; } }; } static public class G22JavaObjectVisualizer implements Swingable, IFieldsToList { public G22Utils g22utils; public G22JavaObjectVisualizer() { } public G22JavaObjectVisualizer(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } final public G22JavaObjectVisualizer setWithTypeAndTime(boolean withTypeAndTime) { return withTypeAndTime(withTypeAndTime); } public G22JavaObjectVisualizer withTypeAndTime(boolean withTypeAndTime) { this.withTypeAndTime = withTypeAndTime; return this; } final public boolean getWithTypeAndTime() { return withTypeAndTime(); } public boolean withTypeAndTime() { return withTypeAndTime; } public boolean withTypeAndTime = true; final public G22JavaObjectVisualizer setSingleLineLayout(boolean singleLineLayout) { return singleLineLayout(singleLineLayout); } public G22JavaObjectVisualizer singleLineLayout(boolean singleLineLayout) { this.singleLineLayout = singleLineLayout; return this; } final public boolean getSingleLineLayout() { return singleLineLayout(); } public boolean singleLineLayout() { return singleLineLayout; } public boolean singleLineLayout = false; final public G22JavaObjectVisualizer setMaxElements(int maxElements) { return maxElements(maxElements); } public G22JavaObjectVisualizer maxElements(int maxElements) { this.maxElements = maxElements; return this; } final public int getMaxElements() { return maxElements(); } public int maxElements() { return maxElements; } public int maxElements = 1000; final public G22JavaObjectVisualizer setHorizontal(boolean horizontal) { return horizontal(horizontal); } public G22JavaObjectVisualizer horizontal(boolean horizontal) { this.horizontal = horizontal; return this; } final public boolean getHorizontal() { return horizontal(); } public boolean horizontal() { return horizontal; } public boolean horizontal = false; final public G22JavaObjectVisualizer setFloatingPointDigits(int floatingPointDigits) { return floatingPointDigits(floatingPointDigits); } public G22JavaObjectVisualizer floatingPointDigits(int floatingPointDigits) { this.floatingPointDigits = floatingPointDigits; return this; } final public int getFloatingPointDigits() { return floatingPointDigits(); } public int floatingPointDigits() { return floatingPointDigits; } public int floatingPointDigits = 4; public Set seen = identityHashSet(); final public G22JavaObjectVisualizer setObject(Object object) { return object(object); } public G22JavaObjectVisualizer object(Object object) { this.object = object; return this; } final public Object getObject() { return object(); } public Object object() { return object; } transient public Object object; final public G22JavaObjectVisualizer setNanos(long nanos) { return nanos(nanos); } public G22JavaObjectVisualizer nanos(long nanos) { this.nanos = nanos; return this; } final public long getNanos() { return nanos(); } public long nanos() { return nanos; } transient public long nanos = -1; public G22JavaObjectVisualizer(G22Utils g22utils, Object object) { this.object = object; this.g22utils = g22utils; } public String objectInfos() { List infos = new ArrayList(); infos.add(str(shortClassName(object))); for (var __0 : _entrySet(mainVisualizer().properties)) { var key = __0.getKey(); var val = __0.getValue(); String s = n2OrStrOrNull(val); if (nempty(s)) infos.add(key + " " + s); } if (nanos >= 0) { String timeDesc = nanos < 0 ? "" : formatElapsedTimeWithAppropriateUnit(nanosToSeconds(nanos)); infos.add(timeDesc); } return joinNemptiesWithComma(infos); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { printVars("Visualizing", "this", this, "withTypeAndTime", withTypeAndTime); JComponent c = visualizeObject(object); if (withTypeAndTime) { String type = objectInfos(); c = northAndCenterWithMargins(withLabel("Type:", jlabel(type)), c); } return c; } public JComponent visualizeObject(Object object) { return mainVisualizer().visualize(object); } public ObjectVisualizer mainVisualizer_cache; public ObjectVisualizer mainVisualizer() { if (mainVisualizer_cache == null) mainVisualizer_cache = mainVisualizer_load(); return mainVisualizer_cache; } public ObjectVisualizer mainVisualizer_load() { return new ObjectVisualizer().recurse(true).bigFont(true).horizontal(horizontal); } public class ObjectVisualizer { final public ObjectVisualizer setRecurse(boolean recurse) { return recurse(recurse); } public ObjectVisualizer recurse(boolean recurse) { this.recurse = recurse; return this; } final public boolean getRecurse() { return recurse(); } public boolean recurse() { return recurse; } public boolean recurse = false; final public ObjectVisualizer setBigFont(boolean bigFont) { return bigFont(bigFont); } public ObjectVisualizer bigFont(boolean bigFont) { this.bigFont = bigFont; return this; } final public boolean getBigFont() { return bigFont(); } public boolean bigFont() { return bigFont; } public boolean bigFont = false; final public ObjectVisualizer setHorizontal(boolean horizontal) { return horizontal(horizontal); } public ObjectVisualizer horizontal(boolean horizontal) { this.horizontal = horizontal; return this; } final public boolean getHorizontal() { return horizontal(); } public boolean horizontal() { return horizontal; } public boolean horizontal = false; public LinkedHashMap properties = new LinkedHashMap(); public ObjectVisualizer subVisualizer() { return new ObjectVisualizer().horizontal(!horizontal); } public JComponent makeBig(JComponent c) { if (bigFont) return fontSizePlus(10, c); return c; } public JComponent visualize(Object object) { try { return visualize2(object); } catch (Throwable e) { return jErrorView(new RuntimeException("Visualization error", e)); } } public JComponent visualize2(Object object) { if (object instanceof Throwable) return jErrorView((Throwable) object); if (object == null || eq(object, "")) return jpanel(); if (object instanceof Swingable) object = ((Swingable) object).visualize(); if (object instanceof JComponent && getParent((JComponent) object) == null) return ((JComponent) object); if (object instanceof Integer) object = toLong((Integer) object); if (object instanceof Long) return bigText(n2((Long) object)); if (object instanceof Double) return toolTip(str((Double) object), bigText(formatDouble(((Double) object), floatingPointDigits))); if (object instanceof Number) return bigText((Number) object); if (object instanceof Pair) { if (horizontal) return jcenteredline(jlabel("<"), visualize(((Pair) object).a), jlabel(","), visualize(((Pair) object).b), jlabel(">")); else return vstackWithSpacing(visualize(((Pair) object).a), visualize(((Pair) object).b)); } if (object instanceof MakesBufferedImage) object = toBufferedImage((MakesBufferedImage) object); if (object instanceof BufferedImage) { var is = g22utils.stdImageSurface((BufferedImage) object); if (!recurse) is.setAutoZoomToDisplay(false); return jscroll_centered_borderless(is); } if (recurse) { if (object instanceof MultiMap) { propertyLength(l((MultiMap) object)); propertyKeyCount(((MultiMap) object).keyCount()); object = multiMapToMapPairs((MultiMap) object); } if (object instanceof MultiSetMap) { propertyLength(l((MultiSetMap) object)); propertyKeyCount(((MultiSetMap) object).keyCount()); object = multiSetMapToMapPairs((MultiSetMap) object); } if (object instanceof Map) { propertyLength(l((Map) object)); object = mapToPairs((Map) object); } if (isArray(object)) { object = wrapArrayAsImmutableList(object); } if (object instanceof Collection) { propertyLength(l((Collection) object)); var sub = subVisualizer(); var elements = map(cloneTakeFirst(maxElements, ((Collection) object)), element -> sub.visualize(element)); return jscroll_centered_borderless(horizontal ? hstackWithSpacing(elements) : vstackWithSpacing(elements)); } } if (object instanceof String) { propertyLength(l((String) object)); } String string = str(object); if (containsNewLine(string)) return jscroll_borderless(wordWrapTypeWriterTextArea(string)); var lbl = jcenterNarrowLabel(shorten(string)); if (l(string) <= 10) return makeBig(lbl); return lbl; } public void propertyLength(int l) { properties.put("size", l); } public void propertyKeyCount(int l) { properties.put("keys", l); } public JComponent bigText(Object o) { return makeBig(jcenteredLabel(str(o))); } } } 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 PersistableThrowable extends DynamicObject { public String className; public String msg; public String stacktrace; public PersistableThrowable() { } public PersistableThrowable(Throwable e) { if (e == null) className = "Crazy Null Error"; else { className = getClassName(e).replace('/', '.'); msg = e.getMessage(); stacktrace = getStackTrace_noRecord(e); } } public String toString() { return nempty(msg) ? className + ": " + msg : className; } public RuntimeException asRuntimeException() { return new Fail(this); } } static public class ComponentDragger extends MouseAdapter implements IFieldsToList { public ComponentDragger() { } public String toString() { return shortClassName_dropNumberPrefix(this); } public Object[] _fieldsToList() { return null; } public Component component; public MouseEvent mouseDownEvent; public Component clickedOn; public Pt rel; final public ComponentDragger setDebug(boolean debug) { return debug(debug); } public ComponentDragger debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug() { return debug(); } public boolean debug() { return debug; } public boolean debug = false; final public ComponentDragger setBringToFront(boolean bringToFront) { return bringToFront(bringToFront); } public ComponentDragger bringToFront(boolean bringToFront) { this.bringToFront = bringToFront; return this; } final public boolean getBringToFront() { return bringToFront(); } public boolean bringToFront() { return bringToFront; } public boolean bringToFront = false; public ComponentDragger(Component component, MouseEvent mouseDownEvent) { this.mouseDownEvent = mouseDownEvent; this.component = component; } public void start() { if (mouseDownEvent == null) return; clickedOn = mouseDownEvent.getComponent(); if (bringToFront) { print("Bringing to front: " + component); componentToFront(component); repaint(getParent(component)); } rel = pt(mouseDownEvent.getXOnScreen() - component.getX(), mouseDownEvent.getYOnScreen() - component.getY()); addMouseAndMotionListener(clickedOn, this); } public void mouseDragged(MouseEvent e) { updatePosition(e); } public void mouseReleased(MouseEvent e) { if (e.getButton() != mouseDownEvent.getButton()) return; updatePosition(e); removeMouseAdapter(clickedOn, this); if (debug) printVars("ComponentDragger done"); dragDone(); } public void updatePosition(MouseEvent e) { int x = e.getXOnScreen() - rel.x, y = e.getYOnScreen() - rel.y; x = max(x, 0); y = max(y, 0); updatePosition(x, y); } transient public IVF2 updatePosition; public void updatePosition(int x, int y) { if (updatePosition != null) updatePosition.get(x, y); else updatePosition_base(x, y); } final public void updatePosition_fallback(IVF2 _f, int x, int y) { if (_f != null) _f.get(x, y); else updatePosition_base(x, y); } public void updatePosition_base(int x, int y) { if (debug) printVars("ComponentDragger", "rel", rel, "x", x, "y", y); component.setLocation(x, y); } public void dragDone() { } } static public class LASValueDescriptor { public LASValueDescriptor() { } public boolean knownValue() { return false; } public Object value() { return null; } public Class javaClass() { return null; } public boolean javaClassIsExact() { return false; } public boolean canBeNull() { return true; } public boolean canFail() { return false; } public boolean willFail() { return false; } static public class Exact extends LASValueDescriptor implements IFieldsToList { public Class c; public boolean canBeNull = false; public Exact() { } public Exact(Class c, boolean canBeNull) { this.canBeNull = canBeNull; this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ", " + canBeNull + ")"; } public boolean equals(Object o) { if (!(o instanceof Exact)) return false; Exact __1 = (Exact) o; return eq(c, __1.c) && eq(canBeNull, __1.canBeNull); } public int hashCode() { int h = 67394271; h = boostHashCombine(h, _hashCode(c)); h = boostHashCombine(h, _hashCode(canBeNull)); return h; } public Object[] _fieldsToList() { return new Object[] { c, canBeNull }; } public Class javaClass() { return c; } public boolean javaClassIsExact() { return true; } public boolean canBeNull() { return canBeNull; } } static public class NonExact extends LASValueDescriptor implements IFieldsToList { public Class c; public boolean canBeNull = false; public NonExact() { } public NonExact(Class c, boolean canBeNull) { this.canBeNull = canBeNull; this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ", " + canBeNull + ")"; } public boolean equals(Object o) { if (!(o instanceof NonExact)) return false; NonExact __2 = (NonExact) o; return eq(c, __2.c) && eq(canBeNull, __2.canBeNull); } public int hashCode() { int h = 1445514322; h = boostHashCombine(h, _hashCode(c)); h = boostHashCombine(h, _hashCode(canBeNull)); return h; } public Object[] _fieldsToList() { return new Object[] { c, canBeNull }; } public Class javaClass() { return c; } public boolean javaClassIsExact() { return false; } public boolean canBeNull() { return canBeNull; } } static public LASValueDescriptor nonExactCanBeNull(Type c) { return new NonExact(typeToClass(c), true); } static public class KnownValue extends LASValueDescriptor implements IFieldsToList { public Object value; public KnownValue() { } public KnownValue(Object value) { this.value = value; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + value + ")"; } public boolean equals(Object o) { if (!(o instanceof KnownValue)) return false; KnownValue __3 = (KnownValue) o; return eq(value, __3.value); } public int hashCode() { int h = -1456305138; h = boostHashCombine(h, _hashCode(value)); return h; } public Object[] _fieldsToList() { return new Object[] { value }; } public boolean knownValue() { return true; } public Object value() { return value; } public Class javaClass() { return value == null ? null : value.getClass(); } public boolean javaClassIsExact() { return value != null; } public boolean canBeNull() { return value == null; } } static public class WillFail extends LASValueDescriptor { public boolean canFail() { return true; } public boolean willFail() { return true; } } static public LASValueDescriptor fromClass(Class c) { return new NonExact(c, true); } } static public class LASCompileResult { final public LASCompileResult setScript(String script) { return script(script); } public LASCompileResult script(String script) { this.script = script; return this; } final public String getScript() { return script(); } public String script() { return script; } public String script; final public LASCompileResult setParser(GazelleV_LeftArrowScriptParser parser) { return parser(parser); } public LASCompileResult parser(GazelleV_LeftArrowScriptParser parser) { this.parser = parser; return this; } final public GazelleV_LeftArrowScriptParser getParser() { return parser(); } public GazelleV_LeftArrowScriptParser parser() { return parser; } public GazelleV_LeftArrowScriptParser parser; final public LASCompileResult setCompileError(Throwable compileError) { return compileError(compileError); } public LASCompileResult compileError(Throwable compileError) { this.compileError = compileError; return this; } final public Throwable getCompileError() { return compileError(); } public Throwable compileError() { return compileError; } public Throwable compileError; public GazelleV_LeftArrowScript.Script parsedScript; public RunResultWithTimestamps compileLog; public String toString() { if (compileError != null) return errorToString(); if (parsedScript == null) return "Not compiled yet"; return "Compiled OK" + (compileLog == null ? "" : " in " + n2(max(1, compileLog.duration().toMillis())) + " ms"); } public String errorToString() { return exceptionToStringShorter_dontDropOuterExceptions(compileError); } public boolean runnable() { return parsedScript != null; } public void compile() { compileLog = runResultWithTimestamps_dontPrintStackTrace(() -> { if (parser == null) parser = makeParser(); return parsedScript = parser.parse(script); }); if (compileLog.isError()) { var e = compileLog.getError(); compileError(e); } } final public GazelleV_LeftArrowScript.Script get() { return parsedScript(); } public GazelleV_LeftArrowScript.Script parsedScript() { return parsedScript; } public GazelleV_LeftArrowScript.Script parsedScriptMandatory() { if (compileError != null) throw fail(compileError); return parsedScript; } transient public IF0 makeParser; public GazelleV_LeftArrowScriptParser makeParser() { return makeParser != null ? makeParser.get() : makeParser_base(); } final public GazelleV_LeftArrowScriptParser makeParser_fallback(IF0 _f) { return _f != null ? _f.get() : makeParser_base(); } public GazelleV_LeftArrowScriptParser makeParser_base() { return null; } public LineAndColumn errorLineAndCol() { return parseLineAndColumn(str(compileError)); } } public interface IF0WithChangeListeners extends IF0, IHasChangeListeners { } static public class ClassNameResolver { final public ClassNameResolver setByteCodePath(File byteCodePath) { return byteCodePath(byteCodePath); } public ClassNameResolver byteCodePath(File byteCodePath) { this.byteCodePath = byteCodePath; return this; } final public File getByteCodePath() { return byteCodePath(); } public File byteCodePath() { return byteCodePath; } public File byteCodePath = byteCodePathForClass(getClass()); public List importedPackages = itemPlusList("java.lang", endingWith_dropSuffix(standardImports(), ".*")); public Set allFullyQualifiedClassNames_cache; public Set allFullyQualifiedClassNames() { if (allFullyQualifiedClassNames_cache == null) allFullyQualifiedClassNames_cache = allFullyQualifiedClassNames_load(); return allFullyQualifiedClassNames_cache; } public Set allFullyQualifiedClassNames_load() { Set set = new HashSet(); assertNotNull(byteCodePath); set.addAll(classNamesInJarOrDir(byteCodePath)); printVars("ClassNameResolver", "byteCodePath", byteCodePath, "classesFound", l(set)); set.addAll(classNamesInLoadedJigsawModules()); return set; } public ClassNameResolver init() { allFullyQualifiedClassNames(); return this; } public String findClass(String name) { for (String pkg : importedPackages) { String fullName = pkg + "." + name; if (allFullyQualifiedClassNames().contains(fullName)) return fullName; } return null; } public void printMe() { printVars("ClassNameResolver", "byteCodePath", byteCodePath); print("importedPackages", importedPackages); } } static public class G22ProjectInfo extends Concept { static final public String _fieldOrder = "projectID projectDir historicalProjectDirs useFirefox"; final public String getProjectID() { return projectID(); } public String projectID() { return projectID; } public String projectID = aGlobalID(); public File projectDir; public List historicalProjectDirs = new ArrayList(); final public boolean getUseFirefox() { return useFirefox(); } public boolean useFirefox() { return useFirefox; } public boolean useFirefox = false; public void addHistoricalProjectDir(File dir) { if (syncSetAdd(historicalProjectDirs, dir)) change(); } } public interface G22ProjectActions { public void openObjectInProject(long id); public void openPathInProject(String path); public void editProjectStory(); public void editScripts(); } static public class ImageSurface extends Surface { public BufferedImage image; public double zoomX = 1, zoomY = 1, zoomFactor = 1.5; public Rectangle selection; public List tools = new ArrayList(); public Object overlay; public List overlays = syncL(); public Runnable onSelectionChange; final public ImageSurface setVerbose(boolean verbose) { return verbose(verbose); } public ImageSurface verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; public boolean noMinimumSize = true; public String titleForUpload; public Object onZoom; public boolean specialPurposed = false; final public ImageSurface setAllowPaste(boolean allowPaste) { return allowPaste(allowPaste); } public ImageSurface allowPaste(boolean allowPaste) { this.allowPaste = allowPaste; return this; } final public boolean getAllowPaste() { return allowPaste(); } public boolean allowPaste() { return allowPaste; } public boolean allowPaste = false; final public ImageSurface setZoomable(boolean zoomable) { return zoomable(zoomable); } public ImageSurface zoomable(boolean zoomable) { this.zoomable = zoomable; return this; } final public boolean getZoomable() { return zoomable(); } public boolean zoomable() { return zoomable; } public boolean zoomable = true; public boolean noAlpha = false; public Object interpolationMode = RenderingHints.VALUE_INTERPOLATION_BILINEAR; public Object onNewImage; public BufferedImage imageToDraw; public File file; public boolean autoZoomToDisplay = false; final public ImageSurface setRepaintInThread(boolean repaintInThread) { return repaintInThread(repaintInThread); } public ImageSurface repaintInThread(boolean repaintInThread) { this.repaintInThread = repaintInThread; return this; } final public boolean getRepaintInThread() { return repaintInThread(); } public boolean repaintInThread() { return repaintInThread; } public boolean repaintInThread = false; public BoolVar showingVar; public Pt mousePosition; transient public Set onMousePositionChanged; public ImageSurface onMousePositionChanged(Runnable r) { onMousePositionChanged = createOrAddToSyncLinkedHashSet(onMousePositionChanged, r); return this; } public ImageSurface removeMousePositionChangedListener(Runnable r) { main.remove(onMousePositionChanged, r); return this; } public void mousePositionChanged() { if (onMousePositionChanged != null) for (var listener : onMousePositionChanged) pcallF_typed(listener); } transient public Set onImageChanged; public ImageSurface onImageChanged(Runnable r) { onImageChanged = createOrAddToSyncLinkedHashSet(onImageChanged, r); return this; } public ImageSurface removeImageChangedListener(Runnable r) { main.remove(onImageChanged, r); return this; } public void imageChanged() { if (onImageChanged != null) for (var listener : onImageChanged) pcallF_typed(listener); } transient public Set> onUserModifiedImage; public ImageSurface onUserModifiedImage(IVF1 f) { onUserModifiedImage = createOrAddToSyncLinkedHashSet(onUserModifiedImage, f); return this; } public ImageSurface removeUserModifiedImageListener(IVF1 f) { main.remove(onUserModifiedImage, f); return this; } public void userModifiedImage(BufferedImage image) { if (onUserModifiedImage != null) for (var listener : onUserModifiedImage) pcallF_typed(listener, image); } public ImageSurface() { this(dummyImage()); } static public BufferedImage dummyImage() { return whiteImage(1); } public ImageSurface(MakesBufferedImage image) { this(image != null ? image.getBufferedImage() : dummyImage()); } public ImageSurface(BufferedImage image) { setImage(image); clearSurface = false; onResize(this, () -> performAutoZoom()); bindToComponent(this, () -> performAutoZoom(), null); componentPopupMenu2(this, ImageSurface_popupMenuMaker()); new ImageSurfaceSelector(this); jHandleFileDrop(this, new VF1() { public void get(File f) { try { setImage(loadBufferedImage(f)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setImage(loadBufferedImage(f))"; } }); imageSurfaceOnHover(this, p -> { mousePosition = p; mousePositionChanged(); }); } public ImageSurface(RGBImage image, double zoom) { this(image); setZoom(zoom); } public void fillPopupMenu(JPopupMenu menu, final Point point) { if (zoomable) { JMenuItem miZoomReset = new JMenuItem("Zoom 100%"); miZoomReset.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { setZoom(1.0); centerPoint(point); } }); menu.add(miZoomReset); JMenuItem miZoomIn = new JMenuItem("Zoom in"); miZoomIn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { zoomIn(zoomFactor); centerPoint(point); } }); menu.add(miZoomIn); JMenuItem miZoomOut = new JMenuItem("Zoom out"); miZoomOut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { zoomOut(zoomFactor); centerPoint(point); } }); menu.add(miZoomOut); menu.add(jMenuItemStayCheckedOnClick("Zoom to window", () -> autoZoomToDisplay, () -> setAutoZoomToDisplay(true))); addMenuItem(menu, "Show full screen", new Runnable() { public void run() { try { showFullScreen(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showFullScreen()"; } }); addMenuItem(menu, "Point: " + point.x + "," + point.y + " (image: " + w() + "*" + h() + ")", null); menu.addSeparator(); } if (!specialPurposed) addMenuItem(menu, "Load image...", new Runnable() { public void run() { try { selectFile("Load image", new VF1() { public void get(File f) { try { setImage(loadImage2(f)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setImage(loadImage2(f))"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectFile(\"Load image\",\r\n new VF1() { public void get(File f) c..."; } }); addMenuItem(menu, "Save image...", new Runnable() { public void run() { try { saveImage(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveImage()"; } }); addMenuItem(menu, "Copy image to clipboard", new Runnable() { public void run() { try { copyImageToClipboard(getImage()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyImageToClipboard(getImage())"; } }); if (!specialPurposed || allowPaste) addMenuItem(menu, "Paste image from clipboard", new Runnable() { public void run() { try { loadFromClipboard(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "loadFromClipboard()"; } }); if (!specialPurposed) addMenuItem(menu, "Load image snippet...", new Runnable() { public void run() { try { selectImageSnippet(new VF1() { public void get(String imageID) { try { setImage(loadImage2(imageID)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setImage(loadImage2(imageID))"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectImageSnippet(new VF1() { public void get(String imageID) ctex {..."; } }); if (selection != null) addMenuItem(menu, "Crop", new Runnable() { public void run() { try { crop(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "crop()"; } }); if (!specialPurposed) addMenuItem(menu, "No image", new Runnable() { public void run() { try { noImage(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "noImage()"; } }); } public void noImage() { setImage((BufferedImage) null); } public void crop() { if (selection == null) return; BufferedImage img = cloneClipBufferedImage(getImage(), selection); selection = null; setUserModifiedImage(img); } public void setUserModifiedImage(BufferedImage img) { setImage(img); userModifiedImage(img); } public void loadFromClipboard() { BufferedImage img = getImageFromClipboard(); if (img != null) setUserModifiedImage(img); } transient public IF0 defaultImageDir; public File defaultImageDir() { return defaultImageDir != null ? defaultImageDir.get() : defaultImageDir_base(); } final public File defaultImageDir_fallback(IF0 _f) { return _f != null ? _f.get() : defaultImageDir_base(); } public File defaultImageDir_base() { return getProgramDir(); } public void saveImage() { var image = getImage(); JFileChooser fileChooser = new JFileChooser(defaultImageDir()); if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { try { main.saveImage(image, file = fileChooser.getSelectedFile()); } catch (Throwable e) { popup(e); } } } public void drawImageItself(int w, int h, Graphics2D g) { int iw = getZoomedWidth(), ih = getZoomedHeight(); if (interpolationMode == RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR || zoomX >= 1 || zoomY >= 1) { g.drawImage(image, 0, 0, iw, ih, null); } else g.drawImage(resizeImage(image, iw, ih), 0, 0, null); } public void render(int w, int h, Graphics2D g) { if (verbose) _print("render"); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationMode); g.setColor(Color.white); BufferedImage image = or(imageToDraw, this.image); if (!hasImage()) g.fillRect(0, 0, w, h); else { boolean alpha = !noAlpha && hasTransparency(image); if (alpha) g.fillRect(0, 0, w, h); drawImageItself(w, h, g); int iw = getZoomedWidth(), ih = getZoomedHeight(); if (!alpha) { g.fillRect(iw, 0, w - iw, h); g.fillRect(0, ih, iw, h - ih); } } if (overlay != null) { if (verbose) _print("render overlay"); pcallF(overlay, g); } for (var overlay : cloneList(overlays)) { try { overlay.drawOn(g); } catch (Throwable __e) { printStackTrace(__e); } } if (selection != null) { if (verbose) _print("render selection"); drawSelectionRect(g, selection, Color.green, Color.white); } } public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white) { drawSelectionRect(g, selection, green, white, zoomX, zoomY); } public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white, double zoomX, double zoomY) { g.setColor(green); int top = (int) (selection.y * zoomY); int bottom = (int) ((selection.y + selection.height) * zoomY); int left = (int) (selection.x * zoomX); int right = (int) ((selection.x + selection.width) * zoomX); g.drawRect(left - 1, top - 1, right - left + 1, bottom - top + 1); g.setColor(white); g.drawRect(left - 2, top - 2, right - left + 3, bottom - top + 3); } public ImageSurface setZoom(double zoom) { setZoom(zoom, zoom); return this; } public void setZoom(double zoomX, double zoomY) { autoZoomToDisplay = false; setZoom_dontChangeAutoZoom(zoomX, zoomY); } public void setZoom_dontChangeAutoZoom(double zoomX) { setZoom_dontChangeAutoZoom(zoomX, zoomX); } public void setZoom_dontChangeAutoZoom(double zoomX, double zoomY) { if (this.zoomX == zoomX && this.zoomY == zoomY) return; if (verbose) _print("Setting zoom"); this.zoomX = zoomX; this.zoomY = zoomY; revalidateMe(); repaint(); centerPoint(new Point(getImage().getWidth() / 2, getImage().getHeight() / 2)); pcallF(onZoom); } public Dimension getMinimumSize() { if (metaGet("scaffolding") != null) scaffoldCalled(this, "getMinimumSize"); if (noMinimumSize) return new Dimension(1, 1); int w = getZoomedWidth(); int h = getZoomedHeight(); Dimension min = super.getMinimumSize(); return printIfScaffoldingEnabled(this, new Dimension(Math.max(w, min.width), Math.max(h, min.height))); } public int getZoomedHeight() { return (int) (h() * zoomY); } public int getZoomedWidth() { return (int) (w() * zoomX); } public boolean isShowing_quick() { if (showingVar == null) { swing(() -> { if (showingVar == null) showingVar = componentShowingVar(ImageSurface.this); }); } return showingVar.get(); } public void setImageIfShowing_thisThread(MakesBufferedImage image) { setImageIfShowing_thisThread(toBufferedImage(image)); } public void setImageIfShowing_thisThread(BufferedImage image) { if (isShowing_quick()) setImage_thisThread(image); } public void setImage(MakesBufferedImage image) { swing(() -> { setImage_thisThread(image); }); } public void setImage(BufferedImage img) { swing(() -> { setImage_thisThread(img); }); } public void setImage_thisThread(MakesBufferedImage img) { setImage_thisThread(toBufferedImage(img)); } public void setImage_thisThread(BufferedImage img) { BufferedImage newImage = img != null ? img : dummyImage(); BufferedImage oldImage = image; image = newImage; if (verbose) print("Old image size:" + imageSize(oldImage) + ", new image size: " + imageSize(newImage)); boolean sameSize = imagesHaveSameSize(oldImage, newImage); if (!sameSize) { if (verbose) _print("New image size"); revalidateMe(); } quickRepaint(); pcallF(onNewImage); if (!sameSize && autoZoomToDisplay) zoomToDisplaySize(); imageChanged(); } public void setImageAndZoomToDisplay(BufferedImage img) { setImage(img); zoomToDisplaySize(); } public BufferedImage getImage() { return image; } public double getZoomX() { return zoomX; } public double getZoomY() { return zoomY; } public Dimension getPreferredSize() { if (metaGet("scaffolding") != null) scaffoldCalled(this, "getPreferredSize"); return printIfScaffoldingEnabled(this, new Dimension(getZoomedWidth(), getZoomedHeight())); } public JScrollPane makeScrollPane() { JScrollPane scrollPane = new JScrollPane(this); scrollPane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); return scrollPane; } public void zoomToWindow() { zoomToDisplaySize(); } public void zoomToDisplaySize() { swing(() -> { if (!hasImage()) return; Dimension display = getDisplaySize(); if (display.width == 0 || display.height == 0) return; int w = w(), h = h(); double xRatio = (display.width - 5) / (double) w; double yRatio = (display.height - 5) / (double) h; if (scaffoldingEnabled(this)) printVars("zoomToDisplaySize", "display", display, "w", w, "h", h, "xRatio", xRatio, "yRatio", yRatio); setZoom_dontChangeAutoZoom(min(xRatio, yRatio)); revalidateMe(); }); } final public Dimension getDisplaySize() { if (metaGet("scaffolding") != null) scaffoldCalled(this, "getDisplaySize"); Container c = getParent(); while (c != null) { if (c instanceof JScrollPane) return c.getSize(); c = c.getParent(); } return getSize(); } public void setSelection(Rect r) { setSelection(toRectangle(r)); } public void setSelection(Rectangle r) { if (neq(selection, r)) { selection = r; pcallF(onSelectionChange); quickRepaint(); } } public Rectangle getSelection() { return selection; } public RGBImage getRGBImage() { return new RGBImage(getImage()); } public void centerPoint(Point p) { JScrollPane sp = enclosingScrollPane(this); if (sp == null) return; p = new Point((int) (p.x * getZoomX()), (int) (p.y * getZoomY())); final JViewport viewport = sp.getViewport(); Dimension viewSize = viewport.getExtentSize(); int x = max(0, p.x - viewSize.width / 2); int y = max(0, p.y - viewSize.height / 2); p = new Point(x, y); final Point _p = p; awtLater(new Runnable() { public void run() { try { viewport.setViewPosition(_p); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "viewport.setViewPosition(_p);"; } }); } public Pt pointFromEvent(MouseEvent e) { return pointFromComponentCoordinates(new Pt(e.getX(), e.getY())); } public Pt pointFromComponentCoordinates(Pt p) { return new Pt((int) (p.x / zoomX), (int) (p.y / zoomY)); } public Pt pointToComponentCoordinates(double x, double y) { return new Pt((int) (x * zoomX), (int) (y * zoomY)); } public void uploadTheImage() { } public void showFullScreen() { showFullScreenImageSurface(getImage()); } public void zoomIn(double f) { setZoom(getZoomX() * f, getZoomY() * f); } public void zoomOut(double f) { setZoom(getZoomX() / f, getZoomY() / f); } public ImageSurface setFile(File f) { file = f; return this; } public void setOverlay(IVF1 overlay) { this.overlay = overlay; } public boolean hasImage() { return image != null; } public int w() { return image.getWidth(); } public int h() { return image.getHeight(); } public void setPixelated(boolean b) { assertTrue(b); imageSurface_pixelated(this); } public ImageSurface setAutoZoomToDisplay(boolean b) { if (autoZoomToDisplay = b) zoomToDisplaySize(); return this; } public void quickRepaint() { if (repaintInThread) paintImmediately(0, 0, getWidth(), getHeight()); else repaint(); } public void setTool(ImageSurfaceMouseHandler tool) { swing(() -> { removeAllTools(); addTool(tool); }); } public boolean hasTool(AutoCloseable tool) { return swing(() -> tools.contains(tool)); } public void addTool(ImageSurfaceMouseHandler tool) { swing(() -> { if (!tools.contains(tool)) tool.register(this); }); } public void removeTool(AutoCloseable tool) { swing(() -> { if (tools.contains(tool)) { close(tool); tools.remove(tool); } }); } public void removeAllTools() { closeAllAndClear(tools); } public void performAutoZoom() { if (autoZoomToDisplay) zoomToDisplaySize(); } public void revalidateMe() { revalidateIncludingFullCenterContainer(this); } public void addOverlay(G2Drawable overlay) { overlays.add(overlay); repaint(); } public void clearOverlays() { if (nempty(overlays)) { overlays.clear(); repaint(); } } public void setOverlay(G2Drawable overlay) { clearOverlays(); if (overlay != null) addOverlay(overlay); } public void loadImage(File f) { setImage(loadImage2(f)); } public JComponent visualize() { return jscroll_center_borderless(this); } public A print(A a) { return print("", a); } public A print(String msg, A a) { return _print(msg, a); } } static public VF2 ImageSurface_popupMenuMaker() { return new VF2() { public void get(ImageSurface is, JPopupMenu menu) { try { Point p = is.pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint(); is.fillPopupMenu(menu, p); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Point p = is.pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint();\r..."; } }; } static public class CombinedStringifier implements IStringifier { public CopyOnWriteArrayList> stringifiers = new CopyOnWriteArrayList(); public IStringifier defaultStringifier = new Stringifier_ToString(); public CombinedStringifier(IPartialStringifier... stringifiers) { addAll(this.stringifiers, stringifiers); } public String toString(A o) { for (var stringifier : stringifiers) { String s = stringifier.toStringOpt(o); if (s != null) return s; } return defaultStringifier.toString(o); } public String toString() { return formatFunctionCall("CombinedStringifier", listPlus((List) stringifiers, defaultStringifier)); } } static public class HasTokenRangeWithSrc implements IHasTokenRangeWithSrc { public TokenRangeWithSrc src; public void setTokenRangeWithSrc(TokenRangeWithSrc src) { this.src = src; } public TokenRangeWithSrc tokenRangeWithSrc() { return src; } } static public class FieldVar extends VarWithNotify { public IHasChangeListeners containingObject; public String fieldName; public IF0 getter; public IVF1 setter; public FieldVar(IHasChangeListeners containingObject, String fieldName, IF0 getter, IVF1 setter) { this.setter = setter; this.getter = getter; this.fieldName = fieldName; this.containingObject = containingObject; containingObject.onChangeAndNow(() -> _updateFromObject()); } public void _updateFromObject() { set(getter.get()); } public void fireChange() { setter.get(get()); super.fireChange(); } public FieldVar onChange(IVF1 r) { if (r != null) onChange(() -> r.get(get())); return this; } } static public class ReliableSingleThread implements Runnable { public boolean _isTransient() { return true; } public Object runnable; public String name = "Single Thread"; public boolean cancelBeforeTrigger = false; public boolean waitBetweenCancelAndTrigger = false; public F0 enter; public int cancelTimeOut = 10000; public boolean trigger = false; public Thread thread; public WeakReference threadBeingCancelled; public List inserts = syncL(); public ReliableSingleThread(Object runnable) { this.runnable = runnable; } public ReliableSingleThread(Runnable runnable) { this.runnable = runnable; } public void trigger() { go(); } synchronized public void go() { if (cancelBeforeTrigger) cancelAndPossiblyWait(); trigger = true; if (!running()) { AutoCloseable __1 = callF(enter); try { thread = startThread(name, new Runnable() { public void run() { try { AutoCloseable __2 = callF(enter); try { _run(); } finally { _close(__2); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp callF(enter);\r\n _run();"; } }); } finally { _close(__1); } } } public void run() { go(); } public void get() { go(); } synchronized public boolean running() { return thread != null; } public void triggerAndWait() { trigger(); waitUntilDone(); } public void waitUntilDone() { while (running()) sleep(1); } public void _run() { try { while (licensed()) { Thread oldThread; synchronized (this) { var currentInserts = syncGetAndClear(inserts); pcallFAll(currentInserts); if (!trigger) { thread = null; break; } oldThread = getWeakRef(threadBeingCancelled); trigger = false; } if (oldThread != null && oldThread != currentThread()) oldThread.join(cancelTimeOut); pcallF(runnable); } } catch (Exception __e) { throw rethrow(__e); } } synchronized public void cancel() { if (thread == null) return; threadBeingCancelled = new WeakReference(thread); cancelAndInterruptThread(thread); thread = null; } public void cancelAndWait() { Thread _thread; synchronized (this) { if (thread == null) return; _thread = thread; threadBeingCancelled = new WeakReference(thread); thread = null; } cancelAndInterruptThread(_thread); } public void cancelAndTrigger() { cancelAndPossiblyWait(); trigger(); } synchronized public boolean triggered() { return trigger; } public void cleanMeUp() { cancel(); } public ReliableSingleThread cancelBeforeTrigger() { cancelBeforeTrigger = true; return this; } public void cancelAndPossiblyWait() { if (waitBetweenCancelAndTrigger) cancel(); } public void insert(Runnable r) { inserts.add(r); trigger(); } synchronized public boolean hasThread() { return thread != null; } } public interface IMultiMap { public Set keySet(); public Collection get(A a); public int size(); public int keyCount(); } static public class FunctionTimings { public Map data = syncMap(); final public void timeCtex(A function, RunnableWithExceptions r) { doCtex(function, r); } public void doCtex(A function, RunnableWithExceptions r) { try { if (r == null) return; long time = nanoTime(); try { r.run(); } finally { time = nanoTime() - time; saveTiming(function, time); } } catch (Exception __e) { throw rethrow(__e); } } public B get(A function, IF0 f) { if (f == null) return null; Var var = new Var(); time(function, () -> var.set(f.get())); return var.get(); } final public void time(A function, Runnable r) { dO(function, r); } public void dO(A function, Runnable r) { if (r == null) return; long time = nanoTime(); try { r.run(); } finally { time = nanoTime() - time; saveTiming(function, time); } } public void saveTiming(A function, long time) { Average avg = syncMapGetOrCreate(data, function, () -> new Average()); avg.add(time); } public Map get() { return cloneMap(data); } final public void clear() { reset(); } public void reset() { data.clear(); } final public String toString() { return render(); } public String render() { return lines(renderedEntries()); } public List renderedEntries() { return ciSorted(map(get(), (f, avg) -> functionToString(f) + ": " + n2(iround(nsToMicroseconds(avg.get()))) + " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")")); } public String toStringSingleLine() { return joinWithComma(renderedEntries()); } public String functionToString(A f) { return firstToUpper(str(f)); } } static public class PtInComponent implements IFieldsToList { public A component; public Pt p; public PtInComponent() { } public PtInComponent(A component, Pt p) { this.p = p; this.component = component; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + component + ", " + p + ")"; } public boolean equals(Object o) { if (!(o instanceof PtInComponent)) return false; PtInComponent __1 = (PtInComponent) o; return eq(component, __1.component) && eq(p, __1.p); } public int hashCode() { int h = -1774729068; h = boostHashCombine(h, _hashCode(component)); h = boostHashCombine(h, _hashCode(p)); return h; } public Object[] _fieldsToList() { return new Object[] { component, p }; } public PtInComponent(Pt p, A component) { this.component = component; this.p = p; } } static public class ResolvableLASClass { public ResolvableLASClass() { } transient public ILASClassLoader lasClassLoader; public LASClassDef classDef; public Class resolvedClass; public ResolvableLASClass(ILASClassLoader lasClassLoader, LASClassDef classDef) { this.classDef = classDef; this.lasClassLoader = lasClassLoader; } public Class get() { if (resolvedClass == null) { if (lasClassLoader == null) throw fail("Need LASClassLoader to define " + classDef.userGivenName); resolvedClass = lasClassLoader.defineLASClass(classDef.finalClassName(), () -> classDef.toBytes()); classDef.init(resolvedClass); } return resolvedClass; } public String toString() { if (resolvedClass != null) return className(resolvedClass); { var __1 = classDef.userGivenName; if (__1 != null) return __1; } if (classDef.classHash_cache != null) return classDef.finalClassNameWithoutPrefix(); return or2(classDef.userGivenName, "script-defined class") + " [unresolved]"; } } static public class LeftArrowScriptAutoCompleter extends Meta implements IFieldsToList { public GazelleV_LeftArrowScriptParser parser; public LeftArrowScriptAutoCompleter() { } public LeftArrowScriptAutoCompleter(GazelleV_LeftArrowScriptParser parser) { this.parser = parser; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + parser + ")"; } public Object[] _fieldsToList() { return new Object[] { parser }; } public List tok; public CharInToken cursor; public String typedCharacters; public ScoredStringSearcher searcher; final public LeftArrowScriptAutoCompleter setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public LeftArrowScriptAutoCompleter g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; public TreeMap> knownVarsByTokenIdx = new TreeMap(); public Map typeHooks = new HashMap(); public LeftArrowScriptAutoCompleter(G22Utils g22utils, GazelleV_LeftArrowScriptParser parser) { this.parser = parser; this.g22utils = g22utils; } public void seekEnd(String text) { seek(text, l(text)); } public void seek(String text, int iChar) { if (tok != null) throw fail("Don't reuse instance"); parser.setText(text); parser.init(); tok = parser.tok; cursor = charIndexToCharInToken(tok, iChar); if (even(cursor.iTok) && cursor.iTok > 0 && cursor.iChar == 0) { cursor.iTok--; cursor.iChar = l(token()); } if (cursor.iTok > 1 && cursor.iChar == 0 && empty(space())) { cursor.iTok -= 2; cursor.iChar = l(token()); } typedCharacters = takeFirst(cursor.token(), cursor.iChar); parser.onKnownVarsSnapshot(knownVars -> knownVarsByTokenIdx.put(parser.tokIdx(), cloneKeys(knownVars))); parser.onTypeHook(type -> typeHooks.put(parser.tokIdx(), type)); try { parser.parse(); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } public String typedCharacters() { return typedCharacters; } public String space() { return get(tok, cursor.iTok - 1); } public String token() { return get(tok, cursor.iTok); } public String prevToken() { return get(tok, cursor.iTok - 2); } public boolean beginningOfCmd() { return eqOneOf(prevToken(), ";", "{", "}") || containsNewLine(space()); } public Collection getCompletions() { return searcher().get_transformListWithinScore(__1 -> stringsSortedByLength(__1)); } public ScoredStringSearcher searcher() { searcher = new ScoredStringSearcher(typedCharacters); searcher.uniquify(true); if (empty(typedCharacters)) searcher.returnAll = true; String prev = prevToken(); if (scaffoldingEnabled(this)) printVars("LeftArrowScriptAutoCompleter", "beginningOfCmd", beginningOfCmd(), "prev", prev, "cursor", cursor, "typedCharacters", typedCharacters, "globalClassNames", l(parser.globalClassNames())); LASValueDescriptor typeHook = typeHooks.get(cursor.iTok); if (typeHook != null && !beginningOfCmd()) { Class c = typeHook.javaClass(); if (c == null) c = Object.class; addToSearcher(methodNames(c)); addToSearcher(fieldNames(c)); } else { if (beginningOfCmd() || !isIdentifier(prev) || eqOneOf(prev, "if", "else")) addToSearcher(globalMethodNames()); addToSearcher(keys(parser.globalClassNames())); addToSearcher(predefinedExpressions()); Collection knownVars = floorValue(knownVarsByTokenIdx, cursor.iTok); addToSearcher(knownVars); } return searcher; } public Collection predefinedExpressions() { return ll("true", "false", "null"); } transient public IF0> globalMethodNames; public Collection globalMethodNames() { return globalMethodNames != null ? globalMethodNames.get() : globalMethodNames_base(); } final public Collection globalMethodNames_fallback(IF0> _f) { return _f != null ? _f.get() : globalMethodNames_base(); } public Collection globalMethodNames_base() { return concatMap(__71 -> methodNames(__71), parser.functionContainers); } public void addToSearcher(String... l) { addToSearcher(asList(l)); } public void addToSearcher(Iterable l) { for (var s : unnullForIteration(l)) if (!eq(s, typedCharacters)) searcher.add(s); } } static public interface ISetter { public void set(A a); } static public class JG22NetworkPort extends JPanel implements IFieldsToList { public G22Utils g22utils; public JG22NetworkElement element; public G22NetworkElement.Port port; public JG22NetworkPort() { } public JG22NetworkPort(G22Utils g22utils, JG22NetworkElement element, G22NetworkElement.Port port) { this.port = port; this.element = element; this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ", " + element + ", " + port + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils, element, port }; } public int size = 10; public Color outputColor() { return Color.green; } public Color inputColor() { return Color.red; } public void init() { bindChangeListenerToComponent(this, port, () -> update()); componentPopupMenuItems(this, "Show value", runnableThread(new Runnable() { public void run() { try { showValue(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showValue();"; } }), "Disconnect", runnableThread(new Runnable() { public void run() { try { disconnect(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disconnect();"; } }), "Delete port", runnableThread(new Runnable() { public void run() { try { delete(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "delete();"; } })); onMouseDown(this, event -> { var dragger = new ComponentDragger(this, event); dragger.updatePosition = (x, y) -> { Pt p = pt(x, y); Rect r = toRect(main.getBounds(element.visualize())); double dTop = distancePointToLineSegment(pt(r.x, r.y), pt(r.x2(), r.y), p); double dBottom = distancePointToLineSegment(pt(r.x, r.y2()), pt(r.x2(), r.y2()), p); double dLeft = distancePointToLineSegment(pt(r.x, r.y), pt(r.x, r.y2()), p); double dRight = distancePointToLineSegment(pt(r.x2(), r.y), pt(r.x2(), r.y2()), p); double min = doubleMin(dTop, dBottom, dLeft, dRight); DoublePt pos = doublePt(clampZeroToOne(doubleRatio(x - r.x, r.w)), clampZeroToOne(doubleRatio(y - r.y, r.h))); if (min == dTop) pos.y = 0; else if (min == dBottom) pos.y = 1; else if (min == dLeft) pos.x = 0; else pos.x = 1; port.position(pos); }; dragger.bringToFront(true).start(); }); update(); } public void update() { _print("Updating port " + port); setOpaque(true); setBackground(port.isOutput() ? outputColor() : inputColor()); setSize(size, size); Rect r = toRect(main.getBounds(element.visualize())); r = growRectTopAndLeft(r, size); setLocation(r.x + iround(port.position.x * r.w), r.y + iround(port.position.y * r.h)); setToolTip(this, str(port)); _print("Port " + port.name + " : " + getBounds()); } public void showValue() { G22NetworkElement e; if (port.isOutput()) e = port.element(); else e = port.cable.from.element(); var value = element.parent.networkInstance.getObjectForBlueprint(e); showFrame("Port value", new G22JavaObjectVisualizer(g22utils, value)); } public void disconnect() { port.disconnect(); } public void delete() { port.delete(); } } static public class FailedRule extends RuleWithParams { public List satisfiedConditions; public Exp remainingCondition; public FailedRule() { } public FailedRule(IfThen rule, VarMatches matches, Exp remainingCondition) { this.remainingCondition = remainingCondition; this.matches = matches; this.rule = rule; } public FailedRule(IfThen rule, VarMatches matches, List satisfiedConditions, Exp remainingCondition) { this.remainingCondition = remainingCondition; this.satisfiedConditions = satisfiedConditions; this.matches = matches; this.rule = rule; } } static public class RuleWithParams implements IFieldsToList { static final public String _fieldOrder = "rule matches"; public IfThen rule; public VarMatches matches; public RuleWithParams() { } public RuleWithParams(IfThen rule, VarMatches matches) { this.matches = matches; this.rule = rule; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + rule + ", " + matches + ")"; } public boolean equals(Object o) { if (!(o instanceof RuleWithParams)) return false; RuleWithParams __7 = (RuleWithParams) o; return eq(rule, __7.rule) && eq(matches, __7.matches); } public int hashCode() { int h = 1254104616; h = boostHashCombine(h, _hashCode(rule)); h = boostHashCombine(h, _hashCode(matches)); return h; } public Object[] _fieldsToList() { return new Object[] { rule, matches }; } public String ruleID() { return rule.globalID; } } static public class IfThen implements IFieldsToList { static final public String _fieldOrder = "in out globalID options originalText"; public Exp in; public Exp out; public IfThen() { } public IfThen(Exp in, Exp out) { this.out = out; this.in = in; } public boolean equals(Object o) { if (!(o instanceof IfThen)) return false; IfThen __8 = (IfThen) o; return eq(in, __8.in) && eq(out, __8.out); } public int hashCode() { int h = -2108234502; h = boostHashCombine(h, _hashCode(in)); h = boostHashCombine(h, _hashCode(out)); return h; } public Object[] _fieldsToList() { return new Object[] { in, out }; } public String globalID; public Set options; public String originalText; public String text() { Collection opt = options; if (nempty(globalID)) opt = concatLists(ll("id: " + globalID), opt); return (nempty(opt) ? "[" + joinWithComma(opt) + "] " : "") + (in == null ? "" : in.text() + "\n => ") + nlLogic_text(out); } public String toString() { return text(); } } abstract static public class Exp { abstract public String text(); public String toString() { return text(); } } static public class Func extends Exp implements IFieldsToList { public String name; public Exp arg; public Func() { } public Func(String name, Exp arg) { this.arg = arg; this.name = name; } public boolean equals(Object o) { if (!(o instanceof Func)) return false; Func __0 = (Func) o; return eq(name, __0.name) && eq(arg, __0.arg); } public int hashCode() { int h = 2201316; h = boostHashCombine(h, _hashCode(name)); h = boostHashCombine(h, _hashCode(arg)); return h; } public Object[] _fieldsToList() { return new Object[] { name, arg }; } public List options; public Func(String name, List options, Exp arg) { this.arg = arg; this.options = options; this.name = name; } public String text() { return name + (empty(options) ? "" : "[" + joinWithComma(options) + "]") + "(" + arg.text() + ")"; } public String argText() { return nlLogic_text(arg); } } static public class And extends Exp implements IFieldsToList { public Exp a; public Exp b; public And() { } public And(Exp a, Exp b) { this.b = b; this.a = a; } public boolean equals(Object o) { if (!(o instanceof And)) return false; And __1 = (And) o; return eq(a, __1.a) && eq(b, __1.b); } public int hashCode() { int h = 65975; h = boostHashCombine(h, _hashCode(a)); h = boostHashCombine(h, _hashCode(b)); return h; } public Object[] _fieldsToList() { return new Object[] { a, b }; } public String text() { return a.text() + "\n && " + b.text(); } } static public class ExpNot extends Exp implements IFieldsToList { public Exp a; public ExpNot() { } public ExpNot(Exp a) { this.a = a; } public boolean equals(Object o) { if (!(o instanceof ExpNot)) return false; ExpNot __2 = (ExpNot) o; return eq(a, __2.a); } public int hashCode() { int h = 2089649046; h = boostHashCombine(h, _hashCode(a)); return h; } public Object[] _fieldsToList() { return new Object[] { a }; } public String text() { return "!" + a.text(); } } abstract static public class Literal extends Exp { } static public class Sentence extends Literal implements IFieldsToList { public List tok; public Sentence() { } public Sentence(List tok) { this.tok = tok; } public boolean equals(Object o) { if (!(o instanceof Sentence)) return false; Sentence __3 = (Sentence) o; return eq(tok, __3.tok); } public int hashCode() { int h = 1327381123; h = boostHashCombine(h, _hashCode(tok)); return h; } public Object[] _fieldsToList() { return new Object[] { tok }; } public String text() { return join(tok); } } static public class Sentence2 extends Literal implements IFieldsToList { public String text; public Sentence2() { } public Sentence2(String text) { this.text = text; } public boolean equals(Object o) { if (!(o instanceof Sentence2)) return false; Sentence2 __4 = (Sentence2) o; return eq(text, __4.text); } public int hashCode() { int h = -1800858097; h = boostHashCombine(h, _hashCode(text)); return h; } public Object[] _fieldsToList() { return new Object[] { text }; } public String text() { return text; } } static public class Eq extends Exp implements IFieldsToList { public Exp left; public Exp right; public Eq() { } public Eq(Exp left, Exp right) { this.right = right; this.left = left; } public boolean equals(Object o) { if (!(o instanceof Eq)) return false; Eq __5 = (Eq) o; return eq(left, __5.left) && eq(right, __5.right); } public int hashCode() { int h = 2252; h = boostHashCombine(h, _hashCode(left)); h = boostHashCombine(h, _hashCode(right)); return h; } public Object[] _fieldsToList() { return new Object[] { left, right }; } public String text() { return left.text() + " = " + right.text(); } } static public interface MakesBufferedImage extends WidthAndHeight { public BufferedImage getBufferedImage(); public default void drawAt(Graphics2D g, int x, int y) { g.drawImage(getBufferedImage(), x, y, null); } } static public class G22AutoStarter extends MetaWithChangeListeners implements AutoCloseable, IFieldsToList { public G22Utils g22utils; public G22AutoStarter() { } public G22AutoStarter(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public transient FieldVar varEnabled_cache; public FieldVar varEnabled() { if (varEnabled_cache == null) varEnabled_cache = varEnabled_load(); return varEnabled_cache; } public FieldVar varEnabled_load() { return new FieldVar(this, "enabled", () -> enabled(), enabled -> enabled(enabled)); } final public G22AutoStarter setEnabled(boolean enabled) { return enabled(enabled); } public G22AutoStarter enabled(boolean enabled) { if (!eq(this.enabled, enabled)) { this.enabled = enabled; change(); } return this; } final public boolean getEnabled() { return enabled(); } public boolean enabled() { return enabled; } volatile public boolean enabled = true; public transient FieldVar varInitialDelay_cache; public FieldVar varInitialDelay() { if (varInitialDelay_cache == null) varInitialDelay_cache = varInitialDelay_load(); return varInitialDelay_cache; } public FieldVar varInitialDelay_load() { return new FieldVar(this, "initialDelay", () -> initialDelay(), initialDelay -> initialDelay(initialDelay)); } final public G22AutoStarter setInitialDelay(int initialDelay) { return initialDelay(initialDelay); } public G22AutoStarter initialDelay(int initialDelay) { if (!eq(this.initialDelay, initialDelay)) { this.initialDelay = initialDelay; change(); } return this; } final public int getInitialDelay() { return initialDelay(); } public int initialDelay() { return initialDelay; } volatile public int initialDelay = 1; public transient FieldVar varNScriptsRun_cache; public FieldVar varNScriptsRun() { if (varNScriptsRun_cache == null) varNScriptsRun_cache = varNScriptsRun_load(); return varNScriptsRun_cache; } public FieldVar varNScriptsRun_load() { return new FieldVar(this, "nScriptsRun", () -> nScriptsRun(), nScriptsRun -> nScriptsRun(nScriptsRun)); } final public G22AutoStarter setNScriptsRun(int nScriptsRun) { return nScriptsRun(nScriptsRun); } public G22AutoStarter nScriptsRun(int nScriptsRun) { if (!eq(this.nScriptsRun, nScriptsRun)) { this.nScriptsRun = nScriptsRun; change(); } return this; } final public int getNScriptsRun() { return nScriptsRun(); } public int nScriptsRun() { return nScriptsRun; } volatile public int nScriptsRun; public transient FieldVar varCurrentScript_cache; public FieldVar varCurrentScript() { if (varCurrentScript_cache == null) varCurrentScript_cache = varCurrentScript_load(); return varCurrentScript_cache; } public FieldVar varCurrentScript_load() { return new FieldVar(this, "currentScript", () -> currentScript(), currentScript -> currentScript(currentScript)); } final public G22AutoStarter setCurrentScript(AutoStartScript currentScript) { return currentScript(currentScript); } public G22AutoStarter currentScript(AutoStartScript currentScript) { if (!eq(this.currentScript, currentScript)) { this.currentScript = currentScript; change(); } return this; } final public AutoStartScript getCurrentScript() { return currentScript(); } public AutoStartScript currentScript() { return currentScript; } volatile public AutoStartScript currentScript; public Flag started = new Flag(); public Flag waited = new Flag(); public Flag ctrlPressed = new Flag(); public List scripts = syncL(); public AutoCloseable ctrlListener; public ReliableSingleThread rst = rst(() -> _run()); public class AutoStartScript extends RunResultWithTimestamps implements IFieldsToList { public G22LeftArrowScript script; public AutoStartScript() { } public AutoStartScript(G22LeftArrowScript script) { this.script = script; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + script + ")"; } public Object[] _fieldsToList() { return new Object[] { script }; } public void run() { try { LASCompileResult cr = script.compileForAutoRun(); if (cr == null) cr = script.compileSaved(); var _cr_2 = cr; run(() -> { G22AutoStarter.this.change(); if (_cr_2 == null) throw fail("Script is not saved: " + script); var parsed = _cr_2.parsedScriptMandatory(); return parsed.get(); }); } catch (Exception __e) { throw rethrow(__e); } } } public void init() { if (ctrlListener != null) return; scripts.clear(); var scripts = conceptsWhere(g22utils.concepts, G22LeftArrowScript.class, "runOnProjectOpen", true); var sorted = sortByCalculatedFieldAlphaNumIC(scripts, s -> s.runOrder); for (var script : sorted) this.scripts.add(new AutoStartScript(script)); change(); ctrlListener = tempAddGlobalCtrlKeyListener(b -> { if (b) { ctrlPressed.raise(); cancel(); } }); } public void start() { print("G22AutoStarter: Start"); if (enabled) rst.get(); } public void _run() { if (!enabled) return; AutoCloseable __1 = g22utils.backgroundProcessesUI.tempAdd("Auto-Start Scripts"); try { if (started.raise()) change(); if (!waited.get()) { print("G22AutoStarter: Sleeping"); while (initialDelay > 0) { sleepSeconds(1); initialDelay(initialDelay - 1); } waited.raise(); change(); print("G22AutoStarter: Slept"); } while (enabled && !done()) { var script = scripts.get(nScriptsRun); currentScript(script); change(); script.run(); nScriptsRun(nScriptsRun + 1); currentScript(null); change(); } change(); close(); } finally { _close(__1); } } public boolean done() { return nScriptsRun >= l(scripts); } public void cancel() { setEnabled(false); } public boolean canResume() { return !done() && !enabled; } public void resume() { if (done()) { infoBox("Nothing to resume - auto-start is done"); return; } if (enabled) { infoBox("Already running"); return; } infoBox("Resuming auto-start"); setEnabled(true); rst.get(); } public String status() { return !enabled ? ctrlPressed.get() ? "Cancelled due to ctrl key" : "Cancelled" : done() ? "Done" : waited.get() ? "Started" : started.get() ? "Pre-start wait (" + formatDouble1(initialDelay) + "s)" : "Not started"; } public String stats() { return status() + ". " + scriptsRunStats(); } public String scriptsRunStats() { return "Scripts run: " + nScriptsRun() + "/" + l(scripts); } public String currentScriptStats() { var s = currentScript; if (s == null) return ""; return "Running: " + s.script; } public void close() { try { if (ctrlListener != null) { { cleanUp(ctrlListener); ctrlListener = null; } change(); } } catch (Exception __e) { throw rethrow(__e); } } public void waitUntilDone() { waitForVarPredicate(varNScriptsRun(), () -> done()); } public boolean ctrlEnabled() { return ctrlListener != null; } } static public int concepts_internStringsLongerThan = 10; static public ThreadLocal concepts_unlisted = new ThreadLocal(); static public boolean concepts_unlistedByDefault = true; public interface IConceptIndex { public void update(Concept c); public void remove(Concept c); } public interface IFieldIndex { public Collection getAll(Val val); public List allValues(); public MultiSet allValues_multiSet(); public IterableIterator objectIterator(); } static public class ConceptsChange { } static public class ConceptCreate extends ConceptsChange implements IFieldsToList { public Concept c; public ConceptCreate() { } public ConceptCreate(Concept c) { this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ")"; } public boolean equals(Object o) { if (!(o instanceof ConceptCreate)) return false; ConceptCreate __3 = (ConceptCreate) o; return eq(c, __3.c); } public int hashCode() { int h = -1751266972; h = boostHashCombine(h, _hashCode(c)); return h; } public Object[] _fieldsToList() { return new Object[] { c }; } } static public class ConceptChange extends ConceptsChange implements IFieldsToList { public Concept c; public ConceptChange() { } public ConceptChange(Concept c) { this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ")"; } public boolean equals(Object o) { if (!(o instanceof ConceptChange)) return false; ConceptChange __4 = (ConceptChange) o; return eq(c, __4.c); } public int hashCode() { int h = -1760609256; h = boostHashCombine(h, _hashCode(c)); return h; } public Object[] _fieldsToList() { return new Object[] { c }; } } static public class ConceptDelete extends ConceptsChange implements IFieldsToList { static final public String _fieldOrder = "id c"; public long id; public Concept c; public ConceptDelete() { } public ConceptDelete(long id, Concept c) { this.c = c; this.id = id; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + id + ", " + c + ")"; } public boolean equals(Object o) { if (!(o instanceof ConceptDelete)) return false; ConceptDelete __5 = (ConceptDelete) o; return id == __5.id && eq(c, __5.c); } public int hashCode() { int h = -1734431213; h = boostHashCombine(h, _hashCode(id)); h = boostHashCombine(h, _hashCode(c)); return h; } public Object[] _fieldsToList() { return new Object[] { id, c }; } } static public class FullChange extends ConceptsChange implements IFieldsToList { public FullChange() { } public String toString() { return shortClassName_dropNumberPrefix(this); } public boolean equals(Object o) { return o instanceof FullChange; } public int hashCode() { int h = 733452095; return h; } public Object[] _fieldsToList() { return null; } } static public class Concepts implements AutoCloseable { public SortedMap concepts = synchroTreeMap(); final public long getIdCounter() { return idCounter(); } public long idCounter() { return idCounter; } public long idCounter; transient public HashMap perClassData; transient public Map miscMap; transient public String programID; transient public File conceptsFile; transient public Concepts parent; transient volatile public long changes, changesWritten, lastChange; transient volatile public java.util.Timer autoSaver; transient volatile public boolean dontSave = false; transient volatile public boolean savingConcepts, noXFullGrab; transient public boolean vmBusSend = true; transient public boolean initialSave = false; transient public int autoSaveInterval = -1000; transient public boolean useGZIP = true, quietSave; transient public ReentrantLock lock = new ReentrantLock(true); transient public ReentrantLock saverLock = new ReentrantLock(true); transient public long lastSaveTook = -1, lastSaveWas, loadTook, uncompressedSize; transient public float maxAutoSavePercentage = 10; transient public List conceptIndices; transient public Map, Map> fieldIndices; transient public Map, Map> ciFieldIndices; transient public List preSave; transient public Object classFinder = _defaultClassFinder(); transient public List onAllChanged = synchroList(); transient public Set onChange = new HashSet(); transient public Object saveWrapper; final public Concepts setModifyOnCreate(boolean modifyOnCreate) { return modifyOnCreate(modifyOnCreate); } public Concepts modifyOnCreate(boolean modifyOnCreate) { this.modifyOnCreate = modifyOnCreate; return this; } final public boolean getModifyOnCreate() { return modifyOnCreate(); } public boolean modifyOnCreate() { return modifyOnCreate; } transient public boolean modifyOnCreate = false; transient public boolean modifyOnBackRef = false; transient public boolean useFileLock = true; transient public FileBasedLock fileLock; transient public boolean storeBaseClassesInStructure = false; transient public boolean useBackRefsForSearches = false; transient public boolean defunct = false; transient public int newBackupEveryXMinutes = 60; public Concepts() { } public Concepts(String programID) { this.programID = programID; } public Concepts(File conceptsFile) { this.conceptsFile = conceptsFile; } synchronized public long internalID() { do { ++idCounter; } while (hasConcept(idCounter)); return idCounter; } synchronized public HashMap perClassData() { if (perClassData == null) perClassData = new HashMap(); return perClassData; } public void initProgramID() { if (programID == null) programID = getDBProgramID(); } public Concepts load(String structure) { return load(structure, false); } public Concepts load(String structure, boolean allDynamic) { clearConcepts(); Map map = unstructureMap(structure, allDynamic, classFinder); concepts.putAll(map); assignConceptsToUs(); calcIdCounter(); return this; } public Concepts load() { initProgramID(); Object dbGrabber = miscMapGet("dbGrabber"); if (dbGrabber != null && !isFalse(callF(dbGrabber))) return this; try { if (tryToGrab()) return this; } catch (Throwable e) { if (!exceptionMessageContains(e, "no xfullgrab")) printShortException(e); print("xfullgrab failed - loading DB of " + programID + " from disk"); } return loadFromDisk(); } public Concepts loadFromDisk() { if (nempty(concepts)) clearConcepts(); long time = now(); Map _concepts = (Map) (unstructureGZFile(conceptsFile(), toIF1(classFinder))); putAll(concepts, _concepts); assignConceptsToUs(); loadTook = now() - time; done("Loaded " + n2(l(concepts), "concept"), time); calcIdCounter(); return this; } public Concepts loadConcepts() { return load(); } public boolean tryToGrab() { if (sameSnippetID(programID, getDBProgramID())) return false; RemoteDB db = connectToDBOpt(programID); try { if (db != null) { loadGrab(db.fullgrab()); return true; } return false; } finally { _close(db); } } public Concepts loadGrab(String grab) { clearConcepts(); DynamicObject_loading.set(true); try { Map map = (Map) unstructure(grab, false, classFinder); concepts.putAll(map); assignConceptsToUs(); for (long l : map.keySet()) idCounter = max(idCounter, l); } finally { DynamicObject_loading.set(null); } return this; } public void assignConceptsToUs() { for (Pair p : mapToPairs((Map) (Map) concepts)) if (!(p.b instanceof Concept)) { print("DROPPING non-existant concept " + p.a + ": " + dynShortName(p.b)); concepts.remove(p.a); } for (Concept c : values(concepts)) c._concepts = this; for (Concept c : values(concepts)) c._doneLoading2(); } public String progID() { return programID == null ? getDBProgramID() : programID; } public Concept getConcept(String id) { return empty(id) ? null : getConcept(parseLong(id)); } public Concept getConcept(long id) { return (Concept) concepts.get((long) id); } public Concept getConcept(RC ref) { return ref == null ? null : getConcept(ref.longID()); } public boolean hasConcept(long id) { return concepts.containsKey((long) id); } public void deleteConcept(long id) { Concept c = getConcept(id); if (c == null) print("Concept " + id + " not found"); else c.delete(); } public void calcIdCounter() { Long lastID = lastKey(concepts); idCounter = lastID == null ? 1 : lastID + 1; } public File conceptsDir() { return dirOfFile(conceptsFile()); } public Concepts conceptsFile(File conceptsFile) { this.conceptsFile = conceptsFile; return this; } public File conceptsFile() { if (conceptsFile != null) return conceptsFile; return getProgramFile(programID, useGZIP ? "concepts.structure.gz" : "concepts.structure"); } public File lockFile() { return newFile(conceptsDir(), "concepts.lock"); } public FileBasedLock fileLock() { if (fileLock == null) fileLock = new FileBasedLock(lockFile()); return fileLock; } public void saveConceptsIfDirty() { saveConcepts(); } public void save() { saveConcepts(); } public void saveConcepts() { vmBus_send("saveConceptsCalled", Concepts.this); if (dontSave) return; initProgramID(); saverLock.lock(); savingConcepts = true; long start = now(), time; try { String s = null; long _changes = changes; if (_changes == changesWritten) return; File f = conceptsFile(); lock.lock(); long fullTime = now(); try { if (useGZIP) { vmBus_send("callingSaveWrapper", Concepts.this, saveWrapper); callRunnableWithWrapper(saveWrapper, new Runnable() { public void run() { try { vmBus_send("callingPreSave", Concepts.this, preSave); callFAll(preSave); vmBus_send("writingFile", Concepts.this, f); uncompressedSize = saveGZStructureToFile(f, cloneMap(concepts), makeStructureData()); vmBus_send("gzFileSaved", Concepts.this, f, uncompressedSize); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "vmBus_send callingPreSave(Concepts.this, preSave);\r\n callFAll(preS..."; } }); newFile(conceptsDir(), "concepts.structure").delete(); } else s = fullStructure(); } finally { lock.unlock(); } changesWritten = _changes; if (!useGZIP) { time = now() - start; if (!quietSave) print("Saving " + toM(l(s)) + "M chars (" + time + " ms)"); start = now(); saveTextFile(f, javaTokWordWrap(s)); newFile(conceptsDir(), "concepts.structure.gz").delete(); } File conceptsFile = conceptsFile(); File backupFile = newFile(conceptsDir(), "backups/" + fileName(conceptsFile) + ".backup" + ymd() + "-" + formatInt(hours(), 2) + (newBackupEveryXMinutes >= 60 ? "" : formatInt(roundDownTo_rev(minutes(), newBackupEveryXMinutes), 2))); copyFile(f, backupFile); time = now() - start; if (!quietSave) print("Saved " + toK(f.length()) + " K, " + n(concepts, "concepts") + " (" + time + " ms)"); lastSaveWas = fullTime; lastSaveTook = now() - fullTime; } finally { savingConcepts = false; saverLock.unlock(); } } public void _autoSaveConcepts() { if (autoSaveInterval < 0 && maxAutoSavePercentage != 0) { long pivotTime = Math.round(lastSaveWas + lastSaveTook * 100.0 / maxAutoSavePercentage); if (now() < pivotTime) { return; } } try { saveConcepts(); } catch (Throwable e) { print("Concept save failed, will try again"); printStackTrace(e); } } public String fullStructure() { return structure(cloneMap(concepts), makeStructureData()); } transient public IF0 makeStructureData; public structure_Data makeStructureData() { return makeStructureData != null ? makeStructureData.get() : makeStructureData_base(); } final public structure_Data makeStructureData_fallback(IF0 _f) { return _f != null ? _f.get() : makeStructureData_base(); } public structure_Data makeStructureData_base() { return finishStructureData(new structure_Data()); } public structure_Data finishStructureData(structure_Data data) { if (storeBaseClassesInStructure) data.storeBaseClasses = true; return data; } public void clearConcepts() { for (Concept c : allConcepts()) c.delete(); } public void fireLegacyChangeEvent() { synchronized (this) { ++changes; lastChange = sysNow(); } if (vmBusSend) vmBus_send("conceptsChanged", this); pcallFAll(onAllChanged); } synchronized public void autoSaveConcepts() { if (autoSaver == null) { if (isTransient()) throw fail("Can't persist transient database"); autoSaver = doEvery_daemon("Concepts Saver for " + conceptsDir(), abs(autoSaveInterval), new Runnable() { public void run() { try { _autoSaveConcepts(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_autoSaveConcepts()"; } }); } } public void close() { cleanMeUp(); } public void cleanMeUp() { try { defunct = true; boolean shouldSave = autoSaver != null; if (autoSaver != null) { autoSaver.cancel(); autoSaver = null; } while (savingConcepts) sleepInCleanUp(10); if (shouldSave) saveConceptsIfDirty(); } catch (Throwable __e) { printStackTrace(__e); } { cleanUp(fileLock); fileLock = null; } } public Map getIDsAndNames() { Map map = new HashMap(); Map cloned = cloneMap(concepts); for (long id : keys(cloned)) map.put(id, cloned.get(id).className); return map; } public void deleteConcepts(List l) { ping(); if (l != null) for (Object o : cloneList(l)) if (o instanceof Long) { Concept c = concepts.get(o); if (c != null) c.delete(); } else if (o instanceof Concept) ((Concept) o).delete(); else warn("Can't delete " + getClassName(o)); } public A conceptOfType(Class type) { IConceptCounter counter = conceptCounterForClass(type); if (counter != null) return (A) first(counter.allConcepts()); return firstOfType(allConcepts(), type); } public List conceptsOfType(Class type) { List l = conceptsOfType_noParent(type); if (parent == null) return l; return concatLists_conservative(l, parent.conceptsOfType(type)); } public List conceptsOfType_noParent(Class type) { ping(); IConceptCounter counter = conceptCounterForClass(type); if (counter != null) return (List) cloneList(counter.allConcepts()); return filterByType(allConcepts(), type); } public List listConcepts(Class type) { return conceptsOfType(type); } public List list(Class type) { return conceptsOfType(type); } public List list_noParent(Class type) { return conceptsOfType_noParent(type); } public List list(String type) { return conceptsOfType(type); } public List conceptsOfType(String type) { return filterByDynamicType(allConcepts(), "main$" + type); } public boolean hasConceptOfType(Class type) { return hasType(allConcepts(), type); } public void persistConcepts() { loadConcepts(); autoSaveConcepts(); } public void conceptPersistence() { persistConcepts(); } public Concepts persist() { persistConcepts(); return this; } public void persist(Integer interval) { if (interval != null) autoSaveInterval = interval; persist(); } public A ensureHas(Class c, Runnable r) { A a = conceptOfType(c); if (a == null) { r.run(); a = conceptOfType(c); if (a == null) throw fail("Concept not made by " + r + ": " + shortClassName(c)); } return a; } public void ensureHas(Class c1, Class c2, Object func) { for (Concept a : conceptsOfType(c1)) { Concept b = findBackRef(a, c2); if (b == null) { callF(func, a); b = findBackRef(a, c2); if (b == null) throw fail("Concept not made by " + func + ": " + shortClassName(c2)); } } } public void forEvery(Class type, Object func) { for (Concept c : conceptsOfType(type)) callF(func, c); } public int deleteAll(Class type) { List l = (List) conceptsOfType(type); for (Concept c : l) c.delete(); return l(l); } public Collection allConcepts() { synchronized (concepts) { return new ArrayList(values(concepts)); } } public IConceptCounter conceptCounterForClass(Class c) { for (IFieldIndex idx : values(mapGet(fieldIndices, c))) if (idx instanceof IConceptCounter) return ((IConceptCounter) idx); for (IFieldIndex idx : values(mapGet(ciFieldIndices, c))) if (idx instanceof IConceptCounter) return ((IConceptCounter) idx); return null; } public int countConcepts(Class c, Object... params) { int n = countConcepts_noParent(c, params); if (parent == null) return n; return n + parent.countConcepts(c, params); } public int countConcepts_noParent(Class c, Object... params) { ping(); if (empty(params)) { IConceptCounter counter = conceptCounterForClass(c); if (counter != null) return counter.countConcepts(); return l(list_noParent(c)); } int n = 0; for (A x : list_noParent(c)) if (checkConceptFields(x, params)) ++n; return n; } public int countConcepts(String c, Object... params) { ping(); if (empty(params)) return l(list(c)); int n = 0; for (Concept x : list(c)) if (checkConceptFields(x, params)) ++n; return n; } public int countConcepts() { return l(concepts); } synchronized public List clonedConceptIndices() { return cloneList(conceptIndices); } synchronized public void addConceptIndex(IConceptIndex index) { if (conceptIndices == null) conceptIndices = new ArrayList(); conceptIndices.add(index); } synchronized public void removeConceptIndex(IConceptIndex index) { if (conceptIndices == null) return; conceptIndices.remove(index); if (empty(conceptIndices)) conceptIndices = null; } synchronized public void addFieldIndex(Class c, String field, IFieldIndex index) { if (fieldIndices == null) fieldIndices = new HashMap(); Map map = fieldIndices.get(c); if (map == null) fieldIndices.put(c, map = new HashMap()); map.put(field, index); } synchronized public void removeFieldIndex(Class c, String field, IFieldIndex index) { Map map = mapGet(fieldIndices, c); mapRemove(map, field); } synchronized public IFieldIndex getFieldIndex(Class c, String field) { if (fieldIndices == null) return null; Map map = fieldIndices.get(c); return map == null ? null : map.get(field); } synchronized public IFieldIndex getAnyIndexForClass(Class c) { return firstValue(fieldIndices == null ? null : fieldIndices.get(c)); } synchronized public void addCIFieldIndex(Class c, String field, IFieldIndex index) { if (ciFieldIndices == null) ciFieldIndices = new HashMap(); Map map = ciFieldIndices.get(c); if (map == null) ciFieldIndices.put(c, map = new HashMap()); map.put(field, index); } synchronized public void removeCIFieldIndex(Class c, String field) { Map map = mapGet(ciFieldIndices, c); mapRemove(map, field); } synchronized public IFieldIndex getCIFieldIndex(Class c, String field) { if (ciFieldIndices == null) return null; Map map = ciFieldIndices.get(c); return map == null ? null : map.get(field); } public RC xnew(String name, Object... values) { return new RC(cnew(name, values)); } public void xset(long id, String field, Object value) { xset(new RC(id), field, value); } public void xset(RC c, String field, Object value) { if (value instanceof RC) value = getConcept((RC) value); cset(getConcept(c), field, value); } public Object xget(long id, String field) { return xget(new RC(id), field); } public Object xget(RC c, String field) { return xgetPost(cget(getConcept(c), field)); } public Object xgetPost(Object o) { o = deref(o); if (o instanceof Concept) return new RC((Concept) o); return o; } public void xdelete(long id) { xdelete(new RC(id)); } public void xdelete(RC c) { getConcept(c).delete(); } public void xdelete(List l) { for (RC c : l) xdelete(c); } public List xlist() { return map("toPassRef", allConcepts()); } public List xlist(String className) { return map("toPassRef", conceptsOfType(className)); } public boolean isTransient() { return eq(programID, "-"); } public String xfullgrab() { if (noXFullGrab) throw fail("no xfullgrab (DB too large)"); Lock __1 = lock(); lock(__1); try { if (changes == changesWritten && !isTransient()) return loadConceptsStructure(programID); return fullStructure(); } finally { unlock(__1); } } public void xshutdown() { cleanKillVM(); } public long xchangeCount() { return changes; } public int xcount() { return countConcepts(); } public void register(Concept c) { ping(); if (c._concepts == this) return; if (c._concepts != null) throw fail("Can't re-register"); c.id = internalID(); c.created = now(); if (modifyOnCreate) c._setModified(c.created); register_phase2(c); vmBus_send("conceptCreated", c); fireChange(new ConceptCreate(c)); } public void register_phase2(Concept c) { c._concepts = this; concepts.put((long) c.id, c); for (Concept.Ref r : c._refs()) r.index(); c.change(); c._onRegistered(); } public void registerKeepingID(Concept c) { if (c._concepts == this) return; if (c._concepts != null) throw fail("Can't re-register"); c._concepts = this; concepts.put((long) c.id, c); c.change(); } public void conceptChanged(Concept c) { fireChange(new ConceptChange(c)); if (conceptIndices != null) for (IConceptIndex index : clonedConceptIndices()) index.update(c); } public boolean hasUnsavedData() { return changes != changesWritten || savingConcepts; } synchronized public Object miscMapGet(Object key) { return mapGet(miscMap, key); } synchronized public Object miscMapPut(Object key, Object value) { if (miscMap == null) miscMap = new HashMap(); return miscMap.put(key, value); } synchronized public void miscMapRemove(Object key) { mapRemove(miscMap, key); } synchronized public A miscMapGetOrCreate(Object key, IF0 create) { if (containsKey(miscMap, key)) return (A) miscMap.get(key); A value = create.get(); miscMapPut(key, value); return value; } public void setParent(Concepts parent) { this.parent = parent; } public void fireChange(ConceptsChange change) { if (change == null) return; pcallFAll(onChange, change); fireLegacyChangeEvent(); } final public void onChange(IVF1 l) { addChangeListener(l); } public void addChangeListener(IVF1 l) { syncAdd(onChange, l); } public void removeChangeListener(IVF1 l) { syncRemove(onChange, l); } public void addPreSave(Runnable r) { preSave = syncAddOrCreate(preSave, r); } public String toString() { return nConcepts(concepts) + " (" + conceptsDir() + ", hash: " + identityHashCode(this) + ")"; } } public interface IConcept { public long _conceptID(); public Concepts concepts(); } static public class Concept extends DynamicObject implements IConcept, ChangeTriggerable { transient public Concepts _concepts; public long id; public long created, _modified; public List backRefs; public Concept(String className) { super(className); _created(); } public Concept() { if (!_loading()) { _created(); } } public Concept(boolean unlisted) { if (!unlisted) _created(); } public boolean includeZeroIDInToString() { return false; } public String toString() { String s = shortDynamicClassName(this); long id = this.id; if (id != 0 || includeZeroIDInToString()) s += " " + id; return s; } static public boolean loading() { return _loading(); } static public boolean _loading() { return dynamicObjectIsLoading(); } public void _created() { if (!concepts_unlistedByDefault && !eq(concepts_unlisted.get(), true)) db_mainConcepts().register(this); } public class TypedRef extends Ref { public TypedRef() { } public Class bType; public TypedRef(Class bType) { this.bType = bType; } public TypedRef(Class bType, B value) { this.bType = bType; set((A) value); } public TypedRef(B value) { set((A) value); } public boolean set(A a) { return super.set(checkValue(a)); } public void check() { checkValue(get()); } public C checkValue(C a) { if (bType != null && a != null) assertIsInstance(a, bType); return a; } public B b() { return (B) value; } } public class Ref implements IRef { public A value; public Ref() { if (!dynamicObjectIsLoading()) registerRef(); } public void registerRef() { vmBus_send("registeringConceptRef", this); } public Ref(A value) { this.value = value; registerRef(); index(); } public Concept concept() { return Concept.this; } public A get() { return value; } public boolean has() { return value != null; } public boolean set(A a) { if (a == value) return false; unindex(); value = a; index(); change(); return true; } public void setIfEmpty(A a) { if (!has()) set(a); } public void set(Ref ref) { set(ref.get()); } public void clear() { set((A) null); } public boolean validRef() { return value != null && _concepts != null && _concepts == value._concepts; } public void index() { if (validRef()) { value._addBackRef(this); change(); } } public Ref unindex() { if (validRef()) { value._removeBackRef(this); change(); } return this; } public void unindexAndDrop() { unindex(); _removeRef(this); } public void change() { Concept.this.change(); } public String toString() { return str(value); } } public class RefL extends AbstractList { public List> l = new ArrayList(); public RefL() { } public RefL(List l) { replaceWithList(l); } public void clear() { while (!isEmpty()) removeLast(this); } public void replaceWithList(List l) { clear(); for (A a : unnullForIteration(l)) add(a); } public A set(int i, A o) { Ref ref = syncGet(l, i); A prev = ref.get(); ref.set(o); return prev; } public void add(int i, A o) { syncAdd(l, i, new Ref(o)); } public A get(int i) { return syncGet(l, i).get(); } public A remove(int i) { return syncRemove(l, i).get(); } public int size() { return syncL(l); } public boolean contains(Object o) { if (o instanceof Concept) for (Ref r : l) if (eq(r.get(), o)) return true; return super.contains(o); } } public void delete() { for (Ref r : unnullForIteration(_refs())) r.unindex(); for (Ref r : cloneList(backRefs)) r.set((Concept) null); backRefs = null; var _concepts = this._concepts; if (_concepts != null) { _concepts.concepts.remove(id); _concepts.fireChange(new ConceptDelete(id, this)); if (_concepts.conceptIndices != null) for (IConceptIndex index : _concepts.conceptIndices) index.remove(this); this._concepts = null; } id = 0; } public BaseXRef export() { return new BaseXRef(_concepts.progID(), id); } final public void _change() { change(); } public void change() { _setModified(now()); _change_withoutUpdatingModifiedField(); } public void _setModified(long modified) { _modified = modified; } final public void _change_withoutUpdatingModifiedField() { _onChange(); if (_concepts != null) _concepts.conceptChanged(this); } public void _onChange() { } public String _programID() { return _concepts == null ? getDBProgramID() : _concepts.progID(); } public void _addBackRef(Concept.Ref ref) { backRefs = addDyn_quickSync(backRefs, ref); _backRefsModified(); } public void _backRefsModified() { if (_concepts != null && _concepts.modifyOnBackRef) change(); } public void _removeBackRef(Concept.Ref ref) { backRefs = removeDyn_quickSync(backRefs, ref); _backRefsModified(); } public void _removeRef(Concept.Ref ref) { } public int _backRefCount() { return syncL(backRefs); } final public void setField(String field, Object value) { _setField(field, value); } public void _setField(String field, Object value) { cset(this, field, value); } public boolean setField_trueIfChanged(String field, Object value) { return cset(this, field, value) != 0; } public A setFieldAndReturn(String field, A value) { setField(field, value); return value; } final public void setFields(Object... values) { _setFields(values); } public void _setFields(Object... values) { cset(this, values); } public Concepts concepts() { return _concepts; } public boolean isDeleted() { return id == 0; } public void _doneLoading() { } public void _doneLoading2() { Map map = _fieldMigrations(); if (map != null) for (Map.Entry __0 : _entrySet(map)) { String oldField = __0.getKey(); FieldMigration m = __0.getValue(); crenameField_noOverwrite(this, oldField, m.newField); } } static public class FieldMigration implements IFieldsToList { public String newField; public FieldMigration() { } public FieldMigration(String newField) { this.newField = newField; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + newField + ")"; } public boolean equals(Object o) { if (!(o instanceof FieldMigration)) return false; FieldMigration __6 = (FieldMigration) o; return eq(newField, __6.newField); } public int hashCode() { int h = 558692372; h = boostHashCombine(h, _hashCode(newField)); return h; } public Object[] _fieldsToList() { return new Object[] { newField }; } } public Map _fieldMigrations() { return null; } public Collection _refs() { return scanConceptForRefs(this); } public Concepts _concepts() { return _concepts; } public boolean _conceptsDefunct() { return _concepts != null && _concepts.defunct; } public boolean _conceptsDefunctOrUnregistered() { return _concepts == null || _concepts.defunct; } public void _onRegistered() { } public boolean addAndChange(Collection cl, A a) { if (cl == null || !cl.add(a)) return false; change(); return true; } public void clearAndChange(Collection cl) { if (cl == null) return; cl.clear(); change(); } public File conceptsDir() { var concepts = concepts(); return concepts == null ? null : concepts.conceptsDir(); } public File fileInConceptsDir(String name) { var dir = conceptsDir(); return dir == null ? null : newFile(dir, name); } public long _conceptID() { return id; } } static public class RC { transient public Object owner; public String id; public RC() { } public RC(long id) { this.id = str(id); } public RC(Object owner, long id) { this.id = str(id); this.owner = owner; } public RC(Concept c) { this(c.id); } public long longID() { return parseLong(id); } public String toString() { return id; } transient public RemoteDB db; public String getString(String field) { return db.xS(this, field); } public Object get(String field) { return db.xget(this, field); } public void set(String field, Object value) { db.xset(this, field, value); } } static public class BaseXRef { public String programID; public long id; public BaseXRef() { } public BaseXRef(String programID, long id) { this.id = id; this.programID = programID; } public boolean equals(Object o) { if (!(o instanceof BaseXRef)) return false; BaseXRef r = (BaseXRef) o; return eq(programID, r.programID) && eq(id, r.id); } public int hashCode() { return programID.hashCode() + (int) id; } } static public class XRef extends Concept { public BaseXRef ref; public XRef() { } public XRef(BaseXRef ref) { this.ref = ref; _doneLoading2(); } public void _doneLoading2() { getIndex().put(ref, this); } public HashMap getIndex() { return getXRefIndex(_concepts); } } static synchronized public HashMap getXRefIndex(Concepts concepts) { HashMap cache = (HashMap) concepts.perClassData().get(XRef.class); if (cache == null) concepts.perClassData.put(XRef.class, cache = new HashMap()); return cache; } static public XRef lookupOrCreateXRef(BaseXRef ref) { XRef xref = getXRefIndex(db_mainConcepts()).get(ref); if (xref == null) xref = new XRef(ref); return xref; } static public void loadAndAutoSaveConcepts() { db_mainConcepts().persist(); } static public void loadAndAutoSaveConcepts(int interval) { db_mainConcepts().persist(interval); } static public RC toPassRef(Concept c) { return new RC(c); } static public void concepts_setUnlistedByDefault(boolean b) { concepts_unlistedByDefault = b; } static public List _stickyLibs_1400546 = ll("#1400546", "#1400547", "#1400548"); public interface IUnstructured { public void _doneLoading(); } static public class G22Network extends ConceptWithChangeListeners { static final public String _fieldOrder = "description elements magneticDistance autoCalculate"; public transient FieldVar varDescription_cache; public FieldVar varDescription() { if (varDescription_cache == null) varDescription_cache = varDescription_load(); return varDescription_cache; } public FieldVar varDescription_load() { return new FieldVar(this, "description", () -> description(), description -> description(description)); } final public G22Network setDescription(String description) { return description(description); } public G22Network description(String description) { if (!eq(this.description, description)) { this.description = description; change(); } return this; } final public String getDescription() { return description(); } public String description() { return description; } public String description; public Collection elements = syncL(); public transient FieldVar varMagneticDistance_cache; public FieldVar varMagneticDistance() { if (varMagneticDistance_cache == null) varMagneticDistance_cache = varMagneticDistance_load(); return varMagneticDistance_cache; } public FieldVar varMagneticDistance_load() { return new FieldVar(this, "magneticDistance", () -> magneticDistance(), magneticDistance -> magneticDistance(magneticDistance)); } final public G22Network setMagneticDistance(int magneticDistance) { return magneticDistance(magneticDistance); } public G22Network magneticDistance(int magneticDistance) { if (!eq(this.magneticDistance, magneticDistance)) { this.magneticDistance = magneticDistance; change(); } return this; } final public int getMagneticDistance() { return magneticDistance(); } public int magneticDistance() { return magneticDistance; } public int magneticDistance = 100; public transient FieldVar varAutoCalculate_cache; public FieldVar varAutoCalculate() { if (varAutoCalculate_cache == null) varAutoCalculate_cache = varAutoCalculate_load(); return varAutoCalculate_cache; } public FieldVar varAutoCalculate_load() { return new FieldVar(this, "autoCalculate", () -> autoCalculate(), autoCalculate -> autoCalculate(autoCalculate)); } final public G22Network setAutoCalculate(boolean autoCalculate) { return autoCalculate(autoCalculate); } public G22Network autoCalculate(boolean autoCalculate) { if (!eq(this.autoCalculate, autoCalculate)) { this.autoCalculate = autoCalculate; change(); } return this; } final public boolean getAutoCalculate() { return autoCalculate(); } public boolean autoCalculate() { return autoCalculate; } public boolean autoCalculate = true; public String toString() { return or2(description, super.toString()); } public Collection doMagneticConnections() { List newCables = new ArrayList(); List inputPorts = new ArrayList(); List outputPorts = new ArrayList(); for (var element : elements) for (var port : element.ports()) (port.isOutput() ? outputPorts : inputPorts).add(port); for (var port1 : inputPorts) { if (port1.isConnected()) continue; Rect bounds1 = port1.bounds(); Lowest best = new Lowest(); for (var port2 : outputPorts) { double distance = rectDistance(bounds1, port2.bounds()); if (distance >= magneticDistance) continue; if (!isSubclassOf(port2.dataType(), port1.dataType())) continue; best.put(port2, distance); } var port2 = best.get(); if (port2 != null) { var cable = new G22NetworkCable().from(port2).to(port1); newCables.add(cable); cable.connect(); print("Made cable: " + cable); } } return newCables; } public void deleteMagneticConnections() { for (var cable : allCables()) if (cable.isAutomatic()) cable.remove(); } public Set allCables() { Set set = new HashSet(); for (var element : elements) for (var port : element.ports()) addIfNotNull(set, port.cable); return set; } } static public class DoublePt implements IDoublePt { public double x, y; public DoublePt() { } public DoublePt(Point p) { x = p.x; y = p.y; } public DoublePt(double x, double y) { this.y = y; this.x = x; } public boolean equals(Object p) { if (p instanceof DoublePt) { return x == ((DoublePt) p).x && y == ((DoublePt) p).y; } return false; } public int hashCode() { return boostHashCombine(main.hashCode(x), main.hashCode(y)); } public String toString() { return x + ", " + y; } public double length() { return sqrt(x * x + y * y); } public double x_double() { return x; } public double y_double() { return y; } } static public class Value implements IF0, IFieldsToList { public A value; public Value() { } public Value(A value) { this.value = value; } public boolean equals(Object o) { if (!(o instanceof Value)) return false; Value __1 = (Value) o; return eq(value, __1.value); } public int hashCode() { int h = 82420049; h = boostHashCombine(h, _hashCode(value)); return h; } public Object[] _fieldsToList() { return new Object[] { value }; } public A get() { return value; } public String toString() { return str(get()); } } static public class G22ScriptResultPanel implements Swingable { public JTabbedPane tabs; public JFastLogView_noWrap logView = jFastLogView_noWrap(); public SingleComponentPanel scpResult = singleComponentPanel(); public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return tabs = jtabs("Result", scpResult, "Log", jscroll_borderless(logView)); } } static public interface IVF2 { public void get(A a, B b); } public interface G22MasterStuff { public RunnablesReferenceQueue runnablesReferenceQueue(); public EphemeralObjectIDs ephemeralObjectIDs(); public File databasesMotherDir(); default public IG22LoadedDB openDatabase(File dir) { return openDatabase(dir, false); } public IG22LoadedDB openDatabase(File dir, boolean hidden); public void closeDatabase(File dir); public void switchToDatabase(File dir); public Collection openConceptDirs(); public IG22LoadedDB getLoadedDB(Concepts concepts); public IG22LoadedDB getLoadedDBForConceptDir(File dir); public Collection getLoadedDBs(); public G22MasterStuff onLoadedDBsChange(Runnable r); public G22MasterStuff removeLoadedDBsChangeListener(Runnable r); public IF1 makeClassFinder(); public IF0WithChangeListeners lvGazelleUserCount(); public ILASClassLoader lasClassLoader(); } public interface Enterable { public AutoCloseable enter(); } static public class PingSourceCancelledException extends RuntimeException implements IFieldsToList { public PingSource pingSource; public PingSourceCancelledException() { } public PingSourceCancelledException(PingSource pingSource) { this.pingSource = pingSource; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + pingSource + ")"; } public Object[] _fieldsToList() { return new Object[] { pingSource }; } } static public class OKOrError implements IF0 { public A value; final public Throwable getError() { return error(); } public Throwable error() { return error; } public Throwable error; public OKOrError() { } public OKOrError(A value) { this.value = value; } public OKOrError(boolean dummy, Throwable error) { this.error = error; assertNotNull(error); } final public boolean isOK() { return ok(); } public boolean ok() { return error == null; } public boolean isError() { return error != null; } public String toString() { return ok() ? str(value) : "Error: " + str(error); } public A get() { return !ok() ? null : value; } public A getMandatory() { if (!ok()) throw rethrow(error); return value; } static public OKOrError ok(A a) { return new OKOrError(a); } static public OKOrError error(Throwable error) { return new OKOrError(false, error); } public void setValue(A value) { this.value = value; error = null; } public void setError(Throwable error) { this.value = null; this.error = error; } public void copyFrom(OKOrError x) { value = x.value; error = x.error; } } static public class G22NetworkCable { final public G22NetworkCable setFrom(G22NetworkElement.Port from) { return from(from); } public G22NetworkCable from(G22NetworkElement.Port from) { this.from = from; return this; } final public G22NetworkElement.Port getFrom() { return from(); } public G22NetworkElement.Port from() { return from; } public G22NetworkElement.Port from; final public G22NetworkCable setTo(G22NetworkElement.Port to) { return to(to); } public G22NetworkCable to(G22NetworkElement.Port to) { this.to = to; return this; } final public G22NetworkElement.Port getTo() { return to(); } public G22NetworkElement.Port to() { return to; } public G22NetworkElement.Port to; final public G22NetworkCable setIsAutomatic(boolean isAutomatic) { return isAutomatic(isAutomatic); } public G22NetworkCable isAutomatic(boolean isAutomatic) { this.isAutomatic = isAutomatic; return this; } final public boolean getIsAutomatic() { return isAutomatic(); } public boolean isAutomatic() { return isAutomatic; } public boolean isAutomatic = false; public void connect() { from.cable(this); to.cable(this); } public void remove() { { if (from != null) from.cable(null); } { if (to != null) to.cable(null); } } public String toString() { return renderVars("G22NetworkCable", "from", from, "to", to, "isAutomatic", isAutomatic); } } static public class LASScope { final public LASScope setUseFixedVars(boolean useFixedVars) { return useFixedVars(useFixedVars); } public LASScope useFixedVars(boolean useFixedVars) { this.useFixedVars = useFixedVars; return this; } final public boolean getUseFixedVars() { return useFixedVars(); } public boolean useFixedVars() { return useFixedVars; } public boolean useFixedVars = false; final public Map getDeclaredVars() { return declaredVars(); } public Map declaredVars() { return declaredVars; } public Map declaredVars = new HashMap(); final public LASScope setParentScope(LASScope parentScope) { return parentScope(parentScope); } public LASScope parentScope(LASScope parentScope) { this.parentScope = parentScope; return this; } final public LASScope getParentScope() { return parentScope(); } public LASScope parentScope() { return parentScope; } public LASScope parentScope; final public LASScope setParentIsDetached(boolean parentIsDetached) { return parentIsDetached(parentIsDetached); } public LASScope parentIsDetached(boolean parentIsDetached) { this.parentIsDetached = parentIsDetached; return this; } final public boolean getParentIsDetached() { return parentIsDetached(); } public boolean parentIsDetached() { return parentIsDetached; } public boolean parentIsDetached = false; public String[] names; public LASScope() { } public LASScope(LASScope parentScope) { this.parentScope = parentScope; } public boolean resolved() { return names != null; } public void addDeclaredVar(String name, LASValueDescriptor type) { if (resolved()) throw fail("Can't add variables to resolved scope"); declaredVars.put(name, type); } public int resolveVar(String name) { resolve(); int idx = indexOfInSortedArray(names, name); if (idx < 0) throw fail("Variable not found in scope: " + name); return idx; } public void resolve() { if (names != null) return; names = empty(declaredVars) ? null : toStringArray(sortedKeys(declaredVars)); } } static public class ConvertLASToJava extends Meta { public Object convert(LASClassDef.FieldDef field) { return "/*settable?*/ " + shortClassName(field.type()) + " " + field.name() + ";"; } public Object convert(GazelleV_LeftArrowScript.FunctionDef f) { return "O " + f.name + "(" + joinWithComma(map(f.args, arg -> "O " + arg)) + ") {\n" + indentx(convert(f.body, true)) + "}\n"; } public Object convertWithLeadingSpace(GazelleV_LeftArrowScript.Evaluable o) { return leadingSpace(o, "") + convert(o); } public Object convertWithLeadingSpace2(GazelleV_LeftArrowScript.Evaluable o) { return replaceIfEqual(leadingSpace(o, ""), " ", "") + convert(o); } public String leadingSpace(GazelleV_LeftArrowScript.Evaluable o, String defaultSpace) { String space = null; var src = o.tokenRangeWithSrc(); if (src != null) space = src.startPtr().mapIdx(idx -> idx & ~1).get(); return or2(space, defaultSpace); } public String trailingSpace(GazelleV_LeftArrowScript.Evaluable o, String defaultSpace) { String space = null; var src = o.tokenRangeWithSrc(); if (src != null) { String rawSpace = src.endPtr().mapIdx(idx -> idx & ~1).get(); space = replaceRegexp(rawSpace, "\n[ \t]+$", "\n"); if (scaffoldingEnabled()) printVars("trailingSpace", "rawSpace", quote(rawSpace), "space", quote(space)); } return or2(space, defaultSpace); } public Object getInstruction(GazelleV_LeftArrowScript.Evaluable o) { Object inner = convert(o); boolean needSemicolon = !(o instanceof GazelleV_LeftArrowScript.ClassDef) && !(o instanceof GazelleV_LeftArrowScript.ForEachBase); String space = trailingSpace(o, "\n"); if (scaffoldingEnabled()) printVars("space", space, "o", className(o), "srcText", quote(o.srcText()), "inner", inner); return inner + (needSemicolon ? ";" : "") + space; } public Object convert(GazelleV_LeftArrowScript.Script script, boolean returnLastResult) { var steps = asList(script.steps); if (returnLastResult) { if (empty(steps)) return "return null;"; var last = last(steps); if (!(last instanceof GazelleV_LeftArrowScript.ReturnFromScript) && !(last instanceof GazelleV_LeftArrowScript.ClassDef)) setLast(steps, new GazelleV_LeftArrowScript.ReturnFromScript(script, last)); } return concatMapStrings(i -> str(getInstruction(i)), steps); } public Object convert(GazelleV_LeftArrowScript.Evaluable o, boolean returnLastResult) { if (o instanceof GazelleV_LeftArrowScript.Script) return convert(((GazelleV_LeftArrowScript.Script) o), returnLastResult); return convert(o); } public Object convert(GazelleV_LeftArrowScript.Evaluable o) { if (o == null) return null; if (o instanceof GazelleV_LeftArrowScript.GetVar) return ((GazelleV_LeftArrowScript.GetVar) o).var; if (o instanceof GazelleV_LeftArrowScript.Script) return convert(((GazelleV_LeftArrowScript.Script) o), false); if (o instanceof GazelleV_LeftArrowScript.ClassDef) { LASClassDef c = ((GazelleV_LeftArrowScript.ClassDef) o).lasClass.classDef; return "class " + c.userGivenName + " " + curly("\n" + appendNewLineIfNempty(indentx(joinNemptiesWithEmptyLines(lines_rtrim(map(__32 -> convert(__32), c.fields)), lines_rtrim(map(__33 -> convert(__33), c.methods)))))); } if (o instanceof GazelleV_LeftArrowScript.Assignment) return ((GazelleV_LeftArrowScript.Assignment) o).var + " = " + convert(((GazelleV_LeftArrowScript.Assignment) o).expression); if (o instanceof GazelleV_LeftArrowScript.VarDeclaration) return "var " + ((GazelleV_LeftArrowScript.VarDeclaration) o).var + " = " + convert(((GazelleV_LeftArrowScript.VarDeclaration) o).expression); if (o instanceof GazelleV_LeftArrowScript.CallMethod) { String targetStr = null; var targetType = ((GazelleV_LeftArrowScript.CallMethod) o).target.returnType(); if (targetType.knownValue()) { Object target = targetType.value(); if (target instanceof Class && eqOneOf(shortClassName((Class) target), "main", "utils")) targetStr = ""; } if (targetStr == null) targetStr = str(convert(((GazelleV_LeftArrowScript.CallMethod) o).target)); return (empty(targetStr) ? "" : targetStr + ".") + new FunctionCall(((GazelleV_LeftArrowScript.CallMethod) o).methodName, map(__34 -> convertWithLeadingSpace2(__34), ((GazelleV_LeftArrowScript.CallMethod) o).args)); } if (o instanceof GazelleV_LeftArrowScript.SetField) return convert(((GazelleV_LeftArrowScript.SetField) o).target) + "." + ((GazelleV_LeftArrowScript.SetField) o).name + " = " + convert(((GazelleV_LeftArrowScript.SetField) o).expr); if (o instanceof GazelleV_LeftArrowScript.CallMethodOrGetField) return convert(((GazelleV_LeftArrowScript.CallMethodOrGetField) o).target) + "." + ((GazelleV_LeftArrowScript.CallMethodOrGetField) o).name + "()"; if (o instanceof GazelleV_LeftArrowScript.NewObject) return "new " + new FunctionCall(shortClassName(((GazelleV_LeftArrowScript.NewObject) o).c), map(__35 -> convert(__35), ((GazelleV_LeftArrowScript.NewObject) o).args)).toStringWithOptionalParens(); if (o instanceof GazelleV_LeftArrowScript.IfThen) return "if (" + convert(((GazelleV_LeftArrowScript.IfThen) o).condition) + ") " + curlyIfScript(((GazelleV_LeftArrowScript.IfThen) o).body) + (((GazelleV_LeftArrowScript.IfThen) o).elseBranch == null ? "" : " else " + curlyIfScript(((GazelleV_LeftArrowScript.IfThen) o).elseBranch)); if (o instanceof GazelleV_LeftArrowScript.Const) { var c = (GazelleV_LeftArrowScript.Const) o; { var __1 = c == null ? null : c.srcText(); if (__1 != null) return __1; } try { return toJava(((GazelleV_LeftArrowScript.Const) o).value); } catch (Throwable __e) { printStackTrace(__e); } } if (o instanceof GazelleV_LeftArrowScript.ForEach) return "fOr (" + ((GazelleV_LeftArrowScript.ForEach) o).var + " : " + convert(((GazelleV_LeftArrowScript.ForEach) o).collection) + ") {\n" + indentx(convert(((GazelleV_LeftArrowScript.ForEach) o).body, false)) + "\n}"; if (o instanceof GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) { int nArgs = ((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).implementedMethod.getParameterCount(); List args = countIteratorToList_incl(1, nArgs, i -> "_" + i); List fullArgs = concatLists(allToString(map(__36 -> convert(__36), ((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).curriedArgs)), args); return roundBracketed(shortClassName(((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).intrface)) + " " + lambdaArgsToString_pureJava(args) + " -> " + new FunctionCall(((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).f.name, fullArgs); } if (o instanceof GazelleV_LeftArrowScript.LambdaDef) return roundBracketed(shortClassName(((GazelleV_LeftArrowScript.LambdaDef) o).intrface)) + " " + joinNemptiesWithSpace(lambdaArgsToString_pureJava(((GazelleV_LeftArrowScript.LambdaDef) o).args), "-> " + curlyIfScript(((GazelleV_LeftArrowScript.LambdaDef) o).body)); if (o instanceof GazelleV_LeftArrowScript.ReturnFromScript) return "ret " + convert(((GazelleV_LeftArrowScript.ReturnFromScript) o).value); warn("Can't convert to Java: " + className(o)); if (o instanceof GazelleV_LeftArrowScript.Base) { var b = (GazelleV_LeftArrowScript.Base) o; { var __2 = b == null ? null : b.srcText(); if (__2 != null) return __2; } } warn("No source reference in script object: " + className(o)); return str(o); } public Object curlyIfScript(GazelleV_LeftArrowScript.Evaluable o) { if (o instanceof GazelleV_LeftArrowScript.Script) return "{\n" + indentx(convert((GazelleV_LeftArrowScript.Script) o)) + "\n}"; return convert(o); } public String get(GazelleV_LeftArrowScript.Evaluable o, boolean returnLastResult) { String src = strOrEmpty(convert(o, returnLastResult)); JavaXPeepholeShortener shortener = new JavaXPeepholeShortener(javaTok(src)); shortener.run(); return join(shortener.tok); } } static public class ThreadPool implements AutoCloseable { public int max = numberOfCores(); public List all = new ArrayList(); public Set used = new HashSet(); public Set free = new HashSet(); public boolean verbose, retired; public class InternalPingSource extends PingSource { } public InternalPingSource internalPingSource = new InternalPingSource(); public MultiSleeper sleeper = new MultiSleeper(); public ThreadPool() { } public ThreadPool(int max) { this.max = max; } synchronized public int maxSize() { return max; } synchronized public int total() { return l(used) + l(free); } transient public Set onCustomerMustWaitAlert; public ThreadPool onCustomerMustWaitAlert(Runnable r) { onCustomerMustWaitAlert = createOrAddToSyncLinkedHashSet(onCustomerMustWaitAlert, r); return this; } public ThreadPool removeCustomerMustWaitAlertListener(Runnable r) { main.remove(onCustomerMustWaitAlert, r); return this; } public void customerMustWaitAlert() { if (onCustomerMustWaitAlert != null) for (var listener : onCustomerMustWaitAlert) pcallF_typed(listener); } public void fireCustomerMustWaitAlert() { vmBus_send("customerMustWaitAlert", this, currentThread()); customerMustWaitAlert(); } public PooledThread acquireThreadOrQueue(Runnable action) { if (action == null) return null; PooledThread t; synchronized (this) { if (_hasFreeAfterCreating()) { t = _firstFreeThread(); markUsed(t); } else t = _anyThread(); } t.addWork(action); return t; } public boolean _hasFreeAfterCreating() { checkNotRetired(); if (nempty(free)) return true; if (total() < max) { PooledThread t = newThread(); all.add(t); free.add(t); return true; } return false; } public PooledThread acquireThreadOrWait(Runnable action) { try { if (action == null) return null; PooledThread t; while (true) { synchronized (this) { if (_hasFreeAfterCreating()) { t = _firstFreeThread(); break; } else _waitWaitWait(); } } t.addWork(action); return t; } catch (Exception __e) { throw rethrow(__e); } } public PooledThread _firstFreeThread() { return first(free); } public PooledThread _anyThread() { return random(used); } public class PooledThread extends Thread { public PooledThread(String name) { super(name); } public AppendableChain q; synchronized public Runnable _grabWorkOrSleep() { try { Runnable r = first(q); if (r == null) { markFree(this); if (verbose) print("Thread sleeps"); synchronized (this) { wait(); } if (verbose) print("Thread woke up"); return null; } q = popFirst(q); return r; } catch (Exception __e) { throw rethrow(__e); } } public void run() { try { pingSource_tl().set(internalPingSource); while (!retired()) { ping(); Runnable r = _grabWorkOrSleep(); if (verbose) print(this + " work: " + r); if (r != null) try { if (verbose) print(this + " running: " + r); r.run(); pingSource_tl().set(internalPingSource); if (verbose) print(this + " done"); } catch (Throwable e) { pingSource_tl().set(internalPingSource); if (verbose) print(this + " error"); printStackTrace(e); } finally { pingSource_tl().set(internalPingSource); if (verbose) print("ThreadPool finally"); } } } catch (Exception __e) { throw rethrow(__e); } } synchronized public boolean isEmpty() { return empty(q); } public void addWork(Runnable r) { if (verbose) print("Added work to " + this + ": " + r); synchronized (this) { q = chainPlus(q, r); notifyAll(); } } } public PooledThread newThread() { PooledThread t = new PooledThread("Thread Pool Inhabitant " + n2(total() + 1)); t.start(); return t; } synchronized public void markFree(PooledThread t) { used.remove(t); free.add(t); notifyAll(); } synchronized public void markUsed(PooledThread t) { free.remove(t); used.add(t); } synchronized public String toString() { return retired() ? "Retired ThreadPool" : "ThreadPool " + roundBracket(commaCombine(n2(used) + " used out of " + n2(total()), max <= total() ? null : "could grow to " + n2(max))); } synchronized public boolean retired() { return retired; } synchronized public void retire() { if (verbose) print("ThreadPool Retiring"); retired = true; for (var thread : free) syncNotifyAll(thread); } public void checkNotRetired() { if (retired()) throw fail("retired"); } synchronized public void close() { try { retire(); } catch (Exception __e) { throw rethrow(__e); } } public void _waitWaitWait() { try { do { fireCustomerMustWaitAlert(); wait(); checkNotRetired(); } while (empty(free)); } catch (Exception __e) { throw rethrow(__e); } } public void dO(String text, Runnable r) { if (r == null) return; new PingSource(this, text).dO(r); } public ISleeper_v2 sleeper() { return sleeper; } } static public class RunnablesReferenceQueue implements AutoCloseable { public ReferenceQueue queue = new ReferenceQueue(); volatile public Thread thread; public Flag closed = new Flag(); final public RunnablesReferenceQueue setTimeout(int timeout) { return timeout(timeout); } public RunnablesReferenceQueue timeout(int timeout) { this.timeout = timeout; return this; } final public int getTimeout() { return timeout(); } public int timeout() { return timeout; } public int timeout = 60000; public RunnablesReferenceQueue() { thread = startThread("RunnablesReferenceQueue", () -> _run()); } public void _run() { try { try { while (ping() && !closed.get()) { Reference ref = queue.remove(timeout); if (ref != null) { if (ref instanceof Runnable) pcallF((Runnable) ref); else warn("RunnablesReferenceQueue: Reference not runnable - " + className(ref)); } } } catch (InterruptedException e) { } finally { thread = null; } } catch (Exception __e) { throw rethrow(__e); } } public void close() { try { closed.raise(); interruptThread(thread); } catch (Exception __e) { throw rethrow(__e); } } final public ReferenceQueue get() { return queue(); } public ReferenceQueue queue() { return queue; } } static public class JPopDownButton extends JButton { public String menuPosition = "left"; public JPopDownButton() { this(""); } public JPopDownButton(String text) { super(joinNemptiesWithSpace(text, unicode_downPointingTriangle())); main.addActionListener(this, new Runnable() { public void run() { try { openMenu(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "openMenu();"; } }); } public JPopDownButton(IVF1 fillMenu) { this(); this.fillMenu = fillMenu; } transient public Set> onFillingMenu; public JPopDownButton onFillingMenu(IVF1 f) { onFillingMenu = createOrAddToSyncLinkedHashSet(onFillingMenu, f); return this; } public JPopDownButton removeFillingMenuListener(IVF1 f) { main.remove(onFillingMenu, f); return this; } public void fillingMenu(JPopupMenu menu) { if (onFillingMenu != null) for (var listener : onFillingMenu) pcallF_typed(listener, menu); } transient public IVF1 fillMenu; public void fillMenu(JPopupMenu menu) { if (fillMenu != null) fillMenu.get(menu); else fillMenu_base(menu); } final public void fillMenu_fallback(IVF1 _f, JPopupMenu menu) { if (_f != null) _f.get(menu); else fillMenu_base(menu); } public void fillMenu_base(JPopupMenu menu) { fillingMenu(menu); } public void openMenu() { JPopupMenu menu = new JPopupMenu(); int emptyCount = menu.getComponentCount(); fillMenu(menu); if (menu.getComponentCount() == emptyCount) return; int x = 0; if (eq(menuPosition, "center")) x = (getWidth() - getPreferredWidth(menu)) / 2; else if (eq(menuPosition, "right")) x = getWidth() - getPreferredWidth(menu); menu.show(this, x, getHeight()); } } 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); } public Duration minusAsDuration(Timestamp ts) { return Duration.ofMillis(minus(ts)); } } 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); } } public interface ILASClassLoader { public Class defineLASClass(String name, IF0 generateClass); public Object rememberClassBytes(boolean rememberClassBytes); } static public class GazelleV_LeftArrowScriptParser extends SimpleLeftToRightParser { public ClassNameResolver classNameResolver; public List functionContainers = new ArrayList(); final public GazelleV_LeftArrowScriptParser setLasClassLoader(ILASClassLoader lasClassLoader) { return lasClassLoader(lasClassLoader); } public GazelleV_LeftArrowScriptParser lasClassLoader(ILASClassLoader lasClassLoader) { this.lasClassLoader = lasClassLoader; return this; } final public ILASClassLoader getLasClassLoader() { return lasClassLoader(); } public ILASClassLoader lasClassLoader() { return lasClassLoader; } public ILASClassLoader lasClassLoader; final public GazelleV_LeftArrowScriptParser setClassDefPrefix(String classDefPrefix) { return classDefPrefix(classDefPrefix); } public GazelleV_LeftArrowScriptParser classDefPrefix(String classDefPrefix) { this.classDefPrefix = classDefPrefix; return this; } final public String getClassDefPrefix() { return classDefPrefix(); } public String classDefPrefix() { return classDefPrefix; } public String classDefPrefix; final public GazelleV_LeftArrowScriptParser setOptimize(boolean optimize) { return optimize(optimize); } public GazelleV_LeftArrowScriptParser optimize(boolean optimize) { this.optimize = optimize; return this; } final public boolean getOptimize() { return optimize(); } public boolean optimize() { return optimize; } public boolean optimize = true; final public GazelleV_LeftArrowScriptParser setUseFixedVarContexts(boolean useFixedVarContexts) { return useFixedVarContexts(useFixedVarContexts); } public GazelleV_LeftArrowScriptParser useFixedVarContexts(boolean useFixedVarContexts) { this.useFixedVarContexts = useFixedVarContexts; return this; } final public boolean getUseFixedVarContexts() { return useFixedVarContexts(); } public boolean useFixedVarContexts() { return useFixedVarContexts; } public boolean useFixedVarContexts = false; public LASScope scope; public LinkedHashMap knownVars = new LinkedHashMap(); public List varAccessesToFix = new ArrayList(); public Set closerTokens = litset(";", "}", ")"); public BuildingScript currentReturnableScript; public BuildingScript currentLoop; public boolean inParens = false; public int idCounter; public Map classDefs = new HashMap(); transient public Set>> onKnownVarsSnapshot; public GazelleV_LeftArrowScriptParser onKnownVarsSnapshot(IVF1> f) { onKnownVarsSnapshot = createOrAddToSyncLinkedHashSet(onKnownVarsSnapshot, f); return this; } public GazelleV_LeftArrowScriptParser removeKnownVarsSnapshotListener(IVF1> f) { main.remove(onKnownVarsSnapshot, f); return this; } public void knownVarsSnapshot(Map knownVars) { if (onKnownVarsSnapshot != null) for (var listener : onKnownVarsSnapshot) pcallF_typed(listener, knownVars); } transient public Set> onTypeHook; public GazelleV_LeftArrowScriptParser onTypeHook(IVF1 f) { onTypeHook = createOrAddToSyncLinkedHashSet(onTypeHook, f); return this; } public GazelleV_LeftArrowScriptParser removeTypeHookListener(IVF1 f) { main.remove(onTypeHook, f); return this; } public void typeHook(LASValueDescriptor type) { if (onTypeHook != null) for (var listener : onTypeHook) pcallF_typed(listener, type); } static public class MethodOnObject implements IFieldsToList { static final public String _fieldOrder = "object method"; public Object object; public String method; public MethodOnObject() { } public MethodOnObject(Object object, String method) { this.method = method; this.object = object; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + object + ", " + method + ")"; } public boolean equals(Object o) { if (!(o instanceof MethodOnObject)) return false; MethodOnObject __15 = (MethodOnObject) o; return eq(object, __15.object) && eq(method, __15.method); } public int hashCode() { int h = 791808543; h = boostHashCombine(h, _hashCode(object)); h = boostHashCombine(h, _hashCode(method)); return h; } public Object[] _fieldsToList() { return new Object[] { object, method }; } } static public class EvaluableWrapper implements IFieldsToList { public GazelleV_LeftArrowScript.Evaluable expr; public EvaluableWrapper() { } public EvaluableWrapper(GazelleV_LeftArrowScript.Evaluable expr) { this.expr = expr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + expr + ")"; } public boolean equals(Object o) { if (!(o instanceof EvaluableWrapper)) return false; EvaluableWrapper __16 = (EvaluableWrapper) o; return eq(expr, __16.expr); } public int hashCode() { int h = 700525824; h = boostHashCombine(h, _hashCode(expr)); return h; } public Object[] _fieldsToList() { return new Object[] { expr }; } } public class BuildingScript { public int id = ++idCounter; final public BuildingScript setReturnable(boolean returnable) { return returnable(returnable); } public BuildingScript returnable(boolean returnable) { this.returnable = returnable; return this; } final public boolean getReturnable() { return returnable(); } public boolean returnable() { return returnable; } public boolean returnable = false; final public BuildingScript setIsLoopBody(boolean isLoopBody) { return isLoopBody(isLoopBody); } public BuildingScript isLoopBody(boolean isLoopBody) { this.isLoopBody = isLoopBody; return this; } final public boolean getIsLoopBody() { return isLoopBody(); } public boolean isLoopBody() { return isLoopBody; } public boolean isLoopBody = false; public BuildingScript returnableParent, loopParent; final public BuildingScript setScope(LASScope scope) { return scope(scope); } public BuildingScript scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public GazelleV_LeftArrowScript.Script script = new GazelleV_LeftArrowScript.Script(); public List steps = new ArrayList(); public Map functionDefs = new HashMap(); public BuildingScript(boolean returnable) { this(); this.returnable = returnable; } public BuildingScript(boolean returnable, boolean isLoopBody) { this(); this.isLoopBody = isLoopBody; this.returnable = returnable; } public BuildingScript() { scope = currentScope(); } public void add(GazelleV_LeftArrowScript.Evaluable step) { if (step != null) steps.add(step); } public GazelleV_LeftArrowScript.Evaluable get() { script.scope = scope; var lastStep = last(steps); if (lastStep instanceof GazelleV_LeftArrowScript.ReturnFromScript) if (((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).script == script) replaceLast(steps, ((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).value); if (!returnable && l(steps) == 1 && empty(functionDefs)) return first(steps); if (nempty(functionDefs)) script.functionDefs = functionDefs; script.steps = toTypedArray(GazelleV_LeftArrowScript.Evaluable.class, steps); return script; } public String toStringLong() { return pnlToLines(steps); } public String toString() { return formatRecordVars("BuildingScript", "id", id, "returnable", returnable, "returnableParent", returnableParent, "script", script); } } public GazelleV_LeftArrowScript.Script parse(String text) { setText(text); init(); return parse(); } public GazelleV_LeftArrowScript.Script parse() { GazelleV_LeftArrowScript.Script script = parseReturnableScript(); for (var varAccess : varAccessesToFix) varAccess.resolve(); if (optimize) script = script.optimizeScript(); return script; } public GazelleV_LeftArrowScript.Script parseReturnableScript() { return (GazelleV_LeftArrowScript.Script) parseScript(new BuildingScript().returnable(true)); } public GazelleV_LeftArrowScript.Evaluable parseScript(BuildingScript script) { return linkToSrc(() -> { script.returnableParent = currentReturnableScript; script.loopParent = currentLoop; if (script.returnable) currentReturnableScript = script; if (script.isLoopBody) currentLoop = script; return parseBuildingScript(script); }); } public GazelleV_LeftArrowScript.Evaluable parseBuildingScript(BuildingScript script) { try { parseScript_2(script); var builtScript = script.get(); currentReturnableScript = script.returnableParent; currentLoop = script.loopParent; return builtScript; } catch (Throwable e) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Parsed so far:\n" + script); throw rethrowAndAppendToMessage(e, squareBracketed(str(lineAndColumn(-1)))); } } public void parseScript_2(BuildingScript script) { AutoCloseable __6 = tempRestoreMap(knownVars); try { AssureAdvance assure = new AssureAdvance(); while (assure.get()) { knownVarsSnapshot(knownVars); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseScript_2: Next token is " + quote(token())); if (is(";")) { next(); continue; } if (isOneOf("}", ")")) break; GazelleV_LeftArrowScript.Evaluable instruction = linkToSrc(() -> parseInstruction(script)); if (instruction != null) script.add(instruction); } if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseScript_2 done"); knownVarsSnapshot(knownVars); } finally { _close(__6); } } public GazelleV_LeftArrowScript.Evaluable parseInstruction(BuildingScript script) { if (is("def")) { parseFunctionDefinition(currentReturnableScript.functionDefs); return null; } if (is("param")) { consume(); String var = assertIdentifier(tpp()); LASValueDescriptor valueDescriptor = new LASValueDescriptor(); if (is(":")) { var type = parseColonType(); valueDescriptor = LASValueDescriptor.nonExactCanBeNull(type); } knownVars.put(var, valueDescriptor); script.script.params = putOrCreateLinkedHashMap(script.script.params, var, valueDescriptor); return null; } if (is("throw")) { consume(); return new GazelleV_LeftArrowScript.Throw(parseExpr()); } if (is("try")) { consume(); GazelleV_LeftArrowScript.Evaluable body = parseCurlyBlock(new BuildingScript()); while (consumeOpt("catch")) { String var = consumeIdentifier(); AutoCloseable __7 = tempAddKnownVars(var); try { GazelleV_LeftArrowScript.Evaluable catchBlock = parseCurlyBlock(new BuildingScript()); body = new GazelleV_LeftArrowScript.TryCatch(body, var, catchBlock); } finally { _close(__7); } } if (consumeOpt("finally")) { GazelleV_LeftArrowScript.Evaluable finallyBlock = parseCurlyBlock(new BuildingScript()); return new GazelleV_LeftArrowScript.TryFinally(body, finallyBlock); } return body; } if (isOneOf("return", "ret")) { consume(); GazelleV_LeftArrowScript.Evaluable expr; if (atCmdEnd()) expr = _const(null); else expr = parseAssignmentOrExpr(); return new GazelleV_LeftArrowScript.ReturnFromScript(currentReturnableScript.script, expr); } if (is("continue")) { consume(); assertCmdEnd(); if (currentLoop == null) throw fail("continue outside of loop"); return new GazelleV_LeftArrowScript.Continue(currentLoop.script); } if (is("temp")) { consume(); GazelleV_LeftArrowScript.Evaluable tempExpr = parseAssignmentOrExpr(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("tempExpr", tempExpr); GazelleV_LeftArrowScript.Evaluable body = parseScript(new BuildingScript()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("body", body); return new GazelleV_LeftArrowScript.TempBlock(tempExpr, body); } if (is("class")) return new GazelleV_LeftArrowScript.ClassDef(new ResolvableLASClass(lasClassLoader, parseClassDef())); return parseAssignmentOrExpr(); } public GazelleV_LeftArrowScript.Evaluable parseAssignmentOrExpr() { { var __3 = parseAssignmentOpt(); if (__3 != null) return __3; } return parseExpr(); } public GazelleV_LeftArrowScript.Evaluable parseAssignmentOpt() { String t = token(); if (isIdentifier(t)) { Type type = null; var ptr = ptr(); if (is(1, ":")) { next(); type = parseColonType(); unconsume(); } if (is(1, "<") && is(2, "-")) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Found assignment"); next(3); GazelleV_LeftArrowScript.Evaluable rhs = parseExpr(); assertNotNull("Expression expected", rhs); boolean newVar = !knownVars.containsKey(t); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("newVar", newVar, "t", t, "knownVars", knownVars); knownVars.put(t, type == null ? new LASValueDescriptor() : LASValueDescriptor.nonExactCanBeNull(type)); return newVar ? new GazelleV_LeftArrowScript.VarDeclaration(t, null, rhs) : new GazelleV_LeftArrowScript.Assignment(t, rhs); } ptr(ptr); } return null; } public GazelleV_LeftArrowScript.Evaluable parseOptionalInnerExpression() { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("parseOptionalInnerExpression", "token", token()); if (atCmdEnd() || isOneOf("{", ",")) return null; return parseInnerExpr(); } public GazelleV_LeftArrowScript.Evaluable _const(Object o) { return new GazelleV_LeftArrowScript.Const(o); } public GazelleV_LeftArrowScript.Evaluable parseInnerExpr() { return parseExpr(true); } public GazelleV_LeftArrowScript.Evaluable parseExpr() { if (metaGet("scaffolding") != null) scaffoldCalled(this, "parseExpr"); return parseExpr(false); } public GazelleV_LeftArrowScript.Evaluable parseExpr(boolean inner) { GazelleV_LeftArrowScript.Evaluable e = linkToSrc(() -> inner ? parseExpr_impl(true) : parseFullExpr()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseExpr done:\n" + GazelleV_LeftArrowScript.indentedScriptStruct(e)); return e; } public GazelleV_LeftArrowScript.Evaluable parseFullExpr() { return parseExprPlusOptionalComma(); } public GazelleV_LeftArrowScript.Evaluable parseExprPlusOptionalComma() { GazelleV_LeftArrowScript.Evaluable expr = parseExpr_impl(false); while (consumeOpt(",")) { expr = parseCall_noCmdEndCheck(expr); } return expr; } public GazelleV_LeftArrowScript.Evaluable parseExpr_impl(boolean inner) { if (atEnd()) return null; String t = token(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("parseExpr", "token", t); if (is(";")) return null; if (is("{")) return parseCurlyBlock(new BuildingScript()); if (is("-") && empty(nextSpace()) && startsWithDigit(token(1)) || startsWithDigit(t)) { var e = parseNumberLiteral(); return inner ? e : parseCall(e); } if (isQuoted(t)) { var e = parseStringLiteral(); return inner ? e : parseCall(e); } if (startsWith(t, '\'')) { consume(); var e = _const(first(unquote(t))); return inner ? e : parseCall(e); } if (isIdentifier(t)) { if (is("while")) return parseWhileLoop(); if (is("for")) return parseForEach(); if (is("if")) return parseIfStatement(); if (is("repeat")) return parseRepeatStatement(); if (is("outer")) { consume(); var a = parseAssignmentOpt(); if (!(a instanceof GazelleV_LeftArrowScript.Assignment)) throw fail("Assignment expected"); return new GazelleV_LeftArrowScript.AssignmentToOuterVar(((GazelleV_LeftArrowScript.Assignment) a).var, ((GazelleV_LeftArrowScript.Assignment) a).expression); } consume(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Consumed identifier " + t + ", next token: " + token() + ", inner: " + inner); return parseExprStartingWithIdentifier(t, inner); } if (eq(t, "(")) { boolean inParensOld = inParens; inParens = true; consume(); var e = parseExpr(); consume(")"); inParens = inParensOld; return inner ? e : parseCall(e); } if (isOneOf("&", "|") && empty(nextSpace()) && is(1, token())) { return parseBinaryOperator(); } throw fail("Identifier, literal, operator or opening parentheses expected (got: " + quote(t)); } public GazelleV_LeftArrowScript.Evaluable parseNumberLiteral() { String t = consumeMultiTokenLiteral(); if (swic(t, "0x")) return _const(parseHexInt(dropFirst(t, 2))); if (swic(t, "0b")) return _const(intFromBinary(dropFirst(t, 2))); if (isInteger(t)) return _const(parseInt(t)); if (endsWith(t, "f")) return _const(parseFloat(t)); if (endsWith(t, "L")) return _const(parseLong(t)); return _const(parseDouble(t)); } public GazelleV_LeftArrowScript.Evaluable parseBinaryOperator() { boolean and = is("&"); next(2); GazelleV_LeftArrowScript.Evaluable a = parseInnerExpr(); GazelleV_LeftArrowScript.Evaluable b = parseInnerExpr(); return and ? new GazelleV_LeftArrowScript.BoolAnd(a, b) : new GazelleV_LeftArrowScript.BoolOr(a, b); } public boolean qualifiedNameContinues() { return empty(prevSpace()) && eq(token(), ".") && empty(nextSpace()) && isIdentifier(token(1)); } public GazelleV_LeftArrowScript.Evaluable parseExprStartingWithIdentifier(String t, boolean inner) { if (eq(t, "true")) return _const(true); if (eq(t, "false")) return _const(false); if (eq(t, "null")) return _const(null); if (eq(t, "new")) { String className = assertIdentifier(tpp()); parseTypeArguments(null); LASClassDef cd = classDefs.get(className); if (cd != null) return new GazelleV_LeftArrowScript.NewObject_LASClass(new ResolvableLASClass(lasClassLoader, cd)); var type = knownVars.get(className); if (type != null) return new GazelleV_LeftArrowScript.NewObject_UnknownClass(new GazelleV_LeftArrowScript.GetVar(className), parseArguments()); Object o = findExternalObject(className); if (o instanceof Class) { Class c = (Class) o; if (c == List.class) c = ArrayList.class; else if (c == Map.class) c = HashMap.class; else if (c == Set.class) c = HashSet.class; return new GazelleV_LeftArrowScript.NewObject(c, parseArguments()); } throw new ClassNotFound(className); } if (scope != null && scope.useFixedVars) { var type = scope.declaredVars.get(t); if (type != null) { var e = new GazelleV_LeftArrowScript.GetFixedVar(scope, t); e.scope(scope); e.returnType(type); varAccessesToFix.add(e); return inner ? e : parseCall(e); } } var type = knownVars.get(t); if (type != null) { var e = new GazelleV_LeftArrowScript.GetVar(t).returnType(type); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Found var acccess: " + e + ", " + (!inner ? "Checking for call" : "Returning expression")); typeHook(type); return inner ? e : parseCall(e); } if (!inner) { var fdef = lookupFunction(t); if (fdef != null) return new GazelleV_LeftArrowScript.CallFunction(fdef, parseArguments()); } if (eq(t, "_context")) return new GazelleV_LeftArrowScript.GetVarContext(); Object o = findExternalObject(t); if (o == null) { throw new UnknownObject(t); } else if (o instanceof EvaluableWrapper) { return inner ? ((EvaluableWrapper) o).expr : parseCall(((EvaluableWrapper) o).expr); } else if (inner) return _const(o); else if (o instanceof Class) { return parseExprStartingWithClass((Class) o); } else if (o instanceof MethodOnObject) { if (inner) throw fail("Can't call methods in arguments"); return new GazelleV_LeftArrowScript.CallMethod(_const(((MethodOnObject) o).object), ((MethodOnObject) o).method, parseArguments()); } else return parseCall(_const(o)); } public GazelleV_LeftArrowScript.Evaluable parseExprStartingWithClass(Class c) { if (atCmdEnd()) return _const(c); if (is("(")) return new GazelleV_LeftArrowScript.NewObject(c, parseArguments()); { var __4 = parseLambdaOpt(c); if (__4 != null) return __4; } if (isIdentifier()) { String name = tpp(); if (hasStaticMethodNamed(c, name)) return new GazelleV_LeftArrowScript.CallMethod(_const(c), name, parseArguments()); if (isInterface(c)) return parseLambdaMethodRef(c, name); var field = getField(c, name); if (field != null) { assertCmdEnd(); if (!isStaticField(field)) throw fail(field + " is not a static field"); return new GazelleV_LeftArrowScript.GetStaticField(field); } throw fail(name + " not found in " + c + " (looked for method or field)"); } else throw fail("Method name expected: " + token()); } public GazelleV_LeftArrowScript.Evaluable parseLambdaOpt(Class c) { int nArgs = 0; while (isIdentifier(token(nArgs))) nArgs++; if (!(is(nArgs, "-") && is(nArgs + 1, ">"))) return null; String[] argNames = consumeArray(nArgs); AutoCloseable __8 = tempAddKnownVars(argNames); try { skip(2); GazelleV_LeftArrowScript.Evaluable body; if (is("{")) body = parseReturnableScript(); else body = parseExpr(); var lambda = new GazelleV_LeftArrowScript.LambdaDef(c, argNames, body); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseLambdaOpt done:\n" + GazelleV_LeftArrowScript.indentedScriptStruct(lambda)); return lambda; } finally { _close(__8); } } public GazelleV_LeftArrowScript.Evaluable parseLambdaMethodRef(Class c, String name) { var fdef = lookupFunction(name); if (fdef != null) { GazelleV_LeftArrowScript.Evaluable[] curriedArguments = parseArguments(); return new GazelleV_LeftArrowScript.CurriedScriptFunctionLambda(c, fdef, curriedArguments); } Object function = findExternalObject(name); if (function == null) throw new UnknownObject(name); if (function instanceof MethodOnObject) { Object target = ((MethodOnObject) function).object; String targetMethod = ((MethodOnObject) function).method; GazelleV_LeftArrowScript.Evaluable[] curriedArguments = parseArguments(); return new GazelleV_LeftArrowScript.CurriedMethodLambda(c, target, targetMethod, curriedArguments); } else if (function instanceof Class) { Class c2 = (Class) function; assertCmdEnd(); var ctors = constructorsWithNumberOfArguments(c2, 1); if (empty(ctors)) throw fail("No single argument constructor found in " + c2); return new GazelleV_LeftArrowScript.CurriedConstructorLambda(c, toArray(Constructor.class, ctors), null); } else throw fail(function + " is not an instantiable class or callable method"); } public GazelleV_LeftArrowScript.FunctionDef lookupFunction(String name) { var script = currentReturnableScript; while (script != null) { var f = script.functionDefs.get(name); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("lookupFunction", "script", script, "name", name, "f", f); if (f != null) return f; script = script.returnableParent; } return null; } public GazelleV_LeftArrowScript.Evaluable[] parseArguments() { List l = new ArrayList(); try { while (true) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseArgumentsAsList: token is " + quote(t())); if (is("+") && empty(nextSpace()) && isIdentifier(token(1))) { consume(); l.add(_const(token())); continue; } if (consumeOpt("<")) { GazelleV_LeftArrowScript.Evaluable a = parseFullExpr(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseArgumentsAsList: token after expr is " + quote(t())); if (a == null) throw fail("expression expected"); l.add(a); break; } GazelleV_LeftArrowScript.Evaluable a = parseOptionalInnerExpression(); if (a == null) break; l.add(a); } return toArrayOrNull(GazelleV_LeftArrowScript.Evaluable.class, l); } catch (Throwable _e) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Arguments parsed so far: " + l); throw rethrow(_e); } } public String consumeMultiTokenLiteral() { return consumeUntilSpaceOr(() -> atCmdEnd() || is(",")); } public boolean atCmdEnd() { return !inParens && atEndOrLineBreak() || closerTokens.contains(token()); } public void assertCmdEnd() { if (!atCmdEnd()) throw fail("Expected end of command, token is: " + quote(token())); } public GazelleV_LeftArrowScript.Evaluable parseCall(GazelleV_LeftArrowScript.Evaluable target) { if (atCmdEnd()) return target; return parseCall_noCmdEndCheck(target); } public GazelleV_LeftArrowScript.Evaluable parseCall_noCmdEndCheck(GazelleV_LeftArrowScript.Evaluable target) { if (!isIdentifier()) return target; var start = ptr(); String name = tpp(); if (eq(token(), "<") && eq(token(1), "-")) { next(2); GazelleV_LeftArrowScript.Evaluable rhs = parseExpr(); return new GazelleV_LeftArrowScript.SetField(target, name, rhs); } var args = parseArguments(); if (nempty(args)) return new GazelleV_LeftArrowScript.CallMethod(target, name, args); else return linkToSrc(start, new GazelleV_LeftArrowScript.CallMethodOrGetField(target, name)); } public A linkToSrc(ListAndIndex start, A a) { if (a instanceof IHasTokenRangeWithSrc) ((IHasTokenRangeWithSrc) a).setTokenRangeWithSrc(new TokenRangeWithSrc(start, ptr().plus(-1))); return a; } public A linkToSrc(IF0 a) { var start = ptr(); return linkToSrc(start, a.get()); } transient public IF1 findExternalObject; public Object findExternalObject(String name) { return findExternalObject != null ? findExternalObject.get(name) : findExternalObject_base(name); } final public Object findExternalObject_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : findExternalObject_base(name); } public Object findExternalObject_base(String name) { { var __5 = parsePrimitiveType(name); if (__5 != null) return __5; } if (qualifiedNameContinues()) { int idx = idx() - 2; do next(2); while (qualifiedNameContinues()); String fqn = joinSubList(tok, idx, idx() - 1); return classForName(fqn); } String fullName = globalClassNames().get(name); if (fullName != null) return classForName(fullName); for (var container : unnullForIteration(functionContainers)) { if (hasMethodNamed(container, name)) { var moo = new MethodOnObject(container, name); return moo; } var field = getField(container, name); if (field != null && isStaticField(field)) return new EvaluableWrapper(new GazelleV_LeftArrowScript.GetStaticField(field)); } return null; } public GazelleV_LeftArrowScriptParser allowTheWorld() { return allowTheWorld(mc()); } public GazelleV_LeftArrowScriptParser allowTheWorld(Object... functionContainers) { for (Object o : unnullForIteration(reversed(functionContainers))) if (!contains(this.functionContainers, o)) { this.functionContainers.add(0, o); globalClassNames_cache = null; } return this; } public void printFunctionDefs(GazelleV_LeftArrowScript.Script script) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print(values(script.functionDefs)); } public AutoCloseable tempAddKnownVars(String... vars) { return tempAddKnownVars(asList(vars)); } public AutoCloseable tempAddKnownVars(Iterable vars) { var newVars = mapWithSingleValue(vars, new LASValueDescriptor()); return tempAddKnownVars(newVars); } public AutoCloseable tempAddKnownVars(Map newVars) { if (scope != null) for (var __1 : _entrySet(newVars)) { var name = __1.getKey(); var type = __1.getValue(); scope.addDeclaredVar(name, type); } return tempMapPutAll(knownVars, newVars); } public GazelleV_LeftArrowScript.FunctionDef parseFunctionDefinition(Map functionDefsToAddTo) { consume("def"); String functionName = assertIdentifier(tpp()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseFunctionDefinition " + functionName); LinkedHashMap args = new LinkedHashMap(); while (isIdentifier()) { String arg = tpp(); var type = typeToValueDescriptor(parseColonTypeOpt()); args.put(arg, type); } var returnType = parseColonTypeOpt(); var scope = newScope(); scope.useFixedVars(useFixedVarContexts); AutoCloseable __9 = tempScope(scope); try { AutoCloseable __10 = tempAddKnownVars(args); try { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Parsing function body"); var functionBody = parseReturnableCurlyBlock(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Defined function " + functionName + ", adding to " + functionDefsToAddTo); var fd = new GazelleV_LeftArrowScript.FunctionDef(functionName, keysList(args), functionBody); fd.scope(scope); if (returnType != null) fd.returnType(returnType); { if (functionDefsToAddTo != null) functionDefsToAddTo.put(functionName, fd); } return fd; } finally { _close(__10); } } finally { _close(__9); } } public LASScope newScope() { return new LASScope(scope); } public LASScope currentScope() { return scope; } public AutoCloseable tempScope(LASScope scope) { var oldScope = currentScope(); this.scope = scope; return () -> { scope.resolve(); this.scope = oldScope; }; } public GazelleV_LeftArrowScript.Script parseReturnableCurlyBlock() { return (GazelleV_LeftArrowScript.Script) parseCurlyBlock(new BuildingScript().returnable(true)); } public GazelleV_LeftArrowScript.Evaluable parseCurlyBlock(BuildingScript script) { consume("{"); boolean inParensOld = inParens; inParens = false; var body = parseScript(script); consume("}"); inParens = inParensOld; return body; } public GazelleV_LeftArrowScript.Evaluable parseWhileLoop() { consume("while"); var condition = parseExpr(); var body = parseCurlyBlock(new BuildingScript().isLoopBody(true)); return new GazelleV_LeftArrowScript.While(condition, body); } public GazelleV_LeftArrowScript.Evaluable parseForEach() { return new ParseForEach().get(); } public class ParseForEach { public GazelleV_LeftArrowScript.Evaluable collection, body; public IF0 finish; public Set vars = new HashSet(); public String addVar(String var) { return addAndReturn(vars, var); } public String consumeVar() { return addVar(consumeIdentifier()); } public void parseBody() { AutoCloseable __11 = tempAddKnownVars(vars); try { body = parseCurlyBlock(new BuildingScript().isLoopBody(true)); } finally { _close(__11); } } public GazelleV_LeftArrowScript.Evaluable get() { consume("for"); if (is(1, "to")) { String var = consumeVar(); consume("to"); GazelleV_LeftArrowScript.Evaluable endValue = parseExpr(); parseBody(); return new GazelleV_LeftArrowScript.ForIntTo(endValue, var, body); } int iIn = relativeIndexOf("in"); if (iIn < 0) throw fail("for without in"); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("iIn", iIn); if (iIn == 1) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForEach(collection, var, body); } else if (iIn == 2) { if (consumeOpt("iterator")) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForIterator(collection, var, body); } else if (consumeOpt("nested")) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForNested(collection, var, body); } else throw fail("Unknown pattern for 'for' loop"); } else if (iIn == 3) { if (isOneOf("pair", "Pair")) { consume(); String varA = consumeVar(); String varB = consumeVar(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("varA", varA, "varB", varB); finish = () -> new GazelleV_LeftArrowScript.ForPairs(collection, body, varA, varB); } else { String varA = consumeVar(); consume(","); String varB = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForKeyValue(collection, body, varA, varB); } } else if (iIn == 4) { consume("index"); String varIndex = consumeVar(); consume(","); String varElement = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForIndex(collection, body, varIndex, varElement); } else throw fail("Unknown pattern for 'for' loop"); consume("in"); collection = parseExpr(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("collection", collection); parseBody(); return finish.get(); } } public GazelleV_LeftArrowScript.Evaluable parseIfStatement() { consume("if"); GazelleV_LeftArrowScript.Evaluable condition, body, elseBranch = null; { AutoCloseable __12 = tempAdd(closerTokens, "then"); try { condition = parseExpr(); } finally { _close(__12); } } if (consumeOpt("then")) { AutoCloseable __13 = tempAdd(closerTokens, "else"); try { body = parseExpr(); if (consumeOpt("else")) elseBranch = parseExpr(); } finally { _close(__13); } } else { body = parseCurlyBlock(new BuildingScript()); if (consumeOpt("else")) { if (is("if")) elseBranch = parseIfStatement(); else elseBranch = parseCurlyBlock(new BuildingScript()); } } return new GazelleV_LeftArrowScript.IfThen(condition, body, elseBranch); } public GazelleV_LeftArrowScript.Evaluable parseRepeatStatement() { consume("repeat"); var n = parseExpr(); var body = parseCurlyBlock(new BuildingScript()); return new GazelleV_LeftArrowScript.RepeatN(n, body); } public void addVar(String var) { addVar(var, new LASValueDescriptor()); } public void addVar(String var, LASValueDescriptor type) { knownVars.put(var, type); } public void addVar(String var, Class type, boolean canBeNull) { addVar(var, typeToValueDescriptor(type, canBeNull)); } public LASValueDescriptor typeToValueDescriptor(Type type) { return typeToValueDescriptor(type, true); } public LASValueDescriptor typeToValueDescriptor(Type type, boolean canBeNull) { return type == null ? new LASValueDescriptor() : new LASValueDescriptor.NonExact(typeToClass(type), canBeNull); } public Map globalClassNames_cache; public Map globalClassNames() { if (globalClassNames_cache == null) globalClassNames_cache = globalClassNames_load(); return globalClassNames_cache; } public Map globalClassNames_load() { var packages = mapToTreeSet(importedPackages(), pkg -> pkg + "."); Map out = new HashMap(); for (var fc : functionContainers) if (fc instanceof Class) { if (isAnonymousClass((Class) fc)) continue; out.put(shortClassName((Class) fc), className((Class) fc)); } var classContainers = classContainerPrefixes(); TreeSet classContainerSet = asTreeSet(classContainers); out.put("List", "java.util.List"); for (var className : classNameResolver().allFullyQualifiedClassNames()) { if (isAnonymousClassName(className)) continue; if (!contains(className, '$')) { String pkg = longestPrefixInTreeSet(className, packages); if (pkg != null) { String shortName = dropPrefix(pkg, className); if (!shortName.contains(".") && !out.containsKey(shortName)) out.put(shortName, className); } } String container = longestPrefixInTreeSet(className, classContainerSet); if (container != null) { String shortName = dropPrefix(container, className); String existing = out.get(shortName); if (existing != null) { int priority = indexOf(classContainers, container); String oldContainer = longestPrefixInTreeSet(existing, classContainerSet); int oldPriority = indexOf(classContainers, oldContainer); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("className", className, "shortName", shortName, "container", container, "priority", priority, "existing", existing, "oldPriority", oldPriority); if (priority > oldPriority) continue; } out.put(shortName, className); } } for (var __0 : _entrySet(javaxClassShortcuts())) { var key = __0.getKey(); var val = __0.getValue(); String fullName = out.get(val); if (fullName != null) out.put(key, fullName); } return out; } transient public IF0> importedPackages; public Collection importedPackages() { return importedPackages != null ? importedPackages.get() : importedPackages_base(); } final public Collection importedPackages_fallback(IF0> _f) { return _f != null ? _f.get() : importedPackages_base(); } public Collection importedPackages_base() { return itemPlus("java.lang", standardImports_fullyImportedPackages()); } public void addClassAlias(String alias, String longName) { String fullName = globalClassNames().get(longName); if (fullName != null) globalClassNames().put(alias, fullName); } public List classContainerPrefixes() { return map(functionContainers, fc -> className(fc) + "$"); } static public class UnknownObject extends RuntimeException implements IFieldsToList { public String name; public UnknownObject() { } public UnknownObject(String name) { this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ")"; } public Object[] _fieldsToList() { return new Object[] { name }; } public String getMessage() { return "Unknown object: " + name; } } static public class ClassNotFound extends UnknownObject { public ClassNotFound(String className) { super(className); } public String getMessage() { return "Class not found: " + name; } } public LASClassDef parseClassDef() { consume("class"); LASClassDef classDef = new LASClassDef(); classDef.verbose(scaffoldingEnabled()); if (nempty(classDefPrefix)) classDef.classDefPrefix(classDefPrefix); String name = consumeIdentifier(); classDef.userGivenName(name); consume("{"); while (!is("}")) { if (is(";")) { next(); continue; } if (is("def")) { AutoCloseable __14 = tempAddKnownVars("this"); try { GazelleV_LeftArrowScript.FunctionDef fd = parseFunctionDefinition(null); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("knownVarsAfterFunctionDef", knownVars); classDef.methods.add(fd); continue; } finally { _close(__14); } } LASClassDef.FieldDef fd = new LASClassDef.FieldDef(); fd.name(consumeIdentifier()); var type = parseColonType(); fd.type(type); classDef.fields.add(fd); } consume("}"); classDefs.put(name, classDef); return classDef; } public Type parseColonTypeOpt() { if (is(":")) return parseColonType(); return null; } public Type parseColonType() { consume(":"); return parseType(); } public Type parseType() { String typeName = consumeIdentifier(); Object type = findExternalObject(typeName); if (!(type instanceof Class)) throw fail("Class not found: " + typeName); return parseTypeArguments((Type) type); } public Type parseTypeArguments(Type type) { if (is("<") && isIdentifier(token(1))) { next(); List args = new ArrayList(); while (true) { args.add(parseType()); if (is(">")) break; consume(","); } consume(">"); if (type != null) type = new ParameterizedTypeImpl(null, type, toTypedArray(Type.class, args)); } return type; } transient public IF1 classForName; public Class classForName(String name) { return classForName != null ? classForName.get(name) : classForName_base(name); } final public Class classForName_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : classForName_base(name); } public Class classForName_base(String name) { try { return Class.forName(name); } catch (Exception __e) { throw rethrow(__e); } } public void copyFunctionContainersFrom(GazelleV_LeftArrowScriptParser parser) { functionContainers = cloneList(parser.functionContainers); globalClassNames_cache = parser.globalClassNames(); } public ClassNameResolver classNameResolver() { if (classNameResolver == null) classNameResolver = new ClassNameResolver().byteCodePath(assertNotNull(getBytecodePathForClass(this))).init(); return classNameResolver; } public GazelleV_LeftArrowScriptParser classNameResolver(ClassNameResolver classNameResolver) { this.classNameResolver = classNameResolver; return this; } public GazelleV_LeftArrowScript.Evaluable parseStringLiteral() { return _const(unquote_relaxedMLS(consume())); } } static public class G22LeftArrowScript extends ConceptWithChangeListeners { static final public String _fieldOrder = "description text clearedForAutoRun editingText importNote runOnProjectOpen runOrder runCount lastResultByMode compileResultForAutoRun compileResultForSaved"; public transient FieldVar varDescription_cache; public FieldVar varDescription() { if (varDescription_cache == null) varDescription_cache = varDescription_load(); return varDescription_cache; } public FieldVar varDescription_load() { return new FieldVar(this, "description", () -> description(), description -> description(description)); } final public G22LeftArrowScript setDescription(String description) { return description(description); } public G22LeftArrowScript description(String description) { if (!eq(this.description, description)) { this.description = description; change(); } return this; } final public String getDescription() { return description(); } public String description() { return description; } public String description; public transient FieldVar varText_cache; public FieldVar varText() { if (varText_cache == null) varText_cache = varText_load(); return varText_cache; } public FieldVar varText_load() { return new FieldVar(this, "text", () -> text(), text -> text(text)); } final public G22LeftArrowScript setText(String text) { return text(text); } public G22LeftArrowScript text(String text) { if (!eq(this.text, text)) { this.text = text; change(); } return this; } final public String getText() { return text(); } public String text() { return text; } public String text; public transient FieldVar> varClearedForAutoRun_cache; public FieldVar> varClearedForAutoRun() { if (varClearedForAutoRun_cache == null) varClearedForAutoRun_cache = varClearedForAutoRun_load(); return varClearedForAutoRun_cache; } public FieldVar> varClearedForAutoRun_load() { return new FieldVar>(this, "clearedForAutoRun", () -> clearedForAutoRun(), clearedForAutoRun -> clearedForAutoRun(clearedForAutoRun)); } final public G22LeftArrowScript setClearedForAutoRun(ClearForAutoRun clearedForAutoRun) { return clearedForAutoRun(clearedForAutoRun); } public G22LeftArrowScript clearedForAutoRun(ClearForAutoRun clearedForAutoRun) { if (!eq(this.clearedForAutoRun, clearedForAutoRun)) { this.clearedForAutoRun = clearedForAutoRun; change(); } return this; } final public ClearForAutoRun getClearedForAutoRun() { return clearedForAutoRun(); } public ClearForAutoRun clearedForAutoRun() { return clearedForAutoRun; } public ClearForAutoRun clearedForAutoRun; public transient FieldVar varEditingText_cache; public FieldVar varEditingText() { if (varEditingText_cache == null) varEditingText_cache = varEditingText_load(); return varEditingText_cache; } public FieldVar varEditingText_load() { return new FieldVar(this, "editingText", () -> editingText(), editingText -> editingText(editingText)); } final public G22LeftArrowScript setEditingText(String editingText) { return editingText(editingText); } public G22LeftArrowScript editingText(String editingText) { if (!eq(this.editingText, editingText)) { this.editingText = editingText; change(); } return this; } final public String getEditingText() { return editingText(); } public String editingText() { return editingText; } public String editingText; public transient FieldVar varImportNote_cache; public FieldVar varImportNote() { if (varImportNote_cache == null) varImportNote_cache = varImportNote_load(); return varImportNote_cache; } public FieldVar varImportNote_load() { return new FieldVar(this, "importNote", () -> importNote(), importNote -> importNote(importNote)); } final public G22LeftArrowScript setImportNote(String importNote) { return importNote(importNote); } public G22LeftArrowScript importNote(String importNote) { if (!eq(this.importNote, importNote)) { this.importNote = importNote; change(); } return this; } final public String getImportNote() { return importNote(); } public String importNote() { return importNote; } public String importNote; public boolean runOnProjectOpen = false; public String runOrder; public long runCount; public Map>> lastResultByMode; @Override public void _doneLoading2() { cMigrateField(this, "code", "text"); } public String myType() { return dropPrefix("G22", shortClassName(this)); } public String toString() { return or2(description, myType() + " " + id); } public void initEditingText() { editingText(unnull(or(editingText, text))); } public void receiveEditingText(String text) { editingText(text); } public String stableText() { return text; } final public void save() { completeEdit(); } public void completeEdit() { String t = editingText; if (t != null) { setTextWithHistory(t); } } public void setTextWithHistory(String text) { if (eq(this.text, text)) return; text(text); saveTextToHistory(); } public String textForEditing() { initEditingText(); return editingText; } public File historyFile() { return fileInConceptsDir("History/" + shortDynName(this) + id + ".history"); } public void saveTextToHistory() { saveFieldToHistory("text", text); } public void saveFieldToHistory(String field, String value) { File historyFile = historyFile(); if (historyFile == null) return; String contents = value == null ? " empty" : " (" + nLines(value) + ", " + nChars(value) + "):\n" + indentx(value) + "\n" + "\n"; appendToTextFile(historyFile, "\n===\n" + "Concept ID: " + id + "\n" + "Date: " + dateWithMSUTC() + "\n" + firstToUpper(field) + contents + "===" + "\n"); } public boolean isSaved() { return text != null; } public boolean isSavedDistinctFromAutoRunVersion() { return isSaved() && !eq(text, codeForAutoRun()); } public boolean isEditing() { return editedText() != null; } public boolean isClearForAutoRun() { return clearedForAutoRun != null; } public String editedText() { return eq(editingText, text) ? null : editingText; } public String codeForAutoRun() { return getVar(clearedForAutoRun()); } public String safestCode() { return or(codeForAutoRun(), stableText()); } public void clearForAutoRun() { if (!isSaved()) return; String text = text(); saveFieldToHistory("Auto-runnable code", text); clearedForAutoRun(new ClearForAutoRun(text)); } public void forgetAutoRunCode() { if (!isClearForAutoRun()) return; saveFieldToHistory("Auto-runnable code", null); clearedForAutoRun(null); compileResultForAutoRun = null; } public void forgetCompileResults() { compileResultForAutoRun = compileResultForSaved = null; } public G22Utils g22utils() { return assertNotNull("g22utils", main.g22utils(_concepts())); } public GazelleV_LeftArrowScriptParser makeParser() { return g22utils().leftArrowParser(); } public LASCompileResult newCompileResult() { return new LASCompileResult(); } transient public LASCompileResult compileResultForAutoRun; public LASCompileResult compileForAutoRun() { String code = codeForAutoRun(); if (code == null) return null; var cr = compileResultForAutoRun; if (cr != null && eq(cr.script, code)) return cr; cr = newCompileResult(); cr.script(code); var parser = makeParser(); cr.parser(parser); cr.compile(); return compileResultForAutoRun = cr; } transient public LASCompileResult compileResultForSaved; public LASCompileResult compileSaved() { String code = stableText(); if (code == null) return null; var cr = compileResultForSaved; if (cr != null && eq(cr.script, code)) return cr; cr = newCompileResult(); cr.script(code); var parser = makeParser(); cr.parser(parser); cr.compile(); return compileResultForSaved = cr; } public LASCompileResult safestCompileResult() { { var __1 = compileForAutoRun(); if (__1 != null) return __1; } return compileSaved(); } public Object evaluateWithoutTimeout() { var cr = safestCompileResult(); if (cr == null) throw fail("Not saved: " + this); AutoCloseable __2 = g22utils().enter(); try { return cr.parsedScriptMandatory().get(); } finally { _close(__2); } } public Object evaluateAutoRunWithoutTimeout() { var cr = compileForAutoRun(); if (cr == null) throw fail("Not cleared for auto-run: " + this); AutoCloseable __3 = g22utils().enter(); try { return cr.parsedScriptMandatory().get(); } finally { _close(__3); } } public String renderRunOnProjectOpenStatus() { return runOnProjectOpen ? "Yes" + appendBracketed(appendPrefixIfNempty("prio ", runOrder)) : null; } } static public class RSyntaxTextAreaWithSearch implements SearchListener, Swingable { public JPanel panel; final public RSyntaxTextArea getTextArea() { return textArea(); } public RSyntaxTextArea textArea() { return textArea; } public RSyntaxTextArea textArea; public CollapsibleSectionPanel csp; public FindDialog findDialog; public ReplaceDialog replaceDialog; public FindToolBar findToolBar; public ReplaceToolBar replaceToolBar; public StatusBar statusBar; public RSyntaxTextAreaWithSearch() { init(); } public RSyntaxTextAreaWithSearch(IF1 wrapStatusLabel) { this.wrapStatusLabel = wrapStatusLabel; init(); } public RSyntaxTextAreaWithSearch(String text) { init(); setText(text); } public RSyntaxTextAreaWithSearch(RSyntaxTextArea textArea) { this.textArea = textArea; init(); } public JComponent visualize() { return panel; } public void init() { swing(() -> { rsyntaxTextArea_fixNumPad(); initSearchDialogs(); panel = new JPanel(new BorderLayout()); csp = new CollapsibleSectionPanel(); panel.add(csp); if (textArea == null) textArea = javaxSyntaxTextArea(); RTextScrollPane sp = new RTextScrollPane(textArea); csp.add(sp); ErrorStrip errorStrip = new ErrorStrip(textArea); panel.add(errorStrip, BorderLayout.LINE_END); statusBar = new StatusBar(); panel.add(statusBar, BorderLayout.SOUTH); }); } transient public IF1 wrapStatusLabel; public JComponent wrapStatusLabel(JComponent label) { return wrapStatusLabel != null ? wrapStatusLabel.get(label) : wrapStatusLabel_base(label); } final public JComponent wrapStatusLabel_fallback(IF1 _f, JComponent label) { return _f != null ? _f.get(label) : wrapStatusLabel_base(label); } public JComponent wrapStatusLabel_base(JComponent label) { return label; } public void addItem(Action a, ButtonGroup bg, JMenu menu) { JRadioButtonMenuItem item = new JRadioButtonMenuItem(a); bg.add(item); menu.add(item); } public void menuLessOperation() { swing(() -> { var mb = createMenuBar(); for (var menu : getMenus(mb)) for (var menuItem : getMenuItems(menu)) { var ks = menuItem.getAccelerator(); if (ks != null) { var action = menuItem.getAction(); textArea.getInputMap().put(ks, action); } } }); } public JMenuBar createMenuBar() { JMenuBar mb = new JMenuBar(); JMenu menu = new JMenu("Search"); menu.add(new JMenuItem(new ShowFindDialogAction())); menu.add(new JMenuItem(new ShowReplaceDialogAction())); menu.add(new JMenuItem(new GoToLineAction())); menu.addSeparator(); int ctrl = getToolkit().getMenuShortcutKeyMask(); int shift = InputEvent.SHIFT_MASK; KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F, ctrl | shift); Action a = csp.addBottomComponent(ks, findToolBar); a.putValue(Action.NAME, "Show Find Search Bar"); menu.add(new JMenuItem(a)); ks = KeyStroke.getKeyStroke(KeyEvent.VK_H, ctrl | shift); a = csp.addBottomComponent(ks, replaceToolBar); a.putValue(Action.NAME, "Show Replace Search Bar"); menu.add(new JMenuItem(a)); mb.add(menu); return mb; } public String getSelectedText() { return textArea.getSelectedText(); } public void initSearchDialogs() { findDialog = new FindDialog((java.awt.Dialog) null, this); replaceDialog = new ReplaceDialog((java.awt.Dialog) null, this); SearchContext context = findDialog.getSearchContext(); replaceDialog.setSearchContext(context); findToolBar = new FindToolBar(this); findToolBar.setSearchContext(context); replaceToolBar = new ReplaceToolBar(this); replaceToolBar.setSearchContext(context); } @Override public void searchEvent(SearchEvent e) { SearchEvent.Type type = e.getType(); SearchContext context = e.getSearchContext(); SearchResult result = null; switch(type) { default: case MARK_ALL: result = SearchEngine.markAll(textArea, context); break; case FIND: result = SearchEngine.find(textArea, context); if (!result.wasFound()) { Caret c = textArea.getCaret(); int pos = c.getDot(); if (context.getSearchForward()) { c.setDot(0); } else { c.setDot(textArea.getDocument().getLength()); } result = SearchEngine.find(textArea, context); if (!result.wasFound()) { c.setDot(pos); UIManager.getLookAndFeel().provideErrorFeedback(textArea); } } break; case REPLACE: result = SearchEngine.replace(textArea, context); if (!result.wasFound()) { UIManager.getLookAndFeel().provideErrorFeedback(textArea); } break; case REPLACE_ALL: result = SearchEngine.replaceAll(textArea, context); JOptionPane.showMessageDialog(null, result.getCount() + " occurrences replaced."); break; } String text = null; if (result.wasFound()) { text = "Text found; occurrences marked: " + result.getMarkedCount(); } else if (type == SearchEvent.Type.MARK_ALL) { if (result.getMarkedCount() > 0) { text = "Occurrences marked: " + result.getMarkedCount(); } else { text = ""; } } else { text = "Text not found"; } setStatus(text); } public class GoToLineAction extends AbstractAction { public GoToLineAction() { super("Go To Line..."); int c = getToolkit().getMenuShortcutKeyMask(); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L, c)); } public void actionPerformed(ActionEvent e) { findDialog.setVisible(false); replaceDialog.setVisible(false); GoToDialog dialog = new GoToDialog((java.awt.Dialog) null); dialog.setMaxLineNumberAllowed(textArea.getLineCount()); showDialogOnSameScreen(dialog, panel); int line = dialog.getLineNumber(); if (line > 0) { try { textArea.setCaretPosition(textArea.getLineStartOffset(line - 1)); } catch (BadLocationException ble) { UIManager.getLookAndFeel().provideErrorFeedback(textArea); ble.printStackTrace(); } } } } public class ShowFindDialogAction extends AbstractAction { public ShowFindDialogAction() { super("Find..."); int c = getToolkit().getMenuShortcutKeyMask(); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, c)); } public void actionPerformed(ActionEvent e) { replaceDialog.setVisible(false); showDialogOnSameScreen(findDialog, panel); } } public class ShowReplaceDialogAction extends AbstractAction { public ShowReplaceDialogAction() { super("Replace..."); int c = getToolkit().getMenuShortcutKeyMask(); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, c)); } public void actionPerformed(ActionEvent e) { findDialog.setVisible(false); showDialogOnSameScreen(replaceDialog, panel); } } public class StatusBar extends JPanel { public JLabel label; public StatusBar() { label = new JLabel(" "); setLayout(new BorderLayout()); add(wrapStatusLabel(label), BorderLayout.CENTER); add(new JLabel(new SizeGripIcon()), BorderLayout.EAST); } public void setText(String label) { main.setText(this.label, label); } } public void setStatus(String text) { statusBar.setText(text); } public void setText(String text) { main.setText(textArea, text); } public String getText() { return main.getText(textArea); } public void setEditorFont(final Font font) { swing(() -> { SyntaxScheme ss = textArea.getSyntaxScheme(); ss = (SyntaxScheme) ss.clone(); for (int i = 0; i < ss.getStyleCount(); i++) if (ss.getStyle(i) != null) ss.getStyle(i).font = font; textArea.setSyntaxScheme(ss); textArea.setFont(font); }); } public Font getEditorFont() { return swing(new F0() { public Font get() { try { return textArea.getFont(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return textArea.getFont();"; } }); } public int getEditorFontSize() { return getEditorFont().getSize(); } public void setEditorFontSize(int size) { setEditorFont(deriveFont(getEditorFont(), size)); } public RSyntaxDocument getDocument() { return (RSyntaxDocument) textArea.getDocument(); } public Toolkit getToolkit() { return panel.getToolkit(); } public JLabel statusLabel() { return statusBar.label; } } static public class Q implements AutoCloseable { public String name = "Unnamed Queue"; public List q = synchroLinkedList(); public ReliableSingleThread rst = new ReliableSingleThread(new Runnable() { public void run() { try { _run(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_run()"; } }); final public boolean getRetired() { return retired(); } public boolean retired() { return retired; } volatile public boolean retired = false; final public Runnable getCurrentJob() { return currentJob(); } public Runnable currentJob() { return currentJob; } volatile public Runnable currentJob; public AtomicLong jobsDone = new AtomicLong(); public Q() { } public Q(String name) { this.name = name; } public void add(Runnable r) { assertNotRetired(); q.add(r); _trigger(); } public void addInFront(Runnable r) { assertNotRetired(); q.add(0, r); _trigger(); } public void _trigger() { rst.name = name; rst.go(); } public void add(Object r) { add(toRunnable(r)); } public void _run() { Runnable r; while (licensed() && !retired && (r = syncPopFirst(q)) != null) { currentJob = r; inc(jobsDone); try { r.run(); } catch (Throwable __e) { printStackTrace(__e); } currentJob = null; } onIdle(); } public void close() { retired = true; } public void done() { } public boolean isEmpty() { return q.isEmpty(); } public int size() { return q.size(); } public Object mutex() { return q; } public List snapshot() { return cloneList(q); } public void onIdle() { } public boolean busy() { return currentJob != null; } public void assertNotRetired() { assertFalse("Queue is retired", retired()); } public boolean hasThread() { return rst.hasThread(); } public long nJobsDone() { return jobsDone.get(); } public String toString() { return (retired ? "Retired " : "") + "Q " + systemHashCodeHex(this) + " (" + (isEmpty() ? "empty" : nEntries(size()) + ", current job: " + currentJob) + ")"; } } static public class ImageSurface_PositionToolTip extends ImageSurfaceMouseHandler { public ImageSurface_PositionToolTip(ImageSurface is) { if (containsInstance(is.tools, ImageSurface_PositionToolTip.class)) return; register(is); } final public void mouseDragged(MouseEvent e) { mouseMoved(e); } public void mouseMoved(MouseEvent e) { setToolTip(is, getPt(e)); } } public interface TransientObject { } static public class G22Variable extends ConceptWithChangeListeners implements IPersistenceInfo { static final public String _fieldOrder = "name value persistent"; public String name; public transient FieldVar varValue_cache; public FieldVar varValue() { if (varValue_cache == null) varValue_cache = varValue_load(); return varValue_cache; } public FieldVar varValue_load() { return new FieldVar(this, "value", () -> value(), value -> value(value)); } final public G22Variable setValue(Object value) { return value(value); } public G22Variable value(Object value) { if (!eq(this.value, value)) { this.value = value; change(); } return this; } final public Object getValue() { return value(); } public Object value() { return value; } volatile public Object value; final public G22Variable setPersistent(boolean persistent) { return persistent(persistent); } public G22Variable persistent(boolean persistent) { this.persistent = persistent; return this; } final public boolean getPersistent() { return persistent(); } public boolean persistent() { return persistent; } public boolean persistent = false; public Map _persistenceInfo() { return litmap("value", persistent); } public Object get() { return value; } public void setValueIfNull(Object defaultValue) { if (defaultValue != null && value == null) value(defaultValue); } } static public class FixedVarContext extends VarContext { public String[] names; public Object[] values; public FixedVarContext() { } public FixedVarContext(String[] names) { this(null, names); this.names = names; } public FixedVarContext(VarContext parent, String[] names) { super(parent); this.names = names; if (names != null) values = new Object[names.length]; } public int indexOfVar(String name) { return indexOfInSortedArray(names, name); } public int indexOfVarMandatory(String name) { int idx = indexOfVar(name); if (idx < 0) throw fail("Variable not found: " + name + ", known: " + joinWithComma(names)); return idx; } public Object get(int idx) { return values[idx]; } public Object get(String name) { int idx = indexOfVar(name); if (idx >= 0) return values[idx]; if (parent != null) return parent.get(name); return null; } public void set(int idx, Object value) { values[idx] = value; } public void set(String name, Object value) { int idx = indexOfVar(name); if (idx >= 0) values[idx] = value; else throw fail("Variable " + name + " not defined in context"); } public AutoCloseable tempSet(String name, Object value) { int idx = indexOfVar(name); if (idx >= 0) { Object old = values[idx]; values[idx] = value; return () -> values[idx] = old; } else throw fail("Variable " + name + " not defined in context"); } public void unset(String name) { set(name, null); } public Map varMap() { Map map = new HashMap(); int n = l(names); for (int i = 0; i < n; i++) map.put(names[i], values[i]); return map; } } static public class EphemeralObjectIDs { public long idCounter; public WeakValueMap idToObject = new WeakValueMap(); public Map objectToID = weakIdentityMap(); public EphemeralObjectIDs runnablesReferenceQueue(RunnablesReferenceQueue queue) { idToObject.queue(queue); return this; } synchronized public long remember(Object o) { if (o == null) return 0; { var __1 = objectToID.get(o); if (__1 != null) return __1; } long id = ++idCounter; idToObject.put(id, o); objectToID.put(o, id); return id; } synchronized public Object get(long id) { if (id == 0) return null; return idToObject.get(id); } synchronized public boolean wasGarbageCollected(long id) { return id > 0 && id <= idCounter && get(id) == null; } } static public class JMenuScroller { public VF1 fillMenu; public JPopupMenu menu; public Component[] menuItems; public MenuScrollItem upItem; public MenuScrollItem downItem; final public MenuScrollListener menuListener = new MenuScrollListener(); public int scrollCount; public int interval; public int topFixedCount; public int bottomFixedCount; public int firstIndex = 0; public int keepVisibleIndex = -1; public static JMenuScroller setScrollerFor(JMenu menu) { return new JMenuScroller(menu); } public static JMenuScroller setScrollerFor(JPopupMenu menu) { return new JMenuScroller(menu); } public static JMenuScroller setScrollerFor(JMenu menu, int scrollCount) { return new JMenuScroller(menu, scrollCount); } public static JMenuScroller setScrollerFor(JPopupMenu menu, int scrollCount) { return new JMenuScroller(menu, scrollCount); } public static JMenuScroller setScrollerFor(JMenu menu, int scrollCount, int interval) { return new JMenuScroller(menu, scrollCount, interval); } public static JMenuScroller setScrollerFor(JPopupMenu menu, int scrollCount, int interval) { return new JMenuScroller(menu, scrollCount, interval); } public static JMenuScroller setScrollerFor(JMenu menu, int scrollCount, int interval, int topFixedCount, int bottomFixedCount) { return new JMenuScroller(menu, scrollCount, interval, topFixedCount, bottomFixedCount); } public static JMenuScroller setScrollerFor(JPopupMenu menu, int scrollCount, int interval, int topFixedCount, int bottomFixedCount) { return new JMenuScroller(menu, scrollCount, interval, topFixedCount, bottomFixedCount); } public JMenuScroller(JMenu menu) { this(menu, 15); } public JMenuScroller(JPopupMenu menu) { this(menu, 15); } public JMenuScroller(JMenu menu, int scrollCount) { this(menu, scrollCount, 150); } public JMenuScroller(JPopupMenu menu, int scrollCount) { this(menu, scrollCount, 150); } public JMenuScroller(JMenu menu, int scrollCount, int interval) { this(menu, scrollCount, interval, 0, 0); } public JMenuScroller(JPopupMenu menu, int scrollCount, int interval) { this(menu, scrollCount, interval, 0, 0); } public JMenuScroller(JMenu menu, int scrollCount, int interval, int topFixedCount, int bottomFixedCount) { this(menu.getPopupMenu(), scrollCount, interval, topFixedCount, bottomFixedCount); } public JMenuScroller(JPopupMenu menu, int scrollCount, int interval, int topFixedCount, int bottomFixedCount) { if (scrollCount <= 0 || interval <= 0) { throw new IllegalArgumentException("scrollCount and interval must be greater than 0"); } if (topFixedCount < 0 || bottomFixedCount < 0) { throw new IllegalArgumentException("topFixedCount and bottomFixedCount cannot be negative"); } upItem = new MenuScrollItem(UP, -1); downItem = new MenuScrollItem(DOWN, +1); setScrollCount(scrollCount); setInterval(interval); setTopFixedCount(topFixedCount); setBottomFixedCount(bottomFixedCount); this.menu = menu; menu.addPopupMenuListener(menuListener); } public int getInterval() { return interval; } public void setInterval(int interval) { if (interval <= 0) { throw new IllegalArgumentException("interval must be greater than 0"); } upItem.setInterval(interval); downItem.setInterval(interval); this.interval = interval; } public int getscrollCount() { return scrollCount; } public void setScrollCount(int scrollCount) { if (scrollCount <= 0) { throw new IllegalArgumentException("scrollCount must be greater than 0"); } this.scrollCount = scrollCount; } public int getTopFixedCount() { return topFixedCount; } public void setTopFixedCount(int topFixedCount) { if (firstIndex <= topFixedCount) { firstIndex = topFixedCount; } else { firstIndex += (topFixedCount - this.topFixedCount); } this.topFixedCount = topFixedCount; } public int getBottomFixedCount() { return bottomFixedCount; } public void setBottomFixedCount(int bottomFixedCount) { this.bottomFixedCount = bottomFixedCount; } public void keepVisible(JMenuItem item) { if (item == null) { keepVisibleIndex = -1; } else { int index = menu.getComponentIndex(item); keepVisibleIndex = index; } } public void keepVisible(int index) { keepVisibleIndex = index; } public void dispose() { if (menu != null) { menu.removePopupMenuListener(menuListener); menu = null; } } @Override public void finalize() throws Throwable { dispose(); } final public void refreshMenu() { if (menuItems != null && menuItems.length > 0) { firstIndex = Math.max(topFixedCount, firstIndex); firstIndex = Math.min(menuItems.length - bottomFixedCount - scrollCount, firstIndex); upItem.setEnabled(firstIndex > topFixedCount); downItem.setEnabled(firstIndex + scrollCount < menuItems.length - bottomFixedCount); menu.removeAll(); for (int i = 0; i < topFixedCount; i++) { menu.add(menuItems[i]); } if (topFixedCount > 0) { menu.addSeparator(); } menu.add(upItem); for (int i = firstIndex; i < scrollCount + firstIndex; i++) { menu.add(menuItems[i]); } menu.add(downItem); if (bottomFixedCount > 0) { menu.addSeparator(); } for (int i = menuItems.length - bottomFixedCount; i < menuItems.length; i++) { menu.add(menuItems[i]); } JComponent parent = (JComponent) upItem.getParent(); parent.revalidate(); parent.repaint(); } } public class MenuScrollListener implements PopupMenuListener { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { if (fillMenu != null) { clearPopupMenu(menu); callF(fillMenu, menu); } setMenuItems(); } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { if (fillMenu != null) clearPopupMenu(menu); else restoreMenuItems(); } @Override public void popupMenuCanceled(PopupMenuEvent e) { if (fillMenu != null) clearPopupMenu(menu); else restoreMenuItems(); } final public void setMenuItems() { menuItems = menu.getComponents(); if (keepVisibleIndex >= topFixedCount && keepVisibleIndex <= menuItems.length - bottomFixedCount && (keepVisibleIndex > firstIndex + scrollCount || keepVisibleIndex < firstIndex)) { firstIndex = Math.min(firstIndex, keepVisibleIndex); firstIndex = Math.max(firstIndex, keepVisibleIndex - scrollCount + 1); } if (menuItems.length > topFixedCount + scrollCount + bottomFixedCount) { refreshMenu(); } } final public void restoreMenuItems() { menu.removeAll(); for (Component component : menuItems) { menu.add(component); } } } public class MenuScrollTimer extends javax.swing.Timer { public MenuScrollTimer(final int increment, int interval) { super(interval, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { firstIndex += increment; refreshMenu(); } }); } } public class MenuScrollItem extends JMenuItem implements ChangeListener { public MenuScrollTimer timer; public MenuScrollItem(MenuIcon icon, int increment) { setIcon(icon); setDisabledIcon(icon); timer = new MenuScrollTimer(increment, interval); addChangeListener(this); } public void setInterval(int interval) { timer.setDelay(interval); } @Override public void stateChanged(ChangeEvent e) { if (isArmed() && !timer.isRunning()) { timer.start(); } if (!isArmed() && timer.isRunning()) { timer.stop(); } } } static public MenuIcon UP = new MenuIcon(9, 1, 9); static public MenuIcon DOWN = new MenuIcon(1, 9, 1); static public class MenuIcon implements Icon { final public int[] xPoints = { 1, 5, 9 }; final public int[] yPoints; public MenuIcon(int... yPoints) { this.yPoints = yPoints; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Dimension size = c.getSize(); Graphics g2 = g.create(size.width / 2 - 5, size.height / 2 - 5, 10, 10); g2.setColor(Color.GRAY); g2.drawPolygon(xPoints, yPoints, 3); if (c.isEnabled()) { g2.setColor(Color.BLACK); g2.fillPolygon(xPoints, yPoints, 3); } g2.dispose(); } @Override public int getIconWidth() { return 0; } @Override public int getIconHeight() { return 10; } } } static public class G22Analyzer extends G22LeftArrowScript { public Ref exampleImage = new Ref(); @Override public GazelleV_LeftArrowScriptParser makeParser() { var parser = super.makeParser(); parser.addVar("image", BufferedImage.class, false); parser.addVar("imageStream", SourceTriggeredStream.class, false); parser.addVar("context", G22AnalysisContext.class, false); return parser; } public class CompiledAnalyzer extends LASCompileResult { final public CompiledAnalyzer setTimeout(double timeout) { return timeout(timeout); } public CompiledAnalyzer timeout(double timeout) { this.timeout = timeout; return this; } final public double getTimeout() { return timeout(); } public double timeout() { return timeout; } public double timeout = 10; public G22AnalysisContext createAnalysisContext(BufferedImage image) { return new G22AnalysisContext(g22utils(), image); } public Object get_impl(G22AnalysisContext context) { FlexibleVarContext ctx = new FlexibleVarContext(); ctx.set("image", context.image); ctx.set("imageStream", context.imageStream); ctx.set("context", context); return parsedScript.get(ctx); } public Object get_impl(BufferedImage image) { return get_impl(createAnalysisContext(image)); } public Object get(BufferedImage image) { return get(createAnalysisContext(image)); } public Object get(G22AnalysisContext context) { if (context.analyzerResults.containsKey(analyzer())) { Object value = context.analyzerResults.get(analyzer()); if (value == G22AnalysisContext.calculating) throw fail("Recursive call to analyzer " + this); return ((OKOrError) value).getMandatory(); } context.analyzerResults.put(analyzer(), G22AnalysisContext.calculating); var result = okOrError(() -> { if (parsedScript == null) rethrow(compileError); if (context.image == null && context.imageStream == null) throw fail("Need image or imageStream"); return g22utils().evalRegisteredCode(timeout, str(G22Analyzer.this), () -> get_impl(context)); }); context.analyzerResults.put(analyzer(), result); return result.getMandatory(); } } public G22Analyzer analyzer() { return this; } public LASCompileResult newCompileResult() { return new CompiledAnalyzer(); } public CompiledAnalyzer compileForAutoRun() { return (CompiledAnalyzer) super.compileForAutoRun(); } } static public class ConceptsComboBox extends JComboBox { public Concepts concepts; public Class conceptClass; public AWTOnConceptChanges updater; final public ConceptsComboBox setAllowNull(boolean allowNull) { return allowNull(allowNull); } public ConceptsComboBox allowNull(boolean allowNull) { this.allowNull = allowNull; return this; } final public boolean getAllowNull() { return allowNull(); } public boolean allowNull() { return allowNull; } public boolean allowNull = false; public ConceptsComboBox(Concepts concepts, Class conceptClass) { this.conceptClass = conceptClass; this.concepts = concepts; updateItems(); updater = new AWTOnConceptChanges(concepts, this, () -> updateItems()); updater.install(); } public void updateItems() { var l = sortTheList(asList(freshList())); if (allowNull) l = nullPlus(l); setComboBoxItems_notifyListeners(this, l); } transient public IF0> freshList; public Collection freshList() { return freshList != null ? freshList.get() : freshList_base(); } final public Collection freshList_fallback(IF0> _f) { return _f != null ? _f.get() : freshList_base(); } public Collection freshList_base() { return main.list(concepts, conceptClass); } transient public IF1, List> sortTheList; public List sortTheList(List l) { return sortTheList != null ? sortTheList.get(l) : sortTheList_base(l); } final public List sortTheList_fallback(IF1, List> _f, List l) { return _f != null ? _f.get(l) : sortTheList_base(l); } public List sortTheList_base(List l) { return sortConceptsByID(l); } public A get() { return getSelectedItem_typed(this); } public void select(long conceptID) { main.setSelectedItem(this, getConcept(concepts, conceptClass, conceptID)); } } static public class RSTADummyParser extends org.fife.ui.rsyntaxtextarea.parser.AbstractParser { final public Pair> getErrors() { return errors(); } public Pair> errors() { return errors; } public Pair> errors; static public class Error { final public Error setStart(LineAndColumn start) { return start(start); } public Error start(LineAndColumn start) { this.start = start; return this; } final public LineAndColumn getStart() { return start(); } public LineAndColumn start() { return start; } public LineAndColumn start; final public Error setEnd(LineAndColumn end) { return end(end); } public Error end(LineAndColumn end) { this.end = end; return this; } final public LineAndColumn getEnd() { return end(); } public LineAndColumn end() { return end; } public LineAndColumn end; final public Error setMsg(String msg) { return msg(msg); } public Error msg(String msg) { this.msg = msg; return this; } final public String getMsg() { return msg(); } public String msg() { return msg; } public String msg; } @Override public org.fife.ui.rsyntaxtextarea.parser.ParseResult parse(RSyntaxDocument doc, String style) { var result = new org.fife.ui.rsyntaxtextarea.parser.DefaultParseResult(this); try { var p = this.errors; if (p == null) return result; String src = p.a; var errors = p.b; if (empty(errors)) return result; String text = doc.getText(0, doc.getLength()); if (!eq(text, src)) { print("RSTADummyParser: Wrong text"); return result; } for (Error e : errors) { LineAndColumn start = e.start; LineAndColumn end = e.end; int lineStart = lineNrToCharIndex(text, start.line); int lineLength = lengthOfLine(text, start.line - 1); result.addNotice(new org.fife.ui.rsyntaxtextarea.parser.DefaultParserNotice(this, e.msg, start.line - 1, lineStart, lineLength)); } } catch (Throwable __e) { printStackTrace(__e); } return result; } public void setErrors(String text, List errors, RSyntaxTextArea textArea) { this.errors = pair(text, errors); { swing(() -> { textArea.forceReparsing(RSTADummyParser.this); }); } } public void install(RSyntaxTextArea textArea) { swing(() -> { textArea.addParser(RSTADummyParser.this); }); } } abstract static public class VarContext { final public VarContext getParent() { return parent(); } public VarContext parent() { return parent; } public VarContext parent; public VarContext() { } public VarContext(VarContext parent) { this.parent = parent; } abstract public Object get(String name); final public void put(String name, Object value) { set(name, value); } abstract public void set(String name, Object value); final public AutoCloseable tempPut(String name, Object value) { return tempSet(name, value); } abstract public AutoCloseable tempSet(String name, Object value); abstract public void unset(String name); abstract public Map varMap(); public void printMe() { pnl(varMap()); print("parent", parent); } final public VarContext setExitFromScript(Object exitFromScript) { return exitFromScript(exitFromScript); } public VarContext exitFromScript(Object exitFromScript) { this.exitFromScript = exitFromScript; return this; } final public Object getExitFromScript() { return exitFromScript(); } public Object exitFromScript() { return exitFromScript; } public Object exitFromScript; final public VarContext setReturnValue(Object returnValue) { return returnValue(returnValue); } public VarContext returnValue(Object returnValue) { this.returnValue = returnValue; return this; } final public Object getReturnValue() { return returnValue(); } public Object returnValue() { return returnValue; } public Object returnValue; public boolean exiting() { ping(); return exitFromScript != null; } } static public interface IAutoCloseableF0 extends IF0, AutoCloseable { } static public class LineAndColumn implements IFieldsToList { static final public String _fieldOrder = "line col getLineText"; public int line; public int col; public LineAndColumn() { } public LineAndColumn(int line, int col) { this.col = col; this.line = line; } public boolean equals(Object o) { if (!(o instanceof LineAndColumn)) return false; LineAndColumn __1 = (LineAndColumn) o; return line == __1.line && col == __1.col; } public int hashCode() { int h = -1128952231; h = boostHashCombine(h, _hashCode(line)); h = boostHashCombine(h, _hashCode(col)); return h; } public Object[] _fieldsToList() { return new Object[] { line, col }; } transient public IF1 getLineText; public String getLineText(int line) { return getLineText != null ? getLineText.get(line) : getLineText_base(line); } final public String getLineText_fallback(IF1 _f, int line) { return _f != null ? _f.get(line) : getLineText_base(line); } public String getLineText_base(int line) { return null; } public String toString() { return "Line " + n2(line) + ", col " + n2(col); } } public interface IG22LoadedDB { public boolean hidden(); public Concepts concepts(); } public interface IBackgroundProcesses { public IBackgroundProcess tempAdd(String name); } static public interface ISleeper_v2 { public Sleeping doLater(Timestamp targetTime, Runnable r); public default Sleeping doAfter(double seconds, Runnable r) { return doLater(tsNow().plusSeconds(seconds), r); } } static public class G22Label extends ConceptWithGlobalID { public String name; public String toString() { return name; } final public boolean textIs(String text) { return nameIs(text); } public boolean nameIs(String text) { return eqic(name, text); } } static public class MetaWithChangeListeners extends Meta implements IHasChangeListeners, ChangeTriggerable { transient public Set onChange; public MetaWithChangeListeners onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public MetaWithChangeListeners removeChangeListener(Runnable r) { main.remove(onChange, r); return this; } public void change() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } } public interface IHasTokenRangeWithSrc { public void setTokenRangeWithSrc(TokenRangeWithSrc src); public TokenRangeWithSrc tokenRangeWithSrc(); default public String srcText() { var src = tokenRangeWithSrc(); return src == null ? null : src.text(); } } public interface IDoublePt { public double x_double(); public double y_double(); } static public class FileWatchService implements AutoCloseable { final public FileWatchService setInterval(int interval) { return interval(interval); } public FileWatchService interval(int interval) { this.interval = interval; return this; } final public int getInterval() { return interval(); } public int interval() { return interval; } public int interval = 50; public int sleepSeconds = 60; public WatchService watchService; public MultiMap> listeners = new MultiMap(); public Thread pollThread; volatile public boolean closed = false; public FileWatchService() { try { watchService = FileSystems.getDefault().newWatchService(); } catch (Exception __e) { throw rethrow(__e); } } public void close() { closed = true; { cleanUp(watchService); watchService = null; } } public WatchKey addListenerImpl(File path, IVF1 listener, WatchEvent.Kind... eventKinds) { try { if (path == null) return null; startPollThread(); WatchKey key = path.toPath().register(watchService, eventKinds); listeners.put(key, listener); return key; } catch (Exception __e) { throw rethrow(__e); } } public void addNonRecursiveListener(File path, IVF1 listener) { addListenerImpl(path, listener, jdk_watchService_allEventKinds()); } public void addRecursiveListener(File path, IVF1 listener) { Set listeningTo = synchroSet(); IVF1 listener2 = new IVF1() { public void get(File f) { boolean isDir = f.isDirectory(); if (isDir && listeningTo.add(f)) try { addListenerImpl(f, this, jdk_watchService_allEventKinds()); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } callF(listener, f); } }; addListenerImpl(path, listener2, jdk_watchService_allEventKinds()); for (File subDir : findAllDirs(path)) addListenerImpl(subDir, listener2, jdk_watchService_allEventKinds()); } synchronized public void startPollThread() { if (pollThread != null) return; pollThread = startThread("File Watch Service", new Runnable() { public void run() { try { try { while (licensed() && !closed) { WatchKey key = watchService.poll(sleepSeconds, TimeUnit.SECONDS); if (key != null) { Path dir = (Path) (key.watchable()); sleep(interval); List> events = key.pollEvents(); LinkedHashSet changedFiles = new LinkedHashSet(); for (WatchEvent event : reversedIterator(events)) { try { final Path changed = (Path) event.context(); if (changed == null) continue; File full = newFile(dir.toFile(), changed.toFile().getPath()); changedFiles.add(full); } catch (Throwable __e) { printStackTrace(__e); } } for (File f : changedFiles) pcallFAll(listeners.get(key), f); key.reset(); } } } catch (ClosedWatchServiceException e) { } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n while (licensed() && !closed) { \r\n WatchKey key = wat..."; } }); } } static public interface WidthAndHeight { default public int w() { return getWidth(); } public int getWidth(); default public int h() { return getHeight(); } public int getHeight(); public default Rect bounds() { return rect(0, 0, getWidth(), getHeight()); } default public int area() { return toInt(areaAsLong()); } default public long areaAsLong() { return longMul(w(), h()); } } public interface IBackgroundProcess extends AutoCloseable { public IBackgroundProcess setInterruptAction(Runnable action); } static public class TokenRangeWithSrc extends TokenRange { public List tok; public TokenRangeWithSrc() { } public TokenRangeWithSrc(List tok, int start) { this.start = start; end = start; } public TokenRangeWithSrc(List tok, int start, int end) { this.end = end; this.start = start; } public TokenRangeWithSrc(ListAndIndex startPtr, ListAndIndex endPtr) { assertNotNull("startPtr", startPtr); assertNotNull("endPtr", endPtr); assertSame(tok = startPtr.list(), endPtr.list()); start = startPtr.idx(); end = endPtr.idx(); } public ListAndIndex startPtr() { return new ListAndIndex(tok, start); } public ListAndIndex endPtr() { return new ListAndIndex(tok, end); } public LineAndColumn startLineAndCol() { return tokenToLineAndColumn(startPtr()); } public LineAndColumn endLineAndCol() { return tokenToLineAndColumn(endPtr()); } public String text() { return joinSubList(tok, start, end); } public String toString() { var start = startLineAndCol(); if (eq(start, end)) return str(start); return start + " to " + endLineAndCol(); } public String fullSourceText() { return join(tok); } } static abstract public class VF2 { abstract public void get(A a, B b); } static public class ConceptWithGlobalID extends Concept implements IHasGlobalID { public GlobalID globalID = aGlobalIDObjUnlessLoading(); public GlobalID globalID() { return globalID; } public String globalIDStr() { return strOrNull(globalID); } public String prependGlobalID(String s) { return globalID == null ? s : "[" + globalID + "] " + s; } } static public class FileBasedLock implements AutoCloseable { public File lockFile; public double timeout = 60.0; public boolean verbose = false; public boolean haveLock = false; public java.util.Timer touchTimer; final public FileBasedLock setContentsForLockFile(String contentsForLockFile) { return contentsForLockFile(contentsForLockFile); } public FileBasedLock contentsForLockFile(String contentsForLockFile) { this.contentsForLockFile = contentsForLockFile; return this; } final public String getContentsForLockFile() { return contentsForLockFile(); } public String contentsForLockFile() { return contentsForLockFile; } public String contentsForLockFile; public FileBasedLock() { } public FileBasedLock(File lockFile) { this.lockFile = lockFile; } public FileBasedLock(File lockFile, double timeout) { this.timeout = timeout; this.lockFile = lockFile; } synchronized public boolean tryToLock() { if (haveLock) return true; if (fileExists(lockFile)) { double age = fileAgeInSeconds(lockFile); double remaining = timeout - age; print("Lock file age: " + lockFile + ": " + iround(age) + " s" + (remaining <= 0 ? " - old, deleting" : " - please start again in " + nSeconds(iceil(remaining)))); if (remaining <= 0) { print("Deleting old lock file (program crashed?): " + lockFile + " (age: " + iround(age) + " seconds)"); deleteFile(lockFile); } } try { mkdirsForFile(lockFile); java.nio.file.Files.createFile(toPath(lockFile)); if (nempty(contentsForLockFile)) writeContents(); acquired(); return true; } catch (Throwable e) { printExceptionShort("Can't lock", e); return false; } } public void writeContents() { saveTextFileWithoutTemp(lockFile, unnull(contentsForLockFile)); } final public void acquired() { haveLock = true; startTouchTimer(); } public void forceLock() { try { print("Force-locking " + lockFile); writeContents(); acquired(); } catch (Exception __e) { throw rethrow(__e); } } public String lockError() { return "Couldn't aquire lock file: " + lockFile; } public void lockOrFail() { if (!tryToLock()) throw fail(lockError()); } synchronized public void startTouchTimer() { if (touchTimer != null) return; double interval = timeout / 2; touchTimer = doEvery(interval, new Runnable() { public void run() { try { doTouch(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "doTouch();"; } }); if (verbose) print("Touch timer started for " + lockFile + " (" + interval + "s)"); } synchronized public void doTouch() { try { if (haveLock) { if (verbose) print("Touching lock file: " + lockFile); touchExistingFile(lockFile); } } catch (Throwable __e) { printStackTrace(__e); } } public synchronized void close() { try { { cleanUp(touchTimer); touchTimer = null; } if (haveLock) { haveLock = false; if (verbose) print("Deleting lock file: " + lockFile); deleteFile(lockFile); } } catch (Throwable __e) { printStackTrace(__e); } } synchronized public void _simulateCrash() { { cleanUp(touchTimer); touchTimer = null; } } public void deleteOnExit() { if (haveLock) lockFile.deleteOnExit(); } public String actualContents() { return loadTextFile(lockFile); } public boolean hasExpectedContents() { return eq(unnull(contentsForLockFile), actualContents()); } } static public class ScoredStringSearcher extends ScoredSearcher_stable { public Set seen; public ScoredStringSearcher() { } public ScoredStringSearcher(String query, Object... __) { super(query); } public ScoredStringSearcher uniquify(boolean b) { seen = b ? new HashSet() : null; return this; } final public void add(String s) { put(s); } public void put(String s) { if (seen == null || seen.add(s)) put(s, s); } public void addAll(Iterable l) { for (var s : unnullForIteration(l)) add(s); } public void addAll(String... l) { addAll(asList(l)); } } static public class WithTimestamp extends Var { public long timestamp; final public Timestamp timestamp() { return getTimestamp(); } final public Timestamp timeStamp() { return getTimestamp(); } public Timestamp getTimestamp() { return timestamp == 0 ? null : new Timestamp(timestamp); } public WithTimestamp() { } public WithTimestamp(long timestamp, A value) { super(value); this.timestamp = timestamp; } public WithTimestamp(A value) { this(now(), value); } public Timestamp timestampObj() { return timestamp == 0 ? null : new Timestamp(timestamp); } public String toString() { return toStringWithTimestamp(super.toString()); } public String toStringQuoted() { return toStringWithTimestamp(quote(super.toString())); } public String toStringWithTimestamp(String s) { return s + " at " + localDateWithSeconds(timestamp); } public boolean olderThanMinutes(double minutes) { return elapsedMinutes_timestamp(timestamp) >= minutes; } public boolean olderThanSeconds(double seconds) { return elapsedSeconds_timestamp(timestamp) >= seconds; } } static public class G22GalleryImage extends ConceptWithChangeListeners { public transient FieldVar varPath_cache; public FieldVar varPath() { if (varPath_cache == null) varPath_cache = varPath_load(); return varPath_cache; } public FieldVar varPath_load() { return new FieldVar(this, "path", () -> path(), path -> path(path)); } final public G22GalleryImage setPath(File path) { return path(path); } public G22GalleryImage path(File path) { if (!eq(this.path, path)) { this.path = path; change(); } return this; } final public File getPath() { return path(); } public File path() { return path; } public File path; public String toString() { return fileName(path); } public boolean imageExists() { return fileExists(path); } final public BufferedImage getImage() { return load(); } public BufferedImage load() { return loadImage2(path); } public File imageFile() { return path; } } static final public class ParameterizedTypeImpl implements ParameterizedType { public ParameterizedTypeImpl() { } public Type ownerType; public Type rawType; public Type[] typeArguments; public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) { this.typeArguments = typeArguments; this.rawType = rawType; this.ownerType = ownerType; } public Type[] getActualTypeArguments() { return typeArguments; } public Type getRawType() { return rawType; } public Type getOwnerType() { return ownerType; } @Override public boolean equals(Object other) { if (other instanceof ParameterizedType) return eq(ownerType, ((ParameterizedType) other).getOwnerType()) && eq(rawType, ((ParameterizedType) other).getRawType()) && eq(asList(typeArguments), asList(((ParameterizedType) other).getActualTypeArguments())); return false; } @Override public int hashCode() { return Arrays.hashCode(typeArguments) ^ rawType.hashCode() ^ _hashCode(ownerType); } @Override public String toString() { int length = typeArguments.length; if (length == 0) return typeToString(rawType); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(typeToString(rawType)).append("<").append(typeToString(typeArguments[0])); for (int i = 1; i < length; i++) { stringBuilder.append(", ").append(typeToString(typeArguments[i])); } return stringBuilder.append(">").toString(); } static public String typeToString(Type type) { return type instanceof Class ? ((Class) type).getName() : type.toString(); } } public interface IStringifier { public String toString(A o); } static public class AWTOnConceptChanges implements AutoCloseable { final public AWTOnConceptChanges setComponent(JComponent component) { return component(component); } public AWTOnConceptChanges component(JComponent component) { this.component = component; return this; } final public JComponent getComponent() { return component(); } public JComponent component() { return component; } public JComponent component; final public AWTOnConceptChanges setAction(Runnable action) { return action(action); } public AWTOnConceptChanges action(Runnable action) { this.action = action; return this; } final public Runnable getAction() { return action(); } public Runnable action() { return action; } public Runnable action; final public AWTOnConceptChanges setConcepts(Concepts concepts) { return concepts(concepts); } public AWTOnConceptChanges concepts(Concepts concepts) { this.concepts = concepts; return this; } final public Concepts getConcepts() { return concepts(); } public Concepts concepts() { return concepts; } public Concepts concepts; final public AWTOnConceptChanges setFirstDelay(int firstDelay) { return firstDelay(firstDelay); } public AWTOnConceptChanges firstDelay(int firstDelay) { this.firstDelay = firstDelay; return this; } final public int getFirstDelay() { return firstDelay(); } public int firstDelay() { return firstDelay; } public int firstDelay; final public AWTOnConceptChanges setDelay(int delay) { return delay(delay); } public AWTOnConceptChanges delay(int delay) { this.delay = delay; return this; } final public int getDelay() { return delay(); } public int delay() { return delay; } public int delay = 500; public long changes = -1; public javax.swing.Timer timer; public AWTOnConceptChanges(Concepts concepts, JComponent component, Runnable action) { this.action = action; this.component = component; this.concepts = concepts; } public void install() { assertNotNull(concepts); timer = installTimer(component, delay, firstDelay, new Runnable() { public void run() { try { _trigger(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_trigger();"; } }); } public void _trigger() { long c = concepts.changes; if (changes != c) { changes = c; { if (action != null) action.run(); } } } public void close() { try { { cleanUp(timer); timer = null; } } catch (Exception __e) { throw rethrow(__e); } } } abstract static public class Surface extends JPanel implements IMeta { public boolean clearSurface = true; public boolean clearOnce = false; volatile public Object meta; public void _setMeta(Object meta) { this.meta = meta; } public Object _getMeta() { return meta; } final public boolean scaffolding() { return scaffoldingEnabled(); } public boolean scaffoldingEnabled() { return main.scaffoldingEnabled(this); } public boolean scaffoldingEnabled(Object o) { return main.scaffoldingEnabled(o); } public Surface() { setDoubleBuffered(false); } public Graphics2D createGraphics2D(int width, int height, Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setBackground(getBackground()); if (clearSurface || clearOnce) { g2.clearRect(0, 0, width, height); clearOnce = false; } return g2; } public abstract void render(int w, int h, Graphics2D g); public void paintImmediately(int x, int y, int w, int h) { RepaintManager repaintManager = null; boolean save = true; if (!isDoubleBuffered()) { repaintManager = RepaintManager.currentManager(this); save = repaintManager.isDoubleBufferingEnabled(); repaintManager.setDoubleBufferingEnabled(false); } super.paintImmediately(x, y, w, h); if (repaintManager != null) repaintManager.setDoubleBufferingEnabled(save); } public void paint(Graphics g) { Dimension d = getSize(); Graphics2D g2 = createGraphics2D(d.width, d.height, g); render(d.width, d.height, g2); g2.dispose(); } } static public class LASClassDef { final public LASClassDef setUserGivenName(String userGivenName) { return userGivenName(userGivenName); } public LASClassDef userGivenName(String userGivenName) { this.userGivenName = userGivenName; return this; } final public String getUserGivenName() { return userGivenName(); } public String userGivenName() { return userGivenName; } public String userGivenName; final public LASClassDef setClassDefPrefix(String classDefPrefix) { return classDefPrefix(classDefPrefix); } public LASClassDef classDefPrefix(String classDefPrefix) { this.classDefPrefix = classDefPrefix; return this; } final public String getClassDefPrefix() { return classDefPrefix(); } public String classDefPrefix() { return classDefPrefix; } public String classDefPrefix = "userCode."; final public LASClassDef setFullCompilation(boolean fullCompilation) { return fullCompilation(fullCompilation); } public LASClassDef fullCompilation(boolean fullCompilation) { this.fullCompilation = fullCompilation; return this; } final public boolean getFullCompilation() { return fullCompilation(); } public boolean fullCompilation() { return fullCompilation; } public boolean fullCompilation = false; final public LASClassDef setVerbose(boolean verbose) { return verbose(verbose); } public LASClassDef verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = true; public List fields = new ArrayList(); public List methods = new ArrayList(); public List methodBodies = new ArrayList(); static public class FieldDef { final public FieldDef setName(String name) { return name(name); } public FieldDef name(String name) { this.name = name; return this; } final public String getName() { return name(); } public String name() { return name; } public String name; final public FieldDef setType(Type type) { return type(type); } public FieldDef type(Type type) { this.type = type; return this; } final public Type getType() { return type(); } public Type type() { return type; } public Type type; } public String structForHash() { return GazelleV_LeftArrowScript.scriptStruct(litorderedmap("userGivenName", userGivenName, "fields", fields, "methods", methods, "fullCompilation", fullCompilation)); } public String classHash_cache; public String classHash() { if (classHash_cache == null) classHash_cache = classHash_load(); return classHash_cache; } public String classHash_load() { String struct = structForHash(); if (verbose) print("structForHash", struct); return md5(struct); } public String finalClassName() { return classDefPrefix() + finalClassNameWithoutPrefix(); } public String finalClassNameWithoutPrefix() { return or2(userGivenName, "C") + "_" + classHash(); } public byte[] toBytes_cache; public byte[] toBytes() { if (toBytes_cache == null) toBytes_cache = toBytes_load(); return toBytes_cache; } public byte[] toBytes_load() { ClassMaker classMaker = new ClassMaker(finalClassName()); var cp = classMaker.getConstantPool(); for (var field : fields) { var type = field.type; var fg = new FieldGen(Const.ACC_PUBLIC, typeToBCELType(type), field.name, cp); if (type instanceof ParameterizedType) fg.addAttribute(new org.apache.bcel.classfile.Signature(cp.addUtf8("Signature"), 2, cp.addUtf8(typeToVMSignature((ParameterizedType) type)), cp.getConstantPool())); classMaker.addField(fg); } for (var method : methods) if (fullCompilation) fullyCompileMethod(classMaker, method); else semiCompileMethod(classMaker, method); classMaker.addDefaultConstructor(); return classMaker.toBytes(); } public void semiCompileMethod(ClassMaker classMaker, GazelleV_LeftArrowScript.FunctionDef method) { int iMethod = l(methodBodies); methodBodies.add(method); String bodyFieldName = "_body" + iMethod; classMaker.addField(new FieldGen(Const.ACC_PUBLIC | Const.ACC_STATIC, classToBCELType(GazelleV_LeftArrowScript.Evaluable.class), bodyFieldName, classMaker.getConstantPool())); int nArgs = l(method.args); MethodMaker mm = new MethodMaker(classMaker, typeToClass(method.returnType), method.name, repArray(Class.class, Object.class, nArgs)); int iThis = 0, iFirstArg = 1, iCtx = iFirstArg + nArgs; mm.newObject(FlexibleVarContext.class); mm.astore(iCtx); mm.aload(iCtx); mm.stringConstant("this"); mm.aload(iThis); mm.invokeVirtual(VarContext.class, void.class, "put", String.class, Object.class); for (int iArg = 0; iArg < nArgs; iArg++) { mm.aload(iCtx); mm.stringConstant(method.args[iArg]); mm.aload(iFirstArg + iArg); mm.invokeVirtual(VarContext.class, void.class, "put", String.class, Object.class); } mm.getStaticField(classMaker.className(), bodyFieldName, GazelleV_LeftArrowScript.Evaluable.class); mm.aload(iCtx); mm.invokeInterface(GazelleV_LeftArrowScript.Evaluable.class, Object.class, "get", VarContext.class); if (method.returnType() != Object.class) mm.checkCast(typeToClass(method.returnType())); mm.areturn(); mm.done(); } public void fullyCompileMethod(ClassMaker classMaker, GazelleV_LeftArrowScript.FunctionDef method) { MethodMaker mm = new MethodMaker(classMaker, typeToClass(method.returnType()), method.name, repArray(Class.class, Object.class, l(method.args))); var tbc = new LASToByteCode(mm) { public JVMStackCellType compileGetVar(GazelleV_LeftArrowScript.GetVar code) { if (eq(code.var, "this")) { mm.aload(0); return JVMStackCellType.objValue; } int iArg = indexOf(method.args, code.var); if (iArg >= 0) { mm.aload(iArg + 1); return JVMStackCellType.objValue; } return super.compileGetVar(code); } }; tbc.postConversion = stackTop -> mm.convertToObject(stackTop); tbc.compileScript(method.body); mm.areturn(); mm.done(); } public void init(Class c) { for (int iMethod = 0; iMethod < l(methodBodies); iMethod++) { String bodyFieldName = "_body" + iMethod; set(c, bodyFieldName, methodBodies.get(iMethod).body); } } } static public class ConceptWithChangeListeners extends Concept implements IHasChangeListeners, ChangeTriggerable { transient public Set onChange; public ConceptWithChangeListeners onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public ConceptWithChangeListeners removeChangeListener(Runnable r) { main.remove(onChange, r); return this; } public void fireChange() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public void _onChange() { super._onChange(); fireChange(); } public void change() { super.change(); } } static public class AppendableChain extends MinimalChain implements Iterable { public MinimalChain last; public int size; public AppendableChain() { } public AppendableChain(A element) { this.element = element; size = 1; last = this; } public AppendableChain(A element, AppendableChain next) { this.next = next; this.element = element; if (next == null) return; MinimalChain b = new MinimalChain(); b.element = next.element; b.next = next.next; this.next = b; last = next.last; size = next.size + 1; } public String toString() { return str(toList()); } public boolean add(A a) { MinimalChain newLast = new MinimalChain(a); last.next = newLast; last = newLast; ++size; return true; } public AppendableChain popFirst() { if (next == null) return null; element = next.element; if (last == next) last = this; next = next.next; --size; return this; } public ArrayList toList() { ArrayList l = emptyList(size); MinimalChain c = this; while (c != null) { l.add(c.element); c = c.next; } return l; } public class ACIt extends IterableIterator { public MinimalChain c = AppendableChain.this; public boolean hasNext() { return c != null; } public A next() { var a = c.element; c = c.next; return a; } } public IterableIterator iterator() { return new ACIt(); } } static public class G22AnalysisContext implements IFieldsToList { public G22Utils g22utils; public BufferedImage image; public G22AnalysisContext() { } public G22AnalysisContext(G22Utils g22utils, BufferedImage image) { this.image = image; this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ", " + image + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils, image }; } public SourceTriggeredStream imageStream; public Map analyzerResults = syncMap(); static public Object calculating; public G22AnalysisContext(G22Utils g22utils, SourceTriggeredStream imageStream) { this.imageStream = imageStream; this.g22utils = g22utils; } public Object callAnalyzer(long analyzerID) { var analyzer = getConcept(g22utils.concepts(), G22Analyzer.class, analyzerID); if (analyzer == null) throw fail("Analyzer with ID " + analyzerID + " not found"); return callAnalyzer(analyzer); } public Object callAnalyzer(G22Analyzer analyzer) { return analyzer.compileForAutoRun().get(this); } } static public class Lowest { public A best; public double score; transient public Object onChange; synchronized public boolean isNewBest(double score) { return best == null || score < this.score; } synchronized public double bestScore() { return best == null ? Double.NaN : score; } public double score() { return bestScore(); } synchronized public float floatScore() { return best == null ? Float.NaN : (float) score; } synchronized public float floatScoreOr(float defaultValue) { return best == null ? defaultValue : (float) score; } public boolean put(A a, double score) { boolean change = false; synchronized (this) { if (a != null && isNewBest(score)) { best = a; this.score = score; change = true; } } if (change) pcallF(onChange); return change; } synchronized public void clear() { best = null; score = 0; } synchronized public A get() { return best; } synchronized public boolean has() { return best != null; } synchronized public Pair pair() { return best == null ? null : new Pair(best, bestScore()); } public String toString() { return "Score " + formatDouble_significant2(score, 4) + ": " + best; } } static public class MultiSleeper extends RestartableCountdown implements ISleeper_v2 { public TreeMultiMap entries = new TreeMultiMap(); public void check() { var time = nextWakeUpTime(); var action = firstValue(entries); setTargetTime(time == null ? 0 : time.sysTime(), new Runnable() { public void run() { try { List toCall; synchronized (MultiSleeper.this) { toCall = entries.get(time); entries.remove(time); } check(); pcallFAll(toCall); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "List toCall;\r\n synchronized(MultiSleeper.this) {\r\n toCa..."; } }); } synchronized public void removeEntry(Timestamp targetTime, Runnable action) { entries.remove(targetTime, action); } synchronized public Timestamp nextWakeUpTime() { return firstKey(entries); } public synchronized Sleeping doLater(Timestamp targetTime, Runnable r) { if (r == null || targetTime == null) return null; targetTime = max(targetTime, tsNow()); entries.put(targetTime, r); check(); return new Sleeping(targetTime, r) { public void close() { try { removeEntry(targetTime, r); } catch (Exception __e) { throw rethrow(__e); } } }; } } static public class JFastLogView_noWrap extends JComponent implements Scrollable { public List lines = syncList(); public boolean endsWithNewLine, verbose; public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return 20; } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return (direction == SwingConstants.HORIZONTAL ? visibleRect.width : visibleRect.height) * 5 / 6; } public boolean getScrollableTracksViewportWidth() { return false; } public boolean getScrollableTracksViewportHeight() { return false; } public void paint(Graphics g) { int w = getWidth(), h = getHeight(); g.setColor(getBackground()); g.fillRect(0, 0, w, h); g.setColor(getForeground()); FontMetrics fm = componentFontMetrics(this); int fh = fm.getHeight(); Rectangle clip = g.getClipBounds(); int start, end; if (clip == null) { start = 0; end = l(lines); } else { start = max(0, clip.y / fh); end = min(l(lines), idiv_ceil(clip.y + clip.height, fh)); } int y = fm.getAscent() + start * fh; for (int i = start; i < end; i++) { String s = get(lines, i); if (s != null) g.drawString(s, 0, y); y += fh; } } public Dimension getPreferredSize() { FontMetrics fm = componentFontMetrics(this); if (fm == null) return new Dimension(50, 50); int fh = fm.getHeight(); int w = 0; for (int i = 0; i < l(lines); i++) { String s = get(lines, i); w = max(w, fm.stringWidth(unnull(s))); } return new Dimension(w, fh * l(lines)); } public JFastLogView_noWrap() { } public JFastLogView_noWrap(String text) { setText(text); } { componentPopupMenuItem(this, "Copy full text", new Runnable() { public void run() { try { copyFullText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyFullText();"; } }); } public boolean setLines(Collection lines) { List newList = asSyncList(lines); if (eq(this.lines, newList)) return false; this.lines = newList; _revalidate(this); return true; } public boolean setText(String text) { endsWithNewLine = endsWithNewLine(text); return setLines(lines(text)); } public void append(String text) { if (nempty(text)) setText(getText() + text); } public String getText() { return lines_rtrimIf(!endsWithNewLine, cloneList(lines)); } public void copyFullText() { copyTextToClipboard(getText()); } } static public class SimpleLeftToRightParser extends Meta { public String text; public List tok; final public ListAndIndex getPtr() { return ptr(); } public ListAndIndex ptr() { return ptr; } public ListAndIndex ptr; public ListAndIndex mainLoopPtr; public String currentToken; public boolean caseInsensitive = false; public List warnings = new ArrayList(); public SimpleLeftToRightParser() { } public SimpleLeftToRightParser(String text) { this.text = text; } public SimpleLeftToRightParser(List tok) { this.tok = tok; } transient public IF1> tokenize; public List tokenize(String text) { return tokenize != null ? tokenize.get(text) : tokenize_base(text); } final public List tokenize_fallback(IF1> _f, String text) { return _f != null ? _f.get(text) : tokenize_base(text); } public List tokenize_base(String text) { return javaTok(text); } final public String token() { return t(); } public String t() { return currentToken; } public String token(int i) { return get(tok, ptr.idx() + i * 2); } final public String consume() { return next(); } final public String tpp() { return next(); } public String next() { var t = t(); next(1); return t; } final public String prevSpace() { return lastSpace(); } public String lastSpace() { return get(tok, ptr.idx() - 1); } public String nextSpace() { return get(tok, ptr.idx() + 1); } public String space(int i) { return get(tok, ptr.idx() + i * 2 + 1); } public void unconsume() { next(-1); } final public boolean eqTok(String a, String b) { return tokEq(a, b); } public boolean tokEq(String a, String b) { return eqOrEqic(caseInsensitive, a, b); } public boolean tokEqOneOf(String a, String... l) { return any(l, b -> tokEq(a, b)); } public boolean is(int i, String t) { return tokEq(token(i), t); } public boolean is(String t) { return tokEq(currentToken, t); } public boolean was(String t) { return tokEq(token(-1), t); } public boolean isOneOf(String... tokens) { return tokEqOneOf(currentToken, tokens); } public String[] consumeArray(int n) { String[] array = new String[n]; for (int i = 0; i < n; i++) array[i] = consume(); return array; } public boolean isInteger() { return isInteger(t()); } public boolean isInteger(String s) { return main.isInteger(s); } public boolean isIdentifier() { return isIdentifier(t()); } public boolean isIdentifier(String s) { return main.isIdentifier(s); } public String consumeIdentifier() { return assertIdentifier(consume()); } public boolean consumeOpt(String token) { if (!is(token)) return false; consume(); return true; } public void consume(String token) { if (!is(token)) throw fail("Expected " + quote(token) + ", got " + describeToken(token())); consume(); } public String describeToken(String token) { return token == null ? "EOF" : quote(token); } public String consumeOneOf(String... tokens) { if (!isOneOf(tokens)) throw fail("Expected one of " + asList(tokens)); return consume(); } public void ptr(ListAndIndex ptr) { this.ptr = ptr; fetch(); } final public int tokIdx() { return idx(); } public int idx() { return ptr.idx(); } public int lTok() { return l(tok); } public int nRemainingTokens() { return (lTok() - idx()) / 2; } final public boolean endOfText() { return atEnd(); } public boolean atEnd() { return ptr.atEnd(); } public void fetch() { currentToken = ptr.get(); } public boolean lineBreak() { return containsLineBreak(get(tok, ptr.idx() - 1)); } public boolean atEndOrLineBreak() { return atEnd() || lineBreak(); } public void init() { if (tok == null) tok = tokenize(text); if (ptr == null) ptr(new ListAndIndex(tok, 1)); } public boolean mainLoop() { init(); if (atEnd()) return false; if (eq(mainLoopPtr, ptr)) throw fail("main loop didn't advance (current token: " + quote(token()) + ")"); mainLoopPtr = ptr; return true; } public class AssureAdvance { public ListAndIndex cur; { init(); } public boolean get() { if (atEnd()) return false; if (eq(cur, ptr)) throw fail("Parse loop didn't advance (current token: " + quote(token()) + ")"); cur = ptr; return true; } } public void unknownToken() { warn("Unknown token: " + t()); } public void warn(String msg) { warnings.add(print(msg)); } final public void skip(int n) { next(n); } public void next(int n) { ptr(min(lTok(), ptr.idx() + n * 2)); } public void ptr(int i) { ptr(new ListAndIndex(tok, min(i | 1, l(tok)))); } public LineAndColumn lineAndColumn() { return tokenToLineAndColumn(ptr); } public LineAndColumn lineAndColumn(int idx) { return tokenToLineAndColumn(ptr.plus(idx * 2)); } public String consumeUntilSpaceOr(IF0 pred) { int i = idx(); do next(); while (!atEnd() && empty(lastSpace()) && !pred.get()); return joinSubList(tok, i, idx() - 1); } public void setText(String text) { this.text = text; tok = null; ptr = null; } public int relativeIndexOf(String token) { int n = nRemainingTokens(); for (int i = 0; i < n; i++) if (eqTok(token(i), token)) return i; return -1; } } static public class MultiSet implements IMultiSet { public Map map = new HashMap(); public int size; public MultiSet(boolean useTreeMap) { if (useTreeMap) map = new TreeMap(); } public MultiSet(TreeMap map) { this.map = map; } public MultiSet() { } public MultiSet(Iterable c) { addAll(c); } public MultiSet(MultiSet ms) { synchronized (ms) { for (A a : ms.keySet()) add(a, ms.get(a)); } } public synchronized int add(A key) { return add(key, 1); } synchronized public void addAll(Iterable c) { if (c != null) for (A a : c) add(a); } synchronized public void addAll(MultiSet ms) { for (A a : ms.keySet()) add(a, ms.get(a)); } synchronized public int add(A key, int count) { if (count <= 0) return 0; size += count; Integer i = map.get(key); map.put(key, i != null ? (count += i) : count); return count; } synchronized public void put(A key, int count) { int oldCount = get(key); if (count == oldCount) return; size += count - oldCount; if (count != 0) map.put(key, count); else map.remove(key); } public synchronized int get(A key) { Integer i = map.get(key); return i != null ? i : 0; } synchronized public boolean contains(A key) { return map.containsKey(key); } synchronized public void remove(A key) { Integer i = map.get(key); if (i != null) { --size; if (i > 1) map.put(key, i - 1); else map.remove(key); } } synchronized public List topTen() { return getTopTen(); } synchronized public List getTopTen() { return getTopTen(10); } synchronized public List getTopTen(int maxSize) { List list = getSortedListDescending(); return list.size() > maxSize ? list.subList(0, maxSize) : list; } synchronized public List highestFirst() { return getSortedListDescending(); } synchronized public List lowestFirst() { return reversedList(getSortedListDescending()); } synchronized public List getSortedListDescending() { List list = new ArrayList(map.keySet()); Collections.sort(list, new Comparator() { public int compare(A a, A b) { return map.get(b).compareTo(map.get(a)); } }); return list; } synchronized public int getNumberOfUniqueElements() { return map.size(); } synchronized public int uniqueSize() { return map.size(); } synchronized public Set asSet() { return map.keySet(); } synchronized public NavigableSet navigableSet() { return navigableKeys((NavigableMap) map); } synchronized public Set keySet() { return map.keySet(); } synchronized public A getMostPopularEntry() { int max = 0; A a = null; for (Map.Entry entry : map.entrySet()) { if (entry.getValue() > max) { max = entry.getValue(); a = entry.getKey(); } } return a; } synchronized public void removeAll(A key) { size -= get(key); map.remove(key); } synchronized public int size() { return size; } synchronized public MultiSet mergeWith(MultiSet set) { MultiSet result = new MultiSet(); for (A a : set.asSet()) { result.add(a, set.get(a)); } return result; } synchronized public boolean isEmpty() { return map.isEmpty(); } synchronized public String toString() { return str(map); } synchronized public void clear() { map.clear(); size = 0; } final public Map toMap() { return asMap(); } synchronized public Map asMap() { return cloneMap(map); } } static public class FunctionCall implements Transformable, IFieldsToList { public Object function; public Object[] args; public FunctionCall() { } public Object[] _fieldsToList() { return new Object[] { function, args }; } static public String _fieldOrder = "function args"; public FunctionCall(Object function, Object... args) { this.args = args; this.function = function; if (empty(this.args)) this.args = null; } public FunctionCall(Object function, List args) { this(function, toObjectArray(args)); } public String toString() { return function + "(" + joinWithComma(allToString(args)) + ")"; } public String toStringWithOptionalParens() { return empty(args) ? str(function) : toString(); } public boolean equals(Object o) { return o instanceof FunctionCall && eq(function, ((FunctionCall) o).function) && objectArraysEqual(args, ((FunctionCall) o).args); } public int hashCode() { return hashAboutObjects(function, asList(args)); } public List args() { return asList(args); } public Object transformUsing(IF1 f) { return new FunctionCall(f.get(function), mapObjectArray(f, args)); } } static public class VarMatches extends WrappedMap { public VarMatches() { super(new LinkedHashMap()); } public VarMatches(Map map) { this(); main.putAll(this, map); } } public interface G2Drawable { public void drawOn(Graphics2D g); default public void drawOn(BufferedImage img) { drawOn(img.createGraphics()); } } static public class ImageSurfaceSelector extends ImageSurfaceMouseHandler { public Point startingPoint; public boolean enabled = true; static public boolean verbose = false; public ImageSurfaceSelector() { } public ImageSurfaceSelector(ImageSurface is) { if (containsInstance(is.tools, ImageSurfaceSelector.class)) return; this.register(is); } public void mousePressed(MouseEvent evt) { if (verbose) print("mousePressed"); if (evt.getButton() != MouseEvent.BUTTON1) return; if (enabled) startingPoint = getPoint(evt); } public void mouseDragged(MouseEvent e) { if (verbose) print("mouseDragged"); if (startingPoint != null) { Point endPoint = getPoint(e); Rectangle r = new Rectangle(startingPoint, new Dimension(endPoint.x - startingPoint.x + 1, endPoint.y - startingPoint.y + 1)); normalize(r); r.width = min(r.width, is.getImage().getWidth() - r.x); r.height = min(r.height, is.getImage().getHeight() - r.y); is.setSelection(r); } if (verbose) print("mouseDragged done"); } public static void normalize(Rectangle r) { if (r.width < 0) { r.x += r.width; r.width = -r.width; } if (r.height < 0) { r.y += r.height; r.height = -r.height; } } public void mouseReleased(MouseEvent e) { if (verbose) print("mouseReleased"); mouseDragged(e); if (getPoint(e).equals(startingPoint)) is.setSelection((Rectangle) null); startingPoint = null; } } abstract static public class ImageSurfaceMouseHandler extends MouseAdapter implements AutoCloseable { public ImageSurface is; public void register(ImageSurface is) { this.is = is; is.tools.add(this); is.addMouseListener(this); is.addMouseMotionListener(this); } public void close() { try { if (is == null) return; is.tools.remove(this); is.removeMouseListener(this); is.removeMouseMotionListener(this); is = null; } catch (Exception __e) { throw rethrow(__e); } } public Pt getPt(MouseEvent e) { return toPt(getPoint(e)); } public Point getPoint(MouseEvent e) { return new Point((int) (e.getX() / is.getZoomX()), (int) (e.getY() / is.getZoomY())); } public ImageSurface getImageSurface() { return is; } } public enum G22ScriptMode { edit, saved, autoRunnable } public interface RunnableWithExceptions { public void run() throws Exception; } static public class PersistableOKOrError implements IF0 { public A value; final public PersistableThrowable getError() { return error(); } public PersistableThrowable error() { return error; } public PersistableThrowable error; public PersistableOKOrError() { } public PersistableOKOrError(A value) { this.value = value; } public PersistableOKOrError(boolean dummy, PersistableThrowable error) { this.error = error; assertNotNull(error); } final public boolean isOK() { return ok(); } public boolean ok() { return error == null; } public String toString() { return ok() ? str(value) : "Error: " + str(error); } public A get() { return !ok() ? null : value; } public A getMandatory() { if (!ok()) throw error.asRuntimeException(); return value; } static public PersistableOKOrError ok(A a) { return new PersistableOKOrError(a); } static public PersistableOKOrError error(PersistableThrowable error) { return new PersistableOKOrError(false, error); } } public interface IPersistenceInfo { public Map _persistenceInfo(); } static public interface IConceptCounter { public Class conceptClass(); public int countConcepts(); public Collection allConcepts(); } static public class JavaXPeepholeShortener implements IFieldsToList { public List tok; public JavaXPeepholeShortener() { } public JavaXPeepholeShortener(List tok) { this.tok = tok; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + tok + ")"; } public Object[] _fieldsToList() { return new Object[] { tok }; } public void run() { try { jreplace(tok, ", ", "+$3", (_tok, nIdx) -> eq(unquote(_get(tok, nIdx + 1)), _get(tok, nIdx + 5))); } catch (Exception __e) { throw rethrow(__e); } } } static public class Average { final public double getSum() { return sum(); } public double sum() { return sum; } public double sum; final public double getN() { return n(); } public double n() { return n; } public double n; public void add(double d) { ++n; sum += d; } public void add(double d, double weight) { n += weight; sum += d * weight; } final public double avg() { return get(); } final public double average() { return get(); } final public double getAverage() { return get(); } public double get() { return doubleRatio(sum, n); } public boolean isEmpty() { return n == 0; } public String toString() { return get() + " (n=" + n + ")"; } public void clear() { n = 0; sum = 0; } } static public interface IRef extends IF0 { public default void replaceValue(A oldValue, A newValue) { } } static public class CharInToken implements IFieldsToList { static final public String _fieldOrder = "tok iTok iChar"; public List tok; public int iTok; public int iChar; public CharInToken() { } public CharInToken(List tok, int iTok, int iChar) { this.iChar = iChar; this.iTok = iTok; this.tok = tok; } public boolean equals(Object o) { if (!(o instanceof CharInToken)) return false; CharInToken __1 = (CharInToken) o; return eq(tok, __1.tok) && iTok == __1.iTok && iChar == __1.iChar; } public int hashCode() { int h = 2081721214; h = boostHashCombine(h, _hashCode(tok)); h = boostHashCombine(h, _hashCode(iTok)); h = boostHashCombine(h, _hashCode(iChar)); return h; } public Object[] _fieldsToList() { return new Object[] { tok, iTok, iChar }; } public String token() { return get(tok, iTok); } public String toString() { return renderRecordVars("CharInToken", "iTok", iTok, "iChar", iChar, "token", token()); } } static public class RemoteDB implements AutoCloseable { public DialogIO db; public String name; public RemoteDB(String s) { this(s, false); } public RemoteDB(String s, boolean autoStart) { name = s; if (isSnippetID(s)) name = dbBotName(s); db = findBot(name); if (db == null) if (autoStart) { nohupJavax(fsI(s)); waitForBotStartUp(name); assertNotNull("Weird problem", db = findBot(s)); } else throw fail("DB " + s + " not running"); } public boolean functional() { return db != null; } public List list() { return adopt((List) rpc(db, "xlist")); } public List list(String className) { return adopt((List) rpc(db, "xlist", className)); } public List xlist() { return list(); } public List xlist(String className) { return list(className); } public List adopt(List l) { if (l != null) for (RC rc : l) adopt(rc); return l; } public RC adopt(RC rc) { if (rc != null) rc.db = this; return rc; } public Object adopt(Object o) { if (o instanceof RC) return adopt((RC) o); return o; } public String xclass(RC o) { return (String) rpc(db, "xclass", o); } public Object xget(RC o, String field) { return adopt(rpc(db, "xget", o, field)); } public String xS(RC o, String field) { return (String) xget(o, field); } public RC xgetref(RC o, String field) { return adopt((RC) xget(o, field)); } public void xset(RC o, String field, Object value) { rpc(db, "xset", o, field, value); } public RC uniq(String className) { RC ref = first(list(className)); if (ref == null) ref = xnew(className); return ref; } public RC xuniq(String className) { return uniq(className); } public RC xnew(String className, Object... values) { return adopt((RC) rpc(db, "xnew", className, values)); } public void xdelete(RC o) { rpc(db, "xdelete", o); } public void xdelete(List l) { rpc(db, "xdelete", l); } public void close() { _close(db); } public String fullgrab() { return (String) rpc(db, "xfullgrab"); } public String xfullgrab() { return fullgrab(); } public void xshutdown() { rpc(db, "xshutdown"); } public long xchangeCount() { return (long) rpc(db, "xchangeCount"); } public int xcount() { return (int) rpc(db, "xcount"); } public void reconnect() { close(); db = findBot(name); } public RC rc(long id) { return new RC(this, id); } } static public class Flag implements Runnable { public boolean up = false; public synchronized boolean raise() { if (!up) { up = true; notifyAll(); return true; } else return false; } public synchronized void waitUntilUp() { try { while (!up) { wait(); } } catch (Exception __e) { throw rethrow(__e); } } public boolean waitUntilUp(double timeout) { if (timeout == infinity()) { waitUntilUp(); return isUp(); } else return waitUntilUp(toMS(timeout)); } public synchronized boolean waitUntilUp(long timeout) { try { if (!up) { wait(timeout); } return isUp(); } catch (Exception __e) { throw rethrow(__e); } } public synchronized boolean isUp() { return up; } public boolean get() { return isUp(); } public String toString() { return isUp() ? "up" : "down"; } public void waitForThisOr(Flag otherFlag) { try { while (!isUp() && !otherFlag.isUp()) Thread.sleep(50); } catch (Exception __e) { throw rethrow(__e); } } public void run() { raise(); } } static public class ClearForAutoRun extends Var { public ClearForAutoRun() { } public ClearForAutoRun(A code) { super(code); } } static public class Stringifier_ToString implements IStringifier { public String toString(Object o) { return str(o); } } public interface IPartialStringifier { public String toStringOpt(A o); } static public class G22TypeDesc { public String exactClassName; public Set implementedClassNames; } abstract static public class Sleeping implements AutoCloseable, IFieldsToList { public Timestamp targetTime; public Runnable action; public Sleeping() { } public Sleeping(Timestamp targetTime, Runnable action) { this.action = action; this.targetTime = targetTime; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + targetTime + ", " + action + ")"; } public Object[] _fieldsToList() { return new Object[] { targetTime, action }; } public long remainingMS() { return targetTime.minus(tsNow()); } } static public class WeakValueMap implements AutoCloseable, IntSize { transient public Set> onValueForKeyReleased; public WeakValueMap onValueForKeyReleased(IVF1 f) { onValueForKeyReleased = createOrAddToSyncLinkedHashSet(onValueForKeyReleased, f); return this; } public WeakValueMap removeValueForKeyReleasedListener(IVF1 f) { main.remove(onValueForKeyReleased, f); return this; } public void valueForKeyReleased(A key) { if (onValueForKeyReleased != null) for (var listener : onValueForKeyReleased) pcallF_typed(listener, key); } public Map> map = syncMap(); public RunnablesReferenceQueue queue; public boolean myQueue = true; public WeakValueMap() { } public WeakValueMap(RunnablesReferenceQueue queue) { this.queue = queue; myQueue = false; } public class MyRef extends WeakReference implements Runnable { public A key; public MyRef(A key, B value) { super(value, queue().get()); this.key = key; } public void run() { try { boolean current = syncMapRemoveKeyAndValuePair(map, key, this); valueForKeyReleased(key); } catch (Exception __e) { throw rethrow(__e); } } } public B get(A key) { return getWeakRef(map.get(key)); } public B put(A key, B value) { synchronized (mutex()) { if (value == null) { B old = getWeakRef(map.get(key)); map.remove(key); return old; } else return getWeakRef(map.put(key, new MyRef(key, value))); } } public Object mutex() { return collectionMutex(map); } public RunnablesReferenceQueue queue() { synchronized (mutex()) { if (queue == null) queue = new RunnablesReferenceQueue(); return queue; } } public void close() { try { if (myQueue) synchronized (mutex()) { { cleanUp(queue); queue = null; } } } catch (Exception __e) { throw rethrow(__e); } } public int size() { return map.size(); } public Map snapshot() { synchronized (mutex()) { Map snapshot = new HashMap(); for (var __0 : _entrySet(map)) { var key = __0.getKey(); var ref = __0.getValue(); mapPut(snapshot, key, getWeakRef(ref)); } return snapshot; } } final public void queue(RunnablesReferenceQueue queue) { setQueue(queue); } public void setQueue(RunnablesReferenceQueue queue) { synchronized (mutex()) { if (queue == null || this.queue == queue) return; if (this.queue != null) throw fail("Can't change queue once we're started"); this.queue = queue; myQueue = false; } } } static public class VarWithNotify extends Var implements IVarWithNotify { transient public Set onChange; public VarWithNotify onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public VarWithNotify removeChangeListener(Runnable r) { main.remove(onChange, r); return this; } public void fireChange() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public VarWithNotify() { } public VarWithNotify(A a) { super(a); } public void set(A a) { A v = get(); if (eq(v, a)) { return; } synchronized (this) { this.v = a; notifyAll(); } fireChange(); } } 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()); } } static public class SourceTriggeredStream extends Meta { public DoneFlag ended = new DoneFlag(true); volatile public A lastElement; public AtomicLong elementCount = new AtomicLong(); transient public Set> onNewElement; public SourceTriggeredStream onNewElement(IVF1 f) { onNewElement = createOrAddToSyncLinkedHashSet(onNewElement, f); return this; } public SourceTriggeredStream removeNewElementListener(IVF1 f) { main.remove(onNewElement, f); return this; } public void newElement(A a) { lastElement = a; inc(elementCount); if (onNewElement != null) for (var listener : onNewElement) pcallF_typed(listener, a); } public void onNewElement(Runnable r) { onNewElement(runnableToIVF1(r)); } public A get() { return lastElement; } public long elementCount() { return elementCount.get(); } public void end() { ended.raise(); } public boolean ended() { return ended.isUp(); } public void catchError(Runnable r) { main.catchError(ended, r); } public void directlyFeedInto(Consumer consumer) { if (consumer != null) onNewElement(a -> consumer.accept(a)); } } static public class RGBImage implements MakesBufferedImage, IRGBImage { transient public BufferedImage bufferedImage; public int width, height; public int[] pixels; public RGBImage() { } public RGBImage(BufferedImage image) { bufferedImage = image; width = image.getWidth(); height = image.getHeight(); pixels = new int[width * height]; var gp = grabbableIntPixels_fastOrSlow(image); if (gp.scanlineStride == width && gp.offset == 0) pixels = gp.data; else { pixels = new int[width * height]; int iIn = 0, iOut = 0; for (int y = 0; y < height; y++) { arrayCopy(gp.data, iIn, pixels, iOut, width); iIn += gp.scanlineStride; iOut += width; } } cleanPixels(); } public RGBImage(Dimension size, Color color) { this(size.width, size.height, color); } public RGBImage(Dimension size, RGB color) { this(size.width, size.height, color); } final public void cleanPixels() { var pixels = this.pixels; for (int i = 0; i < pixels.length; i++) pixels[i] &= 0xFFFFFF; } public RGBImage(int width, int height, int[] pixels) { this.width = width; this.height = height; this.pixels = pixels; } public RGBImage(int w, int h, RGB[] pixels) { this.width = w; this.height = h; this.pixels = asInts(pixels); } public static int[] asInts(RGB[] pixels) { int[] ints = new int[pixels.length]; for (int i = 0; i < pixels.length; i++) ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB(); return ints; } public RGBImage(int w, int h) { this(w, h, Color.black); } public RGBImage(int w, int h, RGB rgb) { this.width = w; this.height = h; this.pixels = new int[w * h]; int col = rgb.asInt(); if (col != 0) for (int i = 0; i < pixels.length; i++) pixels[i] = col; } public RGBImage(RGBImage image) { this(image.width, image.height, copyPixels(image.pixels)); } public RGBImage(int width, int height, Color color) { this(width, height, new RGB(color)); } public RGBImage(MakesBufferedImage img) { this(toBufferedImage(img)); } static public int[] copyPixels(int[] pixels) { int[] copy = new int[pixels.length]; System.arraycopy(pixels, 0, copy, 0, pixels.length); return copy; } public int getIntPixel(int x, int y) { if (inRange(x, y)) return pixels[y * width + x]; else return 0xFFFFFF; } public static RGB asRGB(int packed) { int r = (packed >> 16) & 0xFF; int g = (packed >> 8) & 0xFF; int b = packed & 0xFF; return new RGB(r / 255f, g / 255f, b / 255f); } public RGB getRGB(int x, int y) { if (inRange(x, y)) return asRGB(pixels[y * width + x]); else return new RGB(0xFFFFFF); } public RGB getPixel(int x, int y) { return getRGB(x, y); } public RGB getPixel(Pt p) { return getPixel(p.x, p.y); } public int getWidth() { return width; } public int getHeight() { return height; } public int w() { return width; } public int h() { return height; } public BufferedImage getBufferedImage() { if (bufferedImage == null) { bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) bufferedImage.setRGB(x, y, pixels[y * width + x]); } return bufferedImage; } public RGBImage clip(Rect r) { return r == null ? null : clip(r.getRectangle()); } public RGBImage clip(Rectangle r) { r = fixClipRect(r); if (r.x == 0 && r.y == 0 && r.width == width && r.height == height) return this; int[] newPixels; try { newPixels = new int[r.width * r.height]; } catch (RuntimeException e) { System.out.println(r); throw e; } for (int y = 0; y < r.height; y++) { System.arraycopy(pixels, (y + r.y) * width + r.x, newPixels, y * r.width, r.width); } return new RGBImage(r.width, r.height, newPixels); } final public Rectangle fixClipRect(Rectangle r) { r = r.intersection(new Rectangle(0, 0, width, height)); if (r.isEmpty()) r = new Rectangle(r.x, r.y, 0, 0); return r; } public int getInt(int x, int y) { return pixels[y * width + x]; } public void save(File file) { saveImage(file, getBufferedImage()); } public static RGBImage dummyImage() { return new RGBImage(1, 1, new int[] { 0xFFFFFF }); } public int[] getPixels() { return pixels; } public void setPixel(int x, int y, int r, int g, int b) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y * width + x] = (limitToUByte(r) << 16) | (limitToUByte(g) << 8) | limitToUByte(b); } public void setPixel(int x, int y, RGB rgb) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y * width + x] = rgb.asInt(); } final public void set(int x, int y, Color color) { setPixel(x, y, color); } public void setPixel(int x, int y, Color color) { setPixel(x, y, new RGB(color)); } public void setInt(int x, int y, int rgb) { setPixel(x, y, rgb); } public void setPixel(int x, int y, int rgb) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y * width + x] = rgb; } public void setPixel(Pt p, RGB rgb) { setPixel(p.x, p.y, rgb); } public void setPixel(Pt p, Color color) { setPixel(p.x, p.y, color); } public RGBImage copy() { return new RGBImage(this); } public boolean inRange(int x, int y) { return x >= 0 && y >= 0 && x < width && y < height; } public Dimension getSize() { return new Dimension(width, height); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RGBImage rgbImage = (RGBImage) o; if (height != rgbImage.height) return false; if (width != rgbImage.width) return false; if (!Arrays.equals(pixels, rgbImage.pixels)) return false; return true; } @Override public int hashCode() { int result = width; result = 31 * result + height; result = 31 * result + Arrays.hashCode(pixels); return result; } public String getHex(int x, int y) { return getPixel(x, y).getHexString(); } public RGBImage clip(int x, int y, int width, int height) { return clip(new Rectangle(x, y, width, height)); } public RGBImage clipLine(int y) { return clip(0, y, width, 1); } public int numPixels() { return width * height; } public RGBImage uncacheBufferedImage() { bufferedImage = null; return this; } } static public class MethodMaker { public ClassGen cg; public MethodGen mg; public InstructionList il = new InstructionList(); public ConstantPoolGen cp; public InstructionFactory factory; public int frameSize; final public MethodMaker setVerboseAdd(boolean verboseAdd) { return verboseAdd(verboseAdd); } public MethodMaker verboseAdd(boolean verboseAdd) { this.verboseAdd = verboseAdd; return this; } final public boolean getVerboseAdd() { return verboseAdd(); } public boolean verboseAdd() { return verboseAdd; } public boolean verboseAdd = false; public boolean classConstantWorkaround = false; public MethodMaker(ClassMaker classMaker, Class returnType, String methodName, Class... argumentTypes) { this(classMaker.cg, returnType, methodName, argumentTypes); } public MethodMaker(ClassGen cg, Class returnType, String methodName, Class... argumentTypes) { this(cg, Const.ACC_PUBLIC, returnType, methodName, argumentTypes); } public MethodMaker(ClassGen cg, short modifiers, Class returnType, String methodName, Class... argumentTypes) { this.cg = cg; cp = cg.getConstantPool(); factory = new InstructionFactory(cg); org.apache.bcel.generic.Type[] argTypes = wrapTypes(argumentTypes); mg = new MethodGen(modifiers, wrapType(returnType), argTypes, null, methodName, cg.getClassName(), il, cp); frameSize = l(argTypes) + 1; } static public org.apache.bcel.generic.Type[] wrapTypes(Class[] classes) { org.apache.bcel.generic.Type[] types = new org.apache.bcel.generic.Type[l(classes)]; for (int i = 0; i < l(classes); i++) types[i] = wrapType(classes[i]); return types; } static public org.apache.bcel.generic.Type wrapType(Class c) { return classToBCELType(c); } public int newLocalVar() { return frameSize++; } public MethodMaker newObject(Class c, Class... argTypes) { il.append(factory.createNew(className(c))); il.append(InstructionConst.DUP); Constructor ctor = findConstructor_precise_onTypes(c, argTypes); il.append(factory.createInvoke(className(c), "", org.apache.bcel.generic.Type.VOID, wrapTypes(ctor.getParameterTypes()), Const.INVOKESPECIAL)); return this; } public MethodMaker dup() { il.append(InstructionConst.DUP); return this; } public MethodMaker astore(int var) { il.append(new ASTORE(var)); return this; } public MethodMaker aload(int var) { il.append(new ALOAD(var)); return this; } public MethodMaker stringConstant(String s) { il.append(new PUSH(cp, s)); return this; } public MethodMaker classConstant(Class c) { if (classConstantWorkaround) { stringConstant(c.getName()); invokeStatic(Class.class, Class.class, "forName", String.class); } else { var ldc = new LDC(classRef(c)); assertEquals("classConstant", ldc.getValue(cp), wrapType(c)); il.append(ldc); } return this; } final public MethodMaker intConst(int i) { return intConstant(i); } public MethodMaker intConstant(int i) { if (i >= -1 && i <= 5) return add(new ICONST(i)); if (i == (byte) i) return add(new BIPUSH((byte) i)); if (i == (short) i) return add(new SIPUSH((short) i)); return add(new LDC(cp.addInteger(i))); } final public MethodMaker doubleConst(double d) { return doubleConstant(d); } public MethodMaker doubleConstant(double d) { return add(new LDC2_W(cp.addDouble(d))); } public MethodMaker boolConstant(boolean b) { return intConstant(b ? 1 : 0); } public MethodMaker invokeVirtual(Class c, Class returnType, String methodName, Class... argTypes) { Method m = findNonStaticMethod_precise_onTypes(c, methodName, argTypes); if (m == null) throw fail("Method not found: " + className(c) + "." + formatFunctionCall(methodName, argTypes) + " returning " + className(returnType)); il.append(factory.createInvoke(className(c), methodName, wrapType(m.getReturnType()), wrapTypes(m.getParameterTypes()), Const.INVOKEVIRTUAL)); return this; } public MethodMaker invokeInterface(Class c, Class returnType, String methodName, Class... argTypes) { Method m = mostApplicableMethod_onTypes(filter(nonDefaultInterfaceMethods(c), _m -> _m.getName().equals(methodName)), argTypes); if (m == null) throw fail("Method not found: " + className(c) + "." + formatFunctionCall(methodName, argTypes) + " returning " + className(returnType)); il.append(factory.createInvoke(className(c), methodName, wrapType(m.getReturnType()), wrapTypes(m.getParameterTypes()), Const.INVOKEINTERFACE)); return this; } public MethodMaker invokeStatic(Class c, Class returnType, String methodName, Class... argTypes) { Method m = findMethod_precise_onTypes(c, methodName, argTypes); if (m == null) throw fail("Method not found: " + className(c) + "." + formatFunctionCall(methodName, argTypes) + " returning " + className(returnType)); il.append(factory.createInvoke(className(c), methodName, wrapType(m.getReturnType()), wrapTypes(m.getParameterTypes()), Const.INVOKESTATIC)); return this; } public MethodMaker areturn() { il.append(InstructionConst.ARETURN); return this; } public MethodMaker _return() { il.append(InstructionConst.RETURN); return this; } public MethodMaker add(Instruction i) { il.append(i); if (verboseAdd) print("> " + i); return this; } public A addAndReturn(A i) { add(i); return i; } public MethodMaker add(BranchInstruction i) { il.append(i); if (verboseAdd) print("> " + i); return this; } public A addAndReturn(A i) { add(i); return i; } public void done() { mg.stripAttributes(true); mg.setMaxStack(); mg.setMaxLocals(); cg.addMethod(mg.getMethod()); } public JVMStackCellType convertToObject(JVMStackCellType stackTop) { if (stackTop == JVMStackCellType.objValue) { } else if (stackTop == JVMStackCellType.intValue) invokeStatic(Integer.class, Integer.class, "valueOf", int.class); else if (stackTop == JVMStackCellType.doubleValue) invokeStatic(Double.class, Double.class, "valueOf", double.class); else if (stackTop == JVMStackCellType.none) add(new ACONST_NULL()); else throw fail("TODO: add conversion for stack cell type: " + stackTop); return JVMStackCellType.objValue; } public void discardStackTop(JVMStackCellType stackTop) { if (stackTop == JVMStackCellType.none) { } else if (stackTop == JVMStackCellType.doubleValue || stackTop == JVMStackCellType.longValue) add(new POP2()); else add(new POP()); } public int classRef(Class c) { return cp.addClass((ObjectType) wrapType(assertNotNull(c))); } public MethodMaker checkCast(Class c) { return add(new CHECKCAST(classRef(c))); } public MethodMaker loadNull() { return add(new ACONST_NULL()); } public InstructionHandle here() { return il.append(new NOP()); } public GOTO forwardGoto() { return addAndReturn(new GOTO(null)); } public void returnWithType(JVMStackCellType stackTop) { if (stackTop == JVMStackCellType.objValue) areturn(); else if (stackTop == JVMStackCellType.intValue) add(new IRETURN()); else if (stackTop == JVMStackCellType.doubleValue) add(new DRETURN()); else if (stackTop == JVMStackCellType.none) _return(); else throw fail("TODO: add return for stack cell type: " + stackTop); } public void getStaticField(String className, String fieldName, Class type) { il.append(factory.createGetStatic(className, fieldName, wrapType(type))); } } static public class ScoredSearcher_stable { public int maxResults = 1000; public boolean returnAll = false; public List preparedTerms; public MultiMap byScore = descTreeMultiMap(); public ScoredSearcher_stable() { } public ScoredSearcher_stable(String query, Object... __) { maxResults = optPar("maxResults", __, maxResults); setQuery(query); } public void setQuery(String query) { preparedTerms = scoredSearch_prepare(query); } public void put(A object, String s) { putScored(object, score(s)); } public void putScored(A object, double score) { if (score != 0) byScore.add(score, object); } public void put(A object, Collection fields) { add(object, scoreFields(fields)); } public void putWithWeights(A object, Collection> fields) { scoredSearch_scoreWeighted2(fields, preparedTerms); } public int scoreFields(Collection fields) { return scoredSearch_score(fields, preparedTerms); } public int score(String text) { return returnAll ? 1 : scoredSearch_score(text, preparedTerms); } public void add(A object) { put(object, str(object)); } public void add(A object, Collection fields) { put(object, fields); } public void put(A object, double score) { add(object, score); } public void add(A object, double score) { putScored(object, score); } public List get() { return pairsB(takeFirst(maxResults, multiMapPairIterator(byScore))); } public List get_transformListWithinScore(IF1, List> f) { return pairsB(takeFirst(maxResults, multiMapPairIterator_transformValueList(byScore, f))); } public List> withScores() { return map(takeFirst(maxResults, multiMapPairIterator(byScore)), p -> new Scored(p.b, p.a)); } public A best() { return firstValue(byScore); } } static public class WrappedMap extends AbstractMap { public Map map; public WrappedMap() { } public WrappedMap(Map map) { this.map = map; } public B get(Object key) { return map.get(key); } public B put(A key, B value) { return map.put(key, value); } public boolean containsKey(Object key) { return map.containsKey(key); } public Set> entrySet() { return map.entrySet(); } } static public interface IRGBImage extends MakesBufferedImage { public int getIntPixel(int x, int y); } public enum JVMStackCellType { none, objValue, intValue, longValue, floatValue, doubleValue } static public class LASToByteCode implements IFieldsToList { public MethodMaker m; public LASToByteCode() { } public LASToByteCode(MethodMaker m) { this.m = m; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + m + ")"; } public Object[] _fieldsToList() { return new Object[] { m }; } public boolean callPing = true; final public LASToByteCode setIVarContext(int iVarContext) { return iVarContext(iVarContext); } public LASToByteCode iVarContext(int iVarContext) { this.iVarContext = iVarContext; return this; } final public int getIVarContext() { return iVarContext(); } public int iVarContext() { return iVarContext; } public int iVarContext = -1; public GazelleV_LeftArrowScript.Script returnableScript; final public LASToByteCode setPostConversion(IF1 postConversion) { return postConversion(postConversion); } public LASToByteCode postConversion(IF1 postConversion) { this.postConversion = postConversion; return this; } final public IF1 getPostConversion() { return postConversion(); } public IF1 postConversion() { return postConversion; } public IF1 postConversion; public JVMStackCellType compileScript(GazelleV_LeftArrowScript.Script script) { returnableScript = script; var stackTop = compile(script); if (postConversion != null) stackTop = postConversion.get(stackTop); return stackTop; } public void compileToObject(GazelleV_LeftArrowScript.Evaluable code) { m.convertToObject(compile(code)); } public JVMStackCellType compile(GazelleV_LeftArrowScript.Evaluable code) { if (code instanceof GazelleV_LeftArrowScript.Const) { Object o = ((GazelleV_LeftArrowScript.Const) code).value; if (o == null) { m.add(new ACONST_NULL()); return JVMStackCellType.objValue; } else if (o instanceof String) { m.stringConstant((String) o); return JVMStackCellType.objValue; } else if (o instanceof Integer) { m.intConstant((Integer) o); return JVMStackCellType.intValue; } else if (o instanceof Double) { m.doubleConstant((Double) o); return JVMStackCellType.doubleValue; } else if (o instanceof Class) { m.classConstant((Class) o); return JVMStackCellType.objValue; } else if (o instanceof Boolean) { m.boolConstant((Boolean) o); return JVMStackCellType.intValue; } else throw fail("Can't compile const value: " + toStringWithClass(o)); } else if (code instanceof GazelleV_LeftArrowScript.Script) { var stackTop = JVMStackCellType.none; for (var step : ((GazelleV_LeftArrowScript.Script) code).steps) { if (stackTop != JVMStackCellType.none) m.add(new POP()); stackTop = compile(step); } return stackTop; } else if (code instanceof GazelleV_LeftArrowScript.CallMethod) { compileToObject(((GazelleV_LeftArrowScript.CallMethod) code).target); m.stringConstant(((GazelleV_LeftArrowScript.CallMethod) code).methodName); argumentsAsArray(((GazelleV_LeftArrowScript.CallMethod) code).args); m.invokeStatic(main.class, Object.class, "call", Object.class, String.class, Object[].class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.CallMethodOrGetField) { compileToObject(((GazelleV_LeftArrowScript.CallMethodOrGetField) code).target); m.stringConstant(((GazelleV_LeftArrowScript.CallMethodOrGetField) code).name); m.invokeStatic(main.class, Object.class, "preciseGetOrCallMethod", Object.class, String.class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.SetField) { compileToObject(((GazelleV_LeftArrowScript.SetField) code).target); m.stringConstant(((GazelleV_LeftArrowScript.SetField) code).name); compileToObject(((GazelleV_LeftArrowScript.SetField) code).expr); m.invokeStatic(main.class, Object.class, "set", Object.class, String.class, Object.class); return JVMStackCellType.none; } else if (code instanceof GazelleV_LeftArrowScript.NewObject) { m.classConstant(((GazelleV_LeftArrowScript.NewObject) code).c); argumentsAsArray(((GazelleV_LeftArrowScript.NewObject) code).args); m.invokeStatic(main.class, Object.class, "nuObject", Class.class, Object[].class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.Assignment) { compileToObject(((GazelleV_LeftArrowScript.Assignment) code).expression); m.astore(iTemp()); loadVarContext(); m.stringConstant(((GazelleV_LeftArrowScript.Assignment) code).var); m.aload(iTemp()); m.invokeVirtual(VarContext.class, void.class, "set", String.class, Object.class); m.aload(iTemp()); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.While) { var loopStart = m.il.append(new NOP()); BranchInstruction branch1 = null; if (callPing) { m.invokeStatic(main.class, boolean.class, "ping"); branch1 = new IFEQ(null); m.add(branch1); } compileToBool(((GazelleV_LeftArrowScript.While) code).condition); var branch2 = new IFEQ(null); m.add(branch2); m.discardStackTop(compile(((GazelleV_LeftArrowScript.While) code).body)); m.add(new GOTO(loopStart)); var loopEnd = m.il.append(new NOP()); { if (branch1 != null) branch1.setTarget(loopEnd); } branch2.setTarget(loopEnd); return JVMStackCellType.none; } else if (code instanceof GazelleV_LeftArrowScript.IfThen) { compileToBool(((GazelleV_LeftArrowScript.IfThen) code).condition); var branch1 = new IFEQ(null); m.add(branch1); var stackTop = compile(((GazelleV_LeftArrowScript.IfThen) code).body); if (stackTop == JVMStackCellType.none) { branch1.setTarget(m.here()); return stackTop; } else { m.convertToObject(stackTop); var jumpToEnd = m.forwardGoto(); branch1.setTarget(m.here()); m.loadNull(); jumpToEnd.setTarget(m.here()); return JVMStackCellType.objValue; } } else if (code instanceof GazelleV_LeftArrowScript.GetVar) { return compileGetVar((GazelleV_LeftArrowScript.GetVar) code); } else if (code instanceof GazelleV_LeftArrowScript.ReturnFromScript) { if (((GazelleV_LeftArrowScript.ReturnFromScript) code).script != returnableScript) throw fail("Can only return from current script"); var stackTop = compile(((GazelleV_LeftArrowScript.ReturnFromScript) code).value); if (postConversion != null) stackTop = postConversion.get(stackTop); m.returnWithType(stackTop); return JVMStackCellType.none; } throw fail("Can't compile yet: " + className(code)); } public void argumentsAsArray(GazelleV_LeftArrowScript.Evaluable[] args) { int n = l(args); m.intConst(n); m.add(new ANEWARRAY(m.classRef(Object.class))); for (int iArg = 0; iArg < n; iArg++) { m.dup(); m.intConst(iArg); compileToObject(args[iArg]); m.add(new AASTORE()); } } public void loadVarContext() { assertTrue("Need VarContext", iVarContext >= 0); m.aload(iVarContext); } public Integer iTemp_cache; public int iTemp() { if (iTemp_cache == null) iTemp_cache = iTemp_load(); return iTemp_cache; } public Integer iTemp_load() { return m.newLocalVar(); } public void compileToBool(GazelleV_LeftArrowScript.Evaluable condition) { var stackTop = compile(condition); if (stackTop == JVMStackCellType.objValue) { m.checkCast(Boolean.class); m.invokeVirtual(Boolean.class, boolean.class, "booleanValue"); } else if (stackTop == JVMStackCellType.intValue) { } else throw fail("Can't convert to bool: " + stackTop); } public JVMStackCellType compileGetVar(GazelleV_LeftArrowScript.GetVar code) { loadVarContext(); m.stringConstant(code.var); m.invokeVirtual(VarContext.class, Object.class, "get", String.class); return JVMStackCellType.objValue; } } static public interface IMultiSet { public int add(A key); public int get(A key); } static abstract public class DialogIO implements AutoCloseable { public String line; public boolean eos, loud, noClose; public Lock lock = lock(); abstract public String readLineImpl(); abstract public boolean isStillConnected(); abstract public void sendLine(String line); abstract public boolean isLocalConnection(); abstract public Socket getSocket(); public int getPort() { Socket s = getSocket(); return s == null ? 0 : s.getPort(); } public boolean helloRead = false; public int shortenOutputTo = 500; public String readLineNoBlock() { String l = line; line = null; return l; } public boolean waitForLine() { try { ping(); if (line != null) return true; line = readLineImpl(); if (line == null) eos = true; return line != null; } catch (Exception __e) { throw rethrow(__e); } } public String readLine() { waitForLine(); helloRead = true; return readLineNoBlock(); } public String ask(String s, Object... args) { if (loud) return askLoudly(s, args); if (!helloRead) readLine(); if (args.length != 0) s = format3(s, args); sendLine(s); return readLine(); } public String askLoudly(String s, Object... args) { if (!helloRead) readLine(); if (args.length != 0) s = format3(s, args); print("> " + shorten(s, shortenOutputTo)); sendLine(s); String answer = readLine(); print("< " + shorten(answer, shortenOutputTo)); return answer; } public void pushback(String l) { if (line != null) throw fail(); line = l; helloRead = false; } } static abstract public class DialogHandler implements IDialogHandler { } public interface IDialogHandler { public void run(DialogIO io); } static public class MinimalChain implements Iterable { public A element; public MinimalChain next; public MinimalChain() { } public MinimalChain(A element) { this.element = element; } public MinimalChain(A element, MinimalChain next) { this.next = next; this.element = element; } public String toString() { return str(toList()); } public ArrayList toList() { ArrayList l = new ArrayList(); MinimalChain c = this; while (c != null) { l.add(c.element); c = c.next; } return l; } public void setElement(A a) { element = a; } public void setNext(MinimalChain next) { this.next = next; } public Iterator iterator() { return toList().iterator(); } public A get() { return element; } } static public class DoneFlag extends Flag { transient volatile public Object error; transient public boolean printErrors = false; public DoneFlag() { } public DoneFlag(boolean printErrors) { this.printErrors = printErrors; } public void done() { raise(); } final public void setError(Object error) { done(error); } public void done(Object error) { this.error = error; if (printErrors) printStackTrace_gen(error); raise(); } public boolean hasError() { return error != null; } public boolean isDone() { return isUp(); } } static public interface Transformable { public Object transformUsing(IF1 f); } static public class TreeMultiMap extends MultiMap { public TreeMultiMap() { super(true); } public TreeMultiMap(MultiMap map) { this(); putAll(map); } } static public class RGB { public float r, g, b; public RGB() { } public RGB(float r, float g, float b) { this.r = r; this.g = g; this.b = b; } public RGB(double r, double g, double b) { this.r = (float) r; this.g = (float) g; this.b = (float) b; } public RGB(double[] rgb) { this(rgb[0], rgb[1], rgb[2]); } public RGB(int rgb) { this(new Color(rgb)); } public RGB(double brightness) { this.r = this.g = this.b = max(0f, min(1f, (float) brightness)); } public RGB(Color color) { this.r = color.getRed() / 255f; this.g = color.getGreen() / 255f; this.b = color.getBlue() / 255f; } public RGB(String hex) { int i = l(hex) - 6; r = Integer.parseInt(hex.substring(i, i + 2), 16) / 255f; g = Integer.parseInt(hex.substring(i + 2, i + 4), 16) / 255f; b = Integer.parseInt(hex.substring(i + 4, i + 6), 16) / 255f; } public float getComponent(int i) { return i == 0 ? r : i == 1 ? g : b; } public int getInt(int i) { return i == 0 ? redInt() : i == 1 ? greenInt() : blueInt(); } public Color getColor() { return new Color(r, g, b); } public static RGB newSafe(float r, float g, float b) { return new RGB(Math.max(0, Math.min(1, r)), Math.max(0, Math.min(1, g)), Math.max(0, Math.min(1, b))); } public int asInt() { return getColor().getRGB() & 0xFFFFFF; } public int getInt() { return getColor().getRGB() & 0xFFFFFF; } public int asIntWithAlpha() { return rgbInt(redInt(), greenInt(), blueInt()) | 0xFF000000; } public float getBrightness() { return (r + g + b) / 3.0f; } public String getHexString() { return Integer.toHexString(asInt() | 0xFF000000).substring(2).toUpperCase(); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof RGB)) return false; RGB rgb = (RGB) o; if (Float.compare(rgb.b, b) != 0) return false; if (Float.compare(rgb.g, g) != 0) return false; if (Float.compare(rgb.r, r) != 0) return false; return true; } @Override public int hashCode() { int result = (r != +0.0f ? Float.floatToIntBits(r) : 0); result = 31 * result + (g != +0.0f ? Float.floatToIntBits(g) : 0); result = 31 * result + (b != +0.0f ? Float.floatToIntBits(b) : 0); return result; } public boolean isBlack() { return r == 0f && g == 0f && b == 0f; } public boolean isWhite() { return r == 1f && g == 1f && b == 1f; } public String toString() { return getHexString(); } public int redInt() { return iround(r * 255); } public int greenInt() { return iround(g * 255); } public int blueInt() { return iround(b * 255); } static public float brightnessToFloat(int brightness) { return brightness / 255f; } } static public class ClassMaker { final public String getClassName() { return className(); } public String className() { return className; } public String className; public ClassGen cg; public JavaClass baked; public InMemoryClassLoader classLoader; public Class loadedClass; final public ClassMaker setPrintDisassembly(boolean printDisassembly) { return printDisassembly(printDisassembly); } public ClassMaker printDisassembly(boolean printDisassembly) { this.printDisassembly = printDisassembly; return this; } final public boolean getPrintDisassembly() { return printDisassembly(); } public boolean printDisassembly() { return printDisassembly; } public boolean printDisassembly = false; public ClassMaker(String className) { this.className = className; setClassGen(new ClassGen(className, "java.lang.Object", null, Const.ACC_PUBLIC, null)); } public ClassMaker(Class interfaceToImplement) { className = randomClassName(); setClassGen(new ClassGen(className, "java.lang.Object", null, Const.ACC_PUBLIC, new String[] { main.className(interfaceToImplement) })); addDefaultConstructor(); } public void addDefaultConstructor() { cg.addEmptyConstructor(Const.ACC_PUBLIC); } public void setClassGen(ClassGen cg) { this.cg = cg; cg.setMajor(50); cg.setMinor(0); } public JavaClass bake() { if (baked == null) { baked = cg.getJavaClass(); if (printDisassembly) printClassWithMethods(); } return baked; } public void printClassWithMethods() { print_tabToSingleSpace(bake()); for (var method : baked.getMethods()) { print_tabToSingleSpace("\n" + method); print_tabToSingleSpace(method.getCode()); } } public byte[] getBytes_cache; final public byte[] getBytes() { if (getBytes_cache == null) getBytes_cache = getBytes_load(); return getBytes_cache; } final public byte[] getBytes_load() { return toBytes(); } public byte[] toBytes() { return bake().getBytes(); } public Class load() { if (loadedClass == null) { var bytes = toBytes(); classLoader = new InMemoryClassLoader(myClassLoader()); loadedClass = (Class) classLoader.defineAClass(className, bytes); } return loadedClass; } public A newInstance() { return main.newInstance(load()); } public void addField(FieldGen fg) { cg.addField(fg.getField()); } public ConstantPoolGen getConstantPool() { return cg.getConstantPool(); } } static public interface IHasGlobalID { public GlobalID globalID(); } public interface IntSize { public int size(); } static public class ListAndIndex implements IFieldsToList { static final public String _fieldOrder = "list idx"; public List list; public int idx; public ListAndIndex() { } public ListAndIndex(List list, int idx) { this.idx = idx; this.list = list; } public boolean equals(Object o) { if (!(o instanceof ListAndIndex)) return false; ListAndIndex __1 = (ListAndIndex) o; return eq(list, __1.list) && idx == __1.idx; } public int hashCode() { int h = 276903961; h = boostHashCombine(h, _hashCode(list)); h = boostHashCombine(h, _hashCode(idx)); return h; } public Object[] _fieldsToList() { return new Object[] { list, idx }; } public boolean atEnd() { return idx >= l(list); } public A get() { return _get(list, idx); } public int size() { return l(list); } public String toString() { return subList(list, 0, idx) + ", then " + subList(list, idx); } public ListAndIndex plus(int ofs) { return new ListAndIndex(list, idx + ofs); } public ListAndIndex minus(int ofs) { return new ListAndIndex(list, idx - ofs); } public List list() { return list; } final public int idx() { return index(); } public int index() { return idx; } public ListAndIndex mapIdx(IF1_IntToInt f) { return new ListAndIndex(list, f.get(idx)); } } static public class RestartableCountdown implements AutoCloseable { public java.util.Timer timer; public long targetTime; public long totalSleepTime; synchronized public void setTargetTime(long targetTime, Runnable action) { if (targetTime <= 0) stop(); else if (targetTime != this.targetTime) { start(targetTime - sysNow(), action); this.targetTime = targetTime; } } synchronized public void start(long delayMS, Object action) { stop(); if (delayMS <= 0) { startThread(new Runnable() { public void run() { try { callF(action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(action);"; } }); } else { totalSleepTime += delayMS; timer = doLater_daemon(delayMS, action); targetTime = sysNow() + delayMS; } } public void start(double delaySeconds, Object action) { start(toMS(delaySeconds), action); } synchronized public void stop() { cancelTimer(timer); timer = null; targetTime = 0; } public void close() { stop(); } } static public class TokenRange extends IntRange { public TokenRange() { } public TokenRange(int start, int end) { this.end = end; this.start = start; } } static public class InMemoryClassLoader extends ClassLoader { final public InMemoryClassLoader setRememberClassBytes(boolean rememberClassBytes) { return rememberClassBytes(rememberClassBytes); } public InMemoryClassLoader rememberClassBytes(boolean rememberClassBytes) { this.rememberClassBytes = rememberClassBytes; return this; } final public boolean getRememberClassBytes() { return rememberClassBytes(); } public boolean rememberClassBytes() { return rememberClassBytes; } transient public boolean rememberClassBytes = false; transient public Map classBytes = syncMap(); public InMemoryClassLoader(ClassLoader parent) { super(parent); } public Class defineAClass(String name, byte[] bytes) { Class c = defineClass(name, bytes, 0, bytes.length); if (rememberClassBytes) classBytes.put(c, bytes); return c; } public byte[] getClassBytes(Class c) { return classBytes.get(c); } } static public class IntRange { public int start, end; public IntRange() { } public IntRange(int start, int end) { this.end = end; this.start = start; } public IntRange(IntRange r) { start = r.start; end = r.end; } public boolean equals(Object o) { return stdEq2(this, o); } public int hashCode() { return stdHash2(this); } final public int length() { return end - start; } final public boolean empty() { return start >= end; } final public boolean isEmpty() { return start >= end; } static public String _fieldOrder = "start end"; public String toString() { return "[" + start + ";" + end + "]"; } } static public class Scored extends Var { public float score; public Scored() { } public Scored(A a, float score) { super(a); this.score = score; } public Scored(A a, double score) { super(a); this.score = (float) score; } public float score() { return score; } public String toString() { return toIntPercent(score) + "%: " + str(get()); } } static public interface IF1_IntToInt { public int get(int i); } static public class GlobalID implements Comparable { public long a; public int b; public GlobalID() { } public GlobalID(String id) { assertGlobalID(id); BigInteger value = bigint(0); for (int i = 0; i < l(id); i++) value = plus(mul(value, 26), charDiff(id.charAt(i), 'a')); a = value.longValue(); value = value.shiftRight(64); b = value.shortValue(); } public String toString() { BigInteger value = bigint(b); value = value.shiftLeft(32); value = plus(value, (a >> 32) & 0xFFFFFFFFL); value = value.shiftLeft(32); value = plus(value, a & 0xFFFFFFFFL); return bigintToGlobalID(value); } public boolean equals(Object o) { if (!(o instanceof GlobalID)) return false; return ((GlobalID) o).a == a && ((GlobalID) o).b == b; } public int hashCode() { return (int) a; } public int compareTo(GlobalID id) { int diff = b - id.b; return diff != 0 ? diff : Long.compareUnsigned(a, id.a); } } static public Object preciseGetOrCallMethod(Object object, String name) { if (object == null) return null; if (canCallWithVarargs(object, name)) return call(object, name); return _get(object, name); } 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 Lock dbLock() { return db_mainConcepts().lock; } static public Lock dbLock(Concepts cc) { return cc == null ? null : cc.lock; } static public Lock dbLock(Concept c) { return dbLock(c == null ? null : c._concepts); } static public boolean bareDBMode_on = false; static public void bareDBMode() { bareDBMode(null); } static public void bareDBMode(Integer autoSaveInterval) { bareDBMode_on = true; conceptsAndBot(autoSaveInterval); } static public ThreadLocal DynamicObject_loading = or((ThreadLocal) get(getClass("x30_pkg.x30_util"), "DynamicObject_loading"), new ThreadLocal()); static public ThreadLocal dynamicObjectIsLoading_threadLocal() { return DynamicObject_loading; } static public void onChangeAndNow(JComponent c, Object r) { onUpdateAndNow(c, r); } static public void onChangeAndNow(List l, Object r) { onUpdateAndNow(l, r); } static public void onChangeAndNow(JTextComponent c, IVF1 r) { onUpdateAndNow(c, r); } static public JComboBox onChangeAndNow(JComboBox cb, IVF1 f) { onChange(cb, f); { if (f != null) f.get(getSelectedItem_typed(cb)); } return cb; } static public A onChangeAndNow(A tabs, Runnable r) { if (r != null) { onChange(tabs, r); r.run(); } return tabs; } static public JSlider onChangeAndNow(JSlider s, Runnable f) { if (s != null && f != null) { onChange(s, f); f.run(); } return s; } static public void addMouseAndMotionListener(Component c, MouseAdapter ma) { if (c != null && ma != null) { swing(() -> { c.addMouseListener(ma); c.addMouseMotionListener(ma); }); } } static public Rectangle boundsOnScreen(Component c) { if (c == null) return null; if (c.getParent() instanceof JViewport && c.getParent().getParent() instanceof JScrollPane) c = c.getParent().getParent(); try { return new Rectangle(c.getLocationOnScreen(), c.getSize()); } catch (IllegalComponentStateException e) { return null; } } static public Pt pt(int x, int y) { return new Pt(x, y); } static public Pt pt(int x) { return new Pt(x, x); } static public double distance(double ax, double ay, double bx, double by) { return sqrt(sqr(bx - ax) + sqr(by - ay)); } static public int distance(int a, int b) { return abs(a - b); } static public boolean mouseEventIsInBorder(MouseEvent e) { return swing(() -> { var c = optCast(JComponent.class, e.getComponent()); if (c == null) return false; var border = c.getBorder(); if (border == null) return false; Insets insets = border.getBorderInsets(c); int x = e.getX(), y = e.getY(); int w = c.getWidth(), h = c.getHeight(); boolean result = x < insets.left || x >= w - insets.right || y < insets.top || y >= h - insets.bottom; return result; }); } static public Pt topLeftCorner(Rect r) { return rectTopLeftCorner(r); } static public Pt bottomRightCorner(Rect r) { return r == null ? null : pt(r.x2(), r.y2()); } static public Pt toPt(Point p) { return p == null ? null : new Pt(p.x, p.y); } static public Pt toPt(Dimension d) { return d == null ? null : new Pt(d.width, d.width); } static public Rect rectFromPoints(int x1, int y1, int x2, int y2) { return pointsRect(x1, y1, x2, y2); } static public Rect rectFromPoints(Pt a, Pt b) { return pointsRect(a.x, a.y, b.x, b.y); } static public void printVars(Object... params) { printVars_str(params); } static public void change() { callOpt(getOptMC("mainConcepts"), "allChanged"); } static public void scaffoldCalled(Object obj, Object function, Object... args) { printShortenedFunctionCall(200, (obj == null ? "" : shorten(20, str(obj)) + " :: ") + function, args); } static public JPanel vstack(Object... parts) { return vstack2(parts); } static public JPanel vstack(List parts) { return vstack(toObjectArray(parts)); } static public JLabel jClickableImage_instantToolTip(String imageID, String toolTip, Runnable action) { return onLeftClick(instaToolTip(toolTip, jImageLabel(imageID)), action); } static public String collapse(String s) { return collapseWord(s); } static public JPanel northAndCenterWithMargin(int margin, Component n, Component c) { return northAndCenter(withBottomMargin(margin, n), c); } static public JPanel northAndCenterWithMargin(Component n, Component c) { return northAndCenter(withBottomMargin(n), c); } static public JLabel liveValueLabel(LiveValue lv) { return jLiveValueLabel(lv); } static public JLabel liveValueLabel(IVarWithNotify var) { return jVarLabel(var); } static public JSplitPane jhsplit(Component l, Component r) { return jhsplit(l, r, 0.5); } static public JSplitPane jhsplit(Component l, Component r, double splitPoint, int delay) { return jhsplit(l, r, splitPoint); } static public JSplitPane jhsplit(Component l, Component r, double splitPoint) { return setSplitPaneOnFirstShowing(swingNu(JSplitPane.class, JSplitPane.HORIZONTAL_SPLIT, wrap(l), wrap(r)), splitPoint); } static public JSplitPane jhsplit(double splitPoint, Component l, Component r) { return jhsplit(l, r, splitPoint); } static public List syncMap(Object f, Map map) { return syncMap(map, f); } static public List syncMap(Map map, Object f) { return map(cloneLinkedHashMap(map), f); } static public Map syncMap() { return synchroHashMap(); } static public Map syncMap(Map map) { return synchronizedMap(map); } static public Rect growRectTopAndLeft(Rect r) { return growRectTopAndLeft(r, 1); } static public Rect growRectTopAndLeft(Rect r, int pixels) { return new Rect(r.x - pixels, r.y - pixels, r.w + pixels, r.h + pixels); } static public int syncL(Collection l) { if (l == null) return 0; synchronized (collectionMutex(l)) { return l.size(); } } static public int syncL(Map map) { if (map == null) return 0; synchronized (collectionMutex(map)) { return map.size(); } } static public List syncL() { return syncList(); } static public DoublePt doublePt(double x) { return doublePt(x, x); } static public DoublePt doublePt(double x, double y) { return new DoublePt(x, y); } static public void printFunctionCall(Object fname, Object... args) { print(formatFunctionCall(fname, args)); } 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 byte last(byte[] a) { return l(a) != 0 ? a[l(a) - 1] : 0; } 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 A last(ReverseChain l) { return l == null ? null : l.element; } static public A last(CompactLinkedHashSet set) { return set == null ? null : set.last(); } 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 List antiFilter(Iterable c, Object pred) { if (pred instanceof F1) return antiFilter(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 antiFilter(Object pred, Iterable c) { return antiFilter(c, pred); } static public List antiFilter(Object pred, Object[] c) { return antiFilter(pred, wrapArrayAsList(c)); } static public List antiFilter(Iterable c, F1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (!pred.get(o).booleanValue()) x.add(o); return x; } static public List antiFilter(F1 pred, Iterable c) { return antiFilter(c, pred); } static public List antiFilter(Iterable c, IF1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (!pred.get(o).booleanValue()) x.add(o); return x; } static public List antiFilter(IF1 pred, Iterable c) { return antiFilter(c, pred); } static public double doubleRatio(double x, double y) { return y == 0 ? 0 : x / y; } static public double doubleRatio(Seconds x, Seconds y) { return doubleRatio(x.get(), y.get()); } static public Set createOrAddToSyncLinkedHashSet(Set set, A a) { if (set == null) set = syncLinkedHashSet(); set.add(a); return set; } 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 A pcallF_typed(F0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public B pcallF_typed(F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public void pcallF_typed(VF1 f, A a) { try { { if (f != null) f.get(a); } } catch (Throwable __e) { printStackTrace(__e); } } static public void pcallF_typed(IVF1 f, A a) { try { { if (f != null) f.get(a); } } catch (Throwable __e) { printStackTrace(__e); } } static public void pcallF_typed(IVF2 f, A a, B b) { try { { if (f != null) f.get(a, b); } } catch (Throwable __e) { printStackTrace(__e); } } static public Object pcallF_typed(Runnable r) { try { { if (r != null) r.run(); } } catch (Throwable __e) { printStackTrace(__e); } return null; } static public A pcallF_typed(IF0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public B pcallF_typed(IF1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public ImageSurface pixelatedImageSurface() { var is = imageSurface(); imageSurface_pixelated(is); return is; } static public ImageSurface pixelatedImageSurface(MakesBufferedImage img) { return pixelatedImageSurface(toBufferedImage(img)); } static public ImageSurface pixelatedImageSurface(BufferedImage img) { var is = pixelatedImageSurface(); is.setImage(img); return is; } static public File dbDir() { return programDir(dbProgramID()); } static public BufferedImage toBufferedImage(Object o) { return toBufferedImageOpt(o); } 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 File getBytecodePathForClass(Object o) { return getBytecodePathForClass(_getClass(o)); } static public File getBytecodePathForClass(Class c) { try { return c == null ? null : new File(c.getProtectionDomain().getCodeSource().getLocation().toURI()); } catch (Exception __e) { throw rethrow(__e); } } 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 void createOrRemoveFile(File f, boolean create) { if (create) { if (!fileExists(f)) touchFile(f); } else if (fileExists(f)) removeFile(f); } static public List tlft(String s) { return toLinesFullTrim(s); } static public List tlft(File f) { return toLinesFullTrim(f); } static public File conceptsDir() { return conceptsDir(db_mainConcepts()); } static public File conceptsDir(Concepts cc) { return cc.conceptsDir(); } static public File conceptsDir(String subName) { return conceptsDir(db_mainConcepts(), subName); } static public File conceptsDir(Concepts cc, String subName) { return newFile(conceptsDir(cc), subName); } static public boolean sameFile(File a, File b) { try { return a == null ? b == null : b != null && eq(a.getCanonicalPath(), b.getCanonicalPath()); } catch (Exception __e) { throw rethrow(__e); } } static public String fileName(File f) { return f == null ? null : f.getName(); } static public List llNonNulls(A... a) { List l = new ArrayList(); for (A x : a) if (x != null) l.add(x); return l; } static public LinkedHashMap litorderedmap(Object... x) { LinkedHashMap map = new LinkedHashMap(); litmap_impl(map, x); return map; } static public String or2_rev(String b, String a) { return or2(a, b); } static public String joinNemptiesWithSpacedPlus(Object... strings) { return joinNempties(" + ", strings); } static public String joinNemptiesWithSpacedPlus(Iterable strings) { return joinNempties(" + ", strings); } static public int intMax(Collection c, String field) { int max = Integer.MIN_VALUE; for (Object o : c) max = Math.max(max, toInt(getOpt(o, field))); return max; } static public int intMax(Iterable l) { int max = Integer.MIN_VALUE; for (int i : unnullForIteration(l)) max = Math.max(max, i); return max; } static public int intMax(int... l) { int max = Integer.MIN_VALUE; if (l != null) for (int i : l) max = Math.max(max, i); return max; } 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 int linesOfCode_javaTok(String text) { List tok = javaTok(text); int lines = 0; boolean codeInCurrentLine = false; for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i)) { int lTok = l(t); for (int j = 0; j < lTok; j++) { char c = t.charAt(j); if (c == '\n') codeInCurrentLine = false; else if (!isSpaceEtc(c) && !codeInCurrentLine) { codeInCurrentLine = true; ++lines; } } } else { if (codeInCurrentLine && containsNewLine(t)) codeInCurrentLine = false; } } return lines; } static public File appendToFileName(File f, String suffix) { return fileAppendToName(f, suffix); } static public File appendToFileName(String suffix, File f) { return appendToFileName(f, suffix); } static public String nLabels(long n) { return n2(n, "label"); } static public String nLabels(Collection l) { return nLabels(l(l)); } static public String nLabels(Map map) { return nLabels(l(map)); } static public A uniqCI(Class c, Object... params) { return uniqueConcept(db_mainConcepts(), c, params); } static public A uniqCI(Concepts cc, Class c, Object... params) { AutoCloseable __1 = tempDBLock(cc); try { params = expandParams(c, params); A x = findConceptWhereCI(cc, c, params); if (x == null) { x = unlisted(c); csetAll(x, params); cc.register(x); } return x; } finally { _close(__1); } } static public String shortClassName_dropNumberPrefix(Object o) { return dropNumberPrefix(shortClassName(o)); } 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 File conceptsFile(String progID) { return getProgramFile(progID, conceptsFileName()); } static public File conceptsFile() { return conceptsFile(dbProgramID()); } static public File conceptsFile(Concepts concepts) { return concepts.conceptsFile(); } static public File conceptsFileIn(File dir) { return newFile(dir, conceptsFileName()); } static public List listDirsContainingFileNamed(File dir, String fileName) { return filter(listDirs(dir), d -> isFile(newFile(d, fileName))); } static public boolean cleanUp_interruptThreads = false; static public void cleanUp(Object c) { if (c == null) return; if (c instanceof AutoCloseable) { close_pcall((AutoCloseable) c); return; } if (c instanceof java.util.Timer) { ((java.util.Timer) c).cancel(); return; } if (c instanceof Collection) { cleanUp((Collection) c); return; } if (c instanceof Map) { for (Object o : keys((Map) c)) cleanUp(o); for (Object o : values((Map) c)) cleanUp(o); ((Map) c).clear(); return; } try { preCleanUp(c); setOpt_raw(c, "ping_pauseAll", false); innerCleanUp(c); List androids = (List) getOpt(c, "record_list"); for (Object android : unnull(androids)) pcallOpt(android, "dispose"); List classes = (List) (getOpt(c, "hotwire_classes")); if (classes != null) for (WeakReference cc : classes) { try { cleanUp(cc.get()); } catch (Throwable __e) { printStackTrace(__e); } } if (cleanUp_interruptThreads) { List threads = registeredThreads(c); if (nempty(threads)) { print("cleanUp: Interrupting " + n2(threads, "thread") + ": " + joinWithComma(allToString(threads))); interruptThreads(threads); } } } catch (Throwable __e) { printStackTrace(__e); } setOpt_raw(c, "cleaningUp_flag", false); if (c instanceof Class && ((Class) c).getName().equals("main")) retireClassLoader(((Class) c).getClassLoader()); } static public void cleanUp(Collection l) { if (l == null) return; for (Object c : l) cleanUp(c); l.clear(); } static public A conceptWhere(Class c, Object... params) { return findConceptWhere(c, params); } static public A conceptWhere(Concepts cc, Class c, Object... params) { return findConceptWhere(cc, c, params); } static public A optimizedUniq(Class c, Object... params) { return optimizedUniq(db_mainConcepts(), c, params); } static public A optimizedUniq(Concepts cc, Class c, Object... params) { { var __1 = conceptWhere(cc, c, params); if (__1 != null) return __1; } return uniq(cc, c, params); } static public A waitUntilNotNull(Var v) { return waitForVarToBeNotNull(v); } static public A waitUntilNotNull(IVarWithNotify v) { Var myVar = new Var(); AutoCloseable __1 = tempOnChangeAndNow(v, () -> myVar.set(v.get())); try { return waitUntilNotNull(myVar); } finally { _close(__1); } } static public A waitUntilNotNull(VarWithNotify v) { return waitUntilNotNull((Var) v); } static public void deleteConcept(long id) { db_mainConcepts().deleteConcept(id); } static public void deleteConcept(Concepts concepts, long id) { concepts.deleteConcept(id); } static public void deleteConcept(Concept c) { if (c != null) c.delete(); } static public void deleteConcept(Concept.Ref ref) { if (ref != null) deleteConcept(ref.get()); } static public void close(AutoCloseable c) { _close(c); } static public Double toDoubleOrNull(Object o) { if (o == null) return null; if (o instanceof Number) return ((Number) o).doubleValue(); if (o instanceof BigInteger) return ((BigInteger) o).doubleValue(); if (o instanceof String) return parseDouble((String) o); return null; } static public Concept getConcept(long id) { return db_mainConcepts().getConcept(id); } static public Concept getConcept(Concepts concepts, long id) { return concepts.getConcept(id); } static public A getConcept(Class cc, long id) { return getConcept(db_mainConcepts(), cc, id); } static public A getConcept(Concepts concepts, Class cc, long id) { Concept c = concepts.getConcept(id); if (c == null) return null; if (!isInstance(cc, c)) throw fail("Can't convert concept: " + getClassName(c) + " -> " + getClassName(cc) + " (" + id + ")"); return (A) c; } static public double infinity() { return positiveInfinity(); } static public A evalWithTimeoutOrTypedException(int timeoutMS, IF0 f) { return evalWithTimeoutOrTypedException(toSeconds(timeoutMS), f); } static public A evalWithTimeoutOrTypedException(double timeoutSeconds, IF0 f) { Either e = evalWithTimeout(timeoutSeconds, f); if (e.isA()) return (A) e.a(); throw new TimeoutException_Inner(timeoutSeconds, f, e.b()); } static public void cancelThread(Thread t) { if (t == null) return; ping(); synchronized (ping_actions) { ping_actions.put(t, "cancelled"); ping_anyActions = true; } } static public Object dm_os() { { var __1 = vm_generalMap_get("stefansOS"); if (__1 != null) return __1; } return creator(); } static public boolean isSameFile(File a, File b) { return sameFile(a, b); } static public void openInBrowser(String url) { openPlatformBrowser(url); } static public void openInBrowser(URL url) { openPlatformBrowser(url); } static public boolean isOnPATH(String cmd) { return findCmdOnPATH(cmd) != null; } static public String chromeCmd() { return chromeCmd(false); } static public String chromeCmd(boolean needSpeech) { return platformQuote(isWindows() ? f2s(assertNotNull("chrome.exe not found", windowsFindChromeExe())) : isMac() ? "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" : needSpeech ? firstCmdOnPATH_mandatory("google-chrome") : firstCmdOnPATH_mandatory("google-chrome", "chromium-browser")); } static public boolean isRoot() { return isRootUser(); } static public String platformQuote(String s) { return isWindows() ? winQuote(s) : bashQuote(s); } static public String platformQuote(File f) { return platformQuote(f2s(f)); } static public boolean nohup_debug = false; static public boolean nohup_noSlashB = false; static public boolean nohup_keepScriptFile = false; static public ThreadLocal nohup_exitValue = new ThreadLocal(); public static File nohup(File cmd) { return nohup(f2s(cmd)); } public static File nohup(String cmd) { try { File outFile = File.createTempFile("nohup_" + nohup_sanitize(cmd) + "_", ".out"); nohup(cmd, outFile, false); return outFile; } catch (Exception __e) { throw rethrow(__e); } } public static void nohup(String cmd, File outFile, boolean append) { try { String command = nohup_makeNohupCommand(cmd, outFile, append); File scriptFile = File.createTempFile("_realnohup", isWindows() ? ".bat" : ""); print("[nohup] " + command); try { if (nohup_debug) print("[nohup] Script file: " + scriptFile.getPath()); saveTextFile(scriptFile.getPath(), command); String[] command2; if (isWindows()) if (nohup_noSlashB) command2 = new String[] { "cmd", "/c", "start", scriptFile.getPath() }; else command2 = new String[] { "cmd", "/c", "start", "/b", scriptFile.getPath() }; else command2 = new String[] { "/bin/bash", scriptFile.getPath() }; print("[nohup] " + joinWithSpace(quoteAll(command2))); Process process = Runtime.getRuntime().exec(command2); try { process.waitFor(); } catch (InterruptedException e) { throw new RuntimeException(e); } int value = process.exitValue(); nohup_exitValue.set(value); if (value != 0) warn("nohup exit value != 0: " + value); } finally { if (!nohup_keepScriptFile && !isWindows()) scriptFile.delete(); } } catch (Exception __e) { throw rethrow(__e); } } static public String nohup_makeNohupCommand(String cmd, File outFile, boolean append) { mkdirsForFile(outFile); String command; if (isWindows()) command = cmd + (append ? " >>" : " >") + winQuote(outFile.getPath()) + " 2>&1"; else command = "nohup " + cmd + (append ? " >>" : " >") + bashQuote(outFile.getPath()) + " 2>&1 &"; return command; } static public String compilationDateFromClassPath(Object referenceObject) { return loadTextFileResource(classLoader(referenceObject), "compilation-date.txt"); } static public BetterThreadLocal pingSource_tl_var = new BetterThreadLocal() { @Override public PingSource initialValue() { return ping_v3_pingSourceMaker().get(); } }; static public BetterThreadLocal pingSource_tl() { return pingSource_tl_var; } static public void addSeparator(JMenu menu) { menu.addSeparator(); } static public void addSeparator(JPopupMenu menu) { menu.addSeparator(); } static public void truncateContainer(Container c, int n) { swing(() -> { if (c != null) while (c.getComponentCount() > n) c.remove(c.getComponentCount() - 1); }); } static public A packWindow(final A c) { { swing(() -> { Window w = getWindow(c); if (w != null) w.pack(); }); } return c; } static public VF1 toVF1(IVF1 f) { return ivf1ToVF1(f); } static public PtInComponent ptInComponentFromEvent(MouseEvent evt) { return new PtInComponent(evt.getComponent(), pt(evt.getX(), evt.getY())); } static public boolean hasParentOfType(Class type, Component c) { return parentOfType(c, type) != null; } static public Class run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } static public String hijackPrint_tee(Runnable r) { final StringBuilder buf = new StringBuilder(); Object old = interceptPrintInThisThread(new F1() { public Boolean get(String s) { buf.append(s); return true; } }); try { callF(r); return str(buf); } finally { interceptPrintInThisThread(old); } } static public Timestamp tsNow() { return new Timestamp(); } static public OKOrError okOrError(IF0 f) { return okOrError(f, true); } static public OKOrError okOrError(IF0 f, boolean printStackTrace) { try { return OKOrError_ok(f.get()); } catch (Throwable e) { if (printStackTrace) printStackTrace(e); return OKOrError_error(e); } } static public OKOrError okOrError(Runnable r) { return okOrError(runnableToIF0(r)); } static public String formatElapsedTimeWithAppropriateUnit(double seconds) { if (seconds >= 1) return formatDouble(seconds, 3) + " s"; double ms = seconds * 1000; if (ms >= 1) return formatDouble(ms, 3) + " ms"; double us = ms * 1000; if (us >= 1) return formatDouble(us, 3) + " µs"; double ns = us * 1000; return formatDouble(ns, 3) + " ns"; } static public double nanosToSeconds(double nanos) { return nanoSecondsToSeconds(nanos); } static public void setComponent(SingleComponentPanel scp, Component c) { setSCPComponent(scp, c); } static public void setComponent(SingleComponentPanel scp, IF0 c) { if (scp != null) setComponent(scp, callF(c)); } static public boolean removeAll(Collection a, Collection b) { return a != null && b != null && a.removeAll(b); } static public void removeAll(Map a, Collection b) { if (a != null && b != null) for (A x : b) a.remove(x); } static public boolean removeAll(Collection c, B... b) { return c != null && b != null && c.removeAll(Arrays.asList(b)); } static public void removeAll(Map a, A... b) { if (a != null && b != null) for (A x : b) a.remove(x); } 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 A _revalidate(A c) { return revalidate(c); } static public void _revalidate(JFrame f) { revalidate(f); } static public void _revalidate(JInternalFrame f) { revalidate(f); } static public Container _getParent(Component c) { return getParent(c); } static public String commaCombine(Object... l) { return joinNemptiesWithComma(flattenCollectionsAndArrays(ll(l))); } static public WidthAndHeight widthAndHeight(BufferedImage image) { return image == null ? null : widthAndHeight(image.getWidth(), image.getHeight()); } static public WidthAndHeightImpl widthAndHeight(int w, int h) { return new WidthAndHeightImpl(w, h); } static public double sqrt(double x) { return Math.sqrt(x); } static public Pt ptMinus(Pt a, Pt b) { if (b == null) return a; return new Pt(a.x - b.x, a.y - b.y); } static public UnsupportedOperationException unsupportedOperation() { throw new UnsupportedOperationException(); } static public SimpleLiveValue stringLiveValue() { return new SimpleLiveValue(String.class); } static public SimpleLiveValue stringLiveValue(String value) { return new SimpleLiveValue(String.class, value); } static public G22Utils g22utils(Concepts cc) { return (G22Utils) cc.miscMapGet(G22Utils.class); } static public A enableScaffolding(A o) { if (o instanceof IMeta) ((IMeta) o).metaPut("scaffolding", true); return o; } static public int getCaretPosition(final JTextComponent c) { return c == null ? 0 : swing(new F0() { public Integer get() { try { return c.getCaretPosition(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getCaretPosition();"; } }); } static public A onLeftClick(final A c, final Object runnable) { { swing(() -> { c.addMouseListener(leftClickMouseAdapter(runnable)); }); } return c; } static public TrayIcon onLeftClick(final TrayIcon c, final Object runnable) { { swing(() -> { c.addMouseListener(leftClickMouseAdapter_noPt(runnable)); }); } return c; } static public A onLeftClick(final Object runnable, A c) { return onLeftClick(c, runnable); } static public A onLeftClick(Runnable runnable, A c) { return onLeftClick((Object) runnable, c); } static public A onLeftClick(A c, Runnable r) { return onLeftClick(r, c); } static public A onLeftClick(A c, IVF1 r) { return onLeftClick(c, (Object) r); } static public void moveCaretToLineAndCol(JTextArea ta, LineAndColumn lac) { swing(() -> { try { setCaretPosition(ta, ta.getLineStartOffset(lac.line - 1) + lac.col - 1); } catch (Throwable __e) { printStackTrace(__e); } }); } static public A focus(final A a) { if (a != null) swingLater(new Runnable() { public void run() { try { a.requestFocus(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.requestFocus();"; } }); return a; } static public void addMenuItems(JMenu m, Object... x) { fillJMenu(m, x); } static public void addMenuItems(JPopupMenu m, Object... x) { fillJPopupMenu(m, x); } static public JScrollPane jBorderlessHigherScrollPane(JComponent c) { return borderlessScrollPane(jHigherScrollPane(c)); } static public A bindTextComponentToVarWithNotify_noInitialUndo(A tc, IVarWithNotify lv) { onFirstShow(tc, () -> clearTextComponentUndoList(tc)); return bindTextComponentToVarWithNotify(tc, lv); } static public void addKeyListener(final Component c, final KeyListener l) { if (c != null) { swing(() -> { c.addKeyListener(l); }); } } static public KeyListener functionKeyListener(int functionKeyNr, Runnable action) { return new KeyAdapter() { public void keyReleased(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_F1 + functionKeyNr - 1 && ke.getModifiers() == 0) { pcallF(action); } } }; } static public KeyListener ctrlLetterKeyListener(char letter, Runnable action) { return new KeyAdapter() { public void keyReleased(KeyEvent ke) { if (ke.getKeyCode() == charToKeyCode(letter) && ke.getModifiers() == KeyEvent.CTRL_MASK) { pcallF(action); } } }; } static public SingleThread awtCalcEvery(JFrame f, int delay, int firstDelay, final Object runnable) { return awtCalcRegularly(f, delay, firstDelay, runnable); } static public SingleThread awtCalcEvery(JComponent c, int delay, int firstDelay, final Object runnable) { return awtCalcRegularly(c, delay, firstDelay, runnable); } static public SingleThread awtCalcEvery(JFrame f, int delay, final Object runnable) { return awtCalcRegularly(f, delay, delay, runnable); } static public SingleThread awtCalcEvery(int delay, JComponent c, Runnable runnable) { return awtCalcRegularly(c, delay, delay, runnable); } static public SingleThread awtCalcEvery(JComponent c, int delay, Runnable runnable) { return awtCalcRegularly(c, delay, delay, runnable); } static public SingleThread awtCalcEvery(JComponent c, int delay, final Object runnable) { return awtCalcRegularly(c, delay, delay, runnable); } static public SingleThread awtCalcEvery(JComponent c, double delay, Runnable runnable) { return awtCalcEvery(c, delay, (Object) runnable); } static public SingleThread awtCalcEvery(JComponent c, double delay, Object runnable) { return awtCalcEvery(c, toMS_int(delay), runnable); } static public SingleThread awtCalcEvery(JComponent c, double firstDelay, double delay, final Object runnable) { return awtCalcEvery(c, toMS_int(delay), toMS_int(firstDelay), runnable); } static public AutoCompletion installCompletionProvider(DefaultCompletionProvider completionProvider, RSyntaxTextArea textArea) { return swing(() -> { if (completionProvider == null || textArea == null) return null; var autoComplete = new AutoCompletion(completionProvider); autoComplete.setAutoCompleteSingleChoices(false); autoComplete.install(textArea); return autoComplete; }); } static public JPanel jCenteredSection(Component c) { return jCenteredSection("", c); } static public JPanel jCenteredSection(String title, Swingable c) { return jCenteredSection(title, wrap(c)); } static public JPanel jCenteredSection(String title, Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = jSection(title, c); ((TitledBorder) p.getBorder()).setTitleJustification(TitledBorder.CENTER); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = jSection(title, c);\r\n ((TitledBorder) p.getBorder()).setTitleJu..."; } }); } static public JPanel jCenteredSection(String title) { return jCenteredSection(title, jpanel()); } static public JPanel withTopAndLeftMargin(Component c) { return withTopAndLeftMargin(defaultMargin(), c); } static public JPanel withTopAndLeftMargin(int w, Component c) { return swing(() -> { JPanel p = marginPanel(); p.setBorder(BorderFactory.createEmptyBorder(w, w, 0, 0)); p.add(c); return p; }); } static public boolean isShowing(Component c) { return isComponentShowing(c); } static public void runInQAndWait(Q q, Runnable r) { if (r == null) return; if (isInQ(q)) { callF(r); return; } final Flag done = new Flag(); final Var error = new Var(); q.add(new Runnable() { public void run() { try { try { callF(r); } catch (Throwable e) { error.set(e); } finally { done.raise(); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n callF(r);\r\n } catch (Throwable e) {\r\n error.set(e);\r\n ..."; } }); done.waitUntilUp(); if (error.has()) throw rethrow(error.get()); } static public String appendBracketed(Object o) { String b = strOrNull(o); return empty(b) ? "" : "" + " (" + b + ")"; } static public String appendBracketed(String a, String b) { return a + appendBracketed(b); } static public String exceptionToStringShorter_dontDropOuterExceptions(Throwable e) { String msg = hideCredentials(unnull(e.getMessage())); String className = baseClassName(e); if (!eq(className, "RuntimeException") && (msg.indexOf("Error") < 0 && msg.indexOf("Exception") < 0)) return className + prependIfNempty(": ", msg); else return msg; } static public String exceptionToStringShorter(Throwable e) { e = getInnerException(e); return exceptionToStringShorter_dontDropOuterExceptions(e); } static public JTextArea showText(final String title, Object text) { return showText(null, title, text); } static public JTextArea showText(JTextArea ta, final String title, Object text) { final String _text = str(text); if (ta != null) return activateFrameAndReturnComponent(setFrameTitle(title, setText(ta, _text))); return swing(new F0() { public JTextArea get() { try { JTextArea textArea = newTypeWriterTextArea(_text); makeFrame(title, new JScrollPane(textArea)); return textArea; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JTextArea textArea = newTypeWriterTextArea(_text);\r\n makeFrame(title, new ..."; } }); } static public JTextArea showText(Object text) { return showText(str(text)); } static public JTextArea showText(String text) { return showText(autoFrameTitle(), text); } static public JTextArea showText() { return showText(""); } static public String pnlToString(String prefix, Iterable l) { return hijackPrint(new Runnable() { public void run() { try { pnl(prefix, l); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pnl(prefix, l)"; } }); } static public String pnlToString(final Iterable l) { return hijackPrint(new Runnable() { public void run() { try { pnl(l); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pnl(l)"; } }); } static public String pnlToString(final A[] l) { return hijackPrint(new Runnable() { public void run() { try { pnl(l); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pnl(l)"; } }); } static public String pnlToString(final Map map) { return hijackPrint(new Runnable() { public void run() { try { pnl(map); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pnl(map)"; } }); } static public String pnlToString(MultiMap map) { return pnlToString(multiMapToMap(map)); } static public TreeMap toCIMap(Map map) { return asCIMap(map); } static public A setEditable(A a, boolean b) { if (a != null) { swing(() -> { a.setEditable(b); }); } return a; } static public Pair textAndCaretPosition(final JTextComponent tc) { return swing(new F0>() { public Pair get() { try { return pair(getText(tc), getCaretPosition(tc)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return pair(getText(tc), getCaretPosition(tc));"; } }); } static public List lasTok(String s) { return javaTok(s); } static public List lasTok(List tok) { return javaTok(tok); } static public int charToTokenIndex_left(List tok, int charIndex) { int i = 0, idx = 0; while (i < l(tok) && idx + l(tok.get(i)) <= charIndex) { idx += l(tok.get(i)); i++; } return i; } static public String lastIdentifier(List l) { for (int i = l(l) - 1; i >= 0; i--) { String t = l.get(i); if (isIdentifier(t)) return t; } return null; } static public String lookupStandardFunctionOrClassNameIC(String name) { if (isStandardFunction(name) || isStandardClass(name)) return name; { var __1 = resolveKeyIC(stdFunctions_cached(), name); if (__1 != null) return __1; } return resolveKeyIC(stdClasses_cached(), name); } static public String sfOrSCSnippet(String name) { { var __1 = sfSnippet(name); if (__1 != null) return __1; } return scSnippet(name); } static public String snippetURL(String id) { return snippetLink(id); } static public boolean flatInfoBox_alwaysOnTop = true; static public double flatInfoBox_defaultTime = 2.0; static public int flatInfoBox_x = 28, flatInfoBox_y = 5; static public JWindow flatInfoBox(String text) { return flatInfoBox(text, flatInfoBox_defaultTime); } static public JWindow flatInfoBox(final String text, final double seconds) { if (empty(text)) return null; print(text); return flatInfoBox_noprint(text, seconds); } static public JWindow flatInfoBox_noprint(String text) { return flatInfoBox_noprint(text, flatInfoBox_defaultTime); } static public JWindow flatInfoBox_noprint(final String text, final double seconds) { if (empty(text)) return null; logQuotedWithDate(infoBoxesLogFile(), text); if (isHeadless()) return null; return (JWindow) swingAndWait(new F0() { public Object get() { try { final JWindow window = makeUnimportantWindow(flatInfoBox_makePanel(text)); window.pack(); window.setBounds(flatInfoBox_x, flatInfoBox_y, 300, window.getHeight()); if (flatInfoBox_alwaysOnTop) window.setAlwaysOnTop(true); window.setVisible(true); disposeWindowAfter(iround(seconds * 1000), window); return window; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JWindow window = makeUnimportantWindow(flatInfoBox_makePanel(text));\r\n ..."; } }); } static public JWindow flatInfoBox(Throwable e) { showConsole(); printStackTrace(e); return flatInfoBox(exceptionToStringShort(e)); } static public RuntimeException rethrowAndAppendToMessage(Throwable t, String msg) { String haveMsg = t.getMessage(); if (empty(msg) || endsWith(haveMsg, " " + msg)) throw rethrow(t); throw new RuntimeException(joinWithSpace(t.getMessage(), msg), t); } static public String squareBracketed(String s) { return "[" + s + "]"; } static public String joinNemptiesWithComma(Object... strings) { return joinNempties(", ", strings); } static public String joinNemptiesWithComma(Iterable strings) { return joinNempties(", ", strings); } static public long incAtomicLong(AtomicLong l) { return l.incrementAndGet(); } static public PingSource pingSource() { return pingSource_tl().get(); } static public PingSource pingSource(Thread thread) { return pingSource_tl().get(thread); } static public String pnlToLines(String prefix, Iterable l) { return pnlToString(prefix, l); } static public String pnlToLines(Iterable l) { return pnlToString(l); } static public String pnlToLines(A[] l) { return pnlToString(l); } static public String pnlToLines(Map map) { return pnlToString(map); } static public String pnlToLines(MultiMap map) { return pnlToString(map); } static public boolean preciseNuObject_debug = false; static public A preciseNuObject(Class c, Object... args) { try { Constructor[] methods = getDeclaredConstructors_cached(c); if (methods.length == 0) throw fail(c + " doesn't define any constructors"); return preciseNuObject(methods, args); } catch (Exception __e) { throw rethrow(__e); } } static public A preciseNuObject(Constructor[] methods, Object... args) { try { Constructor best = null; int bestScore = Integer.MAX_VALUE; boolean widening = false; if (preciseNuObject_debug) printVars("preciseNuObject", "c", first(methods).getDeclaringClass(), "methods", l(methods)); for (var m : methods) { int score = methodApplicabilityScore_withPrimitiveWidening(m, args); if (score == 0) return (A) m.newInstance(args); if (preciseNuObject_debug) print("Method score: " + m + " " + score); if (abs(score) < bestScore) { best = m; bestScore = abs(score); widening = score < 0; } } if (best != null) if (widening) return (A) invokeConstructorWithWidening(best, args); else return (A) best.newInstance(args); methodSearch: for (var m : methods) { { if (!(m.isVarArgs())) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return (A) m.newInstance(newArgs); } var c = first(methods).getDeclaringClass(); throw fail("No matching constructor found: " + formatFunctionCall(c, map(__72 -> _getClass(__72), args))); } catch (Exception __e) { throw rethrow(__e); } } static public Object[] mapToArrayOrNull(A[] l, IF1 f) { if (l == null) return null; int n = l.length; if (n == 0) return null; Object[] array = new Object[n]; for (int i = 0; i < n; i++) array[i] = f.get(l[i]); return array; } static public Object[] mapToArrayOrNull(IF1 f, A[] l) { return mapToArrayOrNull(l, f); } static public Object[] mapToArrayOrNull(IF1 f, Collection l) { int n = l(l); if (n == 0) return null; 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[] mapToArrayOrNull(Collection l, IF1 f) { return mapToArrayOrNull(l, f); } static public String formatFunctionCall(String fname, Object... args) { return formatFunctionCall((Object) fname, args); } static public String formatFunctionCall(Object fname, Object... args) { return fname + "(" + joinWithComma(allToString(args)) + ")"; } static public String formatFunctionCall(String fname, Iterable args) { return formatFunctionCall((Object) fname, args); } static public String formatFunctionCall(Object fname, Iterable args) { return formatFunctionCall(fname, toObjectArray(args)); } static public String resolve(String host) { return hostToIP(host); } static public String strOrClassName(Object o) { if (o instanceof Class) return className((Class) o); return str(o); } static public String toStringWithClass(Object o) { return o == null ? null : className(o) + " - " + o; } static public boolean newPreciseCall_debug = false; static public Object newPreciseCall(Object o, String method, Object... args) { try { if (o == null) return null; boolean staticCall = o instanceof Class; Class c = staticCall ? (Class) o : o.getClass(); Object target = staticCall ? null : o; _MethodCache cache = callOpt_getCache(c); List methods = cache.cache.get(method); Method best = null; int bestScore = Integer.MAX_VALUE; boolean widening = false; if (newPreciseCall_debug) printVars("newPreciseCall", "method", method, "staticCall", staticCall, "c", c, "methods", l(methods)); if (methods != null) for (Method m : methods) { if (staticCall && !isStaticMethod(m)) continue; int score = methodApplicabilityScore_withPrimitiveWidening(m, args); if (score == 0) return invokeMethod(m, target, args); if (newPreciseCall_debug) print("Method score: " + m + " " + score); if (abs(score) < bestScore) { best = m; bestScore = abs(score); widening = score < 0; } } if (best != null) if (widening) return invokeMethodWithWidening(best, target, args); else return invokeMethod(best, target, args); return callWithVarargs(o, method, args); } catch (Exception __e) { throw rethrow(__e); } } static public List findMethodsNamed_cached(Object obj, String method) { return findMethodsNamed_cached(_getClass(obj), method); } static public List findMethodsNamed_cached(Class c, String method) { if (c == null) return null; return getMethodCache(c).cache.get(method); } static public boolean any(Object pred, Iterable l) { if (l != null) for (A a : l) if (isTrue(callF(pred, a))) return true; return false; } static public boolean any(IF1 pred, Iterable l) { if (l != null) for (A a : l) if (pred.get(a)) return true; return false; } static public boolean any(Iterable l, IF1 pred) { return any(pred, l); } static public boolean any(A[] l, IF1 pred) { if (l != null) for (A a : l) if (pred.get(a)) return true; return false; } static public boolean any(Iterable l) { if (l != null) for (Boolean a : l) if (isTrue(a)) return true; return false; } static public Pair findMethod_withPrimitiveWidening_onTypes(Object o, String method, Class... argTypes) { try { Lowest best = new Lowest(); boolean widening = false; 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))) continue; } int score = methodApplicabilityScore_withPrimitiveWidening_onTypes(m, argTypes); if (abs(score) < Integer.MAX_VALUE) { best.put(m, abs(score)); widening = score < 0; } } return pair(best.get(), widening); } if (o == null) return null; _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) { int score = methodApplicabilityScore_withPrimitiveWidening_onTypes(m, argTypes); if (abs(score) < Integer.MAX_VALUE) { best.put(m, abs(score)); widening = score < 0; } } return pair(best.get(), widening); } catch (Exception __e) { throw rethrow(__e); } } static public Method findSingleInterfaceMethodOrFail(Class intrface) { Method m = findSingleInterfaceMethod(intrface); if (m == null) throw fail(intrface + " is not a single method interface"); return m; } static public A proxyFromInvocationHandler(Class intrface, InvocationHandler handler) { return (A) java.lang.reflect.Proxy.newProxyInstance(intrface.getClassLoader(), new Class[] { intrface }, handler); } static public Object handleObjectMethodsInProxyInvocationHandler(Object invocationHandler, Method implementedMethod, Method method, Object proxy, Object[] actualArgs) { String name = method.getName(); if (name.equals("hashCode")) return invocationHandler.hashCode(); if (name.equals("equals")) return proxy == actualArgs[0]; if (name.equals("toString")) return invocationHandler.toString(); throw fail("No handler for method " + method + " (only have " + implementedMethod + ")"); } static public Object[] concatMethodArgs(Object[] args1, Object[] args2) { int n1, n2; if (args1 == null || (n1 = args1.length) == 0) return args2; if (args2 == null || (n2 = args2.length) == 0) return args1; Object[] args = new Object[n1 + n2]; for (int i = 0; i < n1; i++) args[i] = args1[i]; for (int i = 0; i < n2; i++) args[n1 + i] = args2[i]; return args; } static public Object invokeMethodWithWidening(Method m, Object o, Object... args) { try { try { Class[] types = m.getParameterTypes(); int n = types.length; Object[] args2 = new Object[n]; for (int i = 0; i < n; i++) args2[i] = convertPrimitiveIfNecessary(args[i], types[i]); return m.invoke(o, args2); } 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 Iterator iterator_gen(Object o) { if (o == null) return emptyItIt(); if (o instanceof Iterator) return ((Iterator) o); if (o instanceof Iterable) return ((Iterable) o).iterator(); if (o instanceof Object[]) return arrayIterator((Object[]) o); throw fail("Not iterable: " + className(o)); } static public class mapI_It extends IterableIterator { public Object f; public Iterator i; public mapI_It() { } public mapI_It(Object f, Iterator i) { this.i = i; this.f = f; } public boolean hasNext() { return i.hasNext(); } public Object next() { return callF(f, i.next()); } public String toString() { return formatFunctionCall("mapI", f, i); } } static public IterableIterator mapI(final Object f, final Iterator i) { return new mapI_It(f, i); } static public IterableIterator mapI(IterableIterator i, Object f) { return mapI((Iterator) i, f); } static public IterableIterator mapI(Object f, IterableIterator i) { return mapI((Iterator) i, f); } static public IterableIterator mapI(Iterator i, Object f) { return mapI(f, i); } static public IterableIterator mapI(Iterable i, IF1 f) { return new MapI(f, iterator(i)); } static public IterableIterator mapI(Iterator i, IF1 f) { return new MapI(f, i); } static public IterableIterator mapI(IterableIterator i, IF1 f) { return new MapI(f, i); } static public IterableIterator mapI(IF1 f, Iterable i) { return new MapI(f, iterator(i)); } static public IterableIterator mapI(Iterable i, Object f) { return mapI(f, i.iterator()); } static public IterableIterator mapI(Object f, Iterable i) { return mapI(i, f); } static public > IterableIterator nestedIterator(Iterable c, final F1 makeInnerIterator) { return nestedIterator(iterator(c), makeInnerIterator); } static public > IterableIterator nestedIterator(Iterable c, IF1 makeInnerIterator) { return nestedIterator(iterator(c), makeInnerIterator); } static public > IterableIterator nestedIterator(IterableIterator c, IF1 makeInnerIterator) { return nestedIterator((Iterator) c, makeInnerIterator); } static public > IterableIterator nestedIterator(Iterator it1, IF1 makeInnerIterator) { if (it1 == null || !it1.hasNext()) return emptyItIt(); return iff(new F0() { public A a; public Iterator innerIterator; { nextOuter(); } public void nextOuter() { a = it1.next(); innerIterator = makeInnerIterator.get(a); } public Object get() { while (true) { ping(); if (innerIterator != null && innerIterator.hasNext()) return innerIterator.next(); if (!it1.hasNext()) return endMarker(); nextOuter(); } } }); } static public > IterableIterator nestedIterator(final Iterator it1, F1 makeInnerIterator) { if (it1 == null || !it1.hasNext()) return emptyItIt(); return iff(new F0() { public A a; public Iterator innerIterator; { nextOuter(); } public void nextOuter() { a = it1.next(); innerIterator = makeInnerIterator.get(a); } public Object get() { while (true) { ping(); if (innerIterator != null && innerIterator.hasNext()) return innerIterator.next(); if (!it1.hasNext()) return endMarker(); nextOuter(); } } }); } static public > IterableIterator nestedIterator(IF1 makeInnerIterator, Iterator it1) { return nestedIterator(it1, makeInnerIterator); } static public > IterableIterator nestedIterator(IF1 makeInnerIterator, Collection l) { return nestedIterator(l, makeInnerIterator); } static public String struct(Object o) { return structure(o); } static public String struct(Object o, structure_Data data) { return structure(o, data); } static public List structTok(String s) { return javaTok_noMLS(s); } static public String shortName(Object o) { return shortClassName(o); } static public String indentStructureString(String s) { return indentStructureString(100, s); } static public String indentStructureString(int levels, String s) { if (s == null) return null; return new StructureStringIndenter().levels(levels).get(s); } 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 boolean classIsExportedTo(Class c, java.lang.Module destModule) { if (c == null || destModule == null) return false; java.lang.Module srcModule = c.getModule(); String packageName = c.getPackageName(); return srcModule.isExported(packageName, destModule); } 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 Set allInterfacesImplementedBy(Object o) { return allInterfacesImplementedBy(_getClass(o)); } 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 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 boolean containsKey(Map map, A key) { return map != null && map.containsKey(key); } static public Map putOrCreateSyncMap(Map map, A key, B value) { if (map == null) map = syncHashMap(); map.put(key, value); return map; } static public AutoCloseable tempSet(Object o, final String field, Object value) { return tempSetField(o, field, value); } static public AutoCloseable tempPut(Map map, A key, B value) { if (map != null) { boolean wasContained = map.containsKey(key); B old = map.put(key, value); return () -> { if (wasContained) map.put(key, old); else map.remove(key); }; } return null; } static public List quoteAll(String[] l) { return quoteAll(asList(l)); } static public List quoteAll(Collection l) { List x = new ArrayList(); for (String s : l) x.add(quote(s)); return x; } 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 arraysEqual(Object[] a, Object[] b) { if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) if (neq(a[i], b[i])) return false; return true; } static public void metaPut(IMeta o, Object key, Object value) { metaMapPut(o, key, value); } static public void metaPut(Object o, Object key, Object value) { metaMapPut(o, key, value); } static public Map convertObjectMetaToMap(IMeta o) { return convertObjectMetaToMap(o, () -> makeObjectMetaMap()); } static public Map convertObjectMetaToMap(IMeta o, IF0 createEmptyMap) { if (o == null) return null; Object meta = o._getMeta(); if (meta instanceof Map) return ((Map) meta); var mutex = tempMetaMutex(o); try { var actualMutex = mutex.get(); synchronized (actualMutex) { meta = o._getMeta(); if (meta instanceof Map) return ((Map) meta); Map map = createEmptyMap.get(); if (meta != null) map.put("previousMeta", meta); o._setMeta(map); return map; } } finally { _close(mutex); } } static public void syncMapPutOrRemove(Map map, A key, B value) { syncMapPut2(map, key, value); } static public RuntimeException error() { throw new RuntimeException("fail"); } static public RuntimeException error(String msg) { throw new RuntimeException(msg); } static public String classNameWithIdentity(Object o) { return o == null ? null : withIdentity(o, className(o)); } 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 boolean all(Object pred, Iterable l) { if (l != null) for (Object o : l) if (!isTrue(callF(pred, o))) return false; return true; } static public boolean all(Iterable l, IF1 f) { if (l != null) for (A a : l) if (!f.get(a)) return false; return true; } static public boolean all(IF1 f, Iterable l) { return all(l, f); } static public boolean all(int[] l, IIntPred f) { if (l != null) for (int i : l) if (!f.get(i)) return false; return true; } static public B syncGetOrCreate(Map map, A key, Class c) { try { synchronized (map) { return getOrCreate(map, key, c); } } catch (Exception __e) { throw rethrow(__e); } } static public B syncGetOrCreate(Map map, A key, Object f) { synchronized (map) { return getOrCreate(map, key, f); } } static public B syncGetOrCreate(Class c, Map map, A key) { return syncGetOrCreate(map, key, c); } static public B syncGetOrCreate(Map map, A key, IF0 f) { synchronized (map) { return getOrCreate(map, key, f); } } 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 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 > List allValues(Map map) { List out = new ArrayList(); for (var l : values(map)) addAll(out, l); return out; } 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 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 ReliableSingleThread rstWithPreDelay(int delay, Runnable r) { return rstWithDelay(delay, r); } static public ReliableSingleThread rstWithPreDelay(double seconds, Runnable r) { return rstWithDelay(seconds, r); } static public RSTOverQ rstWithPreDelay(double seconds, Q q, Runnable r) { return new RSTOverQ(q, new Runnable() { public void run() { try { sleepSeconds(seconds); callF(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Sleep " + seconds + "s, then: " + r; } }); } static public Rect combinedChildBounds(Container c) { return mergeRects(map(listChildren(c), child -> toRect(getBounds(child)))); } static public void revalidateIncludingFullCenterContainer(Component c) { if (c == null) return; { swing(() -> { c.revalidate(); var parent = c.getParent(); if (parent != null && parent.getLayout() instanceof GridBagLayout) { parent.revalidate(); } }); } } static public A repaint(A c) { if (c != null) c.repaint(); return c; } static public void fillRect(BufferedImage image, int x, int y, int w, int h, Color color) { Graphics2D g = imageGraphics(image); fillRect(g, x, y, w, h, color); g.dispose(); } static public void fillRect(Graphics g, int x, int y, int w, int h, Color color) { g.setColor(color); g.fillRect(x, y, w, h); } static public void fillRect(int x, int y, int w, int h, Color color) { fillRect(currentImage(), x, y, w, h, color); } static public void fillRect(Rect r, Color color) { fillRect(r.x, r.y, r.w, r.h, color); } static public void fillRect(BufferedImage image, Rect r, Color c) { if (r != null) fillRect(image, r.x, r.y, r.w, r.h, c); } static public void fillRect(Graphics g, Rect r, Color c) { if (r != null) fillRect(g, r.x, r.y, r.w, r.h, c); } 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 void drawLine(BufferedImage image, int x1, int y1, int x2, int y2, Color color) { drawLine(imageGraphics(image), x1, y1, x2, y2, color); } static public void drawLine(Graphics2D g, int x1, int y1, int x2, int y2, Color color) { g.setColor(color); g.drawLine(x1, y1, x2, y2); } static public void drawLine(BufferedImage image, Pt a, Pt b, Color color) { drawLine(imageGraphics(image), a, b, color); } static public void drawLine(Graphics2D g, Pt a, Pt b, Color color) { drawLine(g, a.x, a.y, b.x, b.y, color); } static public double center(DoubleRange r) { return (r.start + r.end) / 2; } static public Pt center(Rect r) { return centerOfRect(r); } static public Pt center(int w, int h) { return pt(w / 2, h / 2); } static public List directChildrenOfType(Container c, Class theClass) { return instancesOf(theClass, getChildren(c)); } static public List directChildrenOfType(Class theClass, Container c) { return directChildrenOfType(c, theClass); } static public void removeFromParent(final Component c) { if (c != null) { swing(() -> { Container cc = c.getParent(); if (cc != null) { cc.remove(c); revalidate(cc); } }); } } static public void componentToFront(Component c) { if (c != null) { swing(() -> { var parent = c.getParent(); { if (parent != null) parent.setComponentZOrder(c, 0); } }); } } static public JCheckBox jVarCheckBox(IVarWithNotify lv) { return jVarCheckBox("", lv); } static public JCheckBox jVarCheckBox(String text, IVarWithNotify lv) { JCheckBox cb = jCheckBox(text); bindCheckBoxToLiveValue(cb, lv); return cb; } static public JSlider jLiveValueSlider_int_bothWays(int min, int max, IVarWithNotify lv) { AtomicInteger changing = new AtomicInteger(); JSlider slider = liveSlider(min, max, clamp(lv.get(), min, max), v -> { if (changing.get() == 0) lv.set(v); }); bindLiveValueListenerToComponent(slider, lv, new Runnable() { public void run() { try { AutoCloseable __1 = tempIncAtomicInt(changing); try { setSliderValue(slider, lv.get()); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp tempIncAtomicInt(changing);\r\n setSliderValue(slider, lv!);"; } }); return slider; } static public JPanel withRightAlignedButtons(JComponent center, Object... params) { return centerAndSouth(center, withMargin(jRightAlignedButtons(params))); } static public JPanel withRightAlignedButtons(Swingable center, Object... params) { return withRightAlignedButtons(wrap(center), params); } static public A newInstance(Class c, Object... args) { return nuObject(c, args); } static public Object newInstance(String className, Object... args) { return nuObject(className, args); } static public String a(String noun) { if (eq(noun, "")) return "?"; return ("aeiou".indexOf(noun.charAt(0)) >= 0 ? "an " : "a ") + noun; } static public String a(String contents, Object... params) { return hfulltag("a", contents, params); } static public String b(Object contents, Object... params) { return tag("b", contents, params); } static public int hashCodeFor(Object a) { return a == null ? 0 : a.hashCode(); } static public long nanos() { return nanoTime(); } static public String n2OrStrOrNull(Object o) { if (o == null) return null; if (o instanceof Number) return n2(((Number) o).longValue()); return str(o); } static public JPanel northAndCenterWithMargins(Component n, Component c) { return applyDefaultMargin(northAndCenter(withBottomMargin(n), c)); } static public JPanel northAndCenterWithMargins(int margin, Component n, Component c) { return applyMargin(margin, northAndCenter(withBottomMargin(margin, n), c)); } static public A fontSizePlus(final int delta, final A c) { if (c != null) { swing(() -> { Font font = c.getFont(); c.setFont(font.deriveFont(font.getSize2D() + delta)); }); } return c; } static public Container getParent(final Component c) { return c == null ? null : swing(new F0() { public Container get() { try { return c.getParent(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getParent();"; } }); } 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 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 String formatDouble(DoubleRange r, int digits) { return r == null ? "null" : "[" + formatDouble(r.start, digits) + ";" + formatDouble(r.end, digits) + "]"; } static public JPanel jcenteredline(final Component... components) { return swing(new F0() { public JPanel get() { try { return jFullCenter(hstackWithSpacing(components)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return jFullCenter(hstackWithSpacing(components));"; } }); } static public JPanel jcenteredline(List components) { return jcenteredline(asArray(Component.class, components)); } 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 JScrollPane jscroll_centered_borderless(Component c) { return borderlessScrollPane(jscroll_centered(c)); } static public List>> multiMapToMapPairs(MultiMap mm) { List>> out = new ArrayList(); for (A key : keys(mm)) out.add(pair(key, mm.get(key))); return out; } static public List>> multiMapToMapPairs(IMultiMap mm) { List>> out = new ArrayList(); for (A key : keys(mm)) out.add(pair(key, mm.get(key))); return out; } static public List>> multiSetMapToMapPairs(MultiSetMap mm) { List>> out = new ArrayList(); for (A key : keys(mm)) out.add(pair(key, mm.get(key))); return out; } static public List> mapToPairs(Map map) { List> l = emptyList(l(map)); if (map != null) for (Map.Entry e : map.entrySet()) l.add(pair(e.getKey(), e.getValue())); return l; } static public boolean isArray(Object o) { return o != null && o.getClass().isArray(); } static public List wrapArrayAsImmutableList(Object array) { if (array == null) return null; if (array instanceof Object[]) return wrapObjectArrayAsImmutableList((Object[]) array); else return wrapPrimitiveArrayAsImmutableList(array); } static public List cloneTakeFirst(Collection l, int n) { n = min(n, l(l)); List out = emptyList(n); if (n != 0) for (A a : l) { out.add(a); if (l(out) >= n) break; } return out; } static public List cloneTakeFirst(int n, Collection l) { return cloneTakeFirst(l, n); } static public List cloneTakeFirst(List l, int n) { return l(l) <= n ? l : cloneSubList(l, 0, n); } static public List cloneTakeFirst(int n, List l) { return cloneTakeFirst(l, n); } static public int hstackWithSpacing_spacing = 10; static public JPanel hstackWithSpacing(Object... parts) { parts = flattenArray2(parts); int spacing = hstackWithSpacing_spacing; int i = 0; if (first(parts) instanceof Integer) { spacing = toInt(first(parts)); ++i; } JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; gbc.fill = GridBagConstraints.VERTICAL; gbc.gridheight = GridBagConstraints.REMAINDER; for (; i < l(parts); i++) { if (i != 0) panel.add(javax.swing.Box.createRigidArea(new Dimension(spacing, 0)), gbc); panel.add(wrapForSmartAdd(parts[i]), gbc); } gbc.weightx = 1; panel.add(jrigid(), gbc); return panel; } static public JScrollPane jscroll_borderless(Component c) { return borderlessScrollPane(jscroll(c)); } static public JTextArea wordWrapTypeWriterTextArea() { return wrappedTextArea(newTypeWriterTextArea()); } static public JTextArea wordWrapTypeWriterTextArea(String text) { return wrappedTextArea(newTypeWriterTextArea(text)); } static public JLabel jcenterNarrowLabel() { return jcenterNarrowLabel(50); } static public JLabel jcenterNarrowLabel(int width) { return jcenterNarrowLabel(width, ""); } static public JLabel jcenterNarrowLabel(String text) { return jcenterNarrowLabel(50, text); } static public JLabel jcenterNarrowLabel(int width, String text) { return centerLabel(jnarrowLabel(width, text)); } static public JLabel jcenteredLabel(String text) { return setHorizontalAlignment(JLabel.CENTER, jLabel(text)); } static public JLabel jcenteredLabel() { return jcenteredLabel(" "); } static public LinkedHashMap cloneLinkedHashMap(Map map) { return map == null ? new LinkedHashMap() : new LinkedHashMap(map); } 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 B second(T3 t) { return t == null ? null : t.b; } static public A second(Producer p) { if (p == null) return null; if (p.next() == null) return null; return p.next(); } static public char second(String s) { return charAt(s, 1); } static public B second(Either e) { return e == null ? null : e.bOpt(); } static public void removeMouseAdapter(Component c, MouseAdapter a) { if (c != null && a != null) { swing(() -> { c.removeMouseListener(a); c.removeMouseMotionListener(a); }); } } static public Class typeToClass(Type type) { if (type == null) return null; if (type instanceof Class) return ((Class) type); if (type instanceof ParameterizedType) return optCast(Class.class, ((ParameterizedType) type).getRawType()); return null; } static public RunResultWithTimestamps runResultWithTimestamps_dontPrintStackTrace(IF0 f) { return new RunResultWithTimestamps().run(f, false); } static public LineAndColumn parseLineAndColumn(String s) { String re = "\\bLine (" + regexpN2() + "), col (" + regexpN2() + ")"; List l = regexpLastGroupsIC(re, s); return l == null ? null : new LineAndColumn(parseIntN2(first(l)), parseIntN2(second(l))); } static public File byteCodePathForClass(Class c) { if (c == null) return null; ClassLoader cl = getClassLoader(c); Collection files = (Collection) (getOpt(cl, "files")); if (files != null) { String name = c.getName().replace('.', '/') + ".class"; for (File location : files) if (dirOrZipContainsPath(location, name)) return location; throw fail(name + " not found in: " + files); } return null; } static public File byteCodePathForClass(Object o) { return byteCodePathForClass(_getClass(o)); } static public List itemPlusList(A a, Collection l) { return concatLists(ll(a), l); } static public List endingWith_dropSuffix(Collection l, String suffix) { List out = new ArrayList(); for (String s : unnullForIteration(l)) if (endsWith(s, suffix)) out.add(dropLast(l(suffix), s)); return out; } static public List endingWith_dropSuffix(String suffix, Collection l) { return endingWith_dropSuffix(l, suffix); } static public List standardImports_cache; static public List standardImports() { if (standardImports_cache == null) standardImports_cache = standardImports_load(); return standardImports_cache; } static public List standardImports_load() { return ll("java.util.*", "java.util.zip.*", "java.util.List", "java.util.regex.*", "java.util.concurrent.*", "java.util.concurrent.atomic.*", "java.util.concurrent.locks.*", "java.util.function.*", "javax.swing.*", "javax.swing.event.*", "javax.swing.text.*", "javax.swing.table.*", "java.io.*", "java.net.*", "java.lang.reflect.*", "java.lang.ref.*", "java.lang.management.*", "java.security.*", "java.security.spec.*", "java.awt.*", "java.awt.event.*", "java.awt.image.*", "java.awt.geom.*", "javax.imageio.*", "java.math.*", "java.time.Duration"); } static public List classNamesInJarOrDir(File dir) { return classNamesInJarOrDir(dir, ""); } static public List classNamesInJarOrDir(File dir, String prefixInJar) { List classes = new ArrayList(); if (dir == null) { } else if (dir.isDirectory()) { for (File f : listFiles(dir)) { String s = f.getName(); if (s.endsWith(".class")) classes.add(dropSuffix(".class", s)); } } else if (dir.isFile()) { try { JarFile jarFile = new JarFile(dir); try { Enumeration e = jarFile.entries(); while (e.hasMoreElements()) { JarEntry je = e.nextElement(); if (je.isDirectory() || je.getName().startsWith("META-INF/") || !je.getName().endsWith(".class")) continue; String className = dropSuffix(".class", je.getName()); className = dropPrefixOrNull(prefixInJar, className); if (className == null) continue; if (className.contains("-")) continue; className = className.replace('/', '.'); classes.add(className); } } finally { jarFile.close(); } } catch (Throwable __e) { printStackTrace(__e); } } return classes; } static public List classNamesInLoadedJigsawModules() { return concatMap(loadedJigsawModuleNames(), moduleName -> classNamesInJigsawModule(moduleName)); } static public String aGlobalID() { return randomID(globalIDLength()); } static public String aGlobalID(Random random) { return randomID(random, globalIDLength()); } static public boolean syncSetAdd(Collection c, A a) { if (c == null) return false; synchronized (collectionMutex(c)) { if (c.contains(a)) return false; c.add(a); return true; } } static public BufferedImage whiteImage(int w, int h) { return newBufferedImage(w, h, Color.white); } static public BufferedImage whiteImage(int size) { return whiteImage(size, size); } static public BufferedImage whiteImage(WidthAndHeight size) { return whiteImage(size.getWidth(), size.getHeight()); } static public JLabel setImage(final BufferedImage img, final JLabel lbl) { if (lbl != null) { swing(() -> { lbl.setIcon(imageIcon(img)); }); } return lbl; } static public JLabel setImage(JLabel lbl, BufferedImage img) { return setImage(img, lbl); } static public JLabel setImage(final String imageID, final JLabel lbl) { if (lbl != null) { swing(() -> { lbl.setIcon(imageIcon(imageID)); }); } return lbl; } static public JLabel setImage(JLabel lbl, String imageID) { return setImage(imageID, lbl); } static public A setImage(A is, BufferedImage img) { { if (is != null) is.setImage(img); } return is; } static public A onResize(A c, Runnable r) { if (c != null && r != null) { swing(() -> { c.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { pcallF(r); } }); }); } return c; } static public A onResize(Runnable r, A c) { return onResize(c, r); } static public void componentPopupMenu2(A component, final VF2 menuMaker) { final WeakReference ref = new WeakReference<>(component); componentPopupMenu(component, new VF1() { public void get(JPopupMenu menu) { try { callF(menuMaker, ref.get(), menu); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(menuMaker, ref!, menu);"; } }); } static public A jHandleFileDrop(A c, final Object onDrop) { new DropTarget(c, new DropTargetAdapter() { public void drop(DropTargetDropEvent e) { try { Transferable tr = e.getTransferable(); DataFlavor[] flavors = tr.getTransferDataFlavors(); for (DataFlavor flavor : flavors) { if (flavor.isFlavorJavaFileListType()) { e.acceptDrop(e.getDropAction()); File file = first((List) tr.getTransferData(flavor)); if (file != null && !isFalse(callF(onDrop, file))) e.dropComplete(true); return; } } } catch (Throwable __e) { printStackTrace(__e); } e.rejectDrop(); } }); return c; } static public A jHandleFileDrop(IVF1 onDrop, A c) { return jHandleFileDrop((Object) onDrop, c); } static public A jHandleFileDrop(Object onDrop, A c) { return jHandleFileDrop(c, onDrop); } static public void imageSurfaceOnHover(ImageSurface is, VF1 onHover) { if (is == null || onHover == null) return; { swing(() -> { MouseAdapter ma = new MouseAdapter() { public void mouseMoved(MouseEvent e) { pick(e); } public void mouseEntered(MouseEvent e) { pick(e); } public void mouseExited(MouseEvent e) { pick(null); } public void pick(MouseEvent e) { try { callF(onHover, e == null ? (Pt) null : is.pointFromEvent(e)); } catch (Throwable __e) { printStackTrace(__e); } } }; is.addMouseMotionListener(ma); is.addMouseListener(ma); }); } } static public void imageSurfaceOnHover(ImageSurface is, IVF1 onHover) { imageSurfaceOnHover(is, toVF1(onHover)); } static public JCheckBoxMenuItem jMenuItemStayCheckedOnClick(String text, IF0 checked, Runnable action) { var mi = swing(() -> new JCheckBoxMenuItem(text, isTrue(checked.get()))); bindToComponent(mi, new Runnable() { public void run() { try { boolean b = isTrue(checked.get()); setChecked(mi, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "boolean b = isTrue(checked!);\r\n setChecked(mi, b);"; } }); addActionListener(mi, () -> { if (!isChecked(mi)) setChecked(mi, true); callF(action); }); return mi; } static public JFrame showFullScreen(JComponent c) { return showFullScreen(defaultFrameTitle(), c); } static public JFrame showFullScreen(final String title, final JComponent c) { return (JFrame) swingAndWait(new F0() { public Object get() { try { GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); if (!gd.isFullScreenSupported()) throw fail("No full-screen mode supported!"); boolean dec = JFrame.isDefaultLookAndFeelDecorated(); if (dec) JFrame.setDefaultLookAndFeelDecorated(false); final JFrame window = new JFrame(title); window.setUndecorated(true); if (dec) JFrame.setDefaultLookAndFeelDecorated(true); registerEscape(window, new Runnable() { public void run() { try { disposeWindow(window); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeWindow(window)"; } }); window.add(wrap(c)); gd.setFullScreenWindow(window); for (int i = 100; i <= 1000; i += 100) awtLater(i, new Runnable() { public void run() { try { window.toFront(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "window.toFront()"; } }); return window; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()\r\n ..."; } }); } static public void selectFile(final String msg, VF1 action) { selectFile(msg, userDir(), action); } static public void selectFile(final String msg, final File defaultFile, VF1 action) { inputFilePath(msg, defaultFile, action); } static public void saveImage(File f, BufferedImage img) { if (hasJPEGExtension(f)) saveJPG(f, img); else savePNG(f, img); } static public void saveImage(BufferedImage img, File f) { saveImage(f, img); } static public A copyImageToClipboard(A img) { TransferableImage trans = new TransferableImage(img); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null); vmBus_send("newClipboardContents", img); print("Copied image to clipboard (" + img.getWidth(null) + "*" + img.getHeight(null) + " px)"); return img; } static public JComponent selectImageSnippet(VF1 onSelect) { return selectSnippetID_v1(onSelect); } static public JComponent selectImageSnippet(String defaultID, VF1 onSelect) { return selectSnippetID_v1(defaultID, onSelect); } static public BufferedImage cloneClipBufferedImage(BufferedImage src, Rectangle clip) { return cloneBufferedImage(clipBufferedImage(src, clip)); } static public BufferedImage cloneClipBufferedImage(BufferedImage src, Rect r) { return cloneBufferedImage(clipBufferedImage(src, r)); } static public BufferedImage cloneClipBufferedImage(BufferedImage src, int x, int y, int w, int h) { return cloneBufferedImage(clipBufferedImage(src, x, y, w, h)); } static public List cloneClipBufferedImage(BufferedImage src, Iterable rects) { return map(rects, r -> cloneClipBufferedImage(src, r)); } static public BufferedImage getImageFromClipboard() { try { Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (t == null) return null; List l = (List) (getTransferData(t, DataFlavor.javaFileListFlavor)); if (nempty(l)) return loadImage2(first(l)); if (t.isDataFlavorSupported(DataFlavor.imageFlavor)) return (BufferedImage) t.getTransferData(DataFlavor.imageFlavor); return imageFromDataURL(getTextFromClipboard()); } catch (Exception __e) { throw rethrow(__e); } } static public void popup(final Throwable throwable) { popupError(throwable); } static public void popup(final String msg) { print(msg); SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, msg); } }); } static public A _print(String s, A a) { return print(s, a); } static public A _print(A a) { return print(a); } static public void _print() { print(); } static public boolean hasTransparency(BufferedImage img) { return img.getColorModel().hasAlpha(); } 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 "return c.getMinimumSize();"; } }); } static public A printIfScaffoldingEnabled(Object o, A a) { return printIfScaffoldingEnabled(o, "", a); } static public A printIfScaffoldingEnabled(Object o, String s, A a) { return printIf(scaffoldingEnabled(o), s, a); } static public BoolVar componentShowingVar(JComponent component) { return swing(() -> { BoolVar flag = new BoolVar(component.isShowing()); component.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { if (flag.get()) print("Warning: bindToComponent logic failure"); flag.set(true); } public void ancestorRemoved(AncestorEvent event) { if (!flag.get()) print("Warning: bindToComponent logic failure"); flag.set(false); } public void ancestorMoved(AncestorEvent event) { } }); return flag; }); } static public WidthAndHeight imageSize(BufferedImage img) { return img == null ? null : widthAndHeight(img.getWidth(), img.getHeight()); } static public WidthAndHeight imageSize(WidthAndHeight img) { return img == null ? null : widthAndHeight(img.getWidth(), img.getHeight()); } static public boolean imagesHaveSameSize(BufferedImage a, BufferedImage b) { return a != null && b != null && a.getWidth() == b.getWidth() && a.getHeight() == b.getHeight(); } static public boolean scaffoldingEnabled(Object o) { return metaGet(o, "scaffolding") != null; } static public JScrollPane enclosingScrollPane(Component c) { while (c.getParent() != null && !(c.getParent() instanceof JViewport) && c.getParent().getComponentCount() == 1) c = c.getParent(); if (!(c.getParent() instanceof JViewport)) return null; c = c.getParent().getParent(); return c instanceof JScrollPane ? (JScrollPane) c : null; } static public void awtLater(int delay, final Object r) { swingLater(delay, r); } static public void awtLater(int delay, Runnable r) { swingLater(delay, r); } static public void awtLater(Object r) { swingLater(r); } static public void awtLater(double delaySeconds, Runnable r) { swingLater(toMS(delaySeconds), r); } static public void awtLater(JComponent component, int delay, Object r) { installTimer(component, r, delay, delay, false); } static public void awtLater(JFrame frame, int delay, Object r) { awtLater(frame.getRootPane(), delay, r); } static public ImageSurface showFullScreenImageSurface(BufferedImage img) { ImageSurface is = jImageSurface(img); showFullScreen(jscroll_centered(disposeFrameOnClick(is))); return is; } static public void imageSurface_pixelated(ImageSurface imageSurface) { if (imageSurface == null) return; imageSurface.setDoubleBuffered(true); imageSurface.noAlpha = true; imageSurface.interpolationMode = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR; repaint(imageSurface); } static public void imageSurface_pixelated(ImageSurface imageSurface, boolean pixelated) { if (pixelated) imageSurface_pixelated(imageSurface); else imageSurface_unpixelated(imageSurface); } static public void closeAllAndClear(Collection l) { if (l == null) return; for (AutoCloseable c : cloneList(l)) { try { close(c); } catch (Throwable __e) { printStackTrace(__e); } } l.clear(); } static public JScrollPane jscroll_center_borderless(Component c) { return jscroll_centered_borderless(c); } static public List listPlus(Collection l, A... more) { return concatLists(l, asList(more)); } static public Class _run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } static public List syncGetAndClear(Collection l) { return syncCloneAndClearList(l); } static public void cancelAndInterruptThread(Thread t) { if (t == null) return; cancelThread(t); t.interrupt(); } static public long nanoTime() { return System.nanoTime(); } static public ThreadLocal saveTiming_last = new ThreadLocal(); static public void saveTiming(long ms) { print(ms + " ms"); saveTiming_noPrint(ms); } static public void saveTiming_noPrint(long ms) { saveTiming_last.set(ms); } static public ThreadLocal saveTiming_tl() { return saveTiming_last; } static public Object time(Object f) { long time = sysNow(); Object o = callF(f); done2_always(str(f), time); return o; } static public A time(F0 f) { return (A) time((Object) f); } static public A time(IF0 f) { return (A) time((Object) f); } static public A time(String msg, IF0 f) { long time = sysNow(); A o = f.get(); done2_always(msg, time); return o; } static public void time(Runnable f) { time(str(f), f); } static public void time(String msg, Runnable f) { time(msg, runnableToIF0(f)); } static public DynamicObject dO(String className, Object... x) { return dynamicObject(className, x); } static public B syncMapGetOrCreate(Map map, A key, Class c) { return syncGetOrCreate(map, key, c); } static public B syncMapGetOrCreate(Map map, A key, Object f) { return syncGetOrCreate(map, key, f); } static public B syncMapGetOrCreate(Class c, Map map, A key) { return syncGetOrCreate(c, map, key); } static public B syncMapGetOrCreate(Map map, A key, IF0 f) { return syncGetOrCreate(map, key, f); } static public List ciSorted(Collection c) { return sortedIgnoreCase(c); } static public double nsToMicroseconds(double ns) { return nanosToMicroseconds(ns); } static public String microSymbol() { return "\u00B5"; } static public String firstToUpper(String s) { if (empty(s)) return s; return Character.toUpperCase(s.charAt(0)) + s.substring(1); } static public CharInToken charIndexToCharInToken(List tok, int charIndex) { int i = 0, idx = 0, lTok; while (i < l(tok) && idx + (lTok = l(tok.get(i))) <= charIndex) { idx += lTok; i++; } return new CharInToken(tok, i, charIndex - idx); } static public List cloneKeys(Map map) { return cloneList(keys(map)); } static public List stringsSortedByLength(Iterable l) { return sortedByCalculatedField(l, new F1() { public Integer get(String s) { try { return l(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "l(s)"; } }); } static public List methodNames(Object o) { return allMethodNames(o); } static public Set fieldNames(Object o) { return allFields(o); } static public boolean isIdentifier(String s) { return isJavaIdentifier(s); } static public B floorValue(NavigableMap map, A key) { if (map == null) return null; var e = map.floorEntry(key); return e == null ? null : e.getValue(); } static public List concatMap(Object f, Iterable l) { return concatLists(map(f, l)); } static public List concatMap(Iterable l, Object f) { return concatMap(f, l); } static public List concatMap(Object f, Object[] l) { return concatLists(map(f, l)); } static public List concatMap(Object[] l, Object f) { return concatMap(f, l); } static public > List concatMap(Iterable l, IF1 f) { return concatMap(l, (Object) f); } static public > List concatMap(IF1 f, Iterable l) { return concatMap(l, f); } static public > List concatMap(IF1 f, A[] l) { return concatMap((Object) f, l); } static public A bindChangeListenerToComponent(A component, IHasChangeListeners hcl, Runnable listener) { return bindHasChangeListenersToComponent(component, hcl, listener); } static public A bindChangeListenerToComponent(IHasChangeListeners hcl, A component, Runnable listener) { return bindChangeListenerToComponent(component, hcl, listener); } static public A componentPopupMenuItems(A c, final Object... params) { componentPopupMenu(c, new VF1() { public void get(JPopupMenu menu) { try { addMenuItems(menu, params); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItems(menu, params)"; } }); return c; } static public double distancePointToLineSegment(Pt a, Pt b, Pt p) { int x1 = a.x, y1 = a.y, x2 = b.x, y2 = b.y, x3 = p.x, y3 = p.y; float px = x2 - x1; float py = y2 - y1; float temp = (px * px) + (py * py); float u = ((x3 - x1) * px + (y3 - y1) * py) / (temp); if (u > 1) u = 1; else if (u < 0) u = 0; float x = x1 + u * px; float y = y1 + u * py; float dx = x - x3; float dy = y - y3; return sqrt(dx * dx + dy * dy); } static public double doubleMin(Iterable l) { double min = Double.MAX_VALUE; for (double d : unnullForIteration(l)) min = Math.min(min, d); return min; } static public double doubleMin(double... l) { double min = Double.MAX_VALUE; for (double d : unnullForIteration(l)) min = Math.min(min, d); return min; } static public float clampZeroToOne(float x) { return x < 0 ? 0 : x > 1 ? 1 : x; } static public double clampZeroToOne(double x) { return x < 0 ? 0 : x > 1 ? 1 : x; } static public A setBackground(final Color color, final A a) { if (a != null) { swing(() -> { a.setBackground(color); }); } return a; } static public A setBackground(A a, Color color) { return setBackground(color, a); } 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 void setLocation(Component c, int p_x, int p_y) { setLocation(c, pt(p_x, p_y)); } static public void setLocation(Component c, Pt p) { if (c != null) { swing(() -> { c.setLocation(p.x, p.y); }); } } 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 String nlLogic_text(Exp e) { return e == null ? null : e.text(); } static public String nlLogic_text(IfThen r) { return r == null ? null : r.text(); } static public ReliableSingleThread rst(Runnable r) { return new ReliableSingleThread(r); } static public Collection conceptsWhere(Class c, Object... params) { return findConceptsWhere(c, params); } static public Collection conceptsWhere(String c, Object... params) { return findConceptsWhere(c, params); } static public Collection conceptsWhere(Concepts concepts, Class c, Object... params) { return findConceptsWhere(concepts, c, params); } static public List sortByCalculatedFieldAlphaNumIC(Iterable c, IF1 f) { List l = cloneList(c); sort(l, (a, b) -> cmpAlphanumIC(f.get(a), f.get(b))); return l; } static public AutoCloseable tempAddGlobalCtrlKeyListener(IVF1 onStatusChanged) { AWTEventListener l = new AWTEventListener() { public Boolean status; public void eventDispatched(AWTEvent evt) { if (evt instanceof InputEvent) { Boolean b = ((InputEvent) evt).isControlDown(); if (!eq(b, status)) pcallF_typed(onStatusChanged, status = b); } } }; Toolkit.getDefaultToolkit().addAWTEventListener(l, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); return () -> Toolkit.getDefaultToolkit().removeAWTEventListener(l); } static public int done_minPrint = 10; static public long done(long startTime, String desc) { long time = now() - startTime; if (time >= done_minPrint) print(desc + " [" + time + " ms]"); return time; } static public long done(String desc, long startTime) { return done(startTime, desc); } static public long done(long startTime) { return done(startTime, ""); } static public String formatDouble1(double d) { return formatDouble(d, 1); } static public A waitForVarPredicate(Var v, IF0 pred) { try { synchronized (v) { while (!pred.get()) v.wait(); return v.get(); } } catch (Exception __e) { throw rethrow(__e); } } static public List getAll(Map map, Collection l) { return lookupAllOpt(map, l); } static public List getAll(Collection l, Map map) { return lookupAllOpt(map, l); } static public > List getAll(Iterable l) { return getVars(l); } static public NavigableMap synchroTreeMap() { return synchroNavigableMap(new TreeMap()); } static public Object _defaultClassFinder_value = defaultDefaultClassFinder(); static public Object _defaultClassFinder() { return _defaultClassFinder_value; } static public boolean hasConcept(Class c, Object... params) { return hasConcept(db_mainConcepts(), c, params); } static public boolean hasConcept(Concepts cc, Class c, Object... params) { return findConceptWhere(cc, c, params) != null; } static public String getDBProgramID_id; static public String getDBProgramID() { return nempty(getDBProgramID_id) ? getDBProgramID_id : programIDWithCase(); } static public Object load(String varName) { readLocally(varName); return get(mc(), varName); } static public Object load(String progID, String varName) { readLocally(progID, varName); return get(mc(), varName); } static public void clearConcepts() { db_mainConcepts().clearConcepts(); } static public void clearConcepts(Concepts concepts) { concepts.clearConcepts(); } static public Map unstructureMap(String s) { return (Map) unstructure(s); } static public Map unstructureMap(String text, boolean allDynamic, Object classFinder) { return (Map) unstructure(text, allDynamic, classFinder); } static public boolean exceptionMessageContains(Throwable e, String s) { return cic(getInnerMessage(e), s); } static public void printShortException(Throwable e) { print(exceptionToStringShort(e)); } static public void printShortException(String s, Throwable e) { print(s, exceptionToStringShort(e)); } static public Object unstructureGZFile(File f) { return unstructureGZFile(f, null); } static public Object unstructureGZFile(File f, IF1 classFinder) { try { if (!fileExists(f)) return null; BufferedReader reader = utf8BufferedReader(gzInputStream(f)); return unstructure_tok(javaTokC_noMLS_onReader(reader), false, classFinder); } catch (Exception __e) { throw rethrow(__e); } } static public IF1 toIF1(final Object f) { if (f == null) return null; if (f instanceof IF1) return (IF1) f; if (isString(f)) { throw fail("callF_legacy"); } return new IF1() { public Object get(Object a) { return callF(f, a); } }; } static public RemoteDB connectToDBOpt(String dbNameOrID) { try { return new RemoteDB(dbNameOrID); } catch (Throwable __e) { return null; } } static public Object unstructure(String text) { return unstructure(text, false); } static public Object unstructure(String text, boolean allDynamic) { return unstructure(text, allDynamic, null); } static public Object unstructure(String text, IF1 classFinder) { return unstructure(text, false, classFinder); } static public int structure_internStringsLongerThan = 50; static public int unstructure_unquoteBufSize = 100; static public int unstructure_tokrefs; abstract static public class unstructure_Receiver { abstract public void set(Object o); } static public Object unstructure(String text, boolean allDynamic, Object classFinder) { if (text == null) return null; return unstructure_tok(javaTokC_noMLS_iterator(text), allDynamic, classFinder); } static public Object unstructure_reader(BufferedReader reader) { return unstructure_tok(javaTokC_noMLS_onReader(reader), false, null); } public interface unstructure_Handler { public void parse(int refID, int tokIndex, unstructure_Receiver out); } static public Object unstructure_tok(final Producer tok, final boolean allDynamic, final Object _classFinder) { final boolean debug = unstructure_debug; final class X { public int i = -1; final public Object classFinder = _classFinder != null ? _classFinder : _defaultClassFinder(); public String mcDollar = actualMCDollar(); public HashMap refs = new HashMap(); public HashMap tokrefs = new HashMap(); public HashSet concepts = new HashSet(); public List stack = new ArrayList(); public Map baseClassMap = new HashMap(); public HashMap innerClassConstructors = new HashMap(); public String curT; public char[] unquoteBuf = new char[unstructure_unquoteBufSize]; final public HashMap handlers = new HashMap(); public X() { try { Class mc = (Class) (callF(_classFinder, "
")); if (mc != null) mcDollar = mc.getName() + "$"; } catch (Throwable __e) { printStackTrace(__e); } makeHandlers(); } public void makeHandlers() { unstructure_Handler h; handlers.put("bigint", (unstructure_Handler) (refID, tokIndex, out) -> out.set(parseBigInt())); handlers.put("d", (unstructure_Handler) (refID, tokIndex, out) -> out.set(parseDouble())); handlers.put("fl", (unstructure_Handler) (refID, tokIndex, out) -> out.set(parseFloat())); handlers.put("sh", (unstructure_Handler) (refID, tokIndex, out) -> { consume(); String t = tpp(); if (t.equals("-")) { t = tpp(); out.set((short) (-parseInt(t))); return; } out.set((short) parseInt(t)); }); handlers.put("enum", (unstructure_Handler) (refID, tokIndex, out) -> { consume(); String t = tpp(); assertTrue(isJavaIdentifier(t)); String fullClassName = mcDollar + t; Class _c = findAClass(fullClassName); if (_c == null) throw fail("Enum class not found: " + fullClassName); int ordinal = parseInt(tpp()); out.set(_c.getEnumConstants()[ordinal]); }); handlers.put("false", h = (unstructure_Handler) (refID, tokIndex, out) -> { consume(); out.set(false); }); handlers.put("f", h); handlers.put("true", h = (unstructure_Handler) (refID, tokIndex, out) -> { consume(); out.set(true); }); handlers.put("t", h); handlers.put("{", (unstructure_Handler) (refID, tokIndex, out) -> parseMap(out)); handlers.put("[", (unstructure_Handler) (refID, tokIndex, out) -> { ArrayList l = new ArrayList(); if (refID >= 0) refs.put(refID, l); this.parseList(l, out); }); handlers.put("bitset", (unstructure_Handler) (refID, tokIndex, out) -> parseBitSet(out)); handlers.put("array", h = (unstructure_Handler) (refID, tokIndex, out) -> parseArray(out)); handlers.put("intarray", h); handlers.put("dblarray", h); } public Class findAClass(String fullClassName) { try { return classFinder != null ? (Class) callF(classFinder, fullClassName) : findClass_fullName(fullClassName); } catch (Throwable __e) { return null; } } public String unquote(String s) { return unquoteUsingCharArray(s, unquoteBuf); } public String t() { return curT; } public String tpp() { String t = curT; consume(); return t; } public void parse(final unstructure_Receiver out) { String t = t(); int refID; if (structure_isMarker(t, 0, l(t))) { refID = parseInt(t.substring(1)); consume(); } else refID = -1; final int tokIndex = i; parse_inner(refID, tokIndex, new unstructure_Receiver() { public void set(Object o) { if (refID >= 0) refs.put(refID, o); if (o != null) tokrefs.put(tokIndex, o); out.set(o); } }); } public void parse_inner(int refID, int tokIndex, unstructure_Receiver out) { String t = t(); Object handler = handlers.get(t); if (handler instanceof unstructure_Handler) { ((unstructure_Handler) handler).parse(refID, tokIndex, out); return; } Class c = (Class) handler; if (c == null) { if (t.startsWith("\"")) { String s = internIfLongerThan(unquote(tpp()), structure_internStringsLongerThan); out.set(s); return; } if (t.startsWith("'")) { out.set(unquoteCharacter(tpp())); return; } if (t.equals("-")) { consume(); t = tpp(); out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return; } if (isInteger(t) || isLongConstant(t)) { consume(); if (isLongConstant(t)) { out.set(parseLong(t)); return; } long l = parseLong(t); boolean isInt = l == (int) l; out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return; } if (t.equals("-")) { consume(); t = tpp(); out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return; } if (isInteger(t) || isLongConstant(t)) { consume(); if (isLongConstant(t)) { out.set(parseLong(t)); return; } long l = parseLong(t); boolean isInt = l == (int) l; out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return; } if (t.equals("File")) { consume(); File f = new File(unquote(tpp())); out.set(f); return; } if (t.startsWith("r") && isInteger(t.substring(1))) { consume(); int ref = Integer.parseInt(t.substring(1)); Object o = refs.get(ref); if (o == null) warn("unsatisfied back reference " + ref); out.set(o); return; } if (t.startsWith("t") && isInteger(t.substring(1))) { consume(); int ref = Integer.parseInt(t.substring(1)); Object o = tokrefs.get(ref); if (o == null) warn("unsatisfied token reference " + ref + " at " + tokIndex); out.set(o); return; } if (t.equals("hashset")) { parseHashSet(out); return; } if (t.equals("lhs")) { parseLinkedHashSet(out); return; } if (t.equals("treeset")) { parseTreeSet(out); return; } if (t.equals("ciset")) { parseCISet(out); return; } if (eqOneOf(t, "hashmap", "hm")) { consume(); parseMap(new HashMap(), out); return; } if (t.equals("lhm")) { consume(); parseMap(new LinkedHashMap(), out); return; } if (t.equals("tm")) { consume(); parseMap(new TreeMap(), out); return; } if (t.equals("cimap")) { consume(); parseMap(ciMap(), out); return; } if (t.equals("ll")) { consume(); LinkedList l = new LinkedList(); if (refID >= 0) refs.put(refID, l); { parseList(l, out); return; } } if (t.equals("syncLL")) { consume(); { parseList(synchroLinkedList(), out); return; } } if (t.equals("sync")) { consume(); { parse(new unstructure_Receiver() { public void set(Object value) { if (value instanceof Map) { if (value instanceof NavigableMap) { out.set(synchroNavigableMap((NavigableMap) value)); return; } if (value instanceof SortedMap) { out.set(synchroSortedMap((SortedMap) value)); return; } { out.set(synchroMap((Map) value)); return; } } else { out.set(synchroList((List) value)); return; } } }); return; } } if (t.equals("ba")) { consume(); String hex = unquote(tpp()); out.set(hexToBytes(hex)); return; } if (t.equals("boolarray")) { consume(); int n = parseInt(tpp()); String hex = unquote(tpp()); out.set(boolArrayFromBytes(hexToBytes(hex), n)); return; } if (t.equals("class")) { out.set(parseClass()); return; } if (t.equals("l")) { parseLisp(out); return; } if (t.equals("null")) { consume(); out.set(null); return; } if (eq(t, "c")) { consume(); t = t(); assertTrue(isJavaIdentifier(t)); concepts.add(t); } if (eq(t, "cu")) { consume(); t = tpp(); assertTrue(isJavaIdentifier(t)); String fullClassName = mcDollar + t; Class _c = findAClass(fullClassName); if (_c == null) throw fail("Class not found: " + fullClassName); parse(new unstructure_Receiver() { public void set(Object value) { out.set(call(_c, "_deserialize", value)); } }); return; } } if (eq(t, "j")) { consume(); out.set(parseJava()); return; } if (eq(t, "bc")) { consume(); String c1 = tpp(); String c2 = tpp(); baseClassMap.put(c1, c2); { parse_inner(refID, i, out); return; } } if (c == null && !isJavaIdentifier(t)) throw new RuntimeException("Unknown token " + (i + 1) + ": " + quote(t)); consume(); String className, fullClassName; if (eq(t(), ".")) { className = t; do { consume(); className += "." + assertIdentifier(tpp()); } while (eq(t(), ".")); fullClassName = className; } else { className = t; fullClassName = mcDollar + t; } if (c == null && !allDynamic) { c = findAClass(fullClassName); handlers.put(className, c); } if (c == null && !allDynamic) { Set seen = new HashSet(); String parent = className; while (true) { String baseName = baseClassMap.get(parent); if (baseName == null) break; if (!seen.add(baseName)) throw fail("Cyclic superclass info: " + baseName); c = findAClass(mcDollar + baseName); if (c == null) print("Base class " + baseName + " of " + parent + " doesn't exist either"); else if (isAbstract(c)) print("Can't instantiate abstract base class: " + c); else { printVars_str("Reverting to base class", "className", className, "baseName", baseName, "c", c); handlers.put(className, c); break; } parent = baseName; } } boolean hasBracket = eq(t(), "("); if (hasBracket) consume(); boolean hasOuter = hasBracket && startsWith(t(), "this$"); DynamicObject dO = null; Object o = null; final String thingName = t; try { if (c != null) { if (hasOuter) try { Constructor ctor = innerClassConstructors.get(c); if (ctor == null) innerClassConstructors.put(c, ctor = nuStubInnerObject_findConstructor(c, classFinder)); o = ctor.newInstance(new Object[] { null }); } catch (Exception e) { print("Error deserializing " + c + ": " + e); o = nuEmptyObject(c); } else o = nuEmptyObject(c); if (o instanceof DynamicObject) dO = (DynamicObject) o; } else { if (concepts.contains(t) && (c = findAClass(mcDollar + "Concept")) != null) o = dO = (DynamicObject) nuEmptyObject(c); else dO = new DynamicObject(); dO.className = className; } } catch (Throwable __e) { printStackTrace(__e); } if (o == null && dO == null) dO = new DynamicObject(); if (refID >= 0) refs.put(refID, o != null ? o : dO); tokrefs.put(tokIndex, o != null ? o : dO); HashMap fields = new HashMap(); Object _o = o; DynamicObject _dO = dO; if (hasBracket) { stack.add(new Runnable() { public void run() { try { if (eq(t(), ",")) consume(); if (eq(t(), ")")) { consume(")"); objRead(_o, _dO, fields, hasOuter); out.set(_o != null ? _o : _dO); } else { final String key = unquote(tpp()); String t = tpp(); if (!eq(t, "=")) throw fail("= expected, got " + t + " after " + quote(key) + " in object " + thingName); stack.add(this); parse(new unstructure_Receiver() { public void set(Object value) { fields.put(key, value); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef unstructure_debug\r\n print(\"in object values, token: \" + t())..."; } }); } else { objRead(o, dO, fields, hasOuter); out.set(o != null ? o : dO); } } public void objRead(Object o, DynamicObject dO, Map fields, boolean hasOuter) { Object outer = fields.get("this$0"); if (outer != null) fields.put("this$1", outer); else { outer = fields.get("this$1"); if (outer != null) fields.put("this$0", outer); } if (o != null) { if (dO != null) { setOptAllDyn_pcall(dO, fields); } else { setOptAll_pcall(o, fields); } if (hasOuter) fixOuterRefs(o); } else for (Map.Entry e : fields.entrySet()) setDynObjectValue(dO, intern(e.getKey()), e.getValue()); if (o != null) pcallOpt_noArgs(o, "_doneLoading"); } public void parseSet(final Set set, final unstructure_Receiver out) { this.parseList(new ArrayList(), new unstructure_Receiver() { public void set(Object o) { set.addAll((List) o); out.set(set); } }); } public void parseLisp(final unstructure_Receiver out) { throw fail("class Lisp not included"); } public void parseBitSet(final unstructure_Receiver out) { consume("bitset"); consume("{"); final BitSet bs = new BitSet(); stack.add(new Runnable() { public void run() { try { if (eq(t(), "}")) { consume("}"); out.set(bs); } else { stack.add(this); parse(new unstructure_Receiver() { public void set(Object o) { bs.set((Integer) o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(bs);\r\n ..."; } }); } public void parseList(final List list, final unstructure_Receiver out) { tokrefs.put(i, list); consume("["); stack.add(new Runnable() { public void run() { try { if (eq(t(), "]")) { consume(); out.set(list); } else { stack.add(this); parse(new unstructure_Receiver() { public void set(Object o) { list.add(o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"]\")) {\r\n consume();\r\n ifdef unstructure_debug\r..."; } }); } public void parseArray(unstructure_Receiver out) { String _type = tpp(); int dims; if (eq(t(), "S")) { _type = "S"; consume(); } if (eq(t(), "/")) { consume(); dims = parseInt(tpp()); } else dims = 1; consume("{"); List list = new ArrayList(); String type = _type; stack.add(new Runnable() { public void run() { try { if (eq(t(), "}")) { consume("}"); if (dims > 1) { Class atype; if (type.equals("intarray")) atype = int.class; else if (type.equals("S")) atype = String.class; else throw todo("multi-dimensional arrays of other types"); out.set(list.toArray((Object[]) newMultiDimensionalOuterArray(atype, dims, l(list)))); } else out.set(type.equals("intarray") ? toIntArray(list) : type.equals("dblarray") ? toDoubleArray(list) : type.equals("S") ? toStringArray(list) : list.toArray()); } else { stack.add(this); parse(new unstructure_Receiver() { public void set(Object o) { list.add(o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n if (dims > 1) {\r\n ..."; } }); } public Object parseClass() { consume("class"); consume("("); String name = unquote(tpp()); consume(")"); Class c = allDynamic ? null : findAClass(name); if (c != null) return c; DynamicObject dO = new DynamicObject(); dO.className = "java.lang.Class"; name = dropPrefix(mcDollar, name); dO.fieldValues.put("name", name); return dO; } public Object parseBigInt() { consume("bigint"); consume("("); String val = tpp(); if (eq(val, "-")) val = "-" + tpp(); consume(")"); return new BigInteger(val); } public Object parseDouble() { consume("d"); consume("("); String val = unquote(tpp()); consume(")"); return Double.parseDouble(val); } public Object parseFloat() { consume("fl"); String val; if (eq(t(), "(")) { consume("("); val = unquote(tpp()); consume(")"); } else { val = unquote(tpp()); } return Float.parseFloat(val); } public void parseHashSet(unstructure_Receiver out) { consume("hashset"); parseSet(new HashSet(), out); } public void parseLinkedHashSet(unstructure_Receiver out) { consume("lhs"); parseSet(new LinkedHashSet(), out); } public void parseTreeSet(unstructure_Receiver out) { consume("treeset"); parseSet(new TreeSet(), out); } public void parseCISet(unstructure_Receiver out) { consume("ciset"); parseSet(ciSet(), out); } public void parseMap(unstructure_Receiver out) { parseMap(new TreeMap(), out); } public Object parseJava() { String j = unquote(tpp()); Matches m = new Matches(); if (jmatch("java.awt.Color[r=*,g=*,b=*]", j, m)) return nuObject("java.awt.Color", parseInt(m.unq(0)), parseInt(m.unq(1)), parseInt(m.unq(2))); else { warn("Unknown Java object: " + j); return null; } } public void parseMap(final Map map, final unstructure_Receiver out) { consume("{"); stack.add(new Runnable() { public boolean v = false; public Object key; public void run() { if (v) { v = false; stack.add(this); if (!eq(tpp(), "=")) throw fail("= expected, got " + t() + " in map of size " + l(map)); parse(new unstructure_Receiver() { public void set(Object value) { map.put(key, value); if (eq(t(), ",")) consume(); } }); } else { if (eq(t(), "}")) { consume("}"); out.set(map); } else { v = true; stack.add(this); parse(new unstructure_Receiver() { public void set(Object o) { key = o; } }); } } } }); } public void consume() { curT = tok.next(); ++i; } public void consume(String s) { if (!eq(t(), s)) { throw fail(quote(s) + " expected, got " + quote(t())); } consume(); } public void parse_initial(unstructure_Receiver out) { consume(); parse(out); while (nempty(stack)) popLast(stack).run(); } } ThreadLocal tlLoading = dynamicObjectIsLoading_threadLocal(); Boolean b = tlLoading.get(); tlLoading.set(true); try { final Var v = new Var(); X x = new X(); x.parse_initial(new unstructure_Receiver() { public void set(Object o) { v.set(o); } }); unstructure_tokrefs = x.tokrefs.size(); return v.get(); } finally { tlLoading.set(b); } } static public boolean unstructure_debug = false; static public String dynShortName(Object o) { return shortDynamicClassName(o); } static public A lastKey(SortedMap map) { return empty(map) ? null : map.lastKey(); } static public void callRunnableWithWrapper(Object wrapper, Runnable r) { if (wrapper == null) callF(r); else callF(wrapper, r); } static public List callFAll(Collection l, Object... args) { return callF_all(l, args); } static public long saveGZStructureToFile(String file, Object o) { return saveGZStructureToFile(getProgramFile(file), o); } static public long saveGZStructureToFile(File file, Object o) { return saveGZStructureToFile(file, o, new structure_Data()); } static public long saveGZStructureToFile(File file, Object o, structure_Data data) { try { File parentFile = file.getParentFile(); if (parentFile != null) parentFile.mkdirs(); File tempFile = tempFileFor(file); if (tempFile.exists()) try { String saveName = tempFile.getPath() + ".saved." + now(); copyFile(tempFile, new File(saveName)); } catch (Throwable e) { printStackTrace(e); } FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath()); CountingOutputStream cos; try { GZIPOutputStream gos = new GZIPOutputStream(fileOutputStream); cos = new CountingOutputStream(gos); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(cos, "UTF-8"); PrintWriter printWriter = new PrintWriter(outputStreamWriter); structureToPrintWriter(o, printWriter, data); printWriter.close(); gos.close(); fileOutputStream.close(); } catch (Throwable e) { fileOutputStream.close(); tempFile.delete(); throw rethrow(e); } if (file.exists() && !file.delete()) throw new IOException("Can't delete " + file.getPath()); if (!tempFile.renameTo(file)) throw new IOException("Can't rename " + tempFile + " to " + file); return cos.getFilePointer(); } catch (Exception __e) { throw rethrow(__e); } } static public long toM(long l) { return (l + 1024 * 1024 - 1) / (1024 * 1024); } static public String toM(long l, int digits) { return formatDouble(toM_double(l), digits); } 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 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 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 hours() { return hours(java.util.Calendar.getInstance()); } static public int hours(java.util.Calendar c) { return c.get(java.util.Calendar.HOUR_OF_DAY); } static public int hours(long time) { return hours(calendarFromTime(time)); } static public int hours(long time, TimeZone tz) { return hours(calendarFromTime(time, tz)); } static public int roundDownTo_rev(int x, int n) { return roundDownTo(n, x); } static public long roundDownTo_rev(long x, long n) { return roundDownTo(n, x); } static public int minutes() { return minutes(java.util.Calendar.getInstance()); } static public int minutes(java.util.Calendar c) { return c.get(java.util.Calendar.MINUTE); } static public long toK(long l) { return (l + 1023) / 1024; } static public String n(long l, String name) { return l + " " + trim(l == 1 ? singular(name) : getPlural(name)); } static public String n(Collection l, String name) { return n(l(l), name); } static public String n(Map m, String name) { return n(l(m), name); } static public String n(Object[] a, String name) { return n(l(a), name); } static public String n(MultiSet ms, String name) { return n(l(ms), name); } static public boolean structure_showTiming, structure_checkTokenCount; static public String structure(Object o) { return structure(o, new structure_Data()); } static public String structure(Object o, structure_Data d) { StringWriter sw = new StringWriter(); d.out = new PrintWriter(sw); structure_go(o, d); String s = str(sw); if (structure_checkTokenCount) { print("token count=" + d.n); assertEquals("token count", l(javaTokC(s)), d.n); } return s; } static public void structure_go(Object o, structure_Data d) { structure_1(o, d); while (nempty(d.stack)) popLast(d.stack).run(); } static public void structureToPrintWriter(Object o, PrintWriter out) { structureToPrintWriter(o, out, new structure_Data()); } static public void structureToPrintWriter(Object o, PrintWriter out, structure_Data d) { d.out = out; structure_go(o, d); } static public boolean structure_allowShortening = false; static public class structure_ClassInfo { public Class c; public String shortName; public List fields; public Method customSerializer; public IVF1 serializeObject; public boolean special = false; public boolean nullInstances = false; public boolean javafy = false; public Object emptyInstance; public void nullInstances(boolean b) { this.nullInstances = b; if (b) special = true; } public void javafy(boolean b) { this.javafy = b; if (b) special = true; } } static public class structure_Data { public PrintWriter out; public int stringSizeLimit; public int shareStringsLongerThan = 20; public boolean noStringSharing = false; public boolean storeBaseClasses = false; public boolean honorFieldOrder = true; public String mcDollar = actualMCDollar(); final public structure_Data setWarnIfUnpersistable(boolean warnIfUnpersistable) { return warnIfUnpersistable(warnIfUnpersistable); } public structure_Data warnIfUnpersistable(boolean warnIfUnpersistable) { this.warnIfUnpersistable = warnIfUnpersistable; return this; } final public boolean getWarnIfUnpersistable() { return warnIfUnpersistable(); } public boolean warnIfUnpersistable() { return warnIfUnpersistable; } public boolean warnIfUnpersistable = true; final public structure_Data setStackTraceIfUnpersistable(boolean stackTraceIfUnpersistable) { return stackTraceIfUnpersistable(stackTraceIfUnpersistable); } public structure_Data stackTraceIfUnpersistable(boolean stackTraceIfUnpersistable) { this.stackTraceIfUnpersistable = stackTraceIfUnpersistable; return this; } final public boolean getStackTraceIfUnpersistable() { return stackTraceIfUnpersistable(); } public boolean stackTraceIfUnpersistable() { return stackTraceIfUnpersistable; } public boolean stackTraceIfUnpersistable = true; final public structure_Data setSkipDefaultValues(boolean skipDefaultValues) { return skipDefaultValues(skipDefaultValues); } public structure_Data skipDefaultValues(boolean skipDefaultValues) { this.skipDefaultValues = skipDefaultValues; return this; } final public boolean getSkipDefaultValues() { return skipDefaultValues(); } public boolean skipDefaultValues() { return skipDefaultValues; } public boolean skipDefaultValues = false; transient public IF1 shouldIncludeField; public boolean shouldIncludeField(Field f) { return shouldIncludeField != null ? shouldIncludeField.get(f) : shouldIncludeField_base(f); } final public boolean shouldIncludeField_fallback(IF1 _f, Field f) { return _f != null ? _f.get(f) : shouldIncludeField_base(f); } public boolean shouldIncludeField_base(Field f) { return true; } public IdentityHashMap seen = new IdentityHashMap(); public HashMap strings = new HashMap(); public HashSet concepts = new HashSet(); public HashMap infoByClass = new HashMap(); public HashMap> persistenceInfo = new HashMap(); public int n; public List stack = new ArrayList(); public structure_Data append(String token) { out.print(token); ++n; return this; } public structure_Data append(int i) { out.print(i); ++n; return this; } public structure_Data append(String token, int tokCount) { out.print(token); n += tokCount; return this; } public structure_Data app(String token) { out.print(token); return this; } public structure_Data app(int i) { out.print(i); return this; } public structure_ClassInfo infoForClass(Class c) { structure_ClassInfo info = infoByClass.get(c); if (info == null) info = newClass(c); return info; } public structure_ClassInfo newClass(Class c) { structure_ClassInfo info = new structure_ClassInfo(); info.c = c; infoByClass.put(c, info); String name = c.getName(); String shortName = dropPrefix("main$", dropPrefix("loadableUtils.utils$", dropPrefix(mcDollar, name))); if (startsWithDigit(shortName)) shortName = name; info.shortName = shortName; try { if (isSyntheticOrAnonymous(c)) { info.nullInstances(true); return info; } if (c.isEnum()) { info.special = true; return info; } if (c.isArray()) { return info; } if ((info.customSerializer = findMethodNamed(c, "_serialize")) != null) info.special = true; if (storeBaseClasses) { Class sup = c.getSuperclass(); if (sup != Object.class) { append("bc "); append(shortDynClassNameForStructure(c)); out.print(" "); append(shortDynClassNameForStructure(sup)); out.print(" "); infoForClass(sup); } } if (eqOneOf(name, "java.awt.Color", "java.lang.ThreadLocal")) info.javafy(true); else if (name.startsWith("sun") || !isPersistableClass(c)) { info.javafy(true); if (warnIfUnpersistable) { String msg = "Class not persistable: " + c + " (anonymous or no default constructor), referenced from " + last(stack); if (stackTraceIfUnpersistable) printStackTrace(new Throwable(msg)); else print(msg); } } else if (skipDefaultValues) { var ctor = getDefaultConstructor(c); if (ctor != null) info.emptyInstance = invokeConstructor(ctor); } } catch (Throwable e) { printStackTrace(e); info.nullInstances(true); } return info; } public void setFields(structure_ClassInfo info, List fields) { info.fields = fields; } public void writeObject(Object o, String shortName, Map fv) { String singleField = fv.size() == 1 ? first(fv.keySet()) : null; append(shortName); n += countDots(shortName) * 2; int l = n; Iterator it = fv.entrySet().iterator(); class WritingObject implements Runnable { public String lastFieldWritten; public void run() { try { if (!it.hasNext()) { if (n != l) append(")"); } else { Map.Entry e = (Map.Entry) (it.next()); append(n == l ? "(" : ", "); append(lastFieldWritten = (String) e.getKey()).append("="); stack.add(this); structure_1(e.getValue(), structure_Data.this); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return shortName + "." + lastFieldWritten; } } stack.add(new WritingObject()); } } static public void structure_1(final Object o, final structure_Data d) { try { if (o == null) { d.append("null"); return; } Class c = o.getClass(); boolean concept = false; concept = o instanceof Concept; structure_ClassInfo info = d.infoForClass(c); List lFields = info.fields; if (lFields == null) { if (o instanceof Number) { PrintWriter out = d.out; if (o instanceof Integer) { int i = ((Integer) o).intValue(); out.print(i); d.n += i < 0 ? 2 : 1; return; } if (o instanceof Long) { long l = ((Long) o).longValue(); out.print(l); out.print("L"); d.n += l < 0 ? 2 : 1; return; } if (o instanceof Short) { short s = ((Short) o).shortValue(); d.append("sh "); out.print(s); d.n += s < 0 ? 2 : 1; return; } if (o instanceof Float) { d.append("fl ", 2); quoteToPrintWriter(str(o), out); return; } if (o instanceof Double) { d.append("d(", 3); quoteToPrintWriter(str(o), out); d.append(")"); return; } if (o instanceof BigInteger) { out.print("bigint("); out.print(o); out.print(")"); d.n += ((BigInteger) o).signum() < 0 ? 5 : 4; return; } } if (o instanceof Boolean) { d.append(((Boolean) o).booleanValue() ? "t" : "f"); return; } if (o instanceof Character) { d.append(quoteCharacter((Character) o)); return; } if (o instanceof File) { d.append("File ").append(quote(((File) o).getPath())); return; } Integer ref = d.seen.get(o); if (o instanceof String && ref == null) ref = d.strings.get((String) o); if (ref != null) { d.append("t").app(ref); return; } if (!(o instanceof String)) d.seen.put(o, d.n); else { String s = d.stringSizeLimit != 0 ? shorten((String) o, d.stringSizeLimit) : (String) o; if (!d.noStringSharing) { if (d.shareStringsLongerThan == Integer.MAX_VALUE) d.seen.put(o, d.n); if (l(s) >= d.shareStringsLongerThan) d.strings.put(s, d.n); } quoteToPrintWriter(s, d.out); d.n++; return; } if (o instanceof Set) { if (((Set) o) instanceof TreeSet) { d.append(isCISet_gen((Set) o) ? "ciset" : "treeset"); structure_1(new ArrayList((Set) o), d); return; } d.append(((Set) o) instanceof LinkedHashSet ? "lhs" : "hashset"); structure_1(new ArrayList((Set) o), d); return; } String name = c.getName(); if (o instanceof Collection && !isJavaXClassName(name)) { if (name.equals("java.util.Collections$SynchronizedList") || name.equals("java.util.Collections$SynchronizedRandomAccessList")) { d.append("sync "); { structure_1(unwrapSynchronizedList(((List) o)), d); return; } } else if (name.equals("java.util.LinkedList")) d.append("ll"); d.append("["); final int l = d.n; final Iterator it = cloneList((Collection) o).iterator(); d.stack.add(new Runnable() { public void run() { try { if (!it.hasNext()) d.append("]"); else { d.stack.add(this); if (d.n != l) d.append(", "); structure_1(it.next(), d); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!it.hasNext())\r\n d.append(\"]\");\r\n else {\r\n d.sta..."; } }); return; } if (o instanceof Map && !startsWith(name, d.mcDollar)) { if (o instanceof LinkedHashMap) d.append("lhm"); else if (o instanceof HashMap) d.append("hm"); else if (o instanceof TreeMap) d.append(isCIMap_gen((TreeMap) o) ? "cimap" : "tm"); else if (name.equals("java.util.Collections$SynchronizedMap") || name.equals("java.util.Collections$SynchronizedSortedMap") || name.equals("java.util.Collections$SynchronizedNavigableMap")) { d.append("sync "); { structure_1(unwrapSynchronizedMap(((Map) o)), d); return; } } d.append("{"); final int l = d.n; final Iterator it = cloneMap((Map) o).entrySet().iterator(); d.stack.add(new Runnable() { public boolean v = false; public Map.Entry e; public void run() { if (v) { d.append("="); v = false; d.stack.add(this); structure_1(e.getValue(), d); } else { if (!it.hasNext()) d.append("}"); else { e = (Map.Entry) it.next(); v = true; d.stack.add(this); if (d.n != l) d.append(", "); structure_1(e.getKey(), d); } } } }); return; } if (c.isArray()) { if (o instanceof byte[]) { d.append("ba ").append(quote(bytesToHex((byte[]) o))); return; } final int n = Array.getLength(o); if (o instanceof boolean[]) { String hex = boolArrayToHex((boolean[]) o); int i = l(hex); while (i > 0 && hex.charAt(i - 1) == '0' && hex.charAt(i - 2) == '0') i -= 2; d.append("boolarray ").append(n).app(" ").append(quote(substring(hex, 0, i))); return; } String atype = "array"; if (o instanceof int[]) { atype = "intarray"; } else if (o instanceof double[]) { atype = "dblarray"; } else { Pair p = arrayTypeAndDimensions(c); if (p.a == int.class) atype = "intarray"; else if (p.a == byte.class) atype = "bytearray"; else if (p.a == boolean.class) atype = "boolarray"; else if (p.a == double.class) atype = "dblarray"; else if (p.a == String.class) { atype = "array S"; d.n++; } else atype = "array"; if (p.b > 1) { atype += "/" + p.b; d.n += 2; } } d.append(atype).append("{"); d.stack.add(new Runnable() { public int i; public void run() { if (i >= n) d.append("}"); else { d.stack.add(this); if (i > 0) d.append(", "); structure_1(Array.get(o, i++), d); } } }); return; } if (o instanceof Class) { d.append("class(", 2).append(quote(((Class) o).getName())).append(")"); return; } if (o instanceof Throwable) { d.append("exception(", 2).append(quote(((Throwable) o).getMessage())).append(")"); return; } if (o instanceof BitSet) { BitSet bs = (BitSet) o; d.append("bitset{", 2); int l = d.n; for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) { if (d.n != l) d.append(", "); d.append(i); } d.append("}"); return; } if (info.javafy) { d.append("j ").append(quote(str(o))); return; } if (info.special) { if (c.isEnum()) { d.append("enum "); d.append(info.shortName); d.out.append(' '); d.append(((Enum) o).ordinal()); return; } if (info.customSerializer != null) { Object o2 = invokeMethod(info.customSerializer, o); if (o2 == o) { } else { d.append("cu "); String shortName = dropPrefix(d.mcDollar, name); d.append(shortName); d.out.append(' '); structure_1(o2, d); return; } } else if (info.nullInstances) { d.append("null"); return; } else if (info.serializeObject != null) { info.serializeObject.get(o); return; } else throw fail("unknown special type"); } String dynName = shortDynClassNameForStructure(o); if (concept && !d.concepts.contains(dynName)) { d.concepts.add(dynName); d.append("c "); } TreeSet fields = new TreeSet(new Comparator() { public int compare(Field a, Field b) { return stdcompare(a.getName(), b.getName()); } }); Class cc = c; while (cc != Object.class) { for (Field field : getDeclaredFields_cached(cc)) { if (!d.shouldIncludeField(field)) continue; String fieldName = field.getName(); if (fieldName.equals("_persistenceInfo")) d.persistenceInfo.put(c, obj -> (Map) fieldGet(field, obj)); if ((field.getModifiers() & (java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.TRANSIENT)) != 0) continue; fields.add(field); } cc = cc.getSuperclass(); } Method persistenceInfoMethod = findInstanceMethod(c, "_persistenceInfo"); if (persistenceInfoMethod != null) d.persistenceInfo.put(c, obj -> (Map) invokeMethod(persistenceInfoMethod, obj)); lFields = asList(d.honorFieldOrder ? fieldObjectsInFieldOrder(c, fields) : fields); int n = l(lFields); for (int i = 0; i < n; i++) { Field f = lFields.get(i); if (f.getName().startsWith("this$")) { lFields.remove(i); lFields.add(0, f); break; } } d.setFields(info, lFields); } else { Integer ref = d.seen.get(o); if (ref != null) { d.append("t").app(ref); return; } d.seen.put(o, d.n); } IF1 piGetter = d.persistenceInfo.get(c); Map persistenceInfo = piGetter == null ? null : piGetter.get(o); if (piGetter == null && o instanceof DynamicObject) persistenceInfo = (Map) getOptDynOnly(((DynamicObject) o), "_persistenceInfo"); LinkedHashMap fv = new LinkedHashMap(); Object defaultInstance = info.emptyInstance; for (Field f : lFields) { Object value, defaultValue = null; try { value = f.get(o); defaultValue = defaultInstance == null ? null : f.get(defaultInstance); } catch (Exception e) { value = "?"; } if (!eq(defaultValue, value) && (persistenceInfo == null || !Boolean.FALSE.equals(persistenceInfo.get(f.getName())))) fv.put(f.getName(), value); } String shortName = info.shortName; if (concept && eq(fv.get("className"), shortName)) fv.remove("className"); if (o instanceof DynamicObject) { putAll(fv, (Map) fv.get("fieldValues")); fv.remove("fieldValues"); if (((DynamicObject) o).className != null) { shortName = shortDynClassNameForStructure((DynamicObject) o); fv.remove("className"); } } d.writeObject(o, shortName, fv); } catch (Exception __e) { throw rethrow(__e); } } static public Collection allConcepts() { return db_mainConcepts().allConcepts(); } static public Collection allConcepts(Concepts concepts) { return concepts.allConcepts(); } static public long sysNow() { ping(); return System.nanoTime() / 1000000; } static public boolean isTransient(Field f) { return (f.getModifiers() & java.lang.reflect.Modifier.TRANSIENT) != 0; } static public FixedRateTimer doEvery_daemon(long delay, final Object r) { return doEvery_daemon(defaultTimerName(), delay, r); } static public FixedRateTimer doEvery_daemon(String timerName, long delay, final Object r) { return doEvery_daemon(timerName, delay, delay, r); } static public FixedRateTimer doEvery_daemon(long delay, long firstDelay, final Object r) { return doEvery_daemon(defaultTimerName(), delay, firstDelay, r); } static public FixedRateTimer doEvery_daemon(String timerName, long delay, long firstDelay, final Object r) { FixedRateTimer timer = new FixedRateTimer(true); timer.scheduleAtFixedRate(smartTimerTask(r, timer, delay), firstDelay, delay); return timer; } static public FixedRateTimer doEvery_daemon(double delaySeconds, final Object r) { return doEvery_daemon(toMS(delaySeconds), r); } static public float abs(float f) { return Math.abs(f); } static public int abs(int i) { return Math.abs(i); } static public double abs(double d) { return Math.abs(d); } static public double abs(Complex c) { return c.abs(); } static public void sleepInCleanUp(long ms) { try { if (ms < 0) return; Thread.sleep(ms); } catch (Exception __e) { throw rethrow(__e); } } static public boolean warn_on = true; static public ThreadLocal> warn_warnings = new ThreadLocal(); static public void warn(String s) { if (warn_on) print("Warning: " + s); } static public void warn(String s, List warnings) { warn(s); if (warnings != null) warnings.add(s); addToCollection(warn_warnings.get(), s); } static public A firstOfType(Collection c, Class type) { for (Object x : c) if (isInstanceX(type, x)) return (A) x; return null; } static public List conceptsOfType(String type) { return db_mainConcepts().conceptsOfType(type); } static public List concatLists_conservative(List a, List b) { if (empty(a)) return b; if (empty(b)) return a; return concatLists(a, b); } static public List concatLists_conservative(Collection a, Collection b) { if (empty(a) && b instanceof List) return ((List) b); if (empty(b) && a instanceof List) return ((List) a); return concatLists(a, b); } static public List filterByType(Iterable c, Class type) { List l = new ArrayList(); if (c != null) for (Object x : c) if (isInstanceX(type, x)) l.add((A) x); return l; } static public List filterByType(Object[] c, Class type) { return filterByType(asList(c), type); } static public List filterByType(Class type, Iterable c) { return filterByType(c, type); } static public List list(Class type) { return list(type, db_mainConcepts()); } static public List list(Class type, Concepts cc) { return cc.list(type); } static public List list(Concepts concepts, Class type) { return concepts.list(type); } static public List list(String type) { return db_mainConcepts().list(type); } static public List list(Concepts concepts, String type) { return concepts.list(type); } static public List list(Concepts concepts) { return asList(concepts.allConcepts()); } static public List filterByDynamicType(Collection c, String type) { List l = new ArrayList(); for (A x : c) if (eq(dynamicClassName(x), type)) l.add(x); return l; } static public boolean hasType(Collection c, Class type) { for (Object x : c) if (isInstanceX(type, x)) return true; return false; } static public A findBackRef(Concept c, Class type) { for (Concept.Ref r : c.backRefs) if (instanceOf(r.concept(), type)) return (A) r.concept(); return null; } static public A findBackRef(Class type, Concept c) { return findBackRef(c, type); } static public boolean checkConceptFields(Concept x, Object... data) { for (int i = 0; i < l(data); i += 2) if (neq(cget(x, (String) data[i]), deref(data[i + 1]))) return false; return true; } static public void mapRemove(Map map, A key) { if (map != null && key != null) map.remove(key); } static public B firstValue(Map map) { return first(values(map)); } static public B firstValue(MultiSetMap map) { return map == null ? null : first(firstValue(map.data)); } static public B firstValue(MultiMap map) { return map == null ? null : first(firstValue(map.data)); } static public Concept cnew(String name, Object... values) { return cnew(db_mainConcepts(), name, values); } static public Concept cnew(Concepts concepts, String name, Object... values) { Class cc = findClass(name); concepts_unlisted.set(true); Concept c; try { c = cc != null ? nuObject(cc) : new Concept(name); } finally { concepts_unlisted.set(null); } csetAll(c, values); concepts.register(c); return c; } static public A cnew(Class cc, Object... values) { return cnew(db_mainConcepts(), cc, values); } static public A cnew(Concepts concepts, Class cc, Object... values) { concepts_unlisted.set(true); A c; try { c = nuObject(cc); } finally { concepts_unlisted.set(null); } csetAll(c, values); concepts.register(c); return c; } static public int cset(Concept c, Object... values) { try { if (c == null) return 0; warnIfOddCount(values = expandParams(c.getClass(), values)); int changes = 0; for (int i = 0; i + 1 < l(values); i += 2) if (_csetField(c, (String) values[i], values[i + 1])) ++changes; return changes; } catch (Exception __e) { throw rethrow(__e); } } static public int cset(Iterable l, Object... values) { int changes = 0; for (Concept c : unnullForIteration(l)) changes += cset(c, values); return changes; } static public int cset(Concept.Ref c, Object... values) { return cset(getVar(c), values); } static public Object cget(Object c, String field) { c = derefRef(c); Object o = getOpt(c, field); return derefRef(o); } static public Object cget(String field, Object c) { return cget(c, field); } static public Object deref(Object o) { if (o instanceof IRef) return ((IRef) o).get(); return o; } static public String loadConceptsStructure(String progID) { return loadTextFilePossiblyGZipped(getProgramFile(progID, "concepts.structure")); } static public String loadConceptsStructure() { return loadConceptsStructure(dbProgramID()); } static public void cleanKillVM() { try { ping(); assertNotOnAWTThread(); cleanKillVM_noSleep(); Object o = new Object(); synchronized (o) { o.wait(); } } catch (Exception __e) { throw rethrow(__e); } } static public void cleanKillVM_noSleep() { call(getJavaX(), "cleanKill"); } static public int countConcepts(Concepts concepts, Class c, Object... params) { return concepts.countConcepts(c, params); } static public int countConcepts(Class c, Object... params) { return db_mainConcepts().countConcepts(c, params); } static public int countConcepts() { return db_mainConcepts().countConcepts(); } static public int countConcepts(String className) { return db_mainConcepts().countConcepts(className); } static public int countConcepts(Concepts concepts, String className) { return concepts.countConcepts(className); } static public int countConcepts(Concepts concepts) { return concepts.countConcepts(); } static public boolean syncAdd(Collection c, A b) { if (c == null) return false; synchronized (collectionMutex(c)) { return c.add(b); } } static public void syncAdd(List l, int idx, A b) { if (l != null) synchronized (collectionMutex(l)) { l.add(idx, b); } } static public boolean syncRemove(Collection c, A b) { if (c == null) return false; synchronized (collectionMutex(c)) { return c.remove(b); } } static public A syncRemove(List l, int idx) { if (l == null) return null; synchronized (collectionMutex(l)) { return l.remove(idx); } } static public B syncRemove(Map map, A key) { return map == null ? null : map.remove(key); } static public List syncAddOrCreate(List l, A a) { if (l == null) l = syncList(); l.add(a); return l; } static public String nConcepts(long n) { return n2(n, "concept"); } static public String nConcepts(Collection l) { return nConcepts(l(l)); } static public String nConcepts(Map map) { return nConcepts(l(map)); } static public String shortDynamicClassName(Object o) { if (o instanceof DynamicObject && ((DynamicObject) o).className != null) return ((DynamicObject) o).className; return shortClassName(o); } static public boolean dynamicObjectIsLoading() { return isUnstructuring(); } 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 void assertIsInstance(Class type, Object o) { if (!isInstance(type, o)) throw fail(_getClass(o) + " is not a subclass of " + type); } static public void assertIsInstance(Object o, Class type) { assertIsInstance(type, o); } static public boolean has(String a, String b, String c) { return false; } static public boolean has(T3 t) { return false; } static public void removeLast(List l) { if (!l.isEmpty()) l.remove(l(l) - 1); } static public void removeLast(List l, int n) { removeSubList(l, l(l) - n); } static public void removeLast(int n, List l) { removeLast(l, n); } static public A syncGet(List l, int idx) { if (l == null || idx < 0) return null; synchronized (l) { return idx < l(l) ? l.get(idx) : null; } } static public B syncGet(Map map, A a) { if (map == null) return null; synchronized (map) { return map.get(a); } } static public List addDyn_quickSync(List l, A a) { if (l == null) l = new ArrayList(); syncAdd(l, a); return l; } static public List removeDyn_quickSync(List l, A a) { if (l == null) return null; synchronized (collectionMutex(l)) { l.remove(a); return empty(l) ? null : l; } } static public void crenameField_noOverwrite(Concept c, String oldField, String newField) { if (c == null || eq(oldField, newField)) return; Object value = cget(c, oldField); if (newField != null && cget(c, newField) == null) cset(c, newField, value); cset(c, oldField, null); } static public Collection scanConceptForRefs(Concept c) { Set refs = new HashSet(); if (c != null) for (Object o : values(objectToMap(c))) { if (o instanceof Concept.Ref) refs.add((Concept.Ref) o); else if (o instanceof Concept.RefL) addAll(refs, ((Concept.RefL) o).l); } return refs; } static public double rectDistance(Rect r1, Rect r2) { double x1, x2, y1, y2; double w, h; if (r1.x > r2.x) { x1 = r2.x; w = r2.w; x2 = r1.x; } else { x1 = r1.x; w = r1.w; x2 = r2.x; } if (r1.y > r2.y) { y1 = r2.y; h = r2.h; y2 = r1.y; } else { y1 = r1.y; h = r1.h; y2 = r2.y; } double a = Math.max(0, x2 - x1 - w); double b = Math.max(0, y2 - y1 - h); return Math.sqrt(a * a + b * b); } static public boolean isSubclassOf(Class a, Class b) { return isSubclass(a, b); } static public int hashCode(Object a) { return a == null ? 0 : a.hashCode(); } static public int hashCode(long l) { return Long.hashCode(l); } static public int hashCode(double d) { return Double.hashCode(d); } static public JFastLogView_noWrap jFastLogView_noWrap() { return jFastLogView_noWrap(""); } static public JFastLogView_noWrap jFastLogView_noWrap(String text) { return withTypeWriterFont(swingNu(JFastLogView_noWrap.class, text)); } static public JTabbedPane jtabs(Object... x) { return fillJTabs(swingNu(JTabbedPane.class), x); } static public String ok(Object o) { return format("ok *", o); } static public String renderVars(Object... params) { return renderVars_str(params); } static public int indexOfInSortedArray(A[] array, A a) { return array == null ? -1 : Arrays.binarySearch(array, a); } static public List sortedKeys(Map map) { return sorted(keys(map)); } static public List sortedKeys(Object map) { return sorted(keys(map)); } static public List sortedKeys(MultiSet ms) { return sorted(keys(ms)); } static public List sortedKeys(MultiMap mm) { return sorted(keys(mm)); } static public String indentx(Object s) { return indentx(strOrEmpty(s)); } static public String indentx(String s) { return indentx(indent_default, s); } static public String indentx(int n, String s) { return dropSuffix(repeat(' ', n), indent(n, s)); } static public String indentx(String indent, String s) { return dropSuffix(indent, indent(indent, s)); } static public A replaceIfEqual(A a, A b, A c) { return eq(a, b) ? c : a; } static public String replaceRegexp(String s, String pat, IF1 f) { return regexpReplace(s, pat, f); } static public String replaceRegexp(String s, String pat, String replacement) { return regexpReplace(s, pat, replacement); } static public void setLast(List l, A a) { replaceLastElement(l, a); } static public String concatMapStrings(Object f, Iterable l) { return concatMap_strings(f, l); } static public String concatMapStrings(Object f, Object[] l) { return concatMap_strings(f, l); } static public String concatMapStrings(Iterable l, Object f) { return concatMap_strings(l, f); } static public String concatMapStrings(Iterable l, IF1 f) { return concatMap_strings(l, f); } static public String concatMapStrings(IF1 f, Iterable l) { return concatMap_strings(f, l); } static public String concatMapStrings(IF1 f, A[] l) { return concatMap_strings(f, l); } static public String curly(String s) { return optionalCurlyBrace(s); } static public String appendNewLineIfNempty(String s) { return empty(s) ? "" : s + "\n"; } static public String joinNemptiesWithEmptyLines(List l) { return joinWithEmptyLines(nempties(l)); } static public String joinNemptiesWithEmptyLines(String... l) { return joinNemptiesWithEmptyLines(asList(l)); } static public String lines_rtrim(Collection lines) { return rtrim_fromLines(lines); } static public String toJava(Object o) { return str(new ToJava().get(o)); } static public List countIteratorToList_incl(int b) { return countIteratorToList_incl(0, b); } static public List countIteratorToList_incl(int a, int b) { return countIteratorToList_inclusive(a, b); } static public List countIteratorToList_incl(int b, IF1 f) { return countIteratorToList_incl(0, b, f); } static public List countIteratorToList_incl(int a, int b, IF1 f) { return countIteratorToList_inclusive(a, b, f); } static public List countIteratorToList_incl(int a, int b, int step) { return countIteratorToList_inclusive(a, b, step); } static public List countIteratorToList_incl(double a, double b, double step, IF1 f) { return countIteratorToList_inclusive(a, b, step, f); } static public List countIteratorToList_incl(double a, double b, double step) { return countIteratorToList_inclusive(a, b, step); } static public List countIteratorToList_incl(IF1 f, double a, double b, double step) { return countIteratorToList_inclusive(f, a, b, step); } static public List countIteratorToList_incl(IF1 f, int a, int b) { return countIteratorToList_incl(f, a, b, 1); } static public List countIteratorToList_incl(IF1 f, int a, int b, int step) { return countIteratorToList_inclusive(f, a, b, step); } static public String roundBracketed(String s) { return roundBracket(s); } static public String lambdaArgsToString_pureJava(String[] args) { return l(args) == 1 ? first(args) : roundBracketed(joinWithComma(args)); } static public String lambdaArgsToString_pureJava(List args) { return lambdaArgsToString_pureJava(toStringArray(args)); } static public String joinNemptiesWithSpace(String... strings) { return joinNempties(" ", strings); } static public String joinNemptiesWithSpace(Collection strings) { return joinNempties(" ", strings); } static volatile public int numberOfCores_value; static public int numberOfCores() { if (numberOfCores_value == 0) numberOfCores_value = Runtime.getRuntime().availableProcessors(); return numberOfCores_value; } static public A popFirst(List l) { if (empty(l)) return null; A a = first(l); l.remove(0); return a; } static public A popFirst(Collection l) { if (empty(l)) return null; A a = first(l); l.remove(a); return a; } static public Pair popFirst(Map map) { if (map == null) return null; var it = map.entrySet().iterator(); if (!it.hasNext()) return null; var p = mapEntryToPair(it.next()); it.remove(); return p; } static public List popFirst(int n, List l) { List part = cloneSubList(l, 0, n); removeSubList(l, 0, n); return part; } static public AppendableChain popFirst(AppendableChain a) { return a == null ? null : a.popFirst(); } static public Chain chainPlus(Chain chain, A a) { return new Chain(a, chain); } static public Chain chainPlus(Chain chain, A... l) { for (A a : unnullForIteration(l)) chain = chainPlus(chain, a); return chain; } static public ReverseChain chainPlus(ReverseChain chain, A a) { return new ReverseChain(chain, a); } static public ReverseChain chainPlus(ReverseChain chain, A... l) { for (A a : unnullForIteration(l)) chain = chainPlus(chain, a); return chain; } static public AppendableChain chainPlus(AppendableChain chain, A a) { if (chain == null) return new AppendableChain(a); chain.add(a); return chain; } static public AppendableChain chainPlus(AppendableChain chain, A... l) { for (A a : unnullForIteration(l)) chain = chainPlus(chain, a); return chain; } static public void syncNotifyAll(Object o) { if (o != null) synchronized (o) { o.notifyAll(); } } static public boolean interruptThread_verbose = false; static public void interruptThread(Thread t) { if (t == null) return; if (interruptThread_verbose) print("Interrupting thread " + t); vm_threadInterruptionReasonsMap().put(t, getStackTrace()); t.interrupt(); URLConnection c = (URLConnection) (vm_generalSubMap("URLConnection per thread").get(t)); if (c != null) { try { print("Closing URLConnection of interrupted thread."); call(c, "disconnect"); } catch (Throwable __e) { printStackTrace(__e); } } } 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 toMS(double seconds) { return (long) (seconds * 1000); } static public long clockTimeToSystemTime(long now) { return now == 0 ? 0 : now + clockToSysTimeDiff(); } 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 int minus(int a, int b) { return a - b; } static public double minus(double a, double b) { return a - b; } static public JPanel withBorder(javax.swing.border.Border border, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(border); 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(border);\r\n p.add..."; } }); } static public int getMinimumHeight(final Component c) { return getMinimumSize(c).height; } 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 void replaceLast(List l, A a) { replaceLastElement(l, a); } static public A[] toTypedArray(Class type, Iterable c) { return toArray(c, type); } static public String formatRecordVars(String recordName, Object... params) { return renderRecordVars(recordName, params); } static public AutoCloseable tempRestoreMap(Map map) { if (map == null) return null; var cloned = cloneMap(map); return () -> copyMap(cloned, map); } static public boolean is(String a, String b) { return false; } static public String assertIdentifier(String s) { return assertIsIdentifier(s); } static public String assertIdentifier(String msg, String s) { return assertIsIdentifier(msg, s); } static public Map putOrCreateLinkedHashMap(Map map, A key, B value) { if (map == null) map = new LinkedHashMap(); map.put(key, value); return map; } static public boolean startsWithDigit(String s) { return nempty(s) && isDigit(s.charAt(0)); } static public int parseHexInt(String s) { return hexToInt(s); } 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 Chain dropFirst(Chain c) { return c == null ? null : c.next; } static public int intFromBinary(String s) { return Integer.parseInt(s, 2); } 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 float parseFloat(String s) { return Float.parseFloat(s); } static public boolean hasStaticMethodNamed(Class c, String method) { if (c == null) return false; var methods = getMethodCache(c).cache.get(method); if (methods != null) for (var m : methods) if (isStaticMethod(m)) return true; return false; } static public boolean isInterface(Class c) { return c != null && c.isInterface(); } static public Field getField(Object o, String field) { if (o == null) return null; return setOpt_findField(_getClass(o), field); } static public Object getField(Field field, Object o) { return fieldGet(field, o); } static public boolean isStaticField(Field f) { return (f.getModifiers() & Modifier.STATIC) != 0; } static public List constructorsWithNumberOfArguments(Class c, int n) { return filter(getDeclaredConstructors_cached(c), con -> l(con.getParameterTypes()) == n); } static public Object[] toArray(Collection c) { return toObjectArray(c); } static public A[] toArray(Class type, Iterable c) { return toArray(c, type); } static public A[] toArray(Class type, Collection c) { return toArray(c, type); } static public A[] toArray(Collection c, Class type) { A[] a = arrayOfType(l(c), type); if (a.length == 0) return a; asList(c).toArray(a); return a; } static public A[] toArray(Iterable c, Class type) { var c2 = asList(c); A[] a = arrayOfType(l(c2), type); if (a.length == 0) return a; c2.toArray(a); return a; } static public A[] toArray(A[] array, Collection c) { if (array == null || c == null) return null; asList(c).toArray(array); return array; } static public A[] toArrayOrNull(Class type, Collection c) { if (empty(c)) return null; return toArray(type, c); } static public Map parsePrimitiveType_map = litmap("int", int.class, "char", char.class, "byte", byte.class, "short", short.class, "long", long.class, "float", float.class, "double", double.class, "bool", boolean.class); static public Class parsePrimitiveType(String s) { return parsePrimitiveType_map.get(s); } static public boolean hasMethodNamed(Object obj, String method) { if (obj == null) return false; if (obj instanceof Class) return hasMethodNamed((Class) obj, method); return hasMethodNamed(obj.getClass(), method); } static public boolean hasMethodNamed(Class c, String method) { if (c == null) return false; return getMethodCache(c).cache.containsKey(method); } static public List reversed(Iterable l) { return reversedList(l); } static public List reversed(A[] l) { return reversedList(asList(l)); } static public String reversed(String s) { return reversedString(s); } static public Map mapWithSingleValue(Iterable l, B b) { HashMap map = new HashMap(); if (l != null) for (A a : l) map.put(a, b); return map; } static public AutoCloseable tempMapPutAll(Map map, Map toAdd) { if (map != null && nempty(toAdd)) { List> toRestore = new ArrayList(); for (var __0 : _entrySet(toAdd)) { var key = __0.getKey(); var value = __0.getValue(); if (key != null && value != null) { B old = map.put(key, value); if (!eq(old, value)) toRestore.add(pair(key, old)); } } return () -> { for (var p : toRestore) mapPutOrRemove(map, p.a, p.b); }; } return null; } static public AutoCloseable tempAdd(Collection l, A a) { if (l == null || l.contains(a)) return null; l.add(a); return new tempAdd_undo(l, a); } static public class tempAdd_undo implements AutoCloseable, IFieldsToList { public Collection l; public A a; public tempAdd_undo() { } public tempAdd_undo(Collection l, A a) { this.a = a; this.l = l; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + l + ", " + a + ")"; } public Object[] _fieldsToList() { return new Object[] { l, a }; } public void close() { try { l.remove(a); } catch (Exception __e) { throw rethrow(__e); } } } static public AutoCloseable tempAdd(Container a, Component b) { if (a == null || b == null) return null; { return swing(() -> { if (b.getParent() == a) return null; a.add(b); return () -> { swing(() -> { if (b.getParent() == a) removeFromParent(b); }); }; }); } } static public TreeSet mapToTreeSet(Object f, Iterable l) { TreeSet x = new TreeSet(); if (l != null) for (Object o : l) x.add(callF(f, o)); return x; } static public TreeSet mapToTreeSet(IF1 f, Iterable l) { TreeSet x = new TreeSet(); if (l != null) for (var o : l) x.add(f.get(o)); return x; } static public TreeSet mapToTreeSet(Iterable l, IF1 f) { return mapToTreeSet(f, l); } static public boolean isAnonymousClass(Class c) { return isAnonymousClassName(className(c)); } static public TreeSet asTreeSet(Collection set) { return set == null ? null : set instanceof TreeSet ? (TreeSet) set : new TreeSet(set); } static public boolean isAnonymousClassName(String s) { for (int i = 0; i < l(s); i++) if (s.charAt(i) == '$' && Character.isDigit(s.charAt(i + 1))) return true; return false; } static public String longestPrefixInTreeSet(String s, TreeSet set) { return longestPrefixInNavigableSet(s, set); } static public Map javaxClassShortcuts_cache; static public Map javaxClassShortcuts() { if (javaxClassShortcuts_cache == null) javaxClassShortcuts_cache = javaxClassShortcuts_load(); return javaxClassShortcuts_cache; } static public Map javaxClassShortcuts_load() { return litmap("O", "Object", "S", "String", "L", "List", "Cl", "Collection", "Int", "Integer"); } static public List itemPlus(A a, Collection l) { return itemPlusList(a, l); } static public List standardImports_fullyImportedPackages() { return endingWith_dropSuffix(standardImports(), ".*"); } static public String unquote_relaxedMLS(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); int n = s.length(); if (s.endsWith("]" + m + "]")) n -= i + 1; return s.substring(i + 1, n); } } return unquoteSingleOrDoubleQuotes(s); } static public void cMigrateField(Concept c, String oldField, String newField) { if (c == null) return; Object oldValue = cget(c, oldField); Object newValue = cget(c, newField); if (oldValue != null && newValue == null) { try { String name = shortDynName(c); print("Migrating " + name + "." + oldField + " -> " + name + "." + newField + " [id " + c.id + "]"); cset(c, newField, oldValue); cset(c, oldField, null); } catch (Throwable __e) { printStackTrace(__e); } } } static public String shortDynName(Object o) { return shortDynamicClassName(o); } static public String nLines(long n) { return n2(n, "line"); } static public String nLines(Collection l) { return nLines(l(l)); } static public String nLines(String s) { return nLines(countLines(s)); } static public String nChars(long n) { return n2(n, "char"); } static public String nChars(String s) { return nChars(l(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 dateWithMSUTC() { return dateWithMSUTC(now()); } static public String dateWithMSUTC(long time) { var format = simpleDateFormat_UTC("yyyy/MM/dd"); return format.format(time) + " " + formatUTCWithMS_24(time); } static public A getVar(IF0 v) { return v == null ? null : v.get(); } static public A getVar(Optional v) { return v == null ? null : v.orElse(null); } static public String appendPrefixIfNempty(String prefix, String s) { return prependIfNempty(prefix, s); } static public Map rsyntaxTextArea_fixNumPad_map = litmap(KeyEvent.VK_UP, KeyEvent.VK_KP_UP, KeyEvent.VK_DOWN, KeyEvent.VK_KP_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_KP_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_KP_RIGHT); static public boolean rsyntaxTextArea_fixNumPad_done = false; static public void rsyntaxTextArea_fixNumPad() { if (rsyntaxTextArea_fixNumPad_done) return; RSyntaxTextAreaDefaultInputMap inputMap = new RSyntaxTextAreaDefaultInputMap(); for (KeyStroke key : inputMap.keys()) { Integer code = rsyntaxTextArea_fixNumPad_map.get(key.getKeyCode()); if (code != null) inputMap.put(KeyStroke.getKeyStroke(code, key.getModifiers()), inputMap.get(key)); } UIManager.put("RSyntaxTextAreaUI.inputMap", inputMap); } static public RSyntaxTextArea javaxSyntaxTextArea() { return swing(new F0() { public RSyntaxTextArea get() { try { RSyntaxTextArea textArea = new RSyntaxTextArea(1, 10); initSyntaxTextArea(textArea); textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); return textArea; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "RSyntaxTextArea textArea = new RSyntaxTextArea(1, 10);\r\n initSyntaxTextAre..."; } }); } static public List getMenus(JMenuBar mb) { if (mb == null) return null; return countIteratorAsList(mb.getMenuCount(), i -> mb.getMenu(i)); } static public List getMenuItems(JMenu menu) { if (menu == null) return null; return nonNulls(countIterator(menu.getItemCount(), i -> menu.getItem(i))); } static public List getMenuItems(JPopupMenu menu) { if (menu == null) return null; return instancesOf(JMenuItem.class, asList(menu.getSubElements())); } static public void showDialogOnSameScreen(JDialog dialog, Component c) { swing(() -> { if (dialog == null) return; Window w = getWindow(c); if (w != null) centerWindowWithin(dialog, screenBounds_safe(screenNrOfWindow(w))); dialog.setVisible(true); }); } static public Font deriveFont(Font font, float size) { return font == null ? null : font.deriveFont(size); } static public List synchroLinkedList() { return synchroList(new LinkedList()); } static public A syncPopFirst(List l) { if (empty(l)) return null; synchronized (l) { A a = first(l); l.remove(0); return a; } } 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 int inc(int i) { return i + 1; } static public long inc(long l) { return l + 1; } static public String systemHashCodeHex(Object o) { return intToHex(identityHashCode(o)); } static public String nEntries(long n) { return n2(n, "entry", "entries"); } static public String nEntries(Collection l) { return nEntries(l(l)); } static public String nEntries(Map map) { return nEntries(l(map)); } static public boolean containsInstance(Iterable i, Class c) { if (i != null) for (Object o : i) if (isInstanceX(c, o)) return true; return false; } static public void register(Concept c) { registerConcept(c); } static public Value value(A a) { return new Value(a); } 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 WeakIdentityHashMap weakIdentityMap() { return weakIdentityHashMap(); } static public void clearPopupMenu(final JPopupMenu menu) { if (menu != null) { swing(() -> { menu.removeAll(); }); } } static public List nullPlus(Collection l) { return itemPlusList(null, l); } static public void setComboBoxItems_notifyListeners(JComboBox cb, Collection items) { if (cb != null) { swing(() -> { if (eq(getComboBoxItems(cb), items)) return; var sel = getSelectedItem_typed(cb); setComboBoxItems(cb, items); var item = getSelectedItem_typed(cb); if (!eq(sel, item)) { if (sel != null && contains(items, sel)) setSelectedItem(cb, sel); else { setSelectedItem(cb, (A) null); setSelectedItem(cb, item); } } }); } } static public List sortConceptsByID(Collection l) { return sortedByCalculatedField(l, c -> c.id); } static public JComboBox setSelectedItem(A item, JComboBox cb) { return selectItem(item, cb); } static public JComboBox setSelectedItem(JComboBox cb, A item) { return selectItem(cb, item); } static public JList setSelectedItem(JList list, A item) { return selectItem(list, item); } static public int lineNrToCharIndex(String s, int lineNr) { int i = 0; while (--lineNr > 0) i = smartIndexOf(s, '\n', i) + 1; return i; } static public int lengthOfLine(String text, int lineNr) { return l(getFromIterator(linesIterator(text), lineNr)); } static public A pnl(A l) { return pnl("", l); } static public A pnl(String prefix, A l) { printNumberedLines(prefix, l); return l; } static public A[] pnl(A[] l) { return pnl("", l); } static public A[] pnl(String prefix, A[] l) { printNumberedLines(prefix, l); return l; } static public A pnl(A map) { printNumberedLines(map); return map; } static public A pnl(String prefix, A map) { printNumberedLines(prefix, map); return map; } static public String pnl(String s) { printNumberedLines(lines(s)); return s; } static public MultiSet pnl(MultiSet ms) { pnl(ms == null ? null : ms.asMap()); return ms; } static public MultiMap pnl(MultiMap mm) { pnl(mm == null ? null : mm.asMap()); return mm; } 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 WatchEvent.Kind[] jdk_watchService_allEventKinds() { return new WatchEvent.Kind[] { ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY, OVERFLOW }; } static public Set synchroSet() { return synchroHashSet(); } static public Set synchroSet(Set set) { return synchronizedSet(set); } static public List findAllDirs(File dir) { List out = new ArrayList(); findAllDirs(dir, out); return out; } static public void findAllDirs(File dir, List out) { out.add(dir); try { for (File f : listFiles(dir)) if (f.isDirectory()) findAllDirs(f, out); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } static public IterableIterator reversedIterator(final List l) { return new IterableIterator() { public int i = l(l) - 1; public boolean hasNext() { return i >= 0; } public A next() { return l.get(i--); } }; } static public long longMul(long a, long b) { return a * b; } static public LineAndColumn tokenToLineAndColumn(ListAndIndex ptr) { return ptr == null ? null : tokenToLineAndColumn(ptr.list(), ptr.idx()); } static public LineAndColumn tokenToLineAndColumn(List tok, int tokenIndex) { int line = 1, col = 1; tokenIndex = min(tokenIndex, l(tok)); for (int i = 0; i < tokenIndex; i++) { String t = tok.get(i); int n = l(t); for (int j = 0; j < n; j++) if (t.charAt(j) == '\n') { ++line; col = 1; } else ++col; } return new LineAndColumn(line, col); } static public double fileAgeInSeconds(File f) { return f == null ? -1 : msToSeconds(now() - fileModificationTime(f)); } static public String nSeconds(long n) { return n2(n, "second"); } static public String nSeconds(Collection l) { return nSeconds(l(l)); } static public int iceil(double d) { return (int) Math.ceil(d); } static public boolean deleteFile(File file) { return file != null && file.delete(); } static public Path toPath(File f) { return f == null ? null : f.toPath(); } static public void printExceptionShort(Throwable e) { printExceptionShort("", e); } static public void printExceptionShort(String prefix, Throwable e) { print(prefix, exceptionToStringShort(e)); } static public File saveTextFileWithoutTemp(File file, String contents) { try { mkdirsForFile(file); var fileOutputStream = newFileOutputStream(file); try { var outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); var printWriter = new PrintWriter(outputStreamWriter); printWriter.print(unnull(contents)); printWriter.close(); return file; } finally { _close(fileOutputStream); } } catch (Exception __e) { throw rethrow(__e); } } 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 void touchExistingFile(File file) { try { if (file == null) return; java.nio.file.Files.setLastModifiedTime(toPath(file), java.nio.file.attribute.FileTime.from(java.time.Instant.now())); } 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 double elapsedMinutes_timestamp(long time) { return toMinutes(now() - time); } static public double elapsedSeconds_timestamp(long time) { return toSeconds(now() - time); } static public Type getRawType(Type t) { if (t instanceof ParameterizedType) return ((ParameterizedType) t).getRawType(); return t; } static public Timer installTimer(JComponent component, Object r, long delay) { return installTimer(component, r, delay, delay); } static public Timer installTimer(RootPaneContainer frame, long delay, Object r) { return installTimer(frame.getRootPane(), r, delay, delay); } static public Timer installTimer(JComponent component, long delay, Object r) { return installTimer(component, r, delay, delay); } static public Timer installTimer(JComponent component, long delay, long firstDelay, Object r) { return installTimer(component, r, delay, firstDelay); } static public Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay) { return installTimer(component, r, delay, firstDelay, true); } static public Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay, final boolean repeats) { if (component == null) return null; return (Timer) swingAndWait(new F0() { public Object get() { try { final Var timer = new Var(); timer.set(new Timer(toInt(delay), new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { AutoCloseable __1 = tempActivity(r); try { try { if (!allPaused()) if (isFalse(callF(r))) cancelTimer(timer.get()); } catch (Throwable __e) { printStackTrace(__e); } } finally { _close(__1); } } catch (Throwable __e) { messageBox(__e); } } })); timer.get().setInitialDelay(toInt(firstDelay)); timer.get().setRepeats(repeats); bindTimerToComponent(timer.get(), component); return timer.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final new Var timer;\r\n timer.set(new Timer(toInt(delay), actionList..."; } }); } static public Timer installTimer(RootPaneContainer frame, long delay, long firstDelay, Object r) { return installTimer(frame.getRootPane(), delay, firstDelay, r); } static public A setDoubleBuffered(A c, boolean b) { { swing(() -> { { if (c != null) c.setDoubleBuffered(b); } }); } return c; } static public Color getBackground(final Component c) { return c == null ? null : swing(new F0() { public Color get() { try { return c.getBackground(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getBackground();"; } }); } static public String md5(String text) { try { if (text == null) return "-"; return bytesToHex(md5_impl(toUtf8(text))); } catch (Exception __e) { throw rethrow(__e); } } static public String md5(byte[] data) { if (data == null) return "-"; return bytesToHex(md5_impl(data)); } static public byte[] md5_impl(byte[] data) { try { return MessageDigest.getInstance("MD5").digest(data); } catch (Exception __e) { throw rethrow(__e); } } static public String md5(File file) { return md5OfFile(file); } static public org.apache.bcel.generic.Type typeToBCELType(Type t) { return classToBCELType(getRawTypeClass(t)); } static public String typeToVMSignature(Type t) { Class c = getRawTypeClass(t); if (t instanceof ParameterizedType) { List args = map(__73 -> getRawTypeClass(__73), ((ParameterizedType) t).getActualTypeArguments()); if (nempty(args)) return classNameToByteCodeFormat(c) + "<" + joinMap(args, arg -> classNameToByteCodeFormat(arg) + ";") + ">;"; } return classNameToByteCodeFormat(c) + ";"; } static public org.apache.bcel.generic.Type classToBCELType(Class c) { if (c == null) return null; if (isPrimitiveType(c)) { if (c == byte.class) return org.apache.bcel.generic.Type.BYTE; if (c == char.class) return org.apache.bcel.generic.Type.BYTE; if (c == short.class) return org.apache.bcel.generic.Type.BYTE; if (c == int.class) return org.apache.bcel.generic.Type.INT; if (c == long.class) return org.apache.bcel.generic.Type.LONG; if (c == double.class) return org.apache.bcel.generic.Type.DOUBLE; if (c == void.class) return org.apache.bcel.generic.Type.VOID; if (c == boolean.class) return org.apache.bcel.generic.Type.BOOLEAN; throw fail("TODO: classToBCELType " + c); } if (isArrayType(c)) { int dimensions = 0; while (c.isArray()) { ++dimensions; c = c.componentType(); } return new ArrayType(classToBCELType(c), dimensions); } return new ObjectType(className(c)); } static public Object[] repArray(Object a, int n) { return arrayrep(a, n); } static public A[] repArray(Class type, A a, int n) { return arrayrep(type, a, n); } static public String formatDouble_significant2(double d, int digits) { try { digits -= max(0, Math.floor(Math.log10(abs(d)) + 1)); return formatDouble(d, digits); } catch (Throwable _e) { print("Had number: " + d + ", digits: " + digits); throw rethrow(_e); } } static public A firstKey(Map map) { return first(keys(map)); } static public A firstKey(IMultiMap map) { return map == null ? null : first(map.keySet()); } static public List syncList() { return synchroList(); } static public List syncList(List l) { return synchroList(l); } static public FontMetrics componentFontMetrics(JComponent c) { Font font = getFont(c); return font == null ? null : swing(new F0() { public FontMetrics get() { try { return c.getFontMetrics(font); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getFontMetrics(font);"; } }); } static public int idiv_ceil(int a, int b) { return (a + b - 1) / b; } static public int idiv_ceil(long a, long b) { return toInt_checked((a + b - 1) / b); } static public List asSyncList(Iterable l) { return asSynchroList(l); } static public boolean endsWithNewLine(String s) { return endsWith(s, "\n"); } static public String lines_rtrimIf(boolean rtrim, List lines) { return rtrim ? lines_rtrim(lines) : lines(lines); } static public boolean eqOrEqic(boolean caseInsensitive, String a, String b) { return caseInsensitive ? eqic(a, b) : eq(a, b); } static public boolean containsLineBreak(String s) { return containsNewLine(s); } static public List reversedList(Iterable l) { List x = cloneList(l); Collections.reverse(x); return x; } 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 NavigableSet navigableKeys(NavigableMap map) { return map == null ? new TreeSet() : map.navigableKeySet(); } static public NavigableSet navigableKeys(MultiSet ms) { return ((NavigableMap) ms.map).navigableKeySet(); } static public NavigableSet navigableKeys(MultiMap mm) { return ((NavigableMap) mm.data).navigableKeySet(); } static public Map> toMap(MultiMap m) { return multiMapToMap(m); } static public String toString(Object o) { return strOrNull(o); } static public boolean objectArraysEqual(Object[] a, Object[] b) { return arraysEqual(a, b); } static public int hashAboutObjects(Object... l) { int hash = 0, n = l(l); for (int i = 0; i < n; i++) hash = boostHashCombine(hash, hashCode(l[i])); return hash; } static public Object[] mapObjectArray(IF1 f, Object[] l) { if (empty(l)) return l; int n = l.length; Object[] a2 = new Object[n]; for (int i = 0; i < n; i++) a2[i] = f.get(l[i]); return a2; } 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 String renderRecordVars(String recordName, Object... params) { List l = new ArrayList(); int i = 0; for (; i + 1 < l(params); i += 2) l.add(params[i] + "=" + params[i + 1]); return formatFunctionCall(recordName, l); } static public String dbBotName(String progIDWithCase) { return fsI_flex(progIDWithCase) + " Concepts"; } static public Map findBot_cache = synchroHashMap(); static public int findBot_timeout = 5000; static public DialogIO findBot(String searchPattern) { String subBot = null; int i = searchPattern.indexOf('/'); if (i >= 0 && (isJavaIdentifier(searchPattern.substring(0, i)) || isInteger(searchPattern.substring(0, i)))) { subBot = searchPattern.substring(i + 1); searchPattern = searchPattern.substring(0, i); if (!isInteger(searchPattern)) searchPattern = "Multi-Port at " + searchPattern + "."; } if (isInteger(searchPattern)) return talkToSubBot(subBot, talkTo(parseInt(searchPattern))); if (eq(searchPattern, "remote")) return talkToSubBot(subBot, talkTo("second.tinybrain.de", 4999)); Integer port = findBot_cache.get(searchPattern); if (port != null) try { DialogIO io = talkTo("localhost", port); io.waitForLine(); String line = io.readLineNoBlock(); if (indexOfIgnoreCase(line, searchPattern) == 0) { call(io, "pushback", line); return talkToSubBot(subBot, io); } } catch (Exception e) { e.printStackTrace(); } List bots = quickBotScan(); for (ProgramScan.Program p : bots) { if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) { findBot_cache.put(searchPattern, p.port); return talkToSubBot(subBot, talkTo("localhost", p.port)); } } for (ProgramScan.Program p : bots) { String botName = firstPartOfHelloString(p.helloString); boolean isVM = startsWithIgnoreCase(p.helloString, "This is a JavaX VM."); boolean shouldRecurse = startsWithIgnoreCase(botName, "Multi-Port") || isVM; if (shouldRecurse) try { Map subBots = (Map) unstructure(sendToLocalBotQuietly(p.port, "list bots")); for (Number vport : subBots.keySet()) { String name = subBots.get(vport); if (startsWithIgnoreCase(name, searchPattern)) return talkToSubBot(vport.longValue(), talkTo("localhost", p.port)); } } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } return null; } static public long waitForBotStartUp_timeoutSeconds = 60; static public String waitForBotStartUp(String botName) { for (int i = 0; i < waitForBotStartUp_timeoutSeconds; i++) { sleepSeconds(i == 0 ? 0 : 1); String addr = getBotAddress(botName); if (addr != null) return addr; } throw fail("Bot not found: " + quote(botName)); } static public Object rpc(String botName, String method, Object... args) { return unstructure_matchOK2OrFail(sendToLocalBot(botName, rpc_makeCall(method, args))); } static public Object rpc(DialogIO bot, String method, Object... args) { return unstructure_matchOK2OrFail(bot.ask(rpc_makeCall(method, args))); } static public String rpc_makeCall(String method, Object... args) { if (empty(args)) return "call " + method; return format("call *", concatLists((List) ll(method), asList(args))); } static public A uniq(Class c, Object... params) { return uniqueConcept(c, params); } static public A uniq(Concepts cc, Class c, Object... params) { return uniqueConcept(cc, c, params); } static public boolean syncMapRemoveKeyAndValuePair(Map map, A key, B value) { if (map == null || key == null || value == null) return false; synchronized (collectionMutex(map)) { B actualValue = map.get(key); if (eq(actualValue, value)) { map.remove(key); return true; } return false; } } static public int seconds() { return seconds(java.util.Calendar.getInstance()); } static public int seconds(java.util.Calendar c) { return c.get(java.util.Calendar.SECOND); } static public void catchError(DoneFlag doneFlag, Runnable r) { try { { if (r != null) r.run(); } } catch (Throwable e) { doneFlag.setError(e); } } static public GrabbableIntPixels grabbableIntPixels_fastOrSlow(BufferedImage image) { try { try { GrabbableIntPixels gp = grabbableIntPixels(image); if (gp != null) return gp; } catch (Throwable __e) { printStackTrace(__e); } int w = image.getWidth(), h = image.getHeight(); int[] data = new int[w * h]; PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, w, h, data, 0, w); if (!pixelGrabber.grabPixels()) throw fail("Could not grab pixels"); return new GrabbableIntPixels(data, w, h, 0, w); } catch (Exception __e) { throw rethrow(__e); } } static public void arrayCopy(Object[] a, Object[] b) { arraycopy(a, b); } static public void arrayCopy(Object src, int srcPos, Object dest, int destPos, int n) { arraycopy(src, srcPos, dest, destPos, n); } static public boolean inRange(int x, int n) { return x >= 0 && x < n; } static public boolean inRange(int x, List l) { return inRange(x, l(l)); } static public boolean inRange(int x, int a, int b) { return x >= a && x < b; } static public int getPixel(BufferedImage img, int x, int y) { return img.getRGB(x, y); } static public int getPixel(BufferedImage img, Pt p) { return img.getRGB(p.x, p.y); } static public int limitToUByte(int i) { return max(0, min(255, i)); } static public void setPixel(BufferedImage img, int p_x, int p_y, Color color) { setPixel(img, pt(p_x, p_y), color); } static public void setPixel(BufferedImage img, Pt p, Color color) { { if (img != null) img.setRGB(p.x, p.y, colorToIntOpaque(color)); } } static public void setPixel(Graphics2D g, int p_x, int p_y, Color color) { setPixel(g, pt(p_x, p_y), color); } static public void setPixel(Graphics2D g, Pt p, Color color) { g.setColor(color); g.drawRect(p.x, p.y, 1, 1); } static public Constructor findConstructor_precise_onTypes(Class c, Class... argTypes) { try { List ctors = constructorsWithNumberOfArguments(c, l(argTypes)); Lowest best = new Lowest(); if (ctors != null) for (Constructor ctor : ctors) { int score = methodApplicabilityScore_onTypes(ctor, argTypes); if (score < Integer.MAX_VALUE) best.put(ctor, score); } return best.get(); } catch (Exception __e) { throw rethrow(__e); } } static public Method findNonStaticMethod_precise_onTypes(Object o, String method, Class... argTypes) { try { Class c = _getClass(o); if (c == null) return null; _MethodCache cache = callOpt_getCache(c); List methods = cache.cache.get(method); Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { { if (isStaticMethod(m)) continue; } int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) best.put(m, score); } return best.get(); } catch (Exception __e) { throw rethrow(__e); } } static public Method mostApplicableMethod_onTypes(Iterable methods, Class... argTypes) { Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) best.put(m, score); } return best.get(); } static public Map nonDefaultInterfaceMethods_cache = newDangerousWeakHashMap(); static public Method[] nonDefaultInterfaceMethods(Class c) { Method[] methods; synchronized (nonDefaultInterfaceMethods_cache) { methods = nonDefaultInterfaceMethods_cache.get(c); if (methods == null) nonDefaultInterfaceMethods_cache.put(c, methods = toTypedArray(Method.class, findNonDefaultInterfaceMethods(c))); } return methods; } static public Method findMethod_precise_onTypes(Object o, String method, Class... argTypes) { try { if (o instanceof Class) { _MethodCache cache = callOpt_getCache((Class) o); List methods = cache.cache.get(method); Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { { if (!(isStaticMethod(m))) continue; } int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) best.put(m, score); } return best.get(); } if (o == null) return null; _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) best.put(m, score); } return best.get(); } catch (Exception __e) { throw rethrow(__e); } } static public MultiMap descTreeMultiMap() { return new MultiMap(descTreeMap()); } static public List scoredSearch_prepare(String query) { return map(__74 -> replacePlusWithSpace(__74), splitAtSpace(query)); } static public float score(Scored s) { return s == null ? 0 : s.score(); } static public double scoredSearch_scoreWeighted2(Collection> l, List words) { double score = 0; if (l != null) for (Pair __0 : l) { String s = pairA(__0); double weight = pairB(__0); score += scoredSearch_score(s, words) * weight; } return score; } static public int scoredSearch_score(Iterable l, List words) { int score = 0; if (l != null) for (String s : l) score += scoredSearch_score(s, words); return score; } static public int scoredSearch_score(String s, List words) { int score = 0; if (nempty(s)) for (String word : unnullForIteration(words)) score += scoredSearch_score_single(s, word); return score; } static public int scoredSearch_score(String s, String query) { return scoredSearch_score(s, scoredSearch_prepare(query)); } static public List pairsB(Collection> l) { return secondOfPairs(l); } static public IterableIterator> multiMapPairIterator(MultiMap mm) { return nestedIterator(iterator(keys(mm.data)), key -> (IterableIterator>) mapI(iterator(mm.data.get(key)), val -> pair(key, val))); } static public IterableIterator> multiMapPairIterator_transformValueList(MultiMap mm, IF1, List> f) { return nestedIterator(iterator(keys(mm.data)), key -> (IterableIterator>) mapI(iterator(f.get(mm.data.get(key))), val -> pair(key, val))); } static volatile public boolean readLine_noReadLine = false; static public String readLine_lastInput; static public String readLine_prefix = "[] "; static public String readLine() { if (readLine_noReadLine) return null; String s = readLineHidden(); if (s != null) { readLine_lastInput = s; print(readLine_prefix + s); } return s; } static public String format3(String pat, Object... args) { if (args.length == 0) return pat; List tok = javaTokPlusPeriod(pat); int argidx = 0; for (int i = 1; i < tok.size(); i += 2) if (tok.get(i).equals("*")) tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null")); return join(tok); } static public String format3_formatArg(Object arg) { if (arg == null) return "null"; if (arg instanceof String) { String s = (String) arg; return isIdentifier(s) || isNonNegativeInteger(s) ? s : quote(s); } if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg); return quote(structure(arg)); } static public A printStackTrace_gen(A e) { if (e instanceof Throwable) printStackTrace((Throwable) e); else print(e); return e; } static public Color getColor(BufferedImage img, int x, int y) { return colorFromRGBA(img.getRGB(x, y)); } static public Color getColor(BufferedImage img, Pt p) { return colorFromRGBA(img.getRGB(p.x, p.y)); } static public int rgbInt(int r, int g, int b) { return (clamp(r, 0, 255) << 16) | (clamp(g, 0, 255) << 8) | clamp(b, 0, 255); } static public int rgbInt(byte r, byte g, byte b) { return (ubyteToInt(r) << 16) | (ubyteToInt(g) << 8) | ubyteToInt(b); } static public int asInt(Object o) { return toInt(o); } static public AtomicLong randomClassName_counter = new AtomicLong(); static public String randomClassName() { return "UserCode" + inc(randomClassName_counter); } static public A print_tabToSingleSpace(A o) { print(tabToSingleSpace(str(o))); return o; } static public ClassLoader myClassLoader() { return _getClass(mc()).getClassLoader(); } static public java.util.Timer doLater_daemon(long delay, final Object r) { final java.util.Timer timer = new java.util.Timer(true); timer.schedule(timerTask(r, timer), delay); return timer; } static public java.util.Timer doLater_daemon(double delaySeconds, final Object r) { return doLater_daemon(toMS(delaySeconds), r); } 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 boolean stdEq2(Object a, Object b) { if (a == null) return b == null; if (b == null) return false; if (a.getClass() != b.getClass()) return false; for (String field : allFields(a)) if (neq(getOpt(a, field), getOpt(b, field))) return false; return true; } static public int stdHash2(Object a) { if (a == null) return 0; return stdHash(a, toStringArray(allFields(a))); } static public int toIntPercent(double ratio) { return roundToInt(ratio * 100); } static public int toIntPercent(float ratio) { return toIntPercent((double) ratio); } static public String assertGlobalID(String s) { return assertPossibleGlobalID(s); } static public BigInteger bigint(String s) { return new BigInteger(s); } static public BigInteger bigint(long l) { return BigInteger.valueOf(l); } static public BigInteger mul(BigInteger a, BigInteger b) { return a.multiply(b); } static public BigInteger mul(BigInteger a, long b) { return a.multiply(bigint(b)); } static public int mul(int a, int b) { return a * b; } static public double mul(double a, double b) { return a * b; } static public String bigintToGlobalID(BigInteger value) { char[] buf = new char[16]; for (int i = 16 - 1; i >= 0; i--) { buf[i] = charPlus('a', mod(value, 26).intValue()); value = div(value, 26); } return str(buf); } static public boolean canCallWithVarargs(Object o, String method, Object... args) { if (o == null) return false; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); if (cache.findStaticMethod(method, args) != null) return true; List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs() && isStaticMethod(m))) continue; } if (massageArgsForVarArgsCall(m, args) != null) return true; } } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); if (cache.findMethod(method, args) != null) return true; List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } if (massageArgsForVarArgsCall(m, args) != null) return true; } } return false; } volatile static public boolean conceptsAndBot_running = false; static public boolean conceptsAndBot_thinOnStart = true; static public void conceptsAndBot() { conceptsAndBot(null); } static public void conceptsAndBot(Integer autoSaveInterval) { if (conceptsAndBot_running) return; conceptsAndBot_running = true; Concepts cc = db_mainConcepts(); cc.programID = getDBProgramID(); try { if (cc.useFileLock) { if (!cc.fileLock().tryToLock()) { ensureDBNotRunning(dbBotStandardName()); cc.fileLock().forceLock(); } } else ensureDBNotRunning(dbBotStandardName()); } catch (Throwable e) { printStackTrace(e); cc.dontSave = true; throw rethrow(e); } cc.persist(autoSaveInterval); dbBot(false); if (conceptsAndBot_thinOnStart) { try { thinAProgramsBackups(getDBProgramID(), true); } catch (Throwable __e) { printStackTrace(__e); } } } static public void onUpdateAndNow(JComponent c, final Object r) { onUpdate(c, r); callF(r); } static public void onUpdateAndNow(JTextComponent c, IVF1 r) { swing(() -> { if (c == null) return; onUpdate(c, r); callF(r, c.getText()); }); } static public void onUpdateAndNow(List l, Object r) { for (JComponent c : l) onUpdate(c, r); callF(r); } static public int sqr(int i) { return i * i; } static public long sqr(long l) { return l * l; } static public double sqr(double d) { return d * d; } static public float sqr(float f) { return f * f; } static public Pt rectTopLeftCorner(Rect r) { return r == null ? null : pt(r.x, r.y); } static public Rect pointsRect(int x1, int y1, int x2, int y2) { return new Rect(x1, y1, x2 - x1, y2 - y1); } static public void printVars_str(Object... params) { print(renderVars_str(params)); } static public Object getOptMC(String field) { return getOpt(mc(), field); } static public void printShortenedFunctionCall(Object fname, Object... args) { printShortenedFunctionCall(100, fname, args); } static public void printShortenedFunctionCall(int len, Object fname, Object... args) { print(shorten(len, formatFunctionCall(fname, args))); } static public JPanel vstack2(final Object... parts) { 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; smartAddWithLayout(panel, gbc, parts); gbc.weighty = 1; 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 A instaToolTip(A c, String toolTip) { return instaToolTip(toolTip, c); } static public A instaToolTip(IF0 toolTip, A c) { new InstantNeverHideToolTip(toolTip, c); return c; } static public A instaToolTip(String toolTip, A c) { new InstantNeverHideToolTip(toolTip, c); return c; } static public JLabel jImageLabel(Image img) { return swingNu(JLabel.class, imageIcon(img)); } static public JLabel jImageLabel(javax.swing.Icon icon) { return swingNu(JLabel.class, icon); } static public JLabel jImageLabel(String imageID) { return jImageLabel(imageIcon(imageID)); } static public JLabel jImageLabel(String text, String imageID) { final JLabel l = swingNu(JLabel.class, text, imageIcon(imageID), JLabel.CENTER); { swing(() -> { l.setVerticalTextPosition(SwingConstants.BOTTOM); l.setHorizontalTextPosition(SwingConstants.CENTER); }); } return l; } static public int withBottomMargin_defaultWidth = 6; static public JPanel withBottomMargin(Component c) { return withBottomMargin(withBottomMargin_defaultWidth, c); } static public JPanel withBottomMargin(final int w, final Component c) { return swing(new F0() { public JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(0, 0, w, 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 JLabel jLiveValueLabel(IF0WithChangeListeners var) { return jVarLabel(var); } static public JLabel jVarLabel(IF0WithChangeListeners var) { return bindJLabelToVar(jlabel(), var); } static public JSplitPane setSplitPaneOnFirstShowing(Component c, double value) { return setSplitPaneOnFirstShowing(c, value, 0); } static public JSplitPane setSplitPaneOnFirstShowing(Component c, double value, int delay) { final JSplitPane sp = first(childrenOfType(c, JSplitPane.class)); if (sp != null) onFirstResize(sp, new Runnable() { public void run() { try { if (delay == 0) sp.setDividerLocation(value); else awtLater(delay, new Runnable() { public void run() { try { sp.setDividerLocation(value); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "sp.setDividerLocation(value);"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef setSplitPaneOnFirstShowing_debug\r\n printVars setSplitPaneOnFirst..."; } }); return sp; } static public List wrapArrayAsList(A[] a) { return a == null ? null : Arrays.asList(a); } static public Set syncLinkedHashSet() { return synchroLinkedHashSet(); } static public ImageSurface imageSurface(BufferedImage img) { return swingNu(ImageSurface.class, img); } static public ImageSurface imageSurface(MakesBufferedImage img) { return swingNu(ImageSurface.class, img); } static public ImageSurface imageSurface() { return swingNu(ImageSurface.class); } static public String dbProgramID() { return getDBProgramID(); } static public BufferedImage toBufferedImageOpt(Object o) { if (o instanceof BufferedImage) return ((BufferedImage) o); if (o instanceof Image) return copyImage((Image) o); if (o instanceof MakesBufferedImage) return ((MakesBufferedImage) o).getBufferedImage(); String c = getClassName(o); if (eqOneOf(c, "main$BWImage", "main$RGBImage")) return (BufferedImage) call(o, "getBufferedImage"); return null; } 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 File touchFile(File file) { try { closeRandomAccessFile(newRandomAccessFile(mkdirsForFile(file), "rw")); return file; } catch (Exception __e) { throw rethrow(__e); } } static public boolean removeFile(File file) { return deleteFile(file); } 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 boolean isSpaceEtc(char c) { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } static public File fileAppendToName(File f, String suffix) { return newFile(f.getPath() + suffix); } static public A uniqueConcept(Class c, Object... params) { return uniqueConcept(db_mainConcepts(), c, params); } static public A uniqueConcept(Concepts cc, Class c, Object... params) { AutoCloseable __1 = tempDBLock(cc); try { params = expandParams(c, params); A x = findConceptWhere(cc, c, params); if (x == null) { x = unlisted(c); csetAll(x, params); cc.register(x); } else { } return x; } finally { _close(__1); } } static public AutoCloseable tempDBLock(Concepts concepts) { return tempLock(concepts.lock); } static public AutoCloseable tempDBLock() { return tempDBLock(db_mainConcepts()); } static public Object[] expandParams(Class c, Object[] params) { if (l(params) == 1) params = new Object[] { singleFieldName(c), params[0] }; else warnIfOddCount(params); return params; } static public A findConceptWhereCI(Class c, Object... params) { return findConceptWhereCI(db_mainConcepts(), c, params); } static public A findConceptWhereCI(Concepts concepts, Class c, Object... params) { params = expandParams(c, params); Lowest>> bestIndex = new Lowest(); if (concepts.ciFieldIndices != null) for (int i = 0; i < l(params); i += 2) { ping(); Object val = params[i + 1]; IFieldIndex index = concepts.getCIFieldIndex(c, (String) params[i]); if (index != null) { Collection l = index.getAll(val); bestIndex.put(() -> l, l(l)); } if (concepts.useBackRefsForSearches && val instanceof Concept) { bestIndex.put(() -> findBackRefs(((Concept) val), c), ((Concept) val)._backRefCount()); } } if (bestIndex.has()) { Collection l = bestIndex.get().get(); if (l(params) == 2) return first(l); for (A x : l) { ping(); if (checkConceptFieldsIC(x, params)) return x; } return null; } else { for (A x : concepts.list(c)) { ping(); if (checkConceptFieldsIC(x, params)) return x; } return null; } } static public Concept findConceptWhereCI(Concepts concepts, String c, Object... params) { for (Concept x : concepts.list(c)) { ping(); if (checkConceptFieldsIC(x, params)) return x; } return null; } static public A unlisted(Class c, Object... args) { concepts_unlisted.set(true); try { return nuObject(c, args); } finally { concepts_unlisted.set(null); } } static public Concept unlisted(String name, Object... args) { Class cc = findClass(name); concepts_unlisted.set(true); try { return cc != null ? nuObject(cc) : new Concept(name); } finally { concepts_unlisted.set(null); } } static public int csetAll(Concept c, Object... values) { return cset(c, values); } static public int csetAll(Iterable l, Object... values) { int n = 0; for (Concept c : unnullForIteration(l)) n += cset(c, values); return n; } static public int csetAll(Concept c, Map values) { int n = 0; for (Map.Entry __0 : _entrySet(values)) { String field = __0.getKey(); Object value = __0.getValue(); n += cset(c, field, value); } return n; } static public String dropNumberPrefix(String s) { return dropFirst(s, indexOfNonDigit(s)); } static public String conceptsFileName() { return "concepts.structure.gz"; } static public List listDirs(File dir) { if (dir == null) return emptyList(); File[] files = dir.listFiles(); List l = new ArrayList(); if (files != null) for (File f : files) if (f.isDirectory()) l.add(f); return l; } static public List listDirs(String dir) { return listDirs(newFile(dir)); } static public void close_pcall(AutoCloseable c) { if (c != null) { try { c.close(); } catch (Throwable __e) { printStackTrace(__e); } } } static public void preCleanUp(Object c) { if (c instanceof Collection) { for (Object o : ((Collection) c)) preCleanUp(o); return; } callOpt(c, "licensed_off"); setOpt_raw(c, "ping_anyActions", true); setOpt_raw(c, "cleaningUp_flag", true); } static public void innerCleanUp(Object c) { if (!isFalse(pcallOpt(c, "cleanMeUp"))) for (String name : sorted(methodsStartingWith(c, "cleanMeUp_"))) try { callOpt(c, name); } catch (Throwable e) { print("Error cleaning up: " + programID(c)); _handleException(e); } } static public void innerCleanUp() { innerCleanUp(mc()); } static public Object pcallOpt(Object o, String method, Object... args) { try { return callOpt(o, method, args); } catch (Throwable __e) { printStackTrace(__e); } return null; } static public List registeredThreads(Object o) { Map map = (Map) (getOpt(o, "_registerThread_threads")); if (map == null) return ll(); map.size(); synchronized (map) { return asList(keys(map)); } } static public List registeredThreads() { _registerThread_threads.size(); return asList(keys(_registerThread_threads)); } static public void interruptThreads(Collection threads) { for (Thread t : unnull(threads)) interruptThread(t); } static public void interruptThreads(Class mainClass) { interruptThreads(registeredThreads(mainClass)); } static public void retireClassLoader(ClassLoader cl) { try { if (isJavaXClassLoader(cl)) setOptAll(cl, "retired", true, "retiredMarker", new DefunctClassLoader()); } catch (Throwable __e) { printStackTrace(__e); } } static public A findConceptWhere(Class c, Object... params) { return findConceptWhere(db_mainConcepts(), c, params); } static public A findConceptWhere(Concepts concepts, Class c, Object... params) { ping(); params = expandParams(c, params); if (concepts.fieldIndices != null) for (int i = 0; i < l(params); i += 2) { IFieldIndex index = concepts.getFieldIndex(c, (String) params[i]); if (index != null) { for (A x : index.getAll(params[i + 1])) if (checkConceptFields(x, params)) return x; return null; } } for (A x : concepts.list(c)) if (checkConceptFields(x, params)) return x; return null; } static public Concept findConceptWhere(Concepts concepts, String c, Object... params) { for (Concept x : concepts.list(c)) if (checkConceptFields(x, params)) return x; return null; } 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 AutoCloseable tempOnChangeAndNow(IHasChangeListeners src, Runnable listener) { if (src == null || listener == null) return null; src.onChangeAndNow(listener); return () -> src.removeChangeListener(listener); } static public double positiveInfinity() { return Double.POSITIVE_INFINITY; } 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 Set evalWithTimeout_inTime = synchroSet(); static public Set evalWithTimeout_allThreads = newWeakHashSet(); static public ThreadLocal evalWithTimeout_threadName = new ThreadLocal(); static public Either evalWithTimeout(double timeoutSeconds, IF0 r) { return (Either) evalWithTimeout(timeoutSeconds, (Object) r); } static public Either evalWithTimeout(int timeoutMS, Object r) { return evalWithTimeout(toSeconds(timeoutMS), r); } static public Either evalWithTimeout(double timeoutSeconds, Object r) { final Flag done = new Flag(); final Flag doneWaiting = new Flag(); final Var var = new Var(); final Var error = new Var(); var printer = print_byThread().get(); Thread t = newThread(getAndClearThreadLocal(evalWithTimeout_threadName), new Runnable() { public void run() { try { try { AutoCloseable __1 = tempSetTL(print_byThread(), printer); try { try { var.set(callF(r)); } finally { evalWithTimeout_allThreads.remove(currentThread()); } } finally { _close(__1); } } catch (Throwable e) { error.set(e); if (doneWaiting.isUp()) printStackTrace_inPossiblyCancelledThread(e); } finally { done.raise(); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n temp tempSetTL(print_byThread(), printer);\r\n \r\n try {\r..."; } }); beforeDelegatingToThread(t); try { startThread(t); evalWithTimeout_inTime.add(t); evalWithTimeout_allThreads.add(t); try { done.waitUntilUp(timeoutSeconds); doneWaiting.raise(); } finally { evalWithTimeout_inTime.remove(t); } if (!done.isUp()) { print("Cancelling thread (timeout)"); cancelAndInterruptThread(t); return either2(t); } if (error.get() != null) rethrow(error.get()); return either1(var.get()); } finally { afterDelegatingToThread(t); } } static public WeakReference creator_class; static public Object creator() { return creator_class == null ? null : creator_class.get(); } static public void openPlatformBrowser(String url) { try { if (isHeadless()) return; print("Opening platform-specific browser on: " + url); Desktop.getDesktop().browse(uri(url)); } catch (Exception __e) { throw rethrow(__e); } } static public void openPlatformBrowser(URL url) { if (url == null) return; openPlatformBrowser(str(url)); } static public File findCmdOnPATH(String cmd) { String path = System.getenv("PATH"); List dirs = splitAt(path, File.pathSeparator); String c = isWindows() ? addSuffix(cmd, ".exe") : cmd; for (String dir : dirs) { File f = new File(dir, c); if (f.isFile()) return f; } return null; } public static boolean isWindows() { return System.getProperty("os.name").contains("Windows"); } static public File windowsFindChromeExe() { return windowsFindExe("Google\\Chrome\\Application\\chrome.exe"); } static public boolean isMac() { return System.getProperty("os.name").toLowerCase().contains("mac"); } static public String firstCmdOnPATH_mandatory(String... cmds) { for (String cmd : cmds) if (onPATH(cmd)) return cmd; throw fail("None of the commands found on PATH: " + asList(cmds)); } static public boolean isRootUser() { return eq(System.getProperty("user.name"), "root"); } public static String winQuote(String text) { if (text == null) return null; return "\"" + text.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r") + "\""; } static public String winQuote(File f) { return winQuote(f.getAbsolutePath()); } static public String bashQuote(String text) { if (text == null) return null; return "\"" + text.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r") + "\""; } static public String bashQuote(File f) { return bashQuote(f.getAbsolutePath()); } static public String nohup_sanitize(String s) { return empty(s) ? s : takeFirst(50, s.replaceAll("[^.a-zA-Z0-9\\-_]", "")); } static public String loadTextFileResource(ClassLoader cl, String name) { return inputStreamToString(cl.getResourceAsStream(name)); } static public ClassLoader classLoader(Object o) { return classLoaderForObject(o); } static public IF0 ping_v3_pingSourceMaker_cache; static public IF0 ping_v3_pingSourceMaker() { if (ping_v3_pingSourceMaker_cache == null) ping_v3_pingSourceMaker_cache = ping_v3_pingSourceMaker_load(); return ping_v3_pingSourceMaker_cache; } static public IF0 ping_v3_pingSourceMaker_load() { return or((IF0) vm_generalMap_get("ping_v3_pingSourceMaker"), () -> null); } 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 A parentOfType(Component _c, Class theClass) { return swing(() -> { Component c = _c; while (c != null) { if (isInstance(theClass, c)) return (A) c; c = c.getParent(); } return null; }); } static public Object interceptPrintInThisThread(Object f) { Object old = print_byThread().get(); print_byThread().set(f); return old; } static public OKOrError OKOrError_ok(A a) { return new OKOrError(a); } static public OKOrError OKOrError_error(Throwable e) { return new OKOrError(false, e); } static public IF0 runnableToIF0(Runnable r) { return r == null ? null : () -> { r.run(); return null; }; } static public double nanoSecondsToSeconds(double nanos) { return nanos * 1e-9; } static public void setSCPComponent(SingleComponentPanel scp, Component c) { if (scp != null) scp.setComponent(c); } 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 MouseAdapter leftClickMouseAdapter(final Object r) { return new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() == 1) pcallF(r, new Pt(e.getPoint())); } }; } static public MouseAdapter leftClickMouseAdapter_noPt(final Object r) { return new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() == 1) pcallF(r); } }; } 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 JScrollPane borderlessScrollPane(JScrollPane sp) { return setBorder(null, withoutViewportBorder(sp)); } static public JScrollPane jHigherScrollPane(final JComponent c) { return swing(new F0() { public JScrollPane get() { try { return new JScrollPane(c) { public Dimension getPreferredSize() { Component view = getViewport().getView(); if (view == null) return super.getPreferredSize(); int pref_width = view.getPreferredSize().width; setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); Dimension dim = new Dimension(pref_width, super.getPreferredSize().height + getHorizontalScrollBar().getSize().height); setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); return dim; } }; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret new JScrollPane(c) {\r\n public Dimension getPreferredSize() {\r\n Co..."; } }); } static public A onFirstShow(A component, Runnable onShow) { return onFirstComponentShow(component, onShow); } static public A onFirstShow(Runnable onShow, A component) { return onFirstShow(component, onShow); } static public void clearTextComponentUndoList(JTextComponent c) { swing(() -> { if (c instanceof RSyntaxTextArea) { ((RSyntaxTextArea) c).discardAllEdits(); return; } UndoManager undo = (UndoManager) (metaGet(c, "UndoManager")); if (undo != null) undo.discardAllEdits(); }); } static public int charToKeyCode(char c) { c = lower(c); assertTrue(c >= 'a' && c <= 'z'); return charDiff(c, 'a') + KeyEvent.VK_A; } static public SingleThread awtCalcRegularly(JComponent component, int delay, int firstDelay, Object runnable) { final SingleThread thread = new SingleThread(); final Runnable r2 = addThreadInfoToRunnable(runnable); final Object info = _threadInfo(); installTimer(component, delay, firstDelay, new Runnable() { public void run() { if (!licensed()) return; _threadInheritInfo(info); thread.go(r2); } }); return thread; } static public SingleThread awtCalcRegularly(JFrame frame, int delay, int firstDelay, final Object runnable) { return awtCalcRegularly(getRootPane(frame), delay, firstDelay, runnable); } static public JPanel jSection(Component c) { return jSection("", c); } static public JPanel jSection(final String title, final Component c) { return swing(new F0() { public JPanel get() { try { Border border = BorderFactory.createBevelBorder(BevelBorder.LOWERED); border = BorderFactory.createTitledBorder(border, title); JSection panel = new JSection(c); panel.setBorder(border); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Border border = BorderFactory.createBevelBorder(BevelBorder.LOWERED);\r\n bo..."; } }); } static public JPanel jSection(String title) { return jSection(title, jpanel()); } static public JPanel jSection(LiveValue lv, Component c) { return jLiveValueSection(lv, c); } static public int defaultMargin() { return withMargin_defaultWidth; } static public boolean isComponentShowing(final Component c) { return c != null && swing(new F0() { public Boolean get() { try { return c.isShowing(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.isShowing();"; } }); } static public boolean isInQ(Q q) { return q != null && isCurrentThread(q.rst.thread); } static public A activateFrameAndReturnComponent(A c) { activateFrame(c); return c; } static public JTextArea newTypeWriterTextArea() { return newTypeWriterTextArea(""); } static public JTextArea newTypeWriterTextArea(String text) { return withTypeWriterFont(jTextArea(text)); } static public String hijackPrint(Runnable r) { StringBuilder buf = new StringBuilder(); Object old = interceptPrintInThisThread(new F1() { public Boolean get(String s) { buf.append(s); return false; } }); try { { if (r != null) r.run(); } return str(buf); } finally { interceptPrintInThisThread(old); } } static public Map> multiMapToMap(MultiMap m) { return m == null ? null : m.data; } static public TreeMap asCIMap(Map map) { return asCaseInsensitiveMap(map); } static public boolean isStandardFunction(String name) { return isIdentifier(name) && stdFunctions_cached().containsKey(name); } static public boolean isStandardClass(String name) { return isIdentifier(name) && standardClassesMap_cached().containsKey(name); } static public String resolveKeyIC(Map map, String key) { return resolveKeyCI(map, key); } static public Map stdFunctions_cached_map; static public Lock stdFunctions_cached_lock = lock(); static public Map stdFunctions_cached() { Lock __0 = stdFunctions_cached_lock; lock(__0); try { if (stdFunctions_cached_map == null) stdFunctions_cached_map = stdFunctions_uncached(); return stdFunctions_cached_map; } finally { unlock(__0); } } static synchronized public void stdFunctions_clearCache() { stdFunctions_cached_map = null; } static public Map stdClasses_cached() { return standardClassesMap_cached(); } static public String sfSnippet(String function) { return stdFunctions_cached().get(function); } static public String scSnippet(String name) { return stdClasses_cached().get(name); } 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 JWindow makeUnimportantWindow(final Component c) { return swing(new F0() { public JWindow get() { try { Map map = (Map) (vm_generalMap_get("unimportant windows")); if (map == null) vm_generalMap_put("unimportant windows", map = (Map) callJavaX("newWeakHashMap")); JWindow w = makeWindow(c); map.put(w, true); return w; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Map map = cast vm_generalMap_get(\"unimportant windows\");\r\n if (map == null..."; } }); } static public JLabel flatInfoBox_makePanel(String text) { return jlabel(text); } static public int methodApplicabilityScore_withPrimitiveWidening(Executable m, Object[] args) { Class[] types = m.getParameterTypes(); if (types.length != l(args)) return Integer.MAX_VALUE; int score = 0; boolean widenings = false; for (int i = 0; i < types.length; i++) { Object a = args[i]; Class c = types[i]; if (a == null) { if (c.isPrimitive()) return Integer.MAX_VALUE; } else { Class t = a.getClass(); int s = typeConversionScoreWithUnboxing(t, c); if (s == Integer.MAX_VALUE) return Integer.MAX_VALUE; if (s < 0) widenings = true; score += abs(s); } } return widenings ? -score : score; } static public Object invokeConstructorWithWidening(Constructor m, Object... args) { try { try { Class[] types = m.getParameterTypes(); int n = types.length; Object[] args2 = new Object[n]; for (int i = 0; i < n; i++) args2[i] = convertPrimitiveIfNecessary(args[i], types[i]); return m.newInstance(args2); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args))); } } catch (Exception __e) { throw rethrow(__e); } } static public String hostToIP(String host) { try { for (InetAddress a : InetAddress.getAllByName(host)) { String ip = a.getHostAddress(); if (isIPv4(ip)) return ip; } throw fail("No IP address found for " + host); } catch (Exception __e) { throw rethrow(__e); } } static public Object callWithVarargs(Object o, String method, Object... args) { return call_withVarargs(o, method, args); } static public _MethodCache getMethodCache(Class c) { return callOpt_getCache(c); } static public int methodApplicabilityScore_withPrimitiveWidening_onTypes(Executable m, Class[] argTypes) { Class[] types = m.getParameterTypes(); if (types.length != l(argTypes)) return Integer.MAX_VALUE; int score = 0; boolean widenings = false; for (int i = 0; i < types.length; i++) { Class t = argTypes[i]; Class c = types[i]; int s = typeConversionScoreWithUnboxing(t, c); if (s == Integer.MAX_VALUE) return Integer.MAX_VALUE; if (s < 0) widenings = true; score += abs(s); } return widenings ? -score : score; } static public Method findSingleInterfaceMethod(Class intrface) { return singletonOpt(findNonDefaultInterfaceMethods(intrface)); } static public Object convertPrimitiveIfNecessary(Object o, Class b) { if (b.isPrimitive()) { if (o instanceof Character) { char x = (char) (((Character) o)); if (b == int.class) return Integer.valueOf(x); if (b == long.class) return Long.valueOf(x); if (b == float.class) return Float.valueOf(x); if (b == double.class) return Double.valueOf(x); } else if (o instanceof Number) { if (b == char.class) return Character.valueOf((char) ((Number) o).intValue()); if (b == short.class) return ((Number) o).shortValue(); if (b == int.class) return ((Number) o).intValue(); if (b == long.class) return ((Number) o).longValue(); if (b == float.class) return ((Number) o).floatValue(); } } return o; } static public IterableIterator emptyItIt() { return emptyIterableIterator(); } static public IterableIterator arrayIterator(A[] l) { return l == null ? null : new IterableIterator() { public int i = 0; public boolean hasNext() { return i < l.length; } public A next() { return l[i++]; } }; } static public IterableIterator iff(Object f) { return iteratorFromFunction_withEndMarker(f); } static public IterableIterator iff(F0 f) { return iteratorFromFunction_withEndMarker(f); } static public IterableIterator iff(IF0 f) { return iteratorFromFunction_withEndMarker(f); } static public Object endMarker() { return iteratorFromFunction_endMarker; } 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 AutoCloseable tempSetField(Object o, String field, Object value) { final Object oldValue = get(o, field); set(o, field, value); return () -> set(o, field, oldValue); } static public AutoCloseable tempSetField(ISetAndGet gs, A value) { if (gs == null) return null; A oldValue = gs.get(); gs.set(value); return () -> gs.set(oldValue); } static public AutoCloseable tempSetField(A value, ISetAndGet gs) { return tempSetField(gs, value); } static public Map makeObjectMetaMap() { return new CompactHashMap(); } static public IAutoCloseableF0 tempMetaMutex(IMeta o) { return o == null ? null : o._tempMetaMutex(); } static public void syncMapPut2(Map map, A key, B value) { if (map != null && key != null) synchronized (collectionMutex(map)) { if (value != null) map.put(key, value); else map.remove(key); } } static public String withIdentity(Object o, String s) { return withIdentityHash(o, s); } static public B getOrCreate(Map map, A key, Class c) { try { B b = map.get(key); if (b == null) map.put(key, b = c.newInstance()); return b; } catch (Exception __e) { throw rethrow(__e); } } static public B getOrCreate(Map map, A key, Object f) { try { B b = map.get(key); if (b == null) map.put(key, b = (B) callF(f)); return b; } catch (Exception __e) { throw rethrow(__e); } } static public B getOrCreate(IF0 f, Map map, A key) { return getOrCreate(map, key, f); } static public B getOrCreate(Map map, A key, IF0 f) { B b = map.get(key); if (b == null) map.put(key, b = f.get()); return b; } static public B getOrCreate(Class c, Map map, A key) { return getOrCreate(map, key, c); } static public int lKeys(MultiMap mm) { return mm == null ? 0 : mm.keysSize(); } 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 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 ReliableSingleThread rstWithDelay(final int delay, final Runnable r) { return new ReliableSingleThread(new Runnable() { public void run() { try { sleep(delay); callF(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "sleep(delay);\r\n callF(r);"; } }); } static public ReliableSingleThread rstWithDelay(double seconds, Runnable r) { return rstWithDelay(toMS_int(seconds), r); } static public Rect mergeRects(List l) { Rect r = first(l); for (int i = 1; i < l(l); i++) r = rectUnion(r, l.get(i)); return r; } static public Rect mergeRects(Rect a, Rect b) { return rectUnion(a, b); } static public List listChildren(Container c) { return getChildren(c); } static public ThreadLocal imageGraphics_antiAlias = new ThreadLocal(); static public Graphics2D imageGraphics(BufferedImage img) { return !isFalse(imageGraphics_antiAlias.get()) ? antiAliasGraphics(img) : createGraphics(img); } static public ThreadLocal currentImage_var = new ThreadLocal(); static public BufferedImage currentImage() { return currentImage_var.get(); } static public void currentImage(BufferedImage img) { currentImage_var.set(img); } 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 "return call(o, method, args);"; } }); } static public Pt centerOfRect(Rect r) { return r == null ? null : new Pt(r.x + r.w / 2, r.y + r.h / 2); } static public List instancesOf(Iterable i, Class c) { return collectInstances(i, c); } static public List instancesOf(Class c, Iterable i) { return collectInstances(c, i); } static public List getChildren(final Container c) { return c == null ? emptyList() : swing(new F0>() { public List get() { try { return asList(c.getComponents()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return asList(c.getComponents());"; } }); } 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, Object onChange) { JCheckBox cb = jCheckBox(text, checked); 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 JCheckBox jCheckBox(boolean checked, String text, IVF1 onChangeAndNow) { var cb = jCheckBox(text, checked); onChangeAndNow(cb, new Runnable() { public void run() { try { onChangeAndNow.get(isChecked(cb)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "onChangeAndNow.get(isChecked(cb));"; } }); return cb; } static public A bindCheckBoxToLiveValue(A cb, SimpleLiveValue lv) { bindChangeListenerToComponent(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: ..."; } }); 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: ..."; } }); return cb; } static public A bindCheckBoxToLiveValue(A cb, IVarWithNotify lv) { bindChangeListenerToComponent(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: ..."; } }); 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: ..."; } }); return cb; } static public JSlider liveSlider(int min, int max, int value, IVF1 onChange) { return swing(() -> { JSlider slider = new JSlider(min, max, value); slider.addChangeListener(new ChangeListener() { public int lastValue = slider.getValue(); public void stateChanged(ChangeEvent e) { int value = slider.getValue(); if (value != lastValue) { lastValue = value; setToolTip(slider, str(value)); pcallF(onChange, value); } } }); return slider; }); } static public float clamp(float x, float a, float b) { return x < a ? a : x > b ? b : x; } static public double clamp(double x, double a, double b) { return x < a ? a : x > b ? b : x; } static public int clamp(int x, int a, int b) { return x < a ? a : x > b ? b : x; } static public long clamp(long x, long a, long b) { return x < a ? a : x > b ? b : x; } static public AutoCloseable tempIncAtomicInt(AtomicInteger v) { if (v == null) return null; incAtomicInt(v); return new AutoCloseable() { public String toString() { return "decAtomicInt(v);"; } public void close() throws Exception { decAtomicInt(v); } }; } static public void setSliderValue(JSlider slider, int value) { if (slider != null) { swing(() -> { slider.setValue(clamp(value, slider.getMinimum(), slider.getMaximum())); }); } } 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 JPanel jRightAlignedButtons(Object... params) { List l = new ArrayList(); for (int i = 0; i < l(params); i += 2) if (params[i] != null) if (params[i] instanceof JComponent) l.add((JComponent) params[i--]); else l.add(jbutton((String) params[i], params[i + 1])); return jRightAlignedLine(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 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 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 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 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 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 JScrollPane jscroll_centered(Component c) { return c instanceof JScrollPane ? ((JScrollPane) c) : jscroll(jFullCenter(c)); } static public List wrapObjectArrayAsImmutableList(A[] array) { if (array == null) return null; int n = Array.getLength(array); return new RandomAccessAbstractList() { public int size() { return n; } public A get(int i) { return array[i]; } }; } static public List wrapPrimitiveArrayAsImmutableList(Object array) { int n = Array.getLength(array); return new RandomAccessAbstractList() { public int size() { return n; } public Object get(int i) { return Array.get(array, i); } }; } 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 A centerLabel(A l) { if (l != null) l.setHorizontalAlignment(SwingConstants.CENTER); return l; } static public JLabel jnarrowLabel() { return jnarrowLabel(50); } static public JLabel jnarrowLabel(int width) { return jnarrowLabel(width, ""); } static public JLabel jnarrowLabel(String text) { return jnarrowLabel(50, text); } static public JLabel jnarrowLabel(int width, String text) { return jMinWidth_pure(width, jlabel(text)); } static public JLabel jnarrowLabel(JLabel lbl) { return jnarrowLabel(50, lbl); } static public JLabel jnarrowLabel(int width, JLabel lbl) { return jMinWidth_pure(width, lbl); } static public A setHorizontalAlignment(final int pos, final A a) { swingCall(a, "setHorizontalAlignment", pos); return a; } static public A setHorizontalAlignment(final int pos, final A a) { swingCall(a, "setHorizontalAlignment", pos); return a; } static public A setHorizontalAlignment(final int pos, final A a) { swingCall(a, "setHorizontalAlignment", pos); return a; } static public JLabel jLabel(String text) { return jlabel(text); } static public JLabel jLabel() { return jlabel(); } static public char charAt(String s, int i) { return s != null && i >= 0 && i < s.length() ? s.charAt(i) : '\0'; } static public String regexpN2() { return "\\d+(?:,\\d+)*"; } static public List regexpLastGroupsIC(String pat, String s) { if (s == null) return null; Matcher m = regexpIC(pat, s); List groups = null; while (m.find()) groups = regexpGetGroups(m); return groups; } static public int parseIntN2(String s) { return parseInt(replace(s, ",", "")); } static public ClassLoader getClassLoader(Object o) { return o == null ? null : _getClass(o).getClassLoader(); } static public boolean dirOrZipContainsPath(File location, String subPath) { try { if (location.isDirectory()) { return new File(location, subPath).exists(); } else if (location.isFile()) { return zipFileContains_falseOnError(location, subPath); } return false; } catch (Exception __e) { throw rethrow(__e); } } static public File[] listFiles(File dir) { File[] files = dir.listFiles(); return files == null ? new File[0] : files; } static public File[] listFiles(String dir) { return listFiles(new File(dir)); } static public String dropPrefixOrNull(String prefix, String s) { return s != null && s.startsWith(prefix) ? s.substring(l(prefix)) : null; } static public List loadedJigsawModuleNames() { var moduleLayer = ModuleLayer.boot(); var modules = moduleLayer.modules(); return map(modules, mod -> mod.getName()); } static public List classNamesInJigsawModule(String moduleName) { return classNamesInJigsawModule(moduleName, javaHome()); } static public List classNamesInJigsawModule(String moduleName, File javaHome) { return classNamesInJarOrDir(jigsawModuleFile(moduleName, javaHome), "classes/"); } static public int randomID_defaultLength = 12; static public String randomID(int length) { return makeRandomID(length); } static public String randomID(Random r, int length) { return makeRandomID(r, length); } static public String randomID() { return randomID(randomID_defaultLength); } static public String randomID(Random r) { return randomID(r, randomID_defaultLength); } static public int globalIDLength() { return 16; } static public BufferedImage newBufferedImage(int w, int h) { return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); } static public BufferedImage newBufferedImage(int w, int h, RGB rgb) { return newBufferedImage(w, h, rgb.getColor()); } static public BufferedImage newBufferedImage(int w, int h, Color color) { BufferedImage img = newBufferedImage(w, h); Graphics2D g = img.createGraphics(); g.setColor(or(color, Color.white)); g.fillRect(0, 0, w, h); return img; } static public BufferedImage newBufferedImage(Pt p, Color color) { return newBufferedImage(p.x, p.y, color); } static public BufferedImage newBufferedImage(int w, int h, int[] pixels) { return intArrayToBufferedImage(pixels, w, h); } 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 String defaultFrameTitle() { return autoFrameTitle(); } static public void defaultFrameTitle(String title) { autoFrameTitle_value = title; } static public void registerEscape(JFrame frame, final Runnable r) { registerEscape_rootPane(frame.getRootPane(), r); } static public void inputFilePath(final String msg, final Object action) { inputFilePath(msg, userDir(), action); } static public void inputFilePath(final String msg, final File defaultFile, final Object action) { swingLater(new Runnable() { public void run() { try { final JTextField tfPath = jtextfield(f2s(or(defaultFile, userDir()))); String title = joinStrings(" | ", msg, programName()); JComponent form = showFormTitled(title, unnull(msg), centerAndEast(tfPath, jbutton("Browse...", new Runnable() { public void run() { try { JFileChooser fileChooser = new JFileChooser(getTextTrim(tfPath)); if (fileChooser.showOpenDialog(tfPath) == JFileChooser.APPROVE_OPTION) { tfPath.setText(fileChooser.getSelectedFile().getAbsolutePath()); tfPath.requestFocus(); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JFileChooser fileChooser = new JFileChooser(getTextTrim(tfPath));\r\n if..."; } })), new Runnable() { public void run() { try { callF(action, new File(getTextTrim(tfPath))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(action, new File(getTextTrim(tfPath)))"; } }); renameSubmitButton(form, "OK"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JTextField tfPath = jtextfield(f2s(or(defaultFile, userDir())));\r\n S..."; } }); } static public boolean hasJPEGExtension(File f) { return ewicOneOf(fileName(f), ".jpg", ".jpeg"); } static public void saveJPG(BufferedImage img, File file) { try { if (!ImageIO.write(img, "jpeg", mkdirsFor(file))) { print("Reconstructing image for saving JPEG"); img = reconstructBufferedImage(img); if (!ImageIO.write(img, "jpeg", file)) throw fail("Couldn't write JPEG: " + file + " (" + img + ")"); } vmBus_send("wroteFile", file); } catch (Exception __e) { throw rethrow(__e); } } static public void saveJPG(File file, BufferedImage img) { try { saveJPG(img, file); } catch (Exception __e) { throw rethrow(__e); } } static public void savePNG(BufferedImage img, File file) { try { File tempFile = new File(file.getPath() + "_temp"); CriticalAction ca = beginCriticalAction("Save " + f2s(file)); try { ImageIO.write(img, "png", mkdirsFor(tempFile)); file.delete(); tempFile.renameTo(file); } finally { ca.done(); } } catch (Exception __e) { throw rethrow(__e); } } static public void savePNG(String file, BufferedImage img) { savePNG(toFile(file), img); } static public void savePNG(File file, BufferedImage img) { savePNG(img, file); } static public void savePNG(File file, RGBImage img) { savePNG(file, img.getBufferedImage()); } static public JComponent selectSnippetID_v1(final VF1 onSelect) { return selectSnippetID_v1("#", onSelect); } static public JComponent selectSnippetID_v1(String defaultID, final VF1 onSelect) { final JTextField tfSnippetID = jtextfield(defaultID); if (eq(defaultID, "#")) moveCaretToEnd(tfSnippetID); JComponent panel; renameSubmitButton(panel = showTitledForm("Select Snippet", "Snippet ID:", tfSnippetID, runnableThread(new Runnable() { public void run() { try { callF(onSelect, fsI(getTextTrim(tfSnippetID))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onSelect, fsI(getTextTrim(tfSnippetID)));"; } })), "Select snippet"); return panel; } static public BufferedImage cloneBufferedImage(BufferedImage image) { return copyImage(image); } static public BufferedImage clipBufferedImage(BufferedImage src, Rectangle clip) { return clipBufferedImage(src, new Rect(clip)); } static public BufferedImage clipBufferedImage(BufferedImage src, Rect r) { if (src == null || r == null) return null; r = intersectRects(r, new Rect(0, 0, src.getWidth(), src.getHeight())); if (rectEmpty(r)) return null; return src.getSubimage(r.x, r.y, r.w, r.h); } static public BufferedImage clipBufferedImage(BufferedImage src, int x, int y, int w, int h) { return clipBufferedImage(src, new Rect(x, y, w, h)); } static public Object getTransferData(Transferable t, DataFlavor flavor) { try { return t != null && t.isDataFlavorSupported(flavor) ? t.getTransferData(flavor) : null; } catch (Exception __e) { throw rethrow(__e); } } static public BufferedImage imageFromDataURL(String url) { return decodeImage(bytesFromDataURL(url)); } static public String getTextFromClipboard() { try { Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) return (String) transferable.getTransferData(DataFlavor.stringFlavor); return null; } catch (Exception __e) { throw rethrow(__e); } } static public void popupError(final Throwable throwable) { throwable.printStackTrace(); SwingUtilities.invokeLater(new Runnable() { public void run() { String text = throwable.toString(); JOptionPane.showMessageDialog(null, text); } }); } static public A printIf(boolean b, A a) { if (b) print(a); return a; } static public A printIf(boolean b, String s, A a) { if (b) print(s, a); return a; } static public ImageSurface jImageSurface() { return swingNu(ImageSurface.class); } static public ImageSurface jImageSurface(MakesBufferedImage img) { return swingNu(ImageSurface.class, img.getBufferedImage()); } static public ImageSurface jImageSurface(BufferedImage img) { return swingNu(ImageSurface.class, img); } static public A disposeFrameOnClick(final A c) { onClick(c, new Runnable() { public void run() { try { disposeFrame(c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeFrame(c)"; } }); return c; } static public void imageSurface_unpixelated(ImageSurface imageSurface) { if (imageSurface == null) return; imageSurface.interpolationMode = RenderingHints.VALUE_INTERPOLATION_BILINEAR; repaint(imageSurface); } static public List syncCloneAndClearList(Collection l) { if (l == null) return emptyList(); synchronized (collectionMutex(l)) { List l2 = cloneList(l); l.clear(); return l2; } } static public long done2_always(long startTime, String desc) { long time = sysNow() - startTime; saveTiming_noPrint(time); print(desc + " [" + time + " ms]"); return time; } static public long done2_always(String desc, long startTime) { return done2_always(startTime, desc); } static public long done2_always(long startTime) { return done2_always(startTime, ""); } static public DynamicObject dynamicObject(String className, Object... x) { DynamicObject d = new DynamicObject(className); for (int i = 0; i < x.length - 1; i += 2) if (x[i + 1] != null) setDyn(d, (String) x[i], x[i + 1]); return d; } static public List sortedIgnoreCase(Collection c) { List l = cloneList(c); Collections.sort(l, caseInsensitiveComparator()); return l; } static public double nanosToMicroseconds(double ns) { return ns / 1000; } static public List sortedByCalculatedField(Iterable c, Object f) { return sortByCalculatedField(c, f); } static public List sortedByCalculatedField(Object f, Iterable c) { return sortedByCalculatedField(c, f); } static public List sortedByCalculatedField(IF1 f, Iterable c) { return sortedByCalculatedField(c, f); } static public List sortedByCalculatedField(Iterable c, IF1 f) { List l = cloneList(c); sort(l, new Comparator() { public int compare(A a, A b) { return stdcompare(f.get(a), f.get(b)); } }); return l; } static public List allMethodNames(Object o) { Class c = _getClass(o); TreeSet names = new TreeSet(); while (c != null) { for (Method m : c.getDeclaredMethods()) names.add(m.getName()); c = c.getSuperclass(); } return asList(names); } 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 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 Collection findConceptsWhere(Class c, Object... params) { return findConceptsWhere(db_mainConcepts(), c, params); } static public Collection findConceptsWhere(String c, Object... params) { return findConceptsWhere(db_mainConcepts(), c, params); } static public Collection findConceptsWhere(Concepts concepts, Class c, Object... params) { ping(); params = expandParams(c, params); if (concepts.fieldIndices != null) for (int i = 0; i < l(params); i += 2) { IFieldIndex index = concepts.getFieldIndex(c, (String) params[i]); if (index != null) { Collection rawList = index.getAll(params[i + 1]); params = dropEntryFromParams(params, i); if (params == null) return rawList; List l = new ArrayList(); for (A x : rawList) if (checkConceptFields(x, params)) l.add(x); return l; } } return filterConcepts(concepts.list(c), params); } static public Collection findConceptsWhere(Concepts concepts, String c, Object... params) { return filterConcepts(concepts.list(c), params); } static public void sort(T[] a, Comparator c) { if (a != null) Arrays.sort(a, c); } static public void sort(T[] a) { if (a != null) Arrays.sort(a); } static public void sort(int[] a) { if (a != null) Arrays.sort(a); } static public void sort(List a, Comparator c) { if (a != null) Collections.sort(a, c); } static public void sort(List a) { if (a != null) Collections.sort(a); } static public int cmpAlphanumIC(String a, String b) { return cmpAlphaNum(a, b); } static public List lookupAllOpt(Map map, Collection l) { List out = new ArrayList(); if (l != null) for (A a : l) addIfNotNull(out, map.get(a)); return out; } static public List lookupAllOpt(Collection l, Map map) { return lookupAllOpt(map, l); } static public > List getVars(Iterable l) { return lambdaMap(__75 -> getVar(__75), l); } static public NavigableMap synchroNavigableMap(NavigableMap map) { return Collections.synchronizedNavigableMap(map); } static public Object defaultDefaultClassFinder() { return new F1() { public Class get(String name) { name = replacePrefix("main$main$", "main$", 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 void readLocally(String progID, String varNames) { readLocally2(mc(), progID, varNames); } static public void readLocally(String varNames) { readLocally2(mc(), programID(), varNames); } static public void readLocally2(Object obj, String varNames) { readLocally2(obj, programID(), varNames); } static public int readLocally_stringLength; static public ThreadLocal readLocally2_allDynamic = new ThreadLocal(); static public ThreadLocal readLocally2_classFinder = new ThreadLocal(); static public void readLocally2(Object obj, String progID, String varNames) { try { boolean allDynamic = isTrue(getAndClearThreadLocal(readLocally2_allDynamic)); for (String variableName : javaTokC(varNames)) { File textFile = new File(programDir(progID), variableName + ".text"); String value = loadTextFile(textFile); if (value != null) set(main.class, variableName, value); else { File structureFile = new File(programDir(progID), variableName + ".structure"); value = loadTextFile(structureFile); if (value == null) { File structureGZFile = new File(programDir(progID), variableName + ".structure.gz"); if (!structureGZFile.isFile()) return; InputStream fis = new FileInputStream(structureGZFile); try { GZIPInputStream gis = newGZIPInputStream(fis); InputStreamReader reader = new InputStreamReader(gis, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(reader); Object o = unstructure_tok(javaTokC_noMLS_onReader(bufferedReader), allDynamic, readLocally2_classFinder.get()); readLocally_set(obj, variableName, o); return; } finally { _close(fis); } } readLocally_stringLength = l(value); if (nempty(value)) readLocally_set(obj, variableName, unstructure(value, allDynamic, readLocally2_classFinder.get())); } } } catch (Exception __e) { throw rethrow(__e); } } static public void readLocally_set(Object c, String varName, Object value) { Object oldValue = get(c, varName); if (oldValue instanceof List && !(oldValue instanceof ArrayList) && value != null) { value = synchroList((List) value); } set(c, varName, value); } 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 getInnerMessage(Throwable e) { if (e == null) return null; return getInnerException(e).getMessage(); } static public BufferedReader utf8BufferedReader(InputStream in) { return utf8bufferedReader(in); } static public BufferedReader utf8BufferedReader(File f) { return utf8bufferedReader(f); } static public Producer javaTokC_noMLS_onReader(final BufferedReader r) { final class X implements Producer { public StringBuilder buf = new StringBuilder(); public char c, d, e = 'x'; public X() { nc(); nc(); nc(); } public void nc() { try { c = d; d = e; if (e == '\0') return; int i = r.read(); e = i < 0 ? '\0' : i == '\0' ? '_' : (char) i; } catch (Exception __e) { throw rethrow(__e); } } public void ncSave() { if (c != '\0') { buf.append(c); nc(); } } public String next() { while (c != '\0') { if (c == ' ' || c == '\t' || c == '\r' || c == '\n') nc(); else if (c == '/' && d == '*') { do nc(); while (c != '\0' && !(c == '*' && d == '/')); nc(); nc(); } else if (c == '/' && d == '/') { do nc(); while (c != '\0' && "\r\n".indexOf(c) < 0); } else break; } if (c == '\0') return null; if (c == '\'' || c == '"') { char opener = c; ncSave(); while (c != '\0') { if (c == opener || c == '\n') { ncSave(); break; } else if (c == '\\') { ncSave(); ncSave(); } else ncSave(); } } else if (Character.isJavaIdentifierStart(c)) do ncSave(); while (Character.isJavaIdentifierPart(c) || c == '\''); else if (Character.isDigit(c)) { do ncSave(); while (Character.isDigit(c)); if (c == 'L') ncSave(); } else ncSave(); String t = buf.toString(); buf.setLength(0); return t; } } return new X(); } static public boolean isString(Object o) { return o instanceof String; } static public Producer javaTokC_noMLS_iterator(final String s) { return javaTokC_noMLS_iterator(s, 0); } static public Producer javaTokC_noMLS_iterator(final String s, final int startIndex) { return new Producer() { final public int l = s.length(); public int i = startIndex; public String next() { if (i >= l) return null; 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) return null; 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))); 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; String t = quickSubstring(s, i, j); i = j; return t; } }; } static public String actualMCDollar() { return actualMC().getName() + "$"; } static public BigInteger parseBigInt(String s) { return new BigInteger(s); } 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 String unquoteUsingCharArray(String s, char[] buf) { 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(); if (l > buf.length) return unquote(s); int n = 0; 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++; } } buf[n++] = (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); char[] x = Character.toChars(code); int lx = x.length; for (int j = 0; j < lx; j++) buf[n++] = x[j]; i += 5; continue; default: ch = nextChar; } i++; } buf[n++] = ch; } return new String(buf, 0, n); } } return s; } static public boolean structure_isMarker(String s, int i, int j) { if (i >= j) return false; if (s.charAt(i) != 'm') return false; ++i; while (i < j) { char c = s.charAt(i); if (c < '0' || c > '9') return false; ++i; } return true; } static public String internIfLongerThan(String s, int l) { return s == null ? null : l(s) >= l ? intern(s) : s; } static public char unquoteCharacter(String s) { assertTrue(s.startsWith("'") && s.length() > 1); return unquote("\"" + s.substring(1, s.endsWith("'") ? s.length() - 1 : s.length()) + "\"").charAt(0); } static public boolean isLongConstant(String s) { if (!s.endsWith("L")) return false; s = s.substring(0, l(s) - 1); return isInteger(s); } static public TreeMap ciMap() { return caseInsensitiveMap(); } static public List parseList(String s) { return (List) safeUnstructure(s); } static public SortedMap synchroSortedMap(SortedMap map) { return Collections.synchronizedSortedMap(map); } static public boolean[] boolArrayFromBytes(byte[] a, int n) { boolean[] b = new boolean[n]; int m = min(n, l(a) * 8); for (int i = 0; i < m; i++) b[i] = (a[i / 8] & 1 << (i & 7)) != 0; return b; } static public Constructor nuStubInnerObject_findConstructor(Class c) { return nuStubInnerObject_findConstructor(c, null); } static public Constructor nuStubInnerObject_findConstructor(Class c, Object classFinder) { try { Class outerType = getOuterClass(c, classFinder); Constructor m = c.getDeclaredConstructor(outerType); makeAccessible(m); return m; } catch (Exception __e) { throw rethrow(__e); } } static public Map nuEmptyObject_cache = newDangerousWeakHashMap(); static public A nuEmptyObject(Class c) { try { Constructor ctr; synchronized (nuEmptyObject_cache) { ctr = nuEmptyObject_cache.get(c); if (ctr == null) { nuEmptyObject_cache.put(c, ctr = nuEmptyObject_findConstructor(c)); makeAccessible(ctr); } } try { return (A) ctr.newInstance(); } catch (InstantiationException e) { if (empty(e.getMessage())) if ((c.getModifiers() & Modifier.ABSTRACT) != 0) throw fail("Can't instantiate abstract class " + className(c), e); else throw fail("Can't instantiate " + className(c), e); else throw rethrow(e); } } catch (Exception __e) { throw rethrow(__e); } } static public Constructor nuEmptyObject_findConstructor(Class c) { for (Constructor m : getDeclaredConstructors_cached(c)) if (m.getParameterTypes().length == 0) return m; throw fail("No default constructor declared in " + c.getName()); } static public void setOptAllDyn_pcall(DynamicObject o, Map fields) { if (fields == null || o == null) return; HashMap fieldMap = instanceFieldsMap(o); for (Map.Entry e : fields.entrySet()) { try { String field = e.getKey(); Object val = e.getValue(); Field f = fieldMap.get(field); if (f != null) smartSet(f, o, val); else { dynamicObject_setRawFieldValue(o, intern(field), val); } } catch (Throwable __e) { printStackTrace(__e); } } } static public void setOptAll_pcall(Object o, Map fields) { if (fields == null) return; for (String field : keys(fields)) try { setOpt(o, field, fields.get(field)); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } static public void setOptAll_pcall(Object o, Object... values) { warnIfOddCount(values); for (int i = 0; i + 1 < l(values); i += 2) { String field = (String) values[i]; Object value = values[i + 1]; try { setOpt(o, field, value); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } } static public void fixOuterRefs(Object o) { try { if (o == null) return; Field[] l = thisDollarOneFields(o.getClass()); if (l.length <= 1) return; Object father = null; for (Field f : l) { father = f.get(o); if (father != null) break; } if (father == null) return; for (Field f : l) f.set(o, father); } catch (Exception __e) { throw rethrow(__e); } } static public String intern(String s) { return fastIntern(s); } static public void pcallOpt_noArgs(Object o, String method) { try { callOpt_noArgs(o, method); } catch (Throwable __e) { printStackTrace(__e); } } static public RuntimeException todo() { throw new RuntimeException("TODO"); } static public RuntimeException todo(Object msg) { throw new RuntimeException("TODO: " + msg); } static public Object newMultiDimensionalOuterArray(Class elementType, int dimensions, int length) { int[] dims = new int[dimensions]; dims[0] = length; return Array.newInstance(elementType, dims); } static public int[] toIntArray(Collection l) { int[] a = new int[l(l)]; int i = 0; if (a.length != 0) for (int x : l) a[i++] = x; return a; } static public double[] toDoubleArray(Collection l) { double[] a = new double[l(l)]; int i = 0; if (a.length != 0) for (double x : l) a[i++] = x; return a; } static public TreeSet ciSet() { return caseInsensitiveSet(); } static public boolean jmatch(String pat, String s) { return jmatch(pat, s, null); } static public boolean jmatch(String pat, String s, Matches matches) { if (s == null) return false; return jmatch(pat, javaTok(s), matches); } static public boolean jmatch(String pat, List toks) { return jmatch(pat, toks, null); } static public boolean jmatch(String pat, List toks, Matches matches) { List tokpat = javaTok(pat); String[] m = match2(tokpat, toks); if (m == null) return false; else { if (matches != null) matches.m = m; return true; } } static public List callF_all(Collection l, Object... args) { return map(l, f -> callF(f, args)); } static public File tempFileFor(File f) { return new File(f.getPath() + "_temp"); } static public double toM_double(long l) { return l / (1024 * 1024.0); } 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 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 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)); } 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 java.util.Calendar calendarFromTime(long time, TimeZone tz) { java.util.Calendar c = java.util.Calendar.getInstance(tz); c.setTimeInMillis(time); return c; } static public java.util.Calendar calendarFromTime(long time) { java.util.Calendar c = java.util.Calendar.getInstance(); c.setTimeInMillis(time); return c; } static public Map singular_specials = litmap("children", "child", "images", "image", "chess", "chess"); static public Set singular_specials2 = litciset("time", "machine", "line", "rule"); static public String singular(String s) { if (s == null) return null; { String __1 = singular_specials.get(s); if (!empty(__1)) return __1; } if (singular_specials2.contains(dropSuffix("s", afterLastSpace(s)))) return dropSuffix("s", s); if (s.endsWith("ness")) return s; if (s.endsWith("ges")) return dropSuffix("s", s); if (endsWith(s, "bases")) return dropLast(s); s = dropSuffix("es", s); s = dropSuffix("s", s); return s; } static public Set getPlural_specials = litciset("sheep", "fish"); static public String getPlural(String s) { if (contains(getPlural_specials, s)) return s; if (ewic(s, "y")) return dropSuffixIgnoreCase("y", s) + "ies"; if (ewicOneOf(s, "ss", "ch")) return s + "es"; if (ewic(s, "s")) return s; return s + "s"; } 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 boolean isSyntheticOrAnonymous(Class c) { return c != null && (c.isSynthetic() || isAnonymousClassName(c.getName())); } static public String shortDynClassNameForStructure(Object o) { if (o instanceof DynamicObject && ((DynamicObject) o).className != null) return ((DynamicObject) o).className; if (o == null) return null; Class c = o instanceof Class ? (Class) o : o.getClass(); String name = c.getName(); return name.startsWith("dyn.") ? classNameToVM(name) : shortenClassName(name); } static public boolean isPersistableClass(Class c) { String name = c.getName(); if (isSubtypeOf(c, TransientObject.class)) return false; if (isAnonymousClassName(name)) return false; if (isBoxedType(c)) return true; if (isArrayType(c)) return true; if (c == Class.class || c == String.class || c == File.class || c == Color.class) return true; if (name.startsWith("java.util.Collections$Synchronized")) return true; if (hasThisDollarFields(c)) return hasSingleArgumentConstructor(c); else return getDefaultConstructor(c) != null; } static public Constructor getDefaultConstructor(Class c) { if (c != null) for (Constructor m : getDeclaredConstructors_cached(c)) if (empty(m.getParameterTypes())) return m; return null; } static public Object invokeConstructor(Constructor m, Object... args) { try { makeAccessible(m); return m.newInstance(args); } catch (Exception __e) { throw rethrow(__e); } } static public int countDots(String s) { int n = l(s), count = 0; for (int i = 0; i < n; i++) if (s.charAt(i) == '.') ++count; return count; } static public void quoteToPrintWriter(String s, PrintWriter out) { if (s == null) { out.print("null"); return; } out.print('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') { out.print('\\'); out.print(c); } else if (c == '\r') out.print("\\r"); else if (c == '\n') out.print("\\n"); else if (c == '\0') out.print("\\0"); else out.print(c); } out.print('"'); } static public String quoteCharacter(char c) { if (c == '\'') return "'\\''"; if (c == '\\') return "'\\\\'"; if (c == '\r') return "'\\r'"; if (c == '\n') return "'\\n'"; if (c == '\t') return "'\\t'"; return "'" + c + "'"; } static public boolean isCISet_gen(Iterable l) { return l instanceof TreeSet && className(((TreeSet) l).comparator()).contains("CIComp"); } static public boolean isJavaXClassName(String s) { return startsWithOneOf(s, "main$", "loadableUtils."); } static public List unwrapSynchronizedList(List l) { if (eqOneOf(className(l), "java.util.Collections$SynchronizedList", "java.util.Collections$SynchronizedRandomAccessList")) return (List) get_raw(l, "list"); return l; } static public boolean isCIMap_gen(Map map) { return map instanceof TreeMap && className(((TreeMap) map).comparator()).contains("CIComp"); } static public Map unwrapSynchronizedMap(Map map) { if (eqOneOf(shortClassName(map), "SynchronizedMap", "SynchronizedSortedMap", "SynchronizedNavigableMap")) return (Map) get_raw(map, "m"); return map; } static public String boolArrayToHex(boolean[] a) { return bytesToHex(boolArrayToBytes(a)); } static public Pair arrayTypeAndDimensions(Object o) { return arrayTypeAndDimensions(_getClass(o)); } static public Pair arrayTypeAndDimensions(Class c) { if (c == null || !c.isArray()) return null; Class elem = c.getComponentType(); if (elem.isArray()) return mapPairB(arrayTypeAndDimensions(elem), dim -> dim + 1); return pair(elem, 1); } static public int stdcompare(Number a, Number b) { return cmp(a, b); } static public int stdcompare(String a, String b) { return cmp(a, b); } static public int stdcompare(long a, long b) { return a < b ? -1 : a > b ? 1 : 0; } static public int stdcompare(Object a, Object b) { return cmp(a, b); } static public Map getDeclaredFields_cache = newDangerousWeakHashMap(); static public Field[] getDeclaredFields_cached(Class c) { Field[] fields; synchronized (getDeclaredFields_cache) { fields = getDeclaredFields_cache.get(c); if (fields == null) { getDeclaredFields_cache.put(c, fields = c.getDeclaredFields()); for (Field f : fields) makeAccessible(f); } } return fields; } static public Object fieldGet(Field f, Object o) { try { return f == null ? null : f.get(o); } catch (Exception __e) { throw rethrow(__e); } } static public Method findInstanceMethod(Class c, String method, Object... args) { while (c != null) { for (Method m : c.getDeclaredMethods()) if (m.getName().equals(method) && findMethod_checkArgs(m, args, false)) return m; c = c.getSuperclass(); } return null; } static public Set fieldObjectsInFieldOrder(Class c, Set fields) { try { var byName = mapToKey(f -> f.getName(), fields); LinkedHashSet out = new LinkedHashSet(); for (String name : unnullForIteration(getFieldOrder(c))) { Field f = byName.get(name); if (f != null) { byName.remove(name); out.add(f); } } addAll(out, fields); return out; } catch (Throwable __0) { printStackTrace(__0); return fields; } } static public String defaultTimerName_name; static public String defaultTimerName() { if (defaultTimerName_name == null) defaultTimerName_name = "A timer by " + programID(); return defaultTimerName_name; } 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 boolean addToCollection(Collection c, A a) { return c != null && c.add(a); } static public String dynamicClassName(Object o) { if (o instanceof DynamicObject && ((DynamicObject) o).className != null) return "main$" + ((DynamicObject) o).className; return className(o); } static public boolean instanceOf(Object o, String className) { if (o == null) return false; String c = o.getClass().getName(); return eq(c, className) || eq(c, "main$" + className); } static public boolean instanceOf(Object o, Class c) { if (c == null) return false; return c.isInstance(o); } static public boolean instanceOf(Class c, Object o) { return instanceOf(o, c); } static public HashMap findClass_cache = new HashMap(); static public Class findClass(String name) { synchronized (findClass_cache) { if (findClass_cache.containsKey(name)) return findClass_cache.get(name); if (!isJavaIdentifier(name)) return null; Class c; try { c = Class.forName("main$" + name); } catch (ClassNotFoundException e) { c = null; } findClass_cache.put(name, c); return c; } } static public void warnIfOddCount(Object... list) { if (odd(l(list))) printStackTrace("Odd list size: " + list); } static public boolean _csetField(Concept c, String field, Object value) { try { Field f = setOpt_findField(c.getClass(), field); if (value instanceof RC) value = c._concepts.getConcept((RC) value); value = deref(value); if (value instanceof String && l((String) value) >= concepts_internStringsLongerThan) value = intern((String) value); if (f == null) { assertIdentifier(field); Object oldVal = mapGet(c.fieldValues, field); if (value instanceof Concept) { if (oldVal instanceof Concept.Ref) return ((Concept.Ref) oldVal).set((Concept) value); else { dynamicObject_setRawFieldValue(c, field, c.new Ref((Concept) value)); c.change(); return true; } } else { if (oldVal instanceof Concept.Ref) ((Concept.Ref) oldVal).unindexAndDrop(); if (eq(oldVal, value)) return false; if (isConceptList(value) && nempty(((List) value))) { dynamicObject_setRawFieldValue(c, field, c.new RefL(((List) value))); c.change(); return true; } if (value == null) { dynamicObject_dropRawField(c, field); } else { if (!isPersistable(value)) throw fail("Can't persist: " + c + "." + field + " = " + value); dynamicObject_setRawFieldValue(c, field, value); } c.change(); return true; } } else if (isSubtypeOf(f.getType(), Concept.Ref.class)) { ((Concept.Ref) f.get(c)).set((Concept) derefRef(value)); c.change(); return true; } else if (isSubtypeOf(f.getType(), Concept.RefL.class)) { ((Concept.RefL) f.get(c)).replaceWithList(lmap(__76 -> derefRef(__76), (List) value)); c.change(); return true; } else { Object old = f.get(c); if (neq(value, old)) { boolean isTransient = isTransient(f); if (!isTransient && !isPersistable(value)) throw fail("Can't persist: " + c + "." + field + " = " + value); f.set(c, value); if (!isTransient) c.change(); return true; } } return false; } catch (Exception __e) { throw rethrow(__e); } } static public Object derefRef(Object o) { if (o instanceof Concept.Ref) o = ((Concept.Ref) o).get(); return o; } static public A derefRef(Concept.Ref r) { return r == null ? null : r.get(); } static public String loadTextFilePossiblyGZipped(String fileName) { return loadTextFilePossiblyGZipped(fileName, null); } static public String loadTextFilePossiblyGZipped(String fileName, String defaultContents) { File gz = new File(fileName + ".gz"); return gz.exists() ? loadGZTextFile(gz) : loadTextFile(fileName, defaultContents); } static public String loadTextFilePossiblyGZipped(File fileName) { return loadTextFilePossiblyGZipped(fileName, null); } static public String loadTextFilePossiblyGZipped(File fileName, String defaultContents) { return loadTextFilePossiblyGZipped(fileName.getPath(), defaultContents); } static public void assertNotOnAWTThread() { assertFalse("Can't do this in AWT thread", isAWTThread()); } static public boolean isUnstructuring() { return isTrue(getTL(dynamicObjectIsLoading_threadLocal())); } static public Concepts newConceptsWithClassFinder(String progID) { Concepts cc = new Concepts(progID); cc.classFinder = _defaultClassFinder(); return cc; } static public Concepts newConceptsWithClassFinder(File conceptsFile) { Concepts cc = new Concepts(assertNotNull(conceptsFile)); cc.classFinder = _defaultClassFinder(); return cc; } static public Concepts newConceptsWithClassFinder(File conceptsFile, IF1 classFinder) { Concepts cc = new Concepts(assertNotNull(conceptsFile)); cc.classFinder = classFinder; return cc; } static public Map objectToMap(Object o) { try { if (o instanceof Map) return (Map) o; TreeMap map = new TreeMap(); Class c = o.getClass(); while (c != Object.class) { Field[] fields = c.getDeclaredFields(); for (final Field field : fields) { if ((field.getModifiers() & Modifier.STATIC) != 0) continue; field.setAccessible(true); final Object value = field.get(o); if (value != null) map.put(field.getName(), value); } c = c.getSuperclass(); } if (o instanceof DynamicObject) putAll(map, ((DynamicObject) o).fieldValues); return map; } catch (Exception __e) { throw rethrow(__e); } } static public List> objectToMap(Iterable l) { if (l == null) return null; List x = new ArrayList(); for (Object o : l) x.add(objectToMap(o)); return x; } static public boolean isSubclass(Class a, Class b) { return a != null && b != null && b.isAssignableFrom(a); } static public A withTypeWriterFont(A c) { return setFont(c, typeWriterFont()); } static public JTabbedPane fillJTabs(final JTabbedPane tabs, final Object... _x) { if (tabs == null) return null; clearTabs(tabs); Object[] x = flattenArray2(_x); int idx = 0; if (get(x, 0) instanceof Integer) { idx = asInt(get(x, 0)); x = dropFirst(x); if (empty(x)) { x = arrayrep(null, idx); idx = 0; } } int n = 0; for (int i = 0; i < l(x); i++) { ++n; Object o = x[i]; if (isComponentOrSwingable(o)) addTab(tabs, "Tab " + n, wrap(o)); else { String toolTip = ""; if (o instanceof WithToolTip) { toolTip = ((WithToolTip) o).toolTip(); o = ((WithToolTip) o).get(); } String name = str(or(o, "Tab " + n)); Component c; if (isComponentOrSwingable(get(x, i + 1))) c = wrap(get(x, ++i)); else c = new JPanel(); addTabWithToolTip(tabs, name, toolTip, wrap(c)); } } if (idx != 0) tabs.setSelectedIndex(min(tabs.getTabCount() - 1, idx)); return tabs; } static public String format(String pat, Object... args) { return format3(pat, args); } static public String renderVars_str(Object... params) { List l = new ArrayList(); int i = 0; if (odd(l(params))) { l.add(strOrNull(first(params))); ++i; } for (; i + 1 < l(params); i += 2) l.add(params[i] + "=" + params[i + 1]); return trim(joinWithComma(l)); } static public List sorted(Collection c, Object comparator) { List l = cloneList(c); sort(l, makeComparator(comparator)); return l; } static public List sorted(Collection c) { List l = cloneList(c); sort(l); return l; } static public List sorted(Comparator comparator, Collection c) { List l = cloneList(c); sort(l, comparator); return l; } 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 int indent_default = 2; static public String indent(int indent) { return repeat(' ', indent); } static public String indent(int indent, String s) { return indent(repeat(' ', indent), s); } static public String indent(String indent, String s) { return indent + replace(unnull(s), "\n", "\n" + indent); } static public String indent(String s) { return indent(indent_default, s); } static public List indent(String indent, List lines) { List l = new ArrayList(); if (lines != null) for (String s : lines) l.add(indent + s); return l; } static public String regexpReplace(String s, String pat, IF1 f) { return regexReplace(s, pat, f); } static public String regexpReplace(String s, String pat, String replacement) { return regexpReplace_direct(s, pat, replacement); } static public void replaceLastElement(List l, A a) { if (nempty(l)) l.set(l(l) - 1, a); } static public String concatMap_strings(Object f, Iterable l) { return join((List) map(f, l)); } static public String concatMap_strings(Object f, Object[] l) { return join((List) map(f, l)); } static public String concatMap_strings(Iterable l, Object f) { return concatMap_strings(f, l); } static public String concatMap_strings(Iterable l, IF1 f) { return concatMap_strings(f, l); } static public String concatMap_strings(IF1 f, Iterable l) { return concatMap_strings((Object) f, l); } static public String concatMap_strings(IF1 f, A[] l) { return concatMap_strings((Object) f, l); } static public String optionalCurlyBrace(String s) { return isCurlyBraced(s) ? s : curlyBrace(s); } static public String joinWithEmptyLines(Iterable l) { return join("\n\n", map(__77 -> rtrim(__77), l)); } static public String joinWithEmptyLines(String... l) { return joinWithEmptyLines(asList(l)); } static public List nempties(Collection c) { return filterNempty(c); } 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 List countIteratorToList_inclusive(int b) { return countIteratorToList_inclusive(0, b); } static public List countIteratorToList_inclusive(int a, int b) { return asList(countIterator_inclusive(a, b)); } static public List countIteratorToList_inclusive(int b, IF1 f) { return countIteratorToList_inclusive(0, b, f); } static public List countIteratorToList_inclusive(int a, int b, IF1 f) { return asList(countIterator_inclusive(a, b, f)); } static public List countIteratorToList_inclusive(int a, int b, int step) { return asList(countIterator_inclusive_step(a, b, step)); } static public List countIteratorToList_inclusive(double a, double b, double step, IF1 f) { return asList(countIterator_inclusive(a, b, step, f)); } static public List countIteratorToList_inclusive(double a, double b, double step) { return asList(countIterator_inclusive_step(a, b, step)); } static public List countIteratorToList_inclusive(IF1 f, double a, double b, double step) { return asList(countIterator_inclusive_step(a, b, step, f)); } static public List countIteratorToList_inclusive(IF1 f, int a, int b) { return countIteratorToList_inclusive(f, a, b, 1); } static public List countIteratorToList_inclusive(IF1 f, int a, int b, int step) { return asList(countIterator_inclusive(a, b, step, f)); } static public long clockToSysTimeDiff() { return sysNow() - now(); } 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 void copyMap(Map a, Map b) { if (a == null || b == null) return; b.clear(); b.putAll(a); } 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 boolean isDigit(char c) { return Character.isDigit(c); } static public int hexToInt(String s) { return Integer.parseInt(s, 16); } 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 A[] arrayOfType(Class type, int n) { return makeArray(type, n); } static public A[] arrayOfType(int n, Class type) { return arrayOfType(type, n); } static public String reversedString(String s) { return reverseString(s); } static public String longestPrefixInNavigableSet(String s, NavigableSet set) { if (set == null || s == null) return null; while (licensed()) { String key = set.floor(s); if (key == null) break; int n = lCommonPrefix(key, s); if (n == l(key)) return key; s = takeFirst(s, n); } return null; } static public int countLines(String s) { return l(toLines(s)); } static public File programFile(String name) { return prepareProgramFile(name); } static public File programFile(String progID, String name) { return prepareProgramFile(progID, name); } static public SimpleDateFormat simpleDateFormat_UTC(String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); return sdf; } static public String formatUTCWithMS_24() { return formatUTCWithMS_24(now()); } static public String formatUTCWithMS_24(long time) { var sdf = new SimpleDateFormat("HH:mm:ss.SSSS"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); return sdf.format(time) + " UTC"; } static public boolean initSyntaxTextArea_numPadFix = true; static public void initSyntaxTextArea(RSyntaxTextArea textArea) { swing(() -> { if (initSyntaxTextArea_numPadFix) new NumPadFixingInputMap().replaceOn(textArea); textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); textArea.setHighlightCurrentLine(false); textArea.setTabSize(2); textArea.setTabsEmulated(true); textArea.setCodeFoldingEnabled(false); textArea.setMarkOccurrences(true); }); } static public List countIteratorAsList(int b) { return countIteratorAsList(0, b); } static public List countIteratorAsList(int a, int b) { return countIteratorToList(a, b); } static public List countIteratorAsList(int b, IF1 f) { return countIteratorAsList(0, b, f); } static public List countIteratorAsList(int a, int b, IF1 f) { return countIteratorToList(a, b, f); } static public List countIteratorAsList(int a, int b, int step) { return countIteratorToList(a, b, step); } static public List countIteratorAsList(double a, double b, double step, IF1 f) { return countIteratorToList(a, b, step, f); } static public List countIteratorAsList(double a, double b, double step) { return countIteratorToList(a, b, step); } static public List countIteratorAsList(IF1 f, double a, double b, double step) { return countIteratorToList(f, a, b, step); } static public List countIteratorAsList(IF1 f, int b) { return countIteratorAsList(f, 0, b); } static public List countIteratorAsList(IF1 f, int a, int b) { return countIteratorToList(f, a, b); } static public IterableIterator countIterator(int b) { return countIterator(0, b); } static public IterableIterator countIterator(int a, int b) { return countIterator_exclusive(a, b); } static public IterableIterator countIterator(int b, IF1 f) { return countIterator(0, b, f); } static public IterableIterator countIterator(int a, int b, IF1 f) { return countIterator_exclusive(a, b, f); } static public IterableIterator countIterator(int a, int b, int step) { return countIterator_exclusive_step(a, b, step); } static public IterableIterator countIterator(double a, double b, double step, IF1 f) { return countIterator_exclusive_step(a, b, step, f); } static public IterableIterator countIterator(double a, double b, double step) { return countIterator_exclusive_step(a, b, step); } static public IterableIterator countIterator(IF1 f, double a, double b, double step) { return countIterator(a, b, step, f); } static public IterableIterator countIterator(IF1 f, int b) { return countIterator(f, 0, b); } static public IterableIterator countIterator(IF1 f, int a, int b) { return countIterator_exclusive(a, b, f); } static public IterableIterator countIterator(List l) { return countIterator(l(l)); } static public void centerWindowWithin(Window w, Rect r) { if (w != null) { swing(() -> { w.setLocation(r.x + (r.w - w.getWidth()) / 2, r.y + (r.h - w.getHeight()) / 2); }); } } static public int screenNrOfWindow(Window w) { if (w == null) return -1; Rect bounds = boundsAsRect(w); return indexOfMax(allScreenBounds(), screen -> area(intersectRects(bounds, screen))); } static public int incAtomicInt(AtomicInteger i) { return i.incrementAndGet(); } static public int incAtomicInt(AtomicInteger i, int delta) { return i.addAndGet(delta); } static public String intToHex(int i) { return bytesToHex(intToBytes(i)); } static public A registerConcept(A c) { return registerConcept(db_mainConcepts(), c); } static public A registerConcept(Concepts cc, A c) { { if (cc != null) cc.register(c); } return c; } static public WeakIdentityHashMap weakIdentityHashMap() { return new WeakIdentityHashMap(); } static public List getComboBoxItems(JComboBox cb) { return cb == null ? null : swing(() -> { ComboBoxModel model = cb.getModel(); int n = model.getSize(); List l = emptyList(n); for (int i = 0; i < n; i++) l.add(model.getElementAt(i)); return l; }); } static public void setComboBoxItems(JComboBox cb, Collection items) { if (cb != null) { swing(() -> { cb.setModel(new DefaultComboBoxModel(new Vector(items))); }); } } static public JComboBox selectItem(A item, JComboBox cb) { if (cb != null) { swing(() -> { cb.setSelectedItem(item); }); } return cb; } static public JComboBox selectItem(JComboBox cb, A item) { return selectItem(item, cb); } static public JList selectItem(JList list, A item) { { swing(() -> { selectRow(list, jlist_indexOf(list, item)); }); } return list; } 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 A getFromIterator(Iterator it, int idx) { if (idx < 0) return null; while (true) { ping(); if (!it.hasNext()) return null; else { A a = it.next(); if (idx-- == 0) return a; } } } static public IterableIterator linesIterator(final String s) { return lines_iterator(s); } static public void printNumberedLines(Map map) { printNumberedLines(mapToLines(map)); } static public void printNumberedLines(String prefix, Map map) { printNumberedLines(prefix, mapToLines(map)); } static public A printNumberedLines(A l) { int i = 0; if (l != null) for (Object a : cloneList(l)) print((++i) + ". " + str(a)); return l; } static public A printNumberedLines(String prefix, A l) { int i = 0; if (l != null) for (Object a : cloneList(l)) print(prefix + (++i) + ". " + str(a)); return l; } static public void printNumberedLines(Object[] l) { printNumberedLines("", l); } static public void printNumberedLines(String prefix, Object[] l) { printNumberedLines(prefix, wrapAsList(l)); } static public void printNumberedLines(Object o) { printNumberedLines(lines(str(o))); } 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 A vmBus_timerStarted(A timer) { vmBus_send("timerStarted", timer, costCenter()); return timer; } static public double msToSeconds(long ms) { return toSeconds(ms); } static public double msToSeconds(double ms) { return toSeconds(ms); } static public long fileModificationTime(File f) { return f == null ? 0 : f.lastModified(); } static public SimpleDateFormat simpleDateFormat_local(String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); sdf.setTimeZone(localTimeZone()); return sdf; } static public double toMinutes(long ms) { return ms / 60000.0; } static public AutoCloseable tempActivity(Object r) { return null; } static public boolean allPaused() { return ping_pauseAll; } static public void bindTimerToComponent(final Timer timer, JFrame f) { bindTimerToComponent(timer, f.getRootPane()); } static public void bindTimerToComponent(final Timer timer, JComponent c) { if (c.isShowing()) timer.start(); c.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { timer.start(); } public void ancestorRemoved(AncestorEvent event) { timer.stop(); } public void ancestorMoved(AncestorEvent event) { } }); } static public boolean md5OfFile_verbose = false; static public String md5OfFile(String path) { return md5OfFile(newFile(path)); } static public String md5OfFile(File f) { try { if (!f.exists()) return "-"; if (md5OfFile_verbose) print("Getting MD5 of " + f); MessageDigest md5 = MessageDigest.getInstance("MD5"); FileInputStream in = new FileInputStream(f); try { byte[] buf = new byte[65536]; int l; while (true) { l = in.read(buf); if (l <= 0) break; md5.update(buf, 0, l); } return bytesToHex(md5.digest()); } finally { _close(in); } } catch (Exception __e) { throw rethrow(__e); } } static public Class getRawTypeClass(Type t) { if (t instanceof ParameterizedType) return (Class) ((ParameterizedType) t).getRawType(); return (Class) t; } static public String classNameToByteCodeFormat(String className) { return "L" + className.replace('.', '/'); } static public String classNameToByteCodeFormat(Class c) { return classNameToByteCodeFormat(className(c)); } static public String joinMap(Object f, Iterable l) { return join(map(f, l)); } static public String joinMap(Iterable l, Object f) { return joinMap(f, l); } static public String joinMap(Iterable l, IF1 f) { return joinMap(f, l); } static public String joinMap(A[] l, IF1 f) { return joinMap(f, l); } static public String joinMap(IF1 f, Iterable l) { return join(map(f, l)); } static public String joinMap(IF1 f, A[] l) { return join(map(f, l)); } static public String joinMap(String separator, Map map, IF2 f) { return join(separator, map(map, f)); } static public boolean isPrimitiveType(Class c) { return c != null && c.isPrimitive(); } static public boolean isArrayType(Class type) { return type != null && type.isArray(); } static public Object[] arrayrep(Object a, int n) { Object[] array = new Object[n]; for (int i = 0; i < n; i++) array[i] = a; return array; } static public A[] arrayrep(Class type, A a, int n) { A[] array = newArray(type, n); for (int i = 0; i < n; i++) array[i] = a; return array; } static public Font getFont(JComponent c) { return c == null ? null : swing(new F0() { public Font get() { try { return c.getFont(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getFont();"; } }); } static public List asSynchroList(Iterable l) { return syncList(cloneList(l)); } 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 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 List reTok(List tok, IntRange r) { if (r != null) reTok(tok, r.start, r.end); return tok; } static public String fsI_flex(String s) { return startsWithDigit(s) ? "#" + s : s; } static public DialogIO talkToSubBot(final long vport, final DialogIO io) { return talkToSubBot(String.valueOf(vport), io); } static public DialogIO talkToSubBot(final String subBot, final DialogIO io) { if (subBot == null) return io; return new talkToSubBot_IO(subBot, io); } static public class talkToSubBot_IO extends DialogIO { public String subBot; public DialogIO io; public talkToSubBot_IO(String subBot, DialogIO io) { this.io = io; this.subBot = subBot; } public boolean isStillConnected() { return io.isStillConnected(); } public String readLineImpl() { return io.readLineImpl(); } public boolean isLocalConnection() { return io.isLocalConnection(); } public Socket getSocket() { return io.getSocket(); } public void close() { try { io.close(); } catch (Exception __e) { throw rethrow(__e); } } public void sendLine(String line) { io.sendLine(format3("please forward to bot *: *", subBot, line)); } } static public DialogIO talkTo(int port) { return talkTo("localhost", port); } static public int talkTo_defaultTimeout = 10000; static public int talkTo_timeoutForReads = 0; static public ThreadLocal> talkTo_byThread = new ThreadLocal(); static public DialogIO talkTo(String ip, int port) { try { String full = ip + ":" + port; Map map = talkTo_byThread.get(); if (map != null && map.containsKey(full)) return map.get(full); if (isLocalhost(ip) && port == vmPort()) return talkToThisVM(); return new talkTo_IO(ip, port); } catch (Exception __e) { throw rethrow(__e); } } static public class talkTo_IO extends DialogIO { public String ip; public int port; public Socket s; public Writer w; public BufferedReader in; public talkTo_IO(String ip, int port) { this.port = port; this.ip = ip; try { s = new Socket(); try { if (talkTo_timeoutForReads != 0) s.setSoTimeout(talkTo_timeoutForReads); s.connect(new InetSocketAddress(ip, port), talkTo_defaultTimeout); } catch (Throwable e) { throw fail("Tried talking to " + ip + ":" + port, e); } w = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); } catch (Exception __e) { throw rethrow(__e); } } public boolean isLocalConnection() { return s.getInetAddress().isLoopbackAddress(); } public boolean isStillConnected() { return !(eos || s.isClosed()); } public void sendLine(String line) { try { Lock __0 = lock; lock(__0); try { w.write(line + "\n"); w.flush(); } finally { unlock(__0); } } catch (Exception __e) { throw rethrow(__e); } } public String readLineImpl() { try { return in.readLine(); } catch (Exception __e) { throw rethrow(__e); } } public void close() { try { if (!noClose) s.close(); } catch (IOException e) { } } public Socket getSocket() { return s; } } 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 quickBotScan() { return ProgramScan.quickBotScan(); } static public List quickBotScan(int[] preferredPorts) { return ProgramScan.quickBotScan(preferredPorts); } static public List quickBotScan(String searchPattern) { List l = new ArrayList(); for (ProgramScan.Program p : ProgramScan.quickBotScan()) if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) l.add(p); return l; } static public String firstPartOfHelloString(String s) { int i = s.lastIndexOf('/'); return i < 0 ? s : rtrim(s.substring(0, i)); } static public String sendToLocalBotQuietly(String bot, String text, Object... args) { text = format3(text, args); DialogIO channel = newFindBot2(bot); try { if (channel == null) throw fail(quote(bot) + " not found"); try { channel.readLine(); channel.sendLine(text); String s = channel.readLine(); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } finally { _close(channel); } } static public String sendToLocalBotQuietly(int port, String text, Object... args) { text = format3(text, args); DialogIO channel = talkTo(port); try { try { channel.readLine(); channel.sendLine(text); String s = channel.readLine(); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } finally { _close(channel); } } static public String getBotAddress(String bot) { List l = fullBotScan(bot); return empty(l) ? null : first(l).address; } static public Object unstructure_matchOK2OrFail(String s) { if (swic(s, "ok ")) return unstructure_startingAtIndex(s, 3); else throw fail(s); } static public String sendToLocalBot(String bot, String text, Object... args) { text = format3(text, args); DialogIO channel = findBot(bot); try { if (channel == null) throw fail(quote(bot) + " not found"); try { channel.readLine(); print(bot + "> " + shorten(text, 80)); channel.sendLine(text); String s = channel.readLine(); print(bot + "< " + shorten(s, 80)); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } finally { _close(channel); } } static public String sendToLocalBot(int port, String text, Object... args) { text = format3(text, args); DialogIO channel = talkTo(port); try { try { channel.readLine(); print(port + "> " + shorten(text, 80)); channel.sendLine(text); String s = channel.readLine(); print(port + "< " + shorten(s, 80)); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } finally { _close(channel); } } static public Boolean grabbableIntPixels_succeeded; static public boolean grabbableIntPixels_enable = true; static public GrabbableIntPixels grabbableIntPixels(BufferedImage img) { if (img == null || !grabbableIntPixels_enable) return null; try { var result = grabbableIntPixels_impl(img); grabbableIntPixels_succeeded = result != null; return result; } catch (Throwable _e) { grabbableIntPixels_succeeded = false; throw rethrow(_e); } } static public GrabbableIntPixels grabbableIntPixels_impl(BufferedImage img) { Raster raster = img.getRaster(); SampleModel _sampleModel = raster.getSampleModel(); if (!(_sampleModel instanceof SinglePixelPackedSampleModel)) return null; SinglePixelPackedSampleModel sampleModel = (SinglePixelPackedSampleModel) _sampleModel; DataBufferInt dataBuffer = (DataBufferInt) (raster.getDataBuffer()); assertEquals(1, dataBuffer.getNumBanks()); assertEquals(DataBuffer.TYPE_INT, dataBuffer.getDataType()); int w = img.getWidth(), h = img.getHeight(); int scanlineStride = sampleModel.getScanlineStride(); int[] pixels = dataBuffer.getData(); int offset = dataBuffer.getOffset(); int translateX = raster.getSampleModelTranslateX(); int translateY = raster.getSampleModelTranslateY(); offset += -translateX - translateY * scanlineStride; return new GrabbableIntPixels(pixels, w, h, offset, scanlineStride); } static public int colorToIntOpaque(Color c) { return c.getRGB() | 0xFF000000; } static public int methodApplicabilityScore_onTypes(Method m, Class[] argTypes) { return methodApplicabilityScore_onTypes((Executable) m, argTypes); } static public int methodApplicabilityScore_onTypes(Executable m, Class[] argTypes) { Class[] types = m.getParameterTypes(); if (types.length != argTypes.length) return Integer.MAX_VALUE; int score = 0; for (int i = 0; i < types.length; i++) { Class a = argTypes[i]; Class c = types[i]; if (c == a) { } else if (isSubclassOf(a, c)) ++score; else return Integer.MAX_VALUE; } return score; } static public List findNonDefaultInterfaceMethods(Class intrface) { if (!isInterface(intrface)) return null; List l = new ArrayList(); _MethodCache cache = getMethodCache(intrface); Class c = intrface; do { for (Method m : c.getDeclaredMethods()) if (m.getDeclaringClass() != Object.class && !m.isDefault() && !isStaticMethod(m)) l.add(m); c = c.getSuperclass(); } while (c != null); return l; } static public TreeMap descTreeMap() { return revTreeMap(); } static public String replacePlusWithSpace(String s) { return replace(s, '+', ' '); } static public List splitAtSpace(String s) { return empty(s) ? emptyList() : asList(s.split("\\s+")); } static public A pairA(Pair p) { return p == null ? null : p.a; } static public B pairB(Pair p) { return p == null ? null : p.b; } static public int scoredSearch_score_single(String s, String query) { int i = indexOfIC_underscore(s, query); if (i < 0) return 0; if (i > 0) return 1; return l(s) == l(query) ? 3 : 2; } static public List secondOfPairs(Collection> l) { return lambdaMap(__78 -> secondOfPair(__78), l); } static public String readLineHidden() { try { if (get(javax(), "readLine_reader") == null) set(javax(), "readLine_reader", new BufferedReader(new InputStreamReader(System.in, "UTF-8"))); try { return ((BufferedReader) get(javax(), "readLine_reader")).readLine(); } finally { consoleClearInput(); } } catch (Exception __e) { throw rethrow(__e); } } 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 boolean isNonNegativeInteger(String s) { int n = l(s); if (n == 0) return false; int i = 0; while (i < n) { char c = s.charAt(i); if (c < '0' || c > '9') return false; ++i; } return true; } static public Color colorFromRGBA(int rgba) { return new Color(rgba, true); } static public int ubyteToInt(byte b) { return b & 0x0FF; } static public int ubyteToInt(char c) { return c & 0x0FF; } static public String tabToSingleSpace(String s) { return replace(s, '\t', ' '); } static public int stdHash(Object a, String... fields) { if (a == null) return 0; int hash = getClassName(a).hashCode(); for (String field : fields) hash = boostHashCombine(hash, hashCode(getOpt(a, field))); return hash; } static public int roundToInt(double d) { return (int) Math.round(d); } static public String assertPossibleGlobalID(String s) { if (!possibleGlobalID(s)) throw fail("Not an acceptable global ID: " + s); return s; } static public char charPlus(char a, int b) { return (char) (((int) a) + b); } static public char charPlus(int b, char a) { return charPlus(a, b); } 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 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 Object iteratorFromFunction_endMarker = new Object(); static public IterableIterator iteratorFromFunction_withEndMarker(final Object f) { class IFF extends IterableIterator { public A a; public boolean have, done; public boolean hasNext() { getNext(); return !done; } public A next() { getNext(); if (done) throw fail(); A _a = a; a = null; have = false; return _a; } public void getNext() { if (done || have) return; Object o = callF(f); if (o == iteratorFromFunction_endMarker) { done = true; return; } a = (A) o; have = true; } } ; return new IFF(); } static public IterableIterator iteratorFromFunction_withEndMarker(final F0 f) { return iteratorFromFunction_withEndMarker_f0(f); } static public void ensureDBNotRunning(String name) { if (hasBot(name)) { try { String framesBot = dropSuffix(".", name) + " Frames"; print("Trying to activate frames of running DB: " + framesBot); if (isOK(sendOpt(framesBot, "activate frames")) && isMainProgram()) cleanKill(); } catch (Throwable __e) { printStackTrace(__e); } throw fail("Already running: " + name); } } static public void ensureDBNotRunning() { ensureDBNotRunning(dbBotStandardName()); } static public String dbBotStandardName() { String home = userHome(); String name = dbBotName(getDBProgramID()); if (neq(home, actualUserHome())) name += " " + quote(home); return name + "."; } static volatile public Android3 dbBot_instance; static public Android3 dbBot() { return dbBot(true); } static public Android3 dbBot(boolean ensureNotRunning) { return dbBot(dbBotStandardName(), ensureNotRunning); } static public Android3 dbBot(String name) { return dbBot(name, true); } static public Android3 dbBot(String name, boolean ensureNotRunning) { if (ensureNotRunning) ensureDBNotRunning(name); return dbBot_instance = methodsBot2(name, assertNotNull(db_mainConcepts()), db_standardExposedMethods(), db_mainConcepts().lock); } static public void thinAProgramsBackups(String progID, boolean doIt) { File dir = programDir(progID); thinAProgramsBackups(dir, doIt); } static public void thinAProgramsBackups(File dir, boolean doIt) { List files = new ArrayList(); Map ageMap = new HashMap(); java.util.regex.Pattern pat = regexp("^(.*)\\.backup(20\\d\\d)(\\d\\d)(\\d\\d)-(\\d\\d)(\\d*)$"); print("Processing backups in " + dir); for (File f : listFilesNotDirs(dir, newFile(dir, "backups"))) { String s = f.getName(); java.util.regex.Matcher matcher = pat.matcher(s); { if (!(matcher.find())) continue; } String originalName = matcher.group(1); { if (!(eq(originalName, "concepts.structure.gz"))) continue; } int year = matcherInt(matcher, 2); int month = matcherInt(matcher, 3); int day = matcherInt(matcher, 4); int hour = matcherInt(matcher, 5); int minute = matcherInt(matcher, 6); long time = timestampFromYMDHM(year, month, day, hour, minute); double age = ((now() - time) / 1000.0 / 60 / 60 / 24); ageMap.put(f, age); files.add(f); } int numDeleted = 0; sortByMap_inPlace(files, ageMap); double lastAge = -1; for (File f : files) { double age = ageMap.get(f); if (!thinAProgramsBackups_shouldKeep(age, lastAge)) { ++numDeleted; if (doIt) { print("Deleting: " + f); f.delete(); } } else { lastAge = age; } } if (numDeleted != 0) print((doIt ? "Deleted: " : "Would delete: ") + n(numDeleted, "file")); } static public boolean thinAProgramsBackups_shouldKeep(double age, double lastAge) { return defaultAgeBasedBackupRetentionStrategy_shouldKeep(age, lastAge); } static public A bindJLabelToVar(A label, IF0WithChangeListeners var) { bindListenerToComponent(label, var, () -> { try { setText(label, strOrNull(var.get())); } catch (Throwable e) { printStackTrace(e); setText(label, "Error"); } }); return label; } 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 void onFirstResize(Component c, Object r) { onFirstResize(c, toRunnable(r)); } static public void onFirstResize(Component c, Runnable r) { if (c != null && r != null) { swing(() -> { c.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { c.removeComponentListener(this); pcallF(r); } }); }); } } static public Set synchroLinkedHashSet() { return synchronizedSet(new CompactLinkedHashSet()); } static public BufferedImage copyImage(Image img) { if (img == null) return null; if (img instanceof BufferedImage) return copyImage((BufferedImage) img); int w = img.getWidth(null), h = img.getHeight(null); BufferedImage bi = newBufferedImage(w, h); drawImage(bi, img); return bi; } static public BufferedImage copyImage(BufferedImage bi) { if (bi == null) return null; ColorModel cm = bi.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster()); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } static public String appendColonIfNempty(String s) { return empty(s) ? "" : s + ": "; } static public void closeRandomAccessFile(RandomAccessFile f) { if (f != null) try { f.close(); callJavaX("dropIO", f); } catch (Throwable e) { printStackTrace(e); } } static public RandomAccessFile newRandomAccessFile(File path, String mode) { try { boolean forWrite = mode.indexOf('w') >= 0; if (forWrite) mkdirsForFile(path); RandomAccessFile f = new RandomAccessFile(path, mode); callJavaX("registerIO", f, path, forWrite); return f; } catch (Exception __e) { throw rethrow(__e); } } static public AutoCloseable tempLock(Lock lock) { return tempLock("", lock); } static public AutoCloseable tempLock(String purpose, Lock lock) { if (lock == null) return null; lock(lock); return new AutoCloseable() { public String toString() { return "unlock(lock);"; } public void close() throws Exception { unlock(lock); } }; } static public String singleFieldName(Class c) { Set l = listFields(c); if (l(l) != 1) throw fail("No single field found in " + c + " (have " + n(l(l), "fields") + ")"); return first(l); } static public List findBackRefs(Collection concepts, Class type) { IdentityHashMap l = new IdentityHashMap(); for (Concept c : concepts) if (c.backRefs != null) for (Concept.Ref r : c.backRefs) if (instanceOf(r.concept(), type)) l.put((A) r.concept(), true); return asList(keys(l)); } static public List findBackRefs(Concept c, Class type) { IdentityHashMap l = new IdentityHashMap(); if (c != null && c.backRefs != null) for (Concept.Ref r : c.backRefs) if (instanceOf(r.concept(), type)) l.put((A) r.concept(), true); return asList(keys(l)); } static public List findBackRefs(Class type, Concept c) { return findBackRefs(c, type); } static public Collection findBackRefs(Concept c) { return findBackRefs(c, Concept.class); } static public boolean checkConceptFieldsIC(Concept x, Object... data) { for (int i = 0; i < l(data); i += 2) if (!eqicOrEq(cget(x, (String) data[i]), deref(data[i + 1]))) return false; return true; } 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 List methodsStartingWith(Object o, final String prefix) { return filter(allMethodNames(o), new F1() { public Object get(String s) { try { return startsWith(s, prefix); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "startsWith(s, prefix)"; } }); } static volatile public PersistableThrowable _handleException_lastException; static public List _handleException_onException = synchroList(ll((IVF1) (__1 -> printStackTrace2(__1)))); static public boolean _handleException_showThreadCancellations = false; static public void _handleException(Throwable e) { _handleException_lastException = persistableThrowable(e); Throwable e2 = innerException(e); if (e2.getClass() == RuntimeException.class && eq(e2.getMessage(), "Thread cancelled.") || e2 instanceof InterruptedException) { if (_handleException_showThreadCancellations) System.out.println(getStackTrace_noRecord(e2)); return; } for (Object f : cloneList(_handleException_onException)) try { callF(f, e); } catch (Throwable e3) { try { printStackTrace2(e3); } catch (Throwable e4) { System.out.println(getStackTrace(e3)); System.out.println(getStackTrace(e4)); } } } static public boolean isJavaXClassLoader(ClassLoader cl) { return startsWithOneOf(className(cl), "main$JavaXClassLoader", "x30$JavaXClassLoader"); } static public void setOptAll(Object o, Map fields) { if (fields == null) return; for (String field : keys(fields)) setOpt(o, field, fields.get(field)); } static public void setOptAll(Object o, Object... values) { warnIfOddCount(values); for (int i = 0; i + 1 < l(values); i += 2) { String field = (String) values[i]; Object value = values[i + 1]; setOpt(o, field, value); } } static public void printStackTrace_inPossiblyCancelledThread(Throwable e) { AutoCloseable __1 = tempUncancelThread(); try { System.out.println(getStackTrace_noRecord(e)); } finally { _close(__1); } } static public List beforeDelegatingToThread_operations = synchroList(); static public void beforeDelegatingToThread(Thread t) { for (Object op : cloneList(beforeDelegatingToThread_operations)) pcallF(op, t); } static public void beforeDelegatingToThread_do(Object f) { setAdd(beforeDelegatingToThread_operations, f); } static public Either either2(B b) { return new Either(2, b); } static public Either either1(A a) { return new Either(1, a); } static public List afterDelegatingToThread_operations = synchroList(); static public void afterDelegatingToThread(Thread t) { for (Object op : cloneList(afterDelegatingToThread_operations)) pcallF(op, t); } static public void afterDelegatingToThread_do(Object f) { setAdd(afterDelegatingToThread_operations, f); } static public URI uri(String uri) { try { return new URI(uri); } catch (Exception __e) { throw rethrow(__e); } } static public List splitAt(String s, String splitter) { if (empty(splitter)) return null; List parts = new ArrayList(); int i = 0; if (s != null) while (i < l(s)) { int j = indexOf(s, splitter, i); if (j < 0) j = l(s); parts.add(substring(s, i, j)); i = j + l(splitter); } return parts; } static public String addSuffix(String s, String suffix) { return s == null || s.endsWith(suffix) ? s : s + suffix; } static public File windowsFindExe(String relativeName) { return firstFileThatExists(map(windowsProgramFilesDirs(), dir -> defaultExtension("exe", newFile(dir, relativeName)))); } static public boolean onPATH(String cmd) { return isOnPATH(cmd); } static public String inputStreamToString(InputStream in) { return utf8streamToString(in); } static public int menuItemCount(JMenu menu) { return menu == null ? 0 : swing(() -> menu.getItemCount()); } static public JScrollPane withoutViewportBorder(JScrollPane sp) { if (sp != null) { swing(() -> { sp.setViewportBorder(null); }); } return sp; } static public A onFirstComponentShow(final A component, final Runnable onShow) { { swing(() -> { component.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { component.removeAncestorListener(this); pcallF(onShow); } public void ancestorRemoved(AncestorEvent event) { } public void ancestorMoved(AncestorEvent event) { } }); }); } return component; } static public String lower(String s) { return s == null ? null : s.toLowerCase(); } static public char lower(char c) { return Character.toLowerCase(c); } static public JRootPane getRootPane(Component c) { Component f = (Component) getPossiblyInternalFrame(c); return f instanceof RootPaneContainer ? (JRootPane) swingCall(f, "getRootPane") : null; } static public class jLiveValueSection_class extends SingleComponentPanel { public LiveValue liveValue; public String getTitle() { return strOrEmpty(liveValue.get()); } public jLiveValueSection_class(LiveValue lv, Component c) { super(c); bindLiveValueListenerToComponent(this, liveValue = lv, new Runnable() { public void run() { try { swingLater(new Runnable() { public void run() { try { setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED), getTitle())); revalidate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setBorder(BorderFactory.createTitledBorder(\r\n BorderFactory.createBeve..."; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "swingLater(r {\r\n setBorder(BorderFactory.createTitledBorder(\r\n Bo..."; } }); } } static public JPanel jLiveValueSection(LiveValue lv, Component c) { return swingNu(jLiveValueSection_class.class, lv, c); } static public boolean isCurrentThread(Thread t) { return t != null && t == currentThread(); } static public boolean activateFrame(final Component c, Object... __) { return swing(new F0() { public Boolean get() { try { Frame f = getAWTFrame(c); if (f == null) return false; if (!f.isVisible()) f.setVisible(true); boolean windowsHack = optPar("windowsHack", __, true); boolean iconified = f.getState() == Frame.ICONIFIED; boolean maximize = boolPar("maximize", __); if (iconified) f.setState(maximize ? Frame.MAXIMIZED_BOTH : Frame.NORMAL); if (windowsHack && !iconified && isWindows()) { boolean fullscreen = f.getExtendedState() == Frame.MAXIMIZED_BOTH; f.setExtendedState(JFrame.ICONIFIED); f.setExtendedState(fullscreen ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL); } f.toFront(); return true; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Frame f = getAWTFrame(c);\r\n if (f == null) false;\r\n if (!f.isVisible())..."; } }); } static public TreeMap asCaseInsensitiveMap(Map map) { if (isCIMap(map)) return (TreeMap) map; TreeMap m = ciMap(); putAll(m, map); return m; } static public TimedCache> standardClassesMap_cached_cache = new TimedCache>(() -> standardClassesMap(), 60.0); static public Map standardClassesMap_cached() { return standardClassesMap_cached_cache.get(); } static public void standardClassesMap_clearCache() { standardClassesMap_cached_cache.clear(); } static public String resolveKeyCI(Map map, String key) { if (map == null) return null; if (map.containsKey(key)) return key; return first(keys(map), k -> eqic(key, k)); } static public Map stdFunctions_uncached() { return stdFunctions_uncached(new HashMap()); } static public Map stdFunctions_uncached(Map map) { for (var snippetID : stdFunctionListSnippetIDs()) parseStdFunctionsList(loadSnippet(snippetID), map); return map; } static public Object callJavaX(String method, Object... args) { return callOpt(getJavaX(), method, args); } static public int typeConversionScoreWithUnboxing(Class a, Class b) { int score = typeConversionScore(a, b); if (score == 0 || score == 1) return score; Class aPrim = boxedToPrimitiveType(a); if (aPrim != null) { int score2 = typeConversionScore(aPrim, b); if (score2 == 0) return 1; else if (score2 != Integer.MAX_VALUE) return score2; } return score; } static public boolean isIPv4(String s) { return s != null && l(javaTokC(s)) == 7 && jfind(javaTok(s), "...") == 1; } static public A singletonOpt(Collection l) { return l(l) == 1 ? first(l) : null; } static public A singletonOpt(A[] l) { return l(l) == 1 ? first(l) : null; } static public IterableIterator emptyIterableIterator_instance = new IterableIterator() { public Object next() { throw fail(); } public boolean hasNext() { return false; } }; static public IterableIterator emptyIterableIterator() { return emptyIterableIterator_instance; } static public String withIdentityHash(Object o, String s) { return o == null ? s : addSuffix(s, "@" + intToHex_flexLength(identityHashCode(o))); } static public Rect rectUnion(Rect a, Rect b) { if (a == null) return b; if (b == null) return a; int x = min(a.x, b.x), y = min(a.y, b.y); int x2 = max(a.x + a.w, b.x + b.w), y2 = max(a.y + a.h, b.y + b.h); return new Rect(x, y, x2 - x, y2 - y); } static public Graphics2D antiAliasGraphics(BufferedImage img) { return antiAliasOn(createGraphics(img)); } static public Map createGraphics_modulators = synchroIdentityHashMap(); static public Graphics2D createGraphics(BufferedImage img) { Graphics2D g = img.createGraphics(); Object mod = createGraphics_modulators.get(img); if (mod != null) callF(mod, g); return g; } static public void createGraphics_modulate(BufferedImage img, Object mod) { mapPut2(createGraphics_modulators, img, mod); } static public List collectInstances(Iterable i, Class c) { List l = new ArrayList(); if (i == null) return l; c = primitiveToBoxedTypeOpt(c); for (Object o : i) if (isInstance(c, o)) l.add(o); return l; } static public List collectInstances(Class c, Iterable i) { return collectInstances(i, c); } static public int decAtomicInt(AtomicInteger i) { return i.decrementAndGet(); } static public JPanel jRightAlignedLine(Component... components) { return jrightAlignedLine(components); } static public JPanel jRightAlignedLine(List components) { return jrightAlignedLine(components); } 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 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 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 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 Object[] asObjectArray(Collection l) { return toObjectArray(l); } static public A jMinWidth_pure(int w, A c) { { swing(() -> { Dimension size = c.getMinimumSize(); c.setMinimumSize(new Dimension(w, size.height)); }); } return c; } static public A jMinWidth_pure(A c, int w) { return jMinWidth_pure(w, c); } static public Matcher regexpIC(Pattern pat, String s) { return pat.matcher(unnull(s)); } static public Matcher regexpIC(String pat, String s) { return compileRegexpIC(pat).matcher(unnull(s)); } static public Pattern regexpIC(String pat) { return compileRegexpIC(pat); } static public List regexpGetGroups(Matcher matcher) { int n = matcher.groupCount(); List l = new ArrayList(); for (int i = 1; i <= n; i++) l.add(matcher.group(i)); return l; } static public List regexpGetGroups(String pat, String s) { Matcher m = regexpMatcher(pat, s); if (m.find()) return regexpGetGroups(m); return null; } static public boolean zipFileContains_falseOnError(File inZip, String fileName) { try { return zipFileContains(inZip, fileName); } catch (Throwable e) { return false; } } static public File javaHome() { return envJavaHome(); } static public File javaHome(String sub) { return newFile(envJavaHome(), sub); } static public File jigsawModuleFile(String moduleName) { return jigsawModuleFile(moduleName, javaHome()); } static public File jigsawModuleFile(String moduleName, File javaHome) { return new File(javaHome, "jmods/" + moduleName + ".jmod"); } static public BufferedImage intArrayToBufferedImage(int[] pixels, int w, int h) { int[] bitMasks = new int[] { 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }; SinglePixelPackedSampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, w, h, bitMasks); DataBufferInt db = new DataBufferInt(pixels, pixels.length); WritableRaster wr = Raster.createWritableRaster(sm, db, new Point()); return new BufferedImageWithMeta(ColorModel.getRGBdefault(), wr, false, null); } static public void registerEscape_rootPane(JComponent rootPane, final Runnable r) { String name = "Escape"; Action action = abstractAction(name, r); KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); rootPane.getActionMap().put(name, action); rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, name); } 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 String programName() { return getProgramName(); } 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(() -> { JPanel panel = showForm_makePanel(false, _parts); showForm_makeFrame(title, panel); return panel; }); } 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 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 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 boolean ewicOneOf(String s, String... l) { if (s != null) for (String x : l) if (ewic(s, x)) return true; return false; } static public BufferedImage reconstructBufferedImage(BufferedImage img) { if (img == null) return null; RGBImage rgb = new RGBImage(img); rgb.uncacheBufferedImage(); return rgb.getBufferedImage(); } static public List beginCriticalAction_inFlight = synchroList(); static public class CriticalAction implements AutoCloseable { public String description; public CriticalAction() { } public CriticalAction(String description) { this.description = description; } final public void close() { done(); } 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 toFile(Object o) { if (o instanceof File) return (File) o; if (o instanceof String) return new File((String) o); throw fail("Not a file: " + o); } static public A moveCaretToEnd(A ta) { setCaretPosition(ta, textAreaTextLength(ta)); return ta; } static public JComponent showTitledForm(String title, Object... _parts) { return showFormTitled(title, _parts); } static public Rect intersectRects(Rect a, Rect b) { int x = max(a.x, b.x), y = max(a.y, b.y); int x2 = min(a.x + a.w, b.x + b.w), y2 = min(a.y + a.h, b.y + b.h); return new Rect(x, y, x2 - x, y2 - y); } static public Rect intersectRects(Rect a, int x1, int y1, int w, int h) { if (a == null || a.x >= x1 && a.y >= y1 && a.x2() < x1 + w && a.y2() < y1 + h) return a; return rectFromPoints(max(a.x, x1), max(a.y, y1), min(a.x2(), x1 + w), min(a.y2(), y1 + h)); } static public boolean rectEmpty(Rect r) { return r == null || r.w <= 0 || r.h <= 0; } static public BufferedImage decodeImage(byte[] data) { try { if (empty(data)) return null; return ImageIO.read(new ByteArrayInputStream(data)); } catch (Exception __e) { throw rethrow(__e); } } static public byte[] bytesFromDataURL(String url) { String pref = "base64,"; int i = indexOf(url, pref); if (i < 0) return null; return base64decode(substring(url, i + l(pref))); } static public void disposeFrame(final Component c) { disposeWindow(c); } static public Comparator caseInsensitiveComparator() { return betterCIComparator(); } static public List sortByCalculatedField(Iterable c, final Object f) { List l = cloneList(c); sort(l, new Comparator() { public int compare(A a, A b) { return stdcompare(callF(f, a), callF(f, b)); } }); return l; } static public Set emptySet() { return new HashSet(); } static public Object[] dropEntryFromParams(Object[] params, int i) { int n = l(params); if (i < 0 || i >= n) return params; if (n == 2) return null; Object[] p = new Object[n - 2]; System.arraycopy(params, 0, p, 0, i); System.arraycopy(params, i + 2, p, i, n - i - 2); return p; } static public List filterConcepts(List list, Object... params) { if (empty(params)) return list; List l = new ArrayList(); for (A x : list) if (checkConceptFields(x, params)) l.add(x); return l; } static public int cmpAlphaNum(String a, String b) { return alphaNumComparator().compare(a, b); } static public List lambdaMap(IF1 f, Iterable l) { return map(l, f); } static public List lambdaMap(IF1 f, A[] l) { return map(l, f); } 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 public String quoteUnlessIdentifierOrInteger(String s) { return quoteIfNotIdentifierOrInteger(s); } 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 String quickSubstring(String s, int i, int j) { if (i >= j) return ""; return s.substring(i, j); } static public Class actualMC() { return or((Class) realMC(), mc()); } static public TreeMap caseInsensitiveMap() { return new TreeMap(caseInsensitiveComparator()); } static public Object safeUnstructure(String s) { return unstructure(s, true); } static public Object safeUnstructure(File f) { return safeUnstructureGZFile(f); } static public Class getOuterClass(Class c) { return getOuterClass(c, null); } static public Class getOuterClass(Class c, Object classFinder) { try { String s = c.getName(); int i = s.lastIndexOf('$'); String name = substring(s, 0, i); return classForName(name, classFinder); } catch (Exception __e) { throw rethrow(__e); } } static public Class getOuterClass(Object o) { return getOuterClass(o, null); } static public Class getOuterClass(Object o, Object classFinder) { return getOuterClass(_getClass(o), classFinder); } static public HashMap instanceFieldsMap(Object o) { return (HashMap) getOpt_getFieldMap(o); } static public Map thisDollarOneFields_cache = newDangerousWeakHashMap(); static public Field[] thisDollarOneFields(Class c) { synchronized (thisDollarOneFields_cache) { Field[] l = thisDollarOneFields_cache.get(c); if (l == null) thisDollarOneFields_cache.put(c, l = thisDollarOneFields_uncached(c)); return l; } } static public Field[] thisDollarOneFields_uncached(Class c) { List fields = new ArrayList(); do { for (Field f : c.getDeclaredFields()) if (f.getName().startsWith("this$")) fields.add(makeAccessible(f)); c = c.getSuperclass(); } while (c != null); return toArray(new Field[l(fields)], fields); } static public Method fastIntern_method; static public String fastIntern(String s) { try { if (s == null) return null; if (fastIntern_method == null) { fastIntern_method = findMethodNamed(javax(), "internPerProgram"); if (fastIntern_method == null) upgradeJavaXAndRestart(); } return (String) fastIntern_method.invoke(null, s); } catch (Exception __e) { throw rethrow(__e); } } static public Map> callOpt_noArgs_cache = newDangerousWeakHashMap(); static public Object callOpt_noArgs(Object o, String method) { try { if (o == null) return null; if (o instanceof Class) return callOpt(o, method); Class c = o.getClass(); HashMap map; synchronized (callOpt_noArgs_cache) { map = callOpt_noArgs_cache.get(c); if (map == null) map = callOpt_noArgs_makeCache(c); } Method m = map.get(method); return m != null ? m.invoke(o) : null; } catch (Exception __e) { throw rethrow(__e); } } static public HashMap callOpt_noArgs_makeCache(Class c) { HashMap map = new HashMap(); Class _c = c; do { for (Method m : c.getDeclaredMethods()) if (m.getParameterTypes().length == 0 && !reflection_isForbiddenMethod(m)) { makeAccessible(m); String name = m.getName(); if (!map.containsKey(name)) map.put(name, m); } _c = _c.getSuperclass(); } while (_c != null); callOpt_noArgs_cache.put(c, map); return map; } static public TreeSet caseInsensitiveSet() { return caseInsensitiveSet_treeSet(); } static public TreeSet caseInsensitiveSet(Collection c) { return caseInsensitiveSet_treeSet(c); } 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 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 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 TreeSet litciset(String... items) { TreeSet set = caseInsensitiveSet(); for (String a : items) set.add(a); return set; } static public TreeSet litciset(Symbol... items) { TreeSet set = treeSet(); for (Symbol a : items) set.add(a); return set; } static public String afterLastSpace(String s) { return s == null ? null : substring(s, s.lastIndexOf(' ') + 1); } static public String dropSuffixIgnoreCase(String suffix, String s) { return ewic(s, suffix) ? s.substring(0, l(s) - l(suffix)) : s; } static public boolean isBoxedType(Class type) { return type == Boolean.class || type == Integer.class || type == Long.class || type == Float.class || type == Short.class || type == Character.class || type == Byte.class || type == Double.class; } static public boolean hasThisDollarFields(Object o) { Matches m = new Matches(); for (var f : allFieldObjects_dontMakeAccessible(o)) if (startsWith(f.getName(), "this$", m) && isInteger(m.rest())) return true; return false; } static public boolean hasSingleArgumentConstructor(Class c) { if (c != null) for (Constructor m : getDeclaredConstructors_cached(c)) if (l(m.getParameterTypes()) == 1) return true; return false; } static public byte[] boolArrayToBytes(boolean[] a) { byte[] b = new byte[(l(a) + 7) / 8]; for (int i = 0; i < l(a); i++) if (a[i]) b[i / 8] |= 1 << (i & 7); return b; } static public List> mapPairB(final Object f, Iterable> l) { return map(l, new F1, Pair>() { public Pair get(Pair p) { try { return p == null ? null : pair(p.a, (C) callF(f, p.b)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "p == null ? null : pair(p.a, (C) callF(f, p.b))"; } }); } static public List> mapPairB(final F1 f, Iterable> l) { return mapPairB((Object) f, l); } static public List> mapPairB(final IF1 f, Iterable> l) { return mapPairB((Object) f, l); } static public List> mapPairB(Iterable> l, IF1 f) { return mapPairB((Object) f, l); } static public Pair mapPairB(IF1 f, Pair p) { return pairMapB(f, p); } static public Pair mapPairB(Pair p, IF1 f) { return pairMapB(f, p); } static public Map mapToKey(Iterable l, IF1 f) { return mapToKeys(l, f); } static public Map mapToKey(IF1 f, Iterable l) { return mapToKeys(f, l); } static public Map> getFieldOrder_cache = weakMap(); static public List getFieldOrder(Object o) { return getFieldOrder(_getClass(o)); } static public List getFieldOrder(Class c) { if (c == null) return null; return getOrCreate(getFieldOrder_cache, c, () -> splitAtSpace(toStringOpt(getOpt(c, "_fieldOrder")))); } static public long fixTimestamp(long timestamp) { return timestamp > now() ? 0 : timestamp; } static public boolean isConceptList(Object o) { if (!(o instanceof List)) return false; List l = (List) o; for (Object x : l) if (!(x instanceof Concept)) return false; return true; } static public void dynamicObject_dropRawField(DynamicObject o, Object key) { if (o == null) return; synchronized (o) { o.fieldValues = (LinkedHashMap) syncMapRemove_deleteMapIfEmpty((Map) o.fieldValues, key); } } static public boolean isPersistable(Object o) { return !isInAnonymousClass(o); } static public List lmap(IF1 f, Iterable l) { return lambdaMap(f, l); } static public List lmap(IF1 f, A[] l) { return lambdaMap(f, l); } static public String loadGZTextFile(File file) { try { if (!file.isFile()) return null; ping(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream fis = new FileInputStream(file); try { GZIPInputStream gis = newGZIPInputStream(fis); byte[] buffer = new byte[1024]; int len; while ((len = gis.read(buffer)) != -1) baos.write(buffer, 0, len); baos.close(); return fromUtf8(baos.toByteArray()); } finally { _close(fis); } } catch (Exception __e) { throw rethrow(__e); } } static public Object getTL(Object o, String name) { return getThreadLocal(o, name); } static public A getTL(ThreadLocal tl) { return getThreadLocal(tl); } static public A getTL(ThreadLocal tl, A defaultValue) { return getThreadLocal(tl, defaultValue); } static public A setFont(final Font font, final A a) { if (a != null) { swing(() -> { a.setFont(font); }); } return a; } static public A setFont(A a, Font font) { return setFont(font, a); } static public A setFont(final String fontID, float fontSize, final A a) { return setFont(loadFont_cached(fontID, fontSize), a); } static public void clearTabs(final JTabbedPane tabs) { if (tabs != null) { swing(() -> { tabs.removeAll(); }); } } static public boolean isComponentOrSwingable(Object o) { if (o instanceof Swingable) return true; return o instanceof Component; } static public void addTab(JTabbedPane tabs, String title) { addTab(tabs, title, jpanel()); } static public void addTab(JTabbedPane tabs, String title, Component c) { if (tabs != null) { swing(() -> { tabs.add(title, wrap(c)); }); } } static public void addTab(JTabbedPane tabs, String title, Swingable c) { if (tabs != null) { swing(() -> { tabs.add(title, wrap(c)); }); } } static public void addTab(JTabbedPane tabs, WithToolTip title, Component c) { addTabWithToolTip(tabs, title.toolTip(), title == null ? null : title.get(), c); } static public void addTab(JTabbedPane tabs, WithToolTip title, Swingable c) { addTabWithToolTip(tabs, title.toolTip(), title == null ? null : title.get(), c); } static public void addTabWithToolTip(JTabbedPane tabs, String title, String toolTip, Component c) { if (tabs == null) return; { swing(() -> { addTab(tabs, title, c); if (nempty(toolTip)) tabs.setToolTipTextAt(tabCount(tabs) - 1, toolTip); }); } } static public void addTabWithToolTip(JTabbedPane tabs, String title, String toolTip, Swingable c) { addTabWithToolTip(tabs, title, toolTip, wrap(c)); } static public Comparator makeComparator(final Object f) { if (f instanceof Comparator) return (Comparator) f; return new Comparator() { public int compare(Object a, Object b) { return (Integer) callF(f, a, b); } }; } static public String regexReplace(String s, String pat, Object f) { Matcher m = Pattern.compile(pat).matcher(s); return regexReplace(m, f); } static public String regexReplace(String s, String pat, String replacement) { return regexpReplace_direct(s, pat, replacement); } static public String regexReplace(Matcher m, Object f) { StringBuffer buf = new StringBuffer(); while (m.find()) m.appendReplacement(buf, m.quoteReplacement(str(callF(f, m)))); m.appendTail(buf); return str(buf); } static public String regexReplace(String s, String pat, IF1 f) { return regexReplace(s, pat, (Object) f); } static public String regexpReplace_direct(String s, String pat, String replacement) { Matcher m = regexp(pat, s); return regexpReplace_direct(m, replacement); } static public String regexpReplace_direct(Matcher m, String replacement) { StringBuffer buf = new StringBuffer(); while (m.find()) m.appendReplacement(buf, replacement); m.appendTail(buf); return str(buf); } static public String curlyBrace(String s) { return "{" + s + "}"; } 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 List filterNempty(Collection c) { List l = new ArrayList(); for (String x : unnull(c)) if (nempty(x)) l.add(x); return l; } static public IterableIterator countIterator_inclusive(final int a, final int b) { return countIterator_exclusive(a, b + 1); } static public IterableIterator countIterator_inclusive(int a, int b, IF1 f) { return countIterator_inclusive(a, b, 1, f); } static public IterableIterator countIterator_inclusive(int a, int b, int step, IF1 f) { return countIterator_inclusive_step(a, b, 1, f); } static public IterableIterator countIterator_inclusive(double a, double b, double step, IF1 f) { return countIterator_inclusive_step(a, b, step, f); } static public IterableIterator countIterator_inclusive_step(int a, final int b, int step) { assertTrue("step > 0", step > 0); return new IterableIterator() { public int i = a; public boolean hasNext() { return i <= b; } public Integer next() { var j = i; i += step; return j; } }; } static public IterableIterator countIterator_inclusive_step(double a, double b, double step) { assertTrue("step > 0", step > 0); return new IterableIterator() { public double i = a; public boolean hasNext() { return i <= b; } public Double next() { var j = i; i += step; return j; } }; } static public IterableIterator countIterator_inclusive_step(double a, double b, double step, IF1 f) { return mapI_if1(f, countIterator_inclusive_step(a, b, step)); } static public IterableIterator countIterator_inclusive_step(int a, int b, int step, IF1 f) { return mapI_if1(f, countIterator_inclusive_step(a, b, step)); } static public A[] makeArray(Class type, int n) { return (A[]) Array.newInstance(type, n); } static public String reverseString(String s) { return empty(s) ? s : new StringBuilder(s).reverse().toString(); } static public int lCommonPrefix(String a, String b) { int i = 0, n = Math.min(l(a), l(b)); while (i < n && a.charAt(i) == b.charAt(i)) ++i; return i; } 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 List countIteratorToList(int b) { return countIteratorToList(0, b); } static public List countIteratorToList(int a, int b) { return asList(countIterator(a, b)); } static public List countIteratorToList(int b, IF1 f) { return countIteratorToList(0, b, f); } static public List countIteratorToList(int a, int b, IF1 f) { return asList(countIterator(a, b, f)); } static public List countIteratorToList(int a, int b, int step) { return asList(countIterator(a, b, step)); } static public List countIteratorToList(double a, double b, double step, IF1 f) { return asList(countIterator(a, b, step, f)); } static public List countIteratorToList(double a, double b, double step) { return asList(countIterator(a, b, step)); } static public List countIteratorToList(IF1 f, double a, double b, double step) { return asList(countIterator(f, a, b, step)); } static public List countIteratorToList(IF1 f, int b) { return countIteratorToList(f, 0, b); } static public List countIteratorToList(IF1 f, int a, int b) { return asList(countIterator(f, a, b)); } static public IterableIterator countIterator_exclusive(int b) { return countIterator_exclusive(0, b); } static public IterableIterator countIterator_exclusive(int a, int b) { return new IterableIterator() { public int i = a; public boolean hasNext() { return i < b; } public Integer next() { return i++; } }; } static public IterableIterator countIterator_exclusive(int b, IF1 f) { return countIterator_exclusive(0, b, f); } static public IterableIterator countIterator_exclusive(int a, int b, IF1 f) { return mapI_if1(f, countIterator_exclusive(a, b)); } static public IterableIterator countIterator_exclusive_step(final int a, final int b, final int step) { assertTrue("step > 0", step > 0); return new IterableIterator() { public int i = a; public boolean hasNext() { return i < b; } public Integer next() { var j = i; i += step; return j; } }; } static public IterableIterator countIterator_exclusive_step(double a, double b, double step) { assertTrue("step > 0", step > 0); return new IterableIterator() { public double i = a; public boolean hasNext() { return i < b; } public Double next() { var j = i; i += step; return j; } }; } static public IterableIterator countIterator_exclusive_step(double a, double b, double step, IF1 f) { return mapI_if1(f, countIterator_exclusive_step(a, b, step)); } static public Rect boundsAsRect(Component c) { return boundsRect(c); } static public int indexOfMax(List l, IF1 f) { Best_comparable best = new Best_comparable(); for (int i = 0; i < l(l); i++) best.put(i, f.get(l.get(i))); return or(best.get(), -1); } static public List allScreenBounds() { return map(__79 -> screenBounds(__79), screenDevices()); } static public int area(Rect r) { return rectArea(r); } static public double area(DoubleRect r) { return r == null ? 0 : r.w * r.h; } static public int area(WidthAndHeight img) { return img == null ? 0 : img.getWidth() * img.getHeight(); } static public byte[] intToBytes(int i) { return new byte[] { (byte) (i >>> 24), (byte) (i >>> 16), (byte) (i >>> 8), (byte) i }; } static public void selectRow(final JTable table, final int i) { if (table != null) { swing(() -> { if (i >= 0 && i < table.getRowCount()) { table.setRowSelectionInterval(i, i); scrollRowToVisible(table, i); } else table.clearSelection(); }); } } static public void selectRow(final JList list, final int i) { if (list != null) { swing(() -> { if (i >= 0 && i < listRowCount(list)) list.setSelectedIndex(i); else list.clearSelection(); }); } } static public int jlist_indexOf(JList list, A item) { return swing(new F0() { public Integer get() { try { ListModel model = list.getModel(); int n = model.getSize(); for (int i = 0; i < n; i++) if (eq(model.getElementAt(i), item)) return i; return -1; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ListModel model = list.getModel();\r\n int n = model.getSize();\r\n for ..."; } }); } static public IterableIterator lines_iterator(final String s) { if (s == null) return emptyIterableIterator(); return iteratorFromFunction(new F0() { public int start = 0; public String get() { int i = toLines_nextLineBreak(s, start); if (i < 0) { String toReturn = s.length() > start ? s.substring(start) : null; start = s.length(); return toReturn; } String toReturn = 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 toReturn; } }); } static public List wrapAsList(A[] a) { return wrapArrayAsList(a); } static public Object costCenter() { return mc(); } static public TimeZone localTimeZone() { return getTimeZone(standardTimeZone()); } static public A[] newArray(Class c, int n) { return typedArray(c, n); } static public Map synchronizedMRUCache(int maxSize) { return synchroMap(new MRUCache(maxSize)); } 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 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, (ITokCondition) 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, IIntPred condition) { return jfind(tok, 1, in, condition); } static public int jfind(List tok, int startIndex, String in, IIntPred condition) { return jfind(tok, startIndex, in, tokCondition(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 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 void replaceCollection(Collection dest, Collection src) { if (dest == src) return; dest.clear(); if (src != null) dest.addAll(src); } static public void replaceListPart(List l, int i, int j, List l2) { replaceSublist(l, i, j, l2); } static public boolean isLocalhost(String ip) { return isLoopbackIP(ip) || eqic(ip, "localhost"); } static public int vmPort() { return myVMPort(); } static public DialogIO talkToThisVM() { return new talkToThisVM_IO(); } static public class talkToThisVM_IO extends DialogIO { public List answers = ll(thisVMGreeting()); public boolean isLocalConnection() { return true; } public boolean isStillConnected() { return true; } public int getPort() { return vmPort(); } public void sendLine(String line) { answers.add(or2(sendToThisVM_newThread(line), "?")); } public String readLineImpl() { try { return popFirst(answers); } catch (Exception __e) { throw rethrow(__e); } } public void close() { } public Socket getSocket() { return null; } } 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 Map newFindBot2_cache = synchroHashMap(); static public boolean newFindBot2_verbose = false; static public DialogIO newFindBot2(String name) { Integer port = newFindBot2_cache.get(name); if (port != null) { if (newFindBot2_verbose) print("newFindBot2: testing " + name + " => " + port); DialogIO io = talkTo(port); String q = format("has bot *", name); String s = io.ask(q); if (match("yes", s)) { io = talkToSubBot(name, io); call(io, "pushback", "?"); return io; } newFindBot2_cache.remove(name); if (newFindBot2_verbose) print("newFindBot2: dropping " + name + " => " + port); } DialogIO io = findBot(name); if (io != null) { newFindBot2_cache.put(name, io.getPort()); if (newFindBot2_verbose) print("newFindBot2: remembering " + name + " => " + port); } return io; } static public class ScannedBot implements IFieldsToList { static final public String _fieldOrder = "helloString address"; public String helloString; public String address; public ScannedBot() { } public ScannedBot(String helloString, String address) { this.address = address; this.helloString = helloString; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + helloString + ", " + address + ")"; } public boolean equals(Object o) { if (!(o instanceof ScannedBot)) return false; ScannedBot __1 = (ScannedBot) o; return eq(helloString, __1.helloString) && eq(address, __1.address); } public int hashCode() { int h = 1660478935; h = boostHashCombine(h, _hashCode(helloString)); h = boostHashCombine(h, _hashCode(address)); return h; } public Object[] _fieldsToList() { return new Object[] { helloString, address }; } } static public List fullBotScan() { return fullBotScan(""); } static public List fullBotScan(String searchPattern) { List bots = new ArrayList(); for (ProgramScan.Program p : quickBotScan()) { String botName = firstPartOfHelloString(p.helloString); boolean isVM = startsWithIgnoreCase(p.helloString, "This is a JavaX VM."); boolean shouldRecurse = swic(botName, "Multi-Port") || isVM; if (swic(botName, searchPattern)) bots.add(new ScannedBot(botName, "" + p.port)); if (shouldRecurse) try { Map subBots = (Map) unstructure(sendToLocalBotQuietly(p.port, "list bots")); for (Number vport : subBots.keySet()) { botName = subBots.get(vport); if (swic(botName, searchPattern)) bots.add(new ScannedBot(botName, p.port + "/" + vport)); } } catch (Exception e) { e.printStackTrace(); } } return bots; } static public Object unstructure_startingAtIndex(String s, int i) { return unstructure_tok(javaTokC_noMLS_iterator(s, i), false, null); } static public TreeMap revTreeMap() { return new TreeMap(reverseComparator()); } static public int indexOfIC_underscore(String a, String b) { int la = l(a), lb = l(b); if (la < lb) return -1; int n = la - lb; elsewhere: for (int i = 0; i <= n; i++) { for (int j = 0; j < lb; j++) { char c2 = b.charAt(j); if (c2 == '_' || eqic(c2, a.charAt(i + j))) { } else continue elsewhere; } return i; } return -1; } static public B secondOfPair(Pair p) { return p == null ? null : p.b; } static public void consoleClearInput() { consoleSetInput(""); } static public boolean possibleGlobalID(String s) { return l(s) == globalIDLength() && allLowerCaseCharacters(s); } static public IterableIterator iteratorFromFunction_withEndMarker_f0(final F0 f) { class IFF2 extends IterableIterator { public A a; public boolean have, done; public boolean hasNext() { getNext(); return !done; } public A next() { getNext(); if (done) throw fail(); A _a = a; a = null; have = false; return _a; } public void getNext() { if (done || have) return; Object o = f.get(); if (o == iteratorFromFunction_endMarker) { done = true; return; } a = (A) o; have = true; } } ; return new IFF2(); } static public boolean hasBot(String searchPattern) { try { DialogIO io = findBot(searchPattern); if (io != null) { io.close(); return true; } else return false; } catch (Exception __e) { throw rethrow(__e); } } static public boolean isOK(String s) { s = trim(s); return swic(s, "ok ") || eqic(s, "ok") || matchStart("ok", s); } static public String sendOpt(String bot, String text, Object... args) { return sendToLocalBotOpt(bot, text, args); } static public boolean isMainProgram() { return creator() == null; } static public void cleanKill() { cleanKillVM(); } static public Android3 methodsBot2(String name, final Object receiver, final List exposedMethods) { return methodsBot2(name, receiver, exposedMethods, null); } static public Android3 methodsBot2(String name, final Object receiver, final List exposedMethods, final Lock lock) { Android3 android = new Android3(); android.greeting = name; android.console = false; android.responder = new Responder() { public String answer(String s, List history) { return exposeMethods2(receiver, s, exposedMethods, lock); } }; return makeBot(android); } static public List db_standardExposedMethods_list = ll("xlist", "xnew", "xset", "xdelete", "xget", "xclass", "xfullgrab", "xshutdown", "xchangeCount", "xcount"); static public List db_standardExposedMethods() { return db_standardExposedMethods_list; } 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 List listFilesNotDirs(String dir) { return listFilesOnly(dir); } static public List listFilesNotDirs(File... dirs) { return listFilesOnly(dirs); } static public int matcherInt(Matcher m, int i) { return parseInt(m.group(i)); } static public long timestampFromYMDHM(int y, int m, int d, int h, int minutes) { return new GregorianCalendar(y, m - 1, d, h, minutes).getTimeInMillis(); } static public List sortByMap_inPlace(List l, Map map) { sort(l, mapComparator(map)); return l; } static public boolean defaultAgeBasedBackupRetentionStrategy_shouldKeep(double age, double lastAge) { if (age <= 1 / 12.0) return true; if (age <= 0.5 && age >= lastAge + 1 / 12.0) return true; if (age <= 7 && age >= lastAge + 1) return true; if (age <= 28 && age >= lastAge + 7) return true; if (age >= lastAge + 365.0 / 12) return true; return false; } static public A bindListenerToComponent(A component, IHasChangeListeners source, Runnable listener) { if (source != null && listener != null) bindToComponent(component, new Runnable() { public void run() { try { source.onChangeAndNow(listener); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "source.onChangeAndNow(listener);"; } }, new Runnable() { public void run() { try { source.removeChangeListener(listener); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "source.removeChangeListener(listener)"; } }); return component; } 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 BufferedImage drawImage(BufferedImage canvas, Image img, Pt p) { return drawImageOnImage(img, canvas, p.x, p.y); } static public void drawImage(BufferedImage g, Image img) { drawImage(graphics(g), img); } static public void drawImage(Graphics2D g, Image img) { drawImage(g, img, 0, 0); } static public void drawImage(Graphics2D g, Image img, Pt p) { drawImage(g, img, p.x, p.y); } static public void drawImage(Graphics2D g, Image img, int x, int y) { { if (g != null) g.drawImage(img, x, y, null); } } static public Set listFields(Object c) { TreeSet fields = new TreeSet(); for (Field f : _getClass(c).getDeclaredFields()) fields.add(f.getName()); return fields; } static public boolean eqicOrEq(Object a, Object b) { return a instanceof String && b instanceof String ? eqic((String) a, (String) b) : eq(a, b); } static public Throwable printStackTrace2(Throwable e) { print(getStackTrace2(e)); return e; } static public void printStackTrace2() { printStackTrace2(new Throwable()); } static public void printStackTrace2(String msg) { printStackTrace2(new Throwable(msg)); } static public Throwable innerException(Throwable e) { return getInnerException(e); } static public AutoCloseable tempUncancelThread() { return tempRemove(ping_actions, Thread.currentThread()); } static public boolean setAdd(Collection c, A a) { if (c == null || c.contains(a)) return false; c.add(a); return true; } static public File firstFileThatExists(String... paths) { return oneOfTheFiles(paths); } static public File firstFileThatExists(File... files) { return oneOfTheFiles(files); } static public File firstFileThatExists(Iterable files) { return oneOfTheFiles(files); } static public List windowsProgramFilesDirs() { return dirsThatExist("C:\\Program Files", "C:\\Program Files (x86)"); } static public File defaultExtension(String ext, File file) { if (empty(ext)) return file; if (file == null || fileHasAnyExtensionAtAll(file)) return file; return appendToFileName(addDotPrefix(ext), file); } static public String defaultExtension(String ext, String fileName) { if (empty(ext)) return fileName; if (fileName == null || contains(fileName, '.')) return fileName; return rjoin(addDotPrefix(ext), fileName); } static public String utf8streamToString(InputStream in) { return readerToString(utf8bufferedReader(in)); } 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 boolean isCIMap(Map m) { return m instanceof TreeMap && ((TreeMap) m).comparator() == caseInsensitiveComparator(); } static public Map standardClassesMap() { return standardClassesMap_uncached(); } static public List stdFunctionListSnippetIDs() { return ll("#1006654", "#761"); } static public Map parseStdFunctionsList(String snippetSrc) { return parseStdFunctionsList(snippetSrc, new LinkedHashMap()); } static public Map parseStdFunctionsList(String snippetSrc, Map map) { List tok = javaTok(snippetSrc); int i = findCodeTokens(tok, "standardFunctions", "=", "litlist", "("); int opening = i + 6; int closing = indexOf(tok, ")", opening) - 1; for (i = opening + 2; i < closing; i += 4) { String[] f = unquote(tok.get(i)).split("/"); map.put(f[1], f[0]); } return map; } static public boolean preferCached = false; static public boolean loadSnippet_debug = false; static public ThreadLocal loadSnippet_silent = new ThreadLocal(); static public ThreadLocal loadSnippet_publicOnly = new ThreadLocal(); static public int loadSnippet_timeout = 30000; static public String loadSnippet(String snippetID) { try { if (snippetID == null) return null; return loadSnippet(parseSnippetID(snippetID), preferCached); } catch (Exception __e) { throw rethrow(__e); } } static public String loadSnippet(String snippetID, boolean preferCached) throws IOException { return loadSnippet(parseSnippetID(snippetID), preferCached); } static public IF1 loadSnippet; static public String loadSnippet(long snippetID) { return loadSnippet != null ? loadSnippet.get(snippetID) : loadSnippet_base(snippetID); } final static public String loadSnippet_fallback(IF1 _f, long snippetID) { return _f != null ? _f.get(snippetID) : loadSnippet_base(snippetID); } static public String loadSnippet_base(long snippetID) { try { return loadSnippet(snippetID, preferCached); } catch (Exception __e) { throw rethrow(__e); } } static public String loadSnippet(long snippetID, boolean preferCached) throws IOException { if (isLocalSnippetID(snippetID)) return loadLocalSnippet(snippetID); IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.loadSnippet(fsI(snippetID)); return loadSnippet_noResourceLoader(snippetID, preferCached); } static public String loadSnippet_noResourceLoader(long snippetID, boolean preferCached) throws IOException { String text; initSnippetCache(); text = DiskSnippetCache_get(snippetID); if (preferCached && text != null) return text; try { if (loadSnippet_debug && text != null) System.err.println("md5: " + md5(text)); String url = tb_mainServer() + "/getraw.php?id=" + snippetID + "&utf8=1"; if (nempty(text)) url += "&md5=" + md5(text); if (!isTrue(loadSnippet_publicOnly.get())) url += standardCredentials(); String text2 = loadSnippet_loadFromServer(url); boolean same = eq(text2, "==*#*=="); if (loadSnippet_debug) print("loadSnippet: same=" + same); if (!same) text = text2; } catch (RuntimeException e) { e.printStackTrace(); throw new IOException("Snippet #" + snippetID + " not found or not public"); } try { initSnippetCache(); DiskSnippetCache_put(snippetID, text); } catch (IOException e) { System.err.println("Minor warning: Couldn't save snippet to cache (" + DiskSnippetCache_getDir() + ")"); } return text; } static public File DiskSnippetCache_dir; public static void initDiskSnippetCache(File dir) { DiskSnippetCache_dir = dir; dir.mkdirs(); } public static synchronized String DiskSnippetCache_get(long snippetID) throws IOException { return loadTextFile(DiskSnippetCache_getFile(snippetID).getPath(), null); } static public File DiskSnippetCache_getFile(long snippetID) { return new File(DiskSnippetCache_dir, "" + snippetID); } public static synchronized void DiskSnippetCache_put(long snippetID, String snippet) throws IOException { saveTextFile(DiskSnippetCache_getFile(snippetID).getPath(), snippet); } public static File DiskSnippetCache_getDir() { return DiskSnippetCache_dir; } public static void initSnippetCache() { if (DiskSnippetCache_dir == null) initDiskSnippetCache(getGlobalCache()); } static public String loadSnippet_loadFromServer(String url) { Integer oldTimeout = setThreadLocal(loadPage_forcedTimeout_byThread, loadSnippet_timeout); try { return isTrue(loadSnippet_silent.get()) ? loadPageSilently(url) : loadPage(url); } finally { loadPage_forcedTimeout_byThread.set(oldTimeout); } } static public int typeConversionScore(Class a, Class b) { if (a == b) return 0; if (b.isPrimitive()) { if (a.isPrimitive()) { if (b == boolean.class) return Integer.MAX_VALUE; if (b == byte.class) return Integer.MAX_VALUE; if (b == char.class) return a == byte.class ? -2 : Integer.MAX_VALUE; if (b == short.class) return a == byte.class ? -2 : Integer.MAX_VALUE; if (b == int.class) return a == byte.class || a == char.class || a == short.class ? -2 : Integer.MAX_VALUE; if (b == long.class) return a == byte.class || a == char.class || a == short.class || a == int.class ? -2 : Integer.MAX_VALUE; if (b == float.class) return a == byte.class || a == char.class || a == short.class || a == int.class ? -2 : Integer.MAX_VALUE; return a != boolean.class ? -2 : Integer.MAX_VALUE; } else { return primitiveToBoxedType(b) == a ? 1 : Integer.MAX_VALUE; } } else { if (a.isPrimitive()) return primitiveToBoxedType(a) == b ? 1 : Integer.MAX_VALUE; if (!b.isAssignableFrom(a)) return Integer.MAX_VALUE; if (a.isInterface() || b.isInterface()) return 1; return subclassDistance(a, b); } } static public Class boxedToPrimitiveType(Class type) { if (type == Boolean.class) return boolean.class; if (type == Integer.class) return int.class; if (type == Long.class) return long.class; if (type == Float.class) return float.class; if (type == Short.class) return short.class; if (type == Character.class) return char.class; if (type == Byte.class) return byte.class; if (type == Double.class) return double.class; return null; } static public Graphics2D antiAliasOn(Graphics2D g) { g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); return g; } static public Map synchroIdentityHashMap() { return synchroMap(new IdentityHashMap()); } static public void mapPut2(Map map, A key, B value) { if (map != null && key != null) if (value != null) map.put(key, value); else map.remove(key); } static public Class primitiveToBoxedTypeOpt(Class type) { return or(primitiveToBoxedType(type), type); } 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 "return RightAlignedLine(components);"; } }); } static public JPanel jrightAlignedLine(List components) { return jrightAlignedLine(asArray(Component.class, components)); } static public Object[] mapToParams(Map map) { return mapToObjectArray(map); } 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 boolean neqic(String a, String b) { return !eqic(a, b); } static public boolean neqic(char a, char b) { return !eqic(a, b); } 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 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 Map compileRegexpIC_cache = syncMRUCache(10); static public java.util.regex.Pattern compileRegexpIC(String pat) { java.util.regex.Pattern p = compileRegexpIC_cache.get(pat); if (p == null) { try { compileRegexpIC_cache.put(pat, p = java.util.regex.Pattern.compile(pat, Pattern.CASE_INSENSITIVE)); } catch (PatternSyntaxException e) { throw rethrow(wrapPatternSyntaxException(e)); } } return p; } static public boolean zipFileContains(File inZip, String fileName) { try { ZipFile zip = new ZipFile(inZip); try { return zipFileContains(zip, fileName); } finally { zip.close(); } } catch (Exception __e) { throw rethrow(__e); } } static public boolean zipFileContains(ZipFile zip, String fileName) { try { return zip.getEntry(fileName) != null; } catch (Exception __e) { throw rethrow(__e); } } static public File envJavaHome() { return newFile(System.getProperty("java.home")); } 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 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(Boolean internalFrame, Object... _parts) { IVF1 closeFrame = isTrue(internalFrame) ? __1 -> disposeInternalFrame(__1) : isFalse(internalFrame) ? __2 -> disposeFrame(__2) : null; return showForm_makeComponents(closeFrame, _parts); } static public List> showForm_makeComponents(IVF1 closeFrame, Object... _parts) { List> l = new ArrayList(); List parts = asList(_parts); JButton submitButton = null; for (int i = 0; i < l(parts); i++) if (parts.get(i) instanceof Swingable) parts.set(i, ((Swingable) parts.get(i)).visualize()); for (int i = 0; i < l(parts); i++) { 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(__80 -> wrapForSmartAdd_jComponent(__80), 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(__81 -> wrapForSmartAdd_jComponent(__81), 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 (closeFrame != null) closeFrame.get(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 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 showFormSubmitButtonName() { return "Submit"; } 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 int textAreaTextLength(JTextComponent ta) { return l(getText(ta)); } static public byte[] base64decode(String s) { byte[] alphaToInt = base64decode_base64toint; int sLen = s.length(); int numGroups = sLen / 4; if (4 * numGroups != sLen) throw new IllegalArgumentException("String length must be a multiple of four."); int missingBytesInLastGroup = 0; int numFullGroups = numGroups; if (sLen != 0) { if (s.charAt(sLen - 1) == '=') { missingBytesInLastGroup++; numFullGroups--; } if (s.charAt(sLen - 2) == '=') missingBytesInLastGroup++; } byte[] result = new byte[3 * numGroups - missingBytesInLastGroup]; int inCursor = 0, outCursor = 0; for (int i = 0; i < numFullGroups; i++) { int ch0 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); int ch1 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); int ch2 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); int ch3 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); result[outCursor++] = (byte) ((ch2 << 6) | ch3); } if (missingBytesInLastGroup != 0) { int ch0 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); int ch1 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); if (missingBytesInLastGroup == 1) { int ch2 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); } } return result; } static public int base64decode_base64toint(char c, byte[] alphaToInt) { int result = alphaToInt[c]; if (result < 0) throw new IllegalArgumentException("Illegal character " + c); return result; } static final public byte[] base64decode_base64toint = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; static public betterCIComparator_C betterCIComparator_instance; static public betterCIComparator_C betterCIComparator() { if (betterCIComparator_instance == null) betterCIComparator_instance = new betterCIComparator_C(); return betterCIComparator_instance; } final static public class betterCIComparator_C implements Comparator { public int compare(String s1, String s2) { if (s1 == null) return s2 == null ? 0 : -1; if (s2 == null) return 1; int n1 = s1.length(); int n2 = s2.length(); int min = Math.min(n1, n2); for (int i = 0; i < min; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) { c1 = Character.toUpperCase(c1); c2 = Character.toUpperCase(c2); if (c1 != c2) { c1 = Character.toLowerCase(c1); c2 = Character.toLowerCase(c2); if (c1 != c2) { return c1 - c2; } } } } return n1 - n2; } } static public AlphanumComparator alphaNumComparator_instance; static public Comparator alphaNumComparator() { if (alphaNumComparator_instance == null) alphaNumComparator_instance = new AlphanumComparator(); return alphaNumComparator_instance; } 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 Object realMC() { return getThreadLocal(realMC_tl()); } static public Object safeUnstructureGZFile(File f) { try { if (!fileExists(f)) return null; BufferedReader reader = utf8BufferedReader(gzInputStream(f)); return unstructure_tok(javaTokC_noMLS_onReader(reader), true, null); } catch (Exception __e) { throw rethrow(__e); } } static public void upgradeJavaXAndRestart() { run("#1001639"); restart(); sleep(); } static public TreeSet caseInsensitiveSet_treeSet() { return new TreeSet(caseInsensitiveComparator()); } static public TreeSet caseInsensitiveSet_treeSet(Collection c) { return toCaseInsensitiveSet_treeSet(c); } 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 TreeSet treeSet() { return new TreeSet(); } static public List allFieldObjects_dontMakeAccessible(Object o) { List fields = new ArrayList(); Class _c = _getClass(o); do { addAll(fields, _c.getDeclaredFields()); _c = _c.getSuperclass(); } while (_c != null); return fields; } static public Pair pairMapB(Object f, Pair p) { return p == null ? null : pair(p.a, callF(f, p.b)); } static public Pair pairMapB(IF1 f, Pair p) { return p == null ? null : pair(p.a, f.get(p.b)); } static public Pair pairMapB(Pair p, Object f) { return pairMap(f, p); } static public Map mapToKeys(Iterable l, IF1 f) { if (l == null) return null; HashMap map = new HashMap(); for (A a : l) map.put(f.get(a), a); return map; } static public Map mapToKeys(IF1 f, A[] l) { return mapToKeys(f, asList(l)); } static public Map mapToKeys(IF1 f, Iterable l) { return mapToKeys(l, f); } static public Map weakMap() { return newWeakHashMap(); } static public String toStringOpt(Object o) { return o instanceof String ? ((String) o) : null; } static public > C syncMapRemove_deleteMapIfEmpty(C map, A key) { if (map != null && key != null) synchronized (collectionMutex(map)) { map.remove(key); if (map.isEmpty()) return null; } return map; } static public boolean isInAnonymousClass(Object o) { if (o == null) return false; return isAnonymousClassName(className(o)); } static public String fromUtf8(byte[] bytes) { try { return bytes == null ? null : new String(bytes, utf8charset()); } catch (Exception __e) { throw rethrow(__e); } } static public Map loadFont_cached_cache = new HashMap(); static synchronized public Font loadFont_cached(String snippetID) { try { snippetID = formatSnippetID(snippetID); Font f = loadFont_cached_cache.get(snippetID); if (f == null) loadFont_cached_cache.put(snippetID, f = loadFont(snippetID, 12f)); return f; } catch (Exception __e) { throw rethrow(__e); } } static synchronized public Font loadFont_cached(String snippetID, float size) { try { return loadFont_cached(snippetID).deriveFont(size); } catch (Exception __e) { throw rethrow(__e); } } static public int tabCount(JTabbedPane tabs) { return tabs == null ? 0 : swing(() -> tabs.getTabCount()); } static public class mapI_if1_It extends IterableIterator { public IF1 f; public Iterator i; public mapI_if1_It() { } public mapI_if1_It(IF1 f, Iterator i) { this.i = i; this.f = f; } public boolean hasNext() { return i.hasNext(); } public B next() { return f.get(i.next()); } public String toString() { return formatFunctionCall("mapI_if1", f, i); } } static public IterableIterator mapI_if1(IF1 f, Iterable i) { return new mapI_if1_It(f, i.iterator()); } static public IterableIterator mapI_if1(Iterable i, IF1 f) { return mapI_if1(f, i); } static public Rect boundsRect(Component c) { return toRect(getBounds(c)); } static public int rectArea(Rect r) { return r == null ? 0 : r.w * r.h; } static public void scrollRowToVisible(JTable t, int rowIndex) { int colIndex = 0; if (!(t.getParent() instanceof JViewport)) return; JViewport viewport = (JViewport) t.getParent(); Rectangle rect = t.getCellRect(rowIndex, colIndex, true); Rectangle viewRect = viewport.getViewRect(); int x = viewRect.x; int y = viewRect.y; if (rect.x >= viewRect.x && rect.x <= (viewRect.x + viewRect.width - rect.width)) { } else if (rect.x < viewRect.x) { x = rect.x; } else if (rect.x > (viewRect.x + viewRect.width - rect.width)) { x = rect.x - viewRect.width + rect.width; } if (rect.y >= viewRect.y && rect.y <= (viewRect.y + viewRect.height - rect.height)) { } else if (rect.y < viewRect.y) { y = rect.y; } else if (rect.y > (viewRect.y + viewRect.height - rect.height)) { y = rect.y - viewRect.height + rect.height; } viewport.setViewPosition(new Point(x, y)); } static public int listRowCount(JList list) { return list == null ? 0 : swing(new F0() { public Integer get() { try { return list.getModel().getSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return list.getModel().getSize();"; } }); } static public IterableIterator iteratorFromFunction(final Object f) { class IFF extends IterableIterator { 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 = (A) callF(f); done = a == null; } } ; return new IFF(); } static public IterableIterator iteratorFromFunction(F0 f) { return iteratorFromFunction_f0(f); } static public IterableIterator iteratorFromFunction(IF0 f) { return iteratorFromFunction_if0(f); } 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 A[] typedArray(Class c, int n) { return (A[]) Array.newInstance(c, n); } static public ITokCondition tokCondition(IIntPred condition) { return condition == null ? null : (tok, nIdx) -> condition.get(nIdx); } 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 List replaceSublist(List l, IntRange r, List y) { return replaceSublist(l, r.start, r.end, y); } 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 boolean isLoopbackIP(String ip) { return eq(ip, "127.0.0.1"); } static public int myVMPort() { List records = (List) (get(getJavaX(), "record_list")); Object android = last(records); return or0((Integer) get(android, "port")); } static public String thisVMGreeting() { List record_list = (List) (get(getJavaX(), "record_list")); Object android = first(record_list); return getString(android, "greeting"); } static public String sendToThisVM_newThread(String s, Object... args) { final String _s = format(s, args); try { return (String) evalInNewThread(new F0() { public Object get() { try { return callStaticAnswerMethod(getJavaX(), _s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return callStaticAnswerMethod(getJavaX(), _s);"; } }); } catch (Throwable e) { e = getInnerException(e); printStackTrace(e); return str(e); } } static public boolean match(String pat, String s) { return match3(pat, s); } static public boolean match(String pat, String s, Matches matches) { return match3(pat, s, matches); } static public boolean match(String pat, List toks, Matches matches) { return match3(pat, toks, matches); } static public Comparator reverseComparator(Comparator c) { return (a, b) -> c.compare(b, a); } static public Comparator reverseComparator() { return (a, b) -> cmp(b, a); } static public void consoleSetInput(final String text) { if (headless()) return; setTextAndSelectAll(consoleInputField(), text); focusConsole(); } static public boolean allLowerCaseCharacters(String s) { for (int i = 0; i < l(s); i++) if (Character.getType(s.charAt(i)) != Character.LOWERCASE_LETTER) return false; return true; } 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 String sendToLocalBotOpt(String bot, String text, Object... args) { if (bot == null) return null; text = format(text, args); DialogIO channel = findBot(bot); try { if (channel == null) { print(quote(bot) + " not found, skipping send: " + quote(text)); return null; } try { channel.readLine(); print(shorten(bot + "> " + text, 200)); channel.sendLine(text); String s = channel.readLine(); print(shorten(bot + "< " + s, 200)); return s; } catch (Throwable e) { e.printStackTrace(); return null; } } finally { _close(channel); } } static public boolean exposeMethods2_debug = false; static public String exposeMethods2(Object receiver, String s, List methodNames) { return exposeMethods2(receiver, s, methodNames, null); } static public String exposeMethods2(Object receiver, String s, List methodNames, Lock lock) { Matches m = new Matches(); if (exposeMethods2_debug) print("Received: " + s); if (match("call *", s, m)) { List l; if (isIdentifier(m.unq(0))) l = ll(m.unq(0)); else l = (List) unstructure(m.unq(0)); String method = getString(l, 0); if (!contains(methodNames, method)) throw fail("Method not allowed: " + method); if (lock != null) lock.lock(); try { if (exposeMethods2_debug) print("Calling: " + method); Object o = call(receiver, method, asObjectArray(subList(l, 1))); if (exposeMethods2_debug) print("Got: " + getClassName(o)); return ok2(structure(o)); } finally { if (lock != null) lock.unlock(); } } if (match("list methods", s)) return ok2(structure(methodNames)); return null; } static public int makeBot(String greeting) { return makeAndroid3(greeting).port; } static public Android3 makeBot(Android3 a) { makeAndroid3(a); return a; } static public Android3 makeBot(String greeting, Object responder) { Android3 a = new Android3(greeting); a.responder = makeResponder(responder); makeBot(a); return a; } static public Android3 makeBot() { return makeAndroid3(defaultBotName()); } static public List listFilesOnly(String dir) { return listFilesOnly(new File(dir)); } static public List listFilesOnly(File... dirs) { return concatMap(dir -> listFilesWithSuffix("", dir), dirs); } static public Comparator mapComparator(final Map map) { return new Comparator() { public int compare(A a, A b) { return cmp(map.get(a), map.get(b)); } }; } static public BufferedImage drawImageOnImage(Image img, BufferedImage canvas, int x, int y) { createGraphics(canvas).drawImage(img, x, y, null); return canvas; } static public BufferedImage drawImageOnImage(Image img, BufferedImage canvas) { return drawImageOnImage(img, canvas, 0, 0); } static public Graphics2D graphics(BufferedImage img) { return imageGraphics(img); } static public String getStackTrace2(Throwable e) { return hideCredentials(getStackTrace(unwrapTrivialExceptionWraps(e)) + replacePrefix("java.lang.RuntimeException: ", "FAIL: ", hideCredentials(str(innerException2(e)))) + "\n"); } static public AutoCloseable tempRemove(Map map, A key) { if (map == null || !map.containsKey(key)) return null; B b = map.get(key); map.remove(key); return new AutoCloseable() { public String toString() { return "map.put(key, b);"; } public void close() throws Exception { map.put(key, b); } }; } static public List dirsThatExist(String... dirs) { return mapNonNulls(dirs, d -> dirOtherwiseNull(newFile(d))); } static public boolean fileHasAnyExtensionAtAll(File f) { return contains(fileName(f), '.'); } static public String addDotPrefix(String s) { return addPrefix(".", s); } static public String rjoin(Iterable strings) { return rjoin("", strings); } static public String rjoin(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 = reversed(strings).iterator(); if (i.hasNext()) { buf.append(i.next()); while (i.hasNext()) buf.append(glue).append(i.next()); } return buf.toString(); } static public String rjoin(String glue, String... strings) { return join(glue, asVirtualReversedList(strings)); } static public String rjoin(Iterable strings, String glue) { return rjoin(glue, strings); } static public String rjoin(String[] strings) { return rjoin("", strings); } static public String readerToString(Reader r) { try { if (r == null) return null; try { StringBuilder buf = new StringBuilder(); int n = 0; while (true) { int ch = r.read(); if (ch < 0) break; buf.append((char) ch); ++n; } return buf.toString(); } finally { r.close(); } } catch (Exception __e) { throw rethrow(__e); } } 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 Map standardClassesMap_uncached() { Map map = new HashMap(); for (String snippetID : standardClassesSnippetIDs()) for (String line : tlft_j(loadSnippet(snippetID))) { int idx = line.indexOf('/'); map.put(takeFirst(idx, line), substring(line, idx + 1)); } return map; } static public String loadLocalSnippet(String snippetID) { return loadLocalSnippet(psI(snippetID)); } static public String loadLocalSnippet(long snippetID) { return loadTextFile(localSnippetFile(snippetID)); } static public Class primitiveToBoxedType(Class type) { if (type == boolean.class) return Boolean.class; if (type == int.class) return Integer.class; if (type == long.class) return Long.class; if (type == float.class) return Float.class; if (type == short.class) return Short.class; if (type == char.class) return Character.class; if (type == byte.class) return Byte.class; if (type == double.class) return Double.class; return null; } static public int subclassDistance(Class a, Class b) { int n = 0; while (a != b) { a = a.getSuperclass(); if (a == null) return Integer.MAX_VALUE; ++n; } return n; } 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 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 RuntimeException wrapPatternSyntaxException(PatternSyntaxException e) { if (e == null) return null; String pat = e.getPattern(); int i = e.getIndex(); return new RuntimeException("Regular expression error between " + multiLineQuoteWithSpaces(substring(pat, 0, i)) + " and " + multiLineQuoteWithSpaces(substring(pat, i)) + " - " + e.getMessage()); } 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 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 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 disposeInternalFrame(Component c) { final JInternalFrame f = getInternalFrame(c); if (f != null) { swing(() -> { vmBus_send("disposingInternalFrame", f); f.dispose(); }); } } static public void setComponentID(Component c, String id) { if (c != null) componentID_map.put(c, id); } static public JComponent wrapForSmartAdd_jComponent(Object o) { return componentToJComponent(wrapForSmartAdd(o)); } 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 boolean isRunnable(Object o) { return o instanceof Runnable || hasMethod(o, "get"); } static public void onEnterInAllTextFields(JComponent c, Runnable action) { if (action == null) return; for (Component tf : allChildren(c)) onEnterIfTextField(tf, action); } static public void onEnterInAllTextFields(List c, Runnable action) { for (Object o : unnull(c)) if (o instanceof JComponent) onEnterInAllTextFields(((JComponent) o), action); } static public A makeBold(final A c) { if (c != null) { swing(() -> { c.setFont(c.getFont().deriveFont(java.awt.Font.BOLD)); }); } return c; } 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 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 ThreadLocal realMC_tl_tl = new ThreadLocal(); static public ThreadLocal realMC_tl() { return realMC_tl_tl; } static public TreeSet toCaseInsensitiveSet_treeSet(Iterable c) { if (isCISet(c)) return (TreeSet) c; TreeSet set = caseInsensitiveSet_treeSet(); addAll(set, c); return set; } static public TreeSet toCaseInsensitiveSet_treeSet(String... x) { TreeSet set = caseInsensitiveSet_treeSet(); addAll(set, x); return set; } static public Pair pairMap(Object f, Pair p) { return p == null ? null : pair(callF(f, p.a), callF(f, p.b)); } static public Pair pairMap(IF1 f, Pair p) { return p == null ? null : pair(callF(f, p.a), callF(f, p.b)); } static public Pair pairMap(Pair p, Object f) { return pairMap(f, p); } static public Font loadFont(String snippetID) { try { return loadFont(snippetID, 12f); } catch (Exception __e) { throw rethrow(__e); } } static public Font loadFont(InputStream in) { try { return Font.createFont(Font.TRUETYPE_FONT, in); } catch (Exception __e) { throw rethrow(__e); } } static public Font loadFont(String snippetID, float fontSize) { return loadFont(loadLibrary(snippetID), fontSize); } static public Font loadFont(File f, float fontSize) { try { return Font.createFont(Font.TRUETYPE_FONT, f).deriveFont(fontSize); } catch (Exception __e) { throw rethrow(__e); } } static public Font loadFont(InputStream in, float fontSize) { try { return Font.createFont(Font.TRUETYPE_FONT, in).deriveFont(fontSize); } catch (Exception __e) { throw rethrow(__e); } } static public IterableIterator iteratorFromFunction_f0(final F0 f) { class IFF2 extends IterableIterator { 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; } } ; return new IFF2(); } static public IterableIterator iteratorFromFunction_if0(final IF0 f) { class IFF2 extends IterableIterator { 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; } } ; return new IFF2(); } 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 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 int or0(Integer i) { return i == null ? 0 : i; } static public long or0(Long l) { return l == null ? 0L : l; } static public double or0(Double d) { return d == null ? 0.0 : d; } 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 evalInNewThread(final Object f) { final Flag flag = new Flag(); final Var var = new Var(); final Var exception = new Var(); { startThread(new Runnable() { public void run() { try { try { var.set(callF(f)); } catch (Throwable e) { exception.set(e); } flag.raise(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n var.set(callF(f));\r\n } catch (Throwable e) {\r\n exception..."; } }); } flag.waitUntilUp(); if (exception.has()) throw rethrow(exception.get()); return var.get(); } static public String callStaticAnswerMethod(List bots, String s) { for (Object c : bots) try { String answer = callStaticAnswerMethod(c, s); if (!empty(answer)) return answer; } catch (Throwable e) { print("Error calling " + getProgramID(c)); e.printStackTrace(); } return null; } static public String callStaticAnswerMethod(Object c, String s) { String answer = (String) callOpt(c, "answer", s, litlist(s)); if (answer == null) answer = (String) callOpt(c, "answer", s); return emptyToNull(answer); } static public String callStaticAnswerMethod(String s) { return callStaticAnswerMethod(mc(), s); } static public String callStaticAnswerMethod(String s, List history) { return callStaticAnswerMethod(mc(), s, history); } static public String callStaticAnswerMethod(Object c, String s, List history) { String answer = (String) callOpt(c, "answer", s, history); if (answer == null) answer = (String) callOpt(c, "answer", s); return emptyToNull(answer); } static public boolean match3(String pat, String s) { return match3(pat, s, null); } static public boolean match3(String pat, String s, Matches matches) { if (pat == null || s == null) return false; return match3(pat, parse3_cachedInput(s), matches); } static public boolean match3(String pat, List toks, Matches matches) { List tokpat = parse3_cachedPattern(pat); return match3(tokpat, toks, matches); } static public boolean match3(List tokpat, List toks, Matches matches) { String[] m = match2(tokpat, toks); if (m == null) return false; if (matches != null) matches.m = m; return true; } static public boolean headless() { return isHeadless(); } static public JTextField setTextAndSelectAll(final JTextField tf, final String text) { if (tf != null) { swing(() -> { tf.setText(text); tf.selectAll(); }); } return tf; } static public JTextField consoleInputField() { Object console = get(getJavaX(), "console"); return (JTextField) getOpt(console, "tfInput"); } static public void focusConsole(String s) { setConsoleInput(s); focusConsole(); } static public void focusConsole() { JComponent tf = consoleInputFieldOrComboBox(); if (tf != null) { tf.requestFocus(); } } static public Map componentID_map = weakHashMap(); static public String componentID(Component c) { return c == null ? null : componentID_map.get(c); } 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 ok2(String s) { return "ok " + s; } static public boolean makeAndroid3_disable = false; static public class Android3 implements AutoCloseable { public String greeting; public boolean publicOverride = false; public int startPort = 5000; public IResponder responder; public boolean console = true; public boolean quiet = false; public boolean daemon = false; public boolean incomingSilent = false; public int incomingPrintLimit = 200; public boolean useMultiPort = true; public boolean recordHistory = false; public boolean verbose = false; public int answerPrintLimit = 500; public boolean newLineAboveAnswer, newLineBelowAnswer; public int port; public long vport; public IDialogHandler handler; public ServerSocket server; public Android3(String greeting) { this.greeting = greeting; } public Android3() { } public void close() { dispose(); } synchronized public void dispose() { if (server != null) { try { server.close(); } catch (IOException e) { print("[internal] " + e); } server = null; } if (vport != 0) { try { print("Disposing " + this); removeFromMultiPort(vport); vport = 0; } catch (Throwable __e) { printStackTrace(__e); } } } public String toString() { return "Bot: " + greeting + " [port " + port + (vport == 0 ? "" : ", vport " + vport) + "]"; } } static abstract public class Responder implements IResponder { } public interface IResponder { public String answer(String s, List history); } static public Android3 makeAndroid3(final String greeting) { return makeAndroid3(new Android3(greeting)); } static public Android3 makeAndroid3(final String greeting, Responder responder) { Android3 android = new Android3(greeting); android.responder = responder; return makeAndroid3(android); } static public Android3 makeAndroid3(final Android3 a) { if (makeAndroid3_disable) return a; if (a.responder == null) a.responder = new Responder() { public String answer(String s, List history) { return callStaticAnswerMethod(s, history); } }; if (!a.quiet) print("[bot] " + a.greeting); if (a.console && (readLine_noReadLine || makeAndroid3_consoleInUse())) a.console = false; record(a); if (a.useMultiPort) a.vport = addToMultiPort(a.greeting, makeAndroid3_verboseResponder(a)); if (a.console) makeAndroid3_handleConsole(a); if (a.useMultiPort) return a; a.handler = makeAndroid3_makeDialogHandler(a); if (a.quiet) startDialogServer_quiet.set(true); try { a.port = a.daemon ? startDialogServerOnPortAboveDaemon(a.startPort, a.handler) : startDialogServerOnPortAbove(a.startPort, a.handler); } finally { startDialogServer_quiet.set(null); } a.server = startDialogServer_serverSocket; return a; } static public void makeAndroid3_handleConsole(final Android3 a) { if (!a.quiet) print("You may also type on this console."); { startThread(new Runnable() { public void run() { try { List history = new ArrayList(); while (licensed()) { String line; try { line = readLine(); } catch (Throwable e) { print(getInnerMessage(e)); break; } if (line == null) break; { history.add(line); history.add(makeAndroid3_getAnswer(line, history, a)); } } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "List history = new ArrayList();\r\n while (licensed()) {\r\n Stri..."; } }); } } static public DialogHandler makeAndroid3_makeDialogHandler(final Android3 a) { return new DialogHandler() { public void run(final DialogIO io) { if (!a.publicOverride && !(publicCommOn() || io.isLocalConnection())) { io.sendLine("Sorry, not allowed"); return; } String dialogID = randomID(8); io.sendLine(a.greeting + " / Your ID: " + dialogID); List history = new ArrayList(); while (io.isStillConnected()) { if (io.waitForLine()) { final String line = io.readLineNoBlock(); String s = dialogID + " at " + now() + ": " + quote(line); if (!a.incomingSilent) print(shorten(s, a.incomingPrintLimit)); if (eq(line, "bye")) { io.sendLine("bye stranger"); return; } Matches m = new Matches(); if (a.recordHistory) history.add(line); String answer; if (match3("this is a continuation of talk *", s, m) || match3("hello bot! this is a continuation of talk *", s, m)) { dialogID = unquote(m.m[0]); answer = "ok"; } else try { makeAndroid3_io.set(io); answer = makeAndroid3_getAnswer(line, history, a); } finally { makeAndroid3_io.set(null); } if (a.recordHistory) history.add(answer); io.sendLine(answer); } } } }; } static public String makeAndroid3_getAnswer(String line, List history, Android3 a) { String answer, originalAnswer; try { originalAnswer = a.responder.answer(line, history); answer = makeAndroid3_fallback(line, history, originalAnswer); } catch (Throwable e) { e = getInnerException(e); printStackTrace(e); originalAnswer = answer = e.toString(); } if (!a.incomingSilent) { if (originalAnswer == null) originalAnswer = "?"; if (a.newLineAboveAnswer) print(); print(">" + dropFirst(indentx(2, shorten(rtrim(originalAnswer), a.answerPrintLimit)))); if (a.newLineBelowAnswer) print(); } return answer; } static public String makeAndroid3_fallback(String s, List history, String answer) { if (answer == null && match3("what is your pid", s)) return getPID(); if (answer == null && match3("what is your program id", s)) return getProgramID(); if (match3("get injection id", s)) return getInjectionID(); if (answer == null) answer = "?"; if (answer.indexOf('\n') >= 0 || answer.indexOf('\r') >= 0) answer = quote(answer); return answer; } static public boolean makeAndroid3_consoleInUse() { if (isTrue(vm_generalMap_get("consoleInUse"))) return true; for (Object o : record_list) if (o instanceof Android3 && ((Android3) o).console) return true; return false; } static public Responder makeAndroid3_verboseResponder(final Android3 a) { return new Responder() { public String answer(String s, List history) { if (a.verbose) print("> " + shorten(s, a.incomingPrintLimit)); String answer = a.responder.answer(s, history); if (a.verbose) print("< " + shorten(answer, a.incomingPrintLimit)); return answer; } }; } static public ThreadLocal makeAndroid3_io = new ThreadLocal(); static public Android3 makeAndroid3() { return makeAndroid3(getProgramTitle() + "."); } static public String makeResponder_callAnswerMethod(Object bot, String s, List history) { String answer = (String) callOpt(bot, "answer", s, history); if (answer == null) answer = (String) callOpt(bot, "answer", s); return answer; } static public Responder makeResponder(final Object bot) { if (bot instanceof Responder) return (Responder) bot; if (bot instanceof String) { String f = (String) bot; return new Responder() { public String answer(String s, List history) { String answer = (String) callOptMC((String) bot, s, history); if (answer == null) answer = (String) callOptMC((String) bot, s); return answer; } }; } return new Responder() { public String answer(String s, List history) { return makeResponder_callAnswerMethod(bot, s, history); } }; } static public String defaultBotName() { return getProgramTitle() + "."; } static public List listFilesWithSuffix(File dir, String suffix) { List l = new ArrayList(); for (File f : listFiles(dir)) if (!f.isDirectory() && (empty(suffix) || endsWithIgnoreCase(f.getName(), suffix))) l.add(f); return l; } static public List listFilesWithSuffix(String suffix, File dir) { return listFilesWithSuffix(dir, suffix); } static public Throwable unwrapTrivialExceptionWraps(Throwable e) { if (e == null) return e; while (e.getClass() == RuntimeException.class && e.getCause() != null && eq(e.getMessage(), str(e.getCause()))) e = e.getCause(); return e; } 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 File dirOtherwiseNull(File dir) { return isDirectory(dir) ? dir : null; } static public List asVirtualReversedList(A[] array) { return wrapAsReversedList(array); } static public List standardClassesSnippetIDs() { return ll("#1003674", "#1034167"); } static public List tlft_j(String text) { return toLinesFullTrim_java(text); } 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 String multiLineQuoteWithSpaces(String s) { return multiLineQuote(" " + s + " "); } 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 > 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 Object vmBus_query(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); { var __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 boolean containsSpace(String s) { return containsSpaces(s); } 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 List allChildren(Component c) { return childrenOfType(c, Component.class); } static public void onEnterIfTextField(Component c, Runnable action) { if (action == null) return; if (c instanceof JTextField) onEnter(((JTextField) c), action); else if (c instanceof JComboBox) onEnter(((JComboBox) c), action); } 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 boolean isCISet(Iterable l) { return l instanceof TreeSet && ((TreeSet) l).comparator() == caseInsensitiveComparator(); } static public String emptyToNull(String s) { return eq(s, "") ? null : s; } static public Map emptyToNull(Map map) { return empty(map) ? null : map; } static public void setConsoleInput(String text) { consoleSetInput(text); } static public JComponent consoleInputFieldOrComboBox() { Object console = get(getJavaX(), "console"); JComboBox cb = (JComboBox) (getOpt(console, "cbInput")); if (cb != null) return cb; return (JTextField) getOpt(console, "tfInput"); } static public List parse3(String s) { return dropPunctuation(javaTokPlusPeriod(s)); } static public void removeFromMultiPort(long vport) { if (vport == 0) return; for (Object port : getMultiPorts()) call(port, "removePort", vport); } static public List record_list = synchroList(); static public void record(Object o) { record_list.add(o); } static public Object addToMultiPort_responder; static public long addToMultiPort(final String botName) { return addToMultiPort(botName, new Object() { public String answer(String s, List history) { String answer = (String) (callOpt(getMainClass(), "answer", s, history)); if (answer != null) return answer; answer = (String) callOpt(getMainClass(), "answer", s); if (answer != null) return answer; if (match3("get injection id", s)) return getInjectionID(); return null; } }); } static public long addToMultiPort(final String botName, final Object responder) { addToMultiPort_responder = responder; startMultiPort(); List ports = getMultiPorts(); if (ports == null) return 0; if (ports.isEmpty()) throw fail("No multiports!"); if (ports.size() > 1) print("Multiple multi-ports. Using last one."); Object port = last(ports); Object responder2 = new Object() { public String answer(String s, List history) { if (match3("get injection id", s)) return getInjectionID(); if (match3("your name", s)) return botName; return (String) call(responder, "answer", s, history); } }; record(responder2); return (Long) call(port, "addResponder", botName, responder2); } static public AtomicInteger dialogServer_clients = new AtomicInteger(); static public boolean dialogServer_printConnects = false; static public ThreadLocal startDialogServer_quiet = new ThreadLocal(); static public Set dialogServer_knownClients = synchroTreeSet(); static public int startDialogServerOnPortAbove(int port, IDialogHandler handler) { while (!forbiddenPort(port) && !startDialogServerIfPortAvailable(port, handler)) ++port; return port; } static public int startDialogServerOnPortAboveDaemon(int port, IDialogHandler handler) { while (!forbiddenPort(port) && !startDialogServerIfPortAvailable(port, handler, true)) ++port; return port; } static public void startDialogServer(int port, IDialogHandler handler) { if (!startDialogServerIfPortAvailable(port, handler)) throw fail("Can't start dialog server on port " + port); } static public boolean startDialogServerIfPortAvailable(int port, final IDialogHandler handler) { return startDialogServerIfPortAvailable(port, handler, false); } static public ServerSocket startDialogServer_serverSocket; static public boolean startDialogServerIfPortAvailable(int port, final IDialogHandler handler, boolean daemon) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); } catch (IOException e) { return false; } final ServerSocket _serverSocket = serverSocket; startDialogServer_serverSocket = serverSocket; Thread thread = new Thread("Socket accept port " + port) { public void run() { try { while (true) { try { final Socket s = _serverSocket.accept(); String client = s.getInetAddress().toString(); if (!dialogServer_knownClients.contains(client) && neq(client, "/127.0.0.1")) { print("connect from " + client + " - clients: " + dialogServer_clients.incrementAndGet()); dialogServer_knownClients.add(client); } String threadName = "Handling client " + s.getInetAddress(); Thread t2 = new Thread(threadName) { public void run() { try { final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); final BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); DialogIO io = new DialogIO() { public boolean isLocalConnection() { return s.getInetAddress().isLoopbackAddress(); } public boolean isStillConnected() { return !(eos || s.isClosed()); } public void sendLine(String line) { try { w.write(line + "\n"); w.flush(); } catch (Exception __e) { throw rethrow(__e); } } public String readLineImpl() { try { return in.readLine(); } catch (Exception __e) { throw rethrow(__e); } } public void close() { try { s.close(); } catch (IOException e) { } } public Socket getSocket() { return s; } }; try { handler.run(io); } finally { if (!io.noClose) s.close(); } } catch (IOException e) { print("[internal] " + e); } finally { } } }; t2.setDaemon(true); t2.start(); } catch (SocketTimeoutException e) { } } } catch (IOException e) { print("[internal] " + e); } } }; if (daemon) thread.setDaemon(true); thread.start(); if (!isTrue(getAndClearThreadLocal(startDialogServer_quiet))) print("Dialog server on port " + port + " started."); return true; } static public boolean publicCommOn() { return "1".equals(loadTextFile(new File(userHome(), ".javax/public-communication"))); } static public String processID_cached; static public String getPID() { if (processID_cached == null) { String name = ManagementFactory.getRuntimeMXBean().getName(); processID_cached = name.replaceAll("@.*", ""); } return processID_cached; } static public String getInjectionID() { return (String) call(getJavaX(), "getInjectionID", getMainClass()); } static public Object callOptMC(String method, Object... args) { return callOpt(mc(), method, args); } static public boolean isDirectory(File f) { return f != null && f.isDirectory(); } static public boolean isDirectory(String path) { return path != null && isDirectory(newFile(path)); } static public List wrapAsReversedList(A[] array) { int n = l(array); return new RandomAccessAbstractList() { public int size() { return n; } public A get(int i) { return array[n - 1 - i]; } public A set(int i, A a) { A old = array[n - 1 - i]; array[n - 1 - i] = a; return old; } }; } static public List toLinesFullTrim_java(String text) { return tlft(joinLines(map(__82 -> javaDropComments(__82), tlft(text)))); } static public String multiLineQuote(String s) { for (int i = 0; ; i++) { String closer = "]" + rep('=', i) + "]"; if (!contains(s, closer)) return "[" + rep('=', i) + "[" + s + closer; } } 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 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 int getScreenWidth() { return getScreenSize().width; } static public int getScreenHeight() { return getScreenSize().height; } 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 Object pcallFAll_returnFirstNotNull(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) { var __1 = pcallF(f, args); if (__1 != null) return __1; } return null; } static public Object pcallFAll_returnFirstNotNull(Iterator it, Object... args) { while (it.hasNext()) { var __2 = pcallF(it.next(), args); if (__2 != null) return __2; } return null; } 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 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 getMultiPorts() { return (List) callOpt(getJavaX(), "getMultiPorts"); } static public void startMultiPort() { List mp = getMultiPorts(); if (mp != null && mp.isEmpty()) { nohupJavax("#1001639"); throw fail("Upgrading JavaX, please restart this program afterwards."); } } static public Set synchroTreeSet() { return Collections.synchronizedSet(new TreeSet()); } static public Set synchroTreeSet(TreeSet set) { return Collections.synchronizedSet(set); } static public boolean forbiddenPort(int port) { return port == 5037; } static public String joinLines(List lines) { return fromLines(lines); } static public String joinLines(String glue, String text) { return join(glue, toLines(text)); } static public String javaDropComments(String s) { return javaDropAllComments(s); } static public Dimension getScreenSize() { return Toolkit.getDefaultToolkit().getScreenSize(); } static public Dimension getScreenSize(int iScreen) { return toDimension(screenBounds(iScreen).widthAndHeight()); } static public boolean isAllUpperCase(String s) { return hasLettersAllUpperCase(s); } static public boolean isUpperCaseLetter(char c) { return Character.isUpperCase(c); } static public List nlTok(String s) { return javaTokPlusPeriod(s); } static public String javaDropAllComments(String s) { return join(javaDropAllComments(javaTok(s))); } static public List javaDropAllComments(List tok) { for (int i = 0; i < l(tok); i += 2) tok.set(i, tok_javaDropCommentsFromWhitespace(tok.get(i))); return tok; } static public Dimension toDimension(WidthAndHeight wh) { return wh == null ? null : new Dimension(wh.getWidth(), wh.getHeight()); } static public boolean hasLettersAllUpperCase(String s) { return hasLetters(s) && !containsLowerCase(s); } static public String tok_javaDropCommentsFromWhitespace(String s) { int l = l(s), j = 0; StringBuilder buf = new StringBuilder(); while (j < l) { char c = s.charAt(j); char d = j + 1 >= l ? '\0' : s.charAt(j + 1); 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 { buf.append(c); ++j; } } return str(buf); } 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 boolean isLowerCase(char c) { return Character.isLowerCase(c); } static public class Chain implements Iterable { public A element; public Chain next; public int size; public Chain() { } public Chain(A element) { this.element = element; size = 1; } public Chain(A element, Chain next) { this.next = next; this.element = element; size = next != null ? next.size + 1 : 1; } public String toString() { return str(toList()); } public ArrayList toList() { ArrayList l = emptyList(size); Chain c = this; while (c != null) { l.add(c.element); c = c.next; } return l; } public Iterator iterator() { return toList().iterator(); } } static public class JSection extends SingleComponentPanel { public JSection(Component c) { super(c); } public String getTitle() { Border border = getBorder(); if (border instanceof TitledBorder) return ((TitledBorder) border).getTitle(); return null; } } static public class MultiSetMap implements IMultiMap { public Map> data = new HashMap>(); public int size; public MultiSetMap() { } public MultiSetMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); } public MultiSetMap(MultiSetMap map) { putAll(map); } public MultiSetMap(Map> data) { this.data = data; } public boolean put(A key, B value) { synchronized (data) { Set set = data.get(key); if (set == null) data.put(key, set = _makeEmptySet()); if (!set.add(value)) return false; { ++size; return true; } } } public boolean add(A key, B value) { return put(key, value); } public void addAll(A key, Collection values) { synchronized (data) { 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); } } final public boolean contains(A key, B value) { return containsPair(key, value); } public boolean containsPair(A key, B value) { synchronized (data) { return get(key).contains(value); } } public void putAll(A key, Collection values) { synchronized (data) { for (B value : values) put(key, value); } } public void removeAll(A key, Collection values) { synchronized (data) { for (B value : values) remove(key, value); } } public Set get(A key) { synchronized (data) { Set set = data.get(key); return set == null ? Collections.emptySet() : set; } } public List getAndClear(A key) { synchronized (data) { List l = cloneList(data.get(key)); remove(key); return l; } } public Set getOpt(A key) { synchronized (data) { return data.get(key); } } public Set getActual(A key) { synchronized (data) { Set set = data.get(key); if (set == null) data.put(key, set = _makeEmptySet()); return set; } } public void clean(A key) { synchronized (data) { Set list = data.get(key); if (list != null && list.isEmpty()) data.remove(key); } } final public Set keys() { return keySet(); } public Set keySet() { synchronized (data) { return data.keySet(); } } public void remove(A key) { synchronized (data) { size -= l(data.get(key)); data.remove(key); } } public void remove(A key, B value) { synchronized (data) { Set set = data.get(key); if (set != null) { if (set.remove(value)) { --size; if (set.isEmpty()) data.remove(key); } } } } public void clear() { synchronized (data) { data.clear(); size = 0; } } public boolean containsKey(A key) { synchronized (data) { return data.containsKey(key); } } public B getFirst(A key) { synchronized (data) { return first(get(key)); } } public void addAll(MultiSetMap map) { putAll(map); } public void putAll(MultiSetMap 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); } } public int size() { synchronized (data) { return size; } } public int getSize(A key) { return l(data.get(key)); } public int count(A key) { return getSize(key); } public Set reverseGet(B b) { synchronized (data) { Set l = new HashSet(); for (A key : data.keySet()) if (data.get(key).contains(b)) l.add(key); return l; } } public A keyForValue(B b) { synchronized (data) { for (A key : data.keySet()) if (data.get(key).contains(b)) return key; return null; } } public Map> asMap() { synchronized (data) { return cloneMap(data); } } public boolean isEmpty() { synchronized (data) { return data.isEmpty(); } } public Set _makeEmptySet() { return new HashSet(); } public Collection> allLists() { synchronized (data) { return new HashSet(data.values()); } } public List allValues() { return concatLists(values(data)); } public List> allEntries() { synchronized (data) { List> l = emptyList(size); for (Map.Entry> __0 : _entrySet(data)) { A a = __0.getKey(); Set set = __0.getValue(); for (B b : set) l.add(pair(a, b)); } return l; } } public Object mutex() { return data; } public String toString() { return "mm" + str(data); } public Pair firstEntry() { synchronized (data) { if (empty(data)) return null; Map.Entry> entry = data.entrySet().iterator().next(); return pair(entry.getKey(), first(entry.getValue())); } } public A firstKey() { synchronized (data) { return main.firstKey(data); } } public A lastKey() { synchronized (data) { return (A) ((NavigableMap) data).lastKey(); } } public A higherKey(Object a) { synchronized (data) { return (A) ((NavigableMap) data).higherKey(a); } } } static public class WithToolTip extends Var { final public WithToolTip setToolTip(String toolTip) { return toolTip(toolTip); } public WithToolTip toolTip(String toolTip) { this.toolTip = toolTip; return this; } final public String getToolTip() { return toolTip(); } public String toolTip() { return toolTip; } public String toolTip; public WithToolTip() { } public WithToolTip(A value, String toolTip) { super(value); this.toolTip = toolTip; } public String toString() { return formatFunctionCall("WithToolTip", toolTip, get()); } } static public class SingleThread { public boolean running = false; public Thread thread; public void run(Object r) { go(r); } synchronized public boolean go(final Object runnable) { if (running) return false; running = true; thread = startThread("Single Thread", new Runnable() { public void run() { try { try { callF(runnable); } finally { _done(); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n callF(runnable);\r\n } finally {\r\n _done();\r\n }"; } }); return true; } synchronized public void _done() { running = false; thread = null; } synchronized public boolean running() { return running; } synchronized public Thread getThread() { return thread; } } static public class StructureStringIndenter { final public StructureStringIndenter setLevels(int levels) { return levels(levels); } public StructureStringIndenter levels(int levels) { this.levels = levels; return this; } final public int getLevels() { return levels(); } public int levels() { return levels; } public int levels = 100; final public StructureStringIndenter setInlineChars(int inlineChars) { return inlineChars(inlineChars); } public StructureStringIndenter inlineChars(int inlineChars) { this.inlineChars = inlineChars; return this; } final public int getInlineChars() { return inlineChars(); } public int inlineChars() { return inlineChars; } public int inlineChars = 40; final public StructureStringIndenter setVerbose(boolean verbose) { return verbose(verbose); } public StructureStringIndenter verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; public List tok; public Map bracketMap; public String get(String s) { if (s == null) return null; tok = javaTokForStructure(s); int n = l(tok); bracketMap = getBracketMap(tok, __1 -> isOpeningBracket(__1), __2 -> isClosingBracket(__2)); int levels = clampToInt(this.levels * 2L); StringBuilder buf = new StringBuilder(); int indent = 0; for (int i = 0; i < n; i++) { String t = tok.get(i); if (isOpeningBracket(t)) { Integer j = or(bracketMap.get(i), n); if (j != null && !tokenRangeLongerThanNChars(tok, i + 1, j + 1, inlineChars)) { buf.append(joinSubList(tok, i, j + 1)); i = j; } else { if (verbose) print("Bracket part longer than " + inlineChars + " chars: " + quote(shortenJoinSubList(inlineChars, tok, i, j + 1))); indent += 2; buf.append(t); if (indent <= levels) buf.append("\n").append(spaces(indent)); } } else if (isClosingBracket(t)) { indent -= 2; if (indent < levels) buf.append("\n").append(spaces(indent)); buf.append(t); } else if (indent <= levels && eq(t, ",")) { buf.append(t).append("\n").append(spaces(indent)); i++; } else buf.append(t); } return str(buf); } } static public class CompactHashMap extends CompactAbstractMap { final static public int INITIAL_SIZE = 3; final static public double LOAD_FACTOR = 0.6; final static public Object nullObject = new Object(); final static public Object deletedObject = new Object(); public int elements; public int freecells; public Object[] table; public CompactHashMap() { this(INITIAL_SIZE); } public CompactHashMap(int size) { table = new Object[(size == 0 ? 1 : size) * 2]; elements = 0; freecells = tableSize(); } public CompactHashMap(Map map) { this(0); if (map != null) putAll(map); } public synchronized int size() { return elements; } public synchronized boolean isEmpty() { return elements == 0; } public synchronized void clear() { elements = 0; for (int ix = 0; ix < tableSize(); ix++) { key(ix, null); value(ix, null); } freecells = tableSize(); } public synchronized boolean containsKey(Object k) { return key(findKeyIndex(k)) != null; } public synchronized boolean containsValue(Object v) { if (v == null) v = (V) nullObject; for (int ix = 0; ix < tableSize(); ix++) if (value(ix) != null && value(ix).equals(v)) return true; return false; } public synchronized Set> entrySet() { return new EntrySet(); } public synchronized V remove(Object k) { int index = findKeyIndex(k); if (key(index) != null) { V v = value(index); key(index, deletedObject); value(index, deletedObject); elements--; return v; } else return null; } public synchronized V put(K k, V v) { if (k == null) k = (K) nullObject; int hash = k.hashCode(); int index = (hash & 0x7FFFFFFF) % tableSize(); int offset = 1; int deletedix = -1; while (key(index) != null && !(key(index).hashCode() == hash && key(index).equals(k))) { if (key(index) == deletedObject) deletedix = index; index = ((index + offset) & 0x7FFFFFFF) % tableSize(); offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (key(index) == null) { if (deletedix != -1) index = deletedix; else freecells--; elements++; key(index, k); value(index, v); if (1 - (freecells / (double) tableSize()) > LOAD_FACTOR) rehash(tableSize() * 2 + 1); return null; } else { V oldv = value(index); value(index, v); return oldv; } } public void rehash(int newCapacity) { int oldCapacity = tableSize(); Object[] newTable = new Object[newCapacity * 2]; for (int ix = 0; ix < oldCapacity; ix++) { Object k = key(ix); if (k == null || k == deletedObject) continue; int hash = k.hashCode(); int index = (hash & 0x7FFFFFFF) % newCapacity; int offset = 1; while (newTable[index * 2] != null) { index = ((index + offset) & 0x7FFFFFFF) % newCapacity; offset = offset * 2 + 1; if (offset == -1) offset = 2; } newTable[index * 2] = k; newTable[index * 2 + 1] = value(ix); } table = newTable; freecells = tableSize() - elements; } public synchronized V get(Object k) { return value(findKeyIndex(k)); } public synchronized Collection values() { return new ValueCollection(); } public synchronized Set keySet() { return new KeySet(); } final public int findKeyIndex(Object k) { if (k == null) k = nullObject; int hash = k.hashCode(); int index = (hash & 0x7FFFFFFF) % tableSize(); int offset = 1; while (key(index) != null && !(key(index).hashCode() == hash && key(index).equals(k))) { index = ((index + offset) & 0x7FFFFFFF) % tableSize(); offset = offset * 2 + 1; if (offset == -1) offset = 2; } return index; } public class KeySet extends AbstractSet { public int size() { synchronized (CompactHashMap.this) { return elements; } } public boolean contains(Object k) { synchronized (CompactHashMap.this) { return containsKey(k); } } public Iterator iterator() { synchronized (CompactHashMap.this) { return new KeyIterator(); } } } public class KeyIterator implements Iterator { public int ix; public KeyIterator() { synchronized (CompactHashMap.this) { for (; ix < tableSize(); ix++) if (value(ix) != null && key(ix) != deletedObject) break; } } public boolean hasNext() { synchronized (CompactHashMap.this) { return ix < tableSize(); } } public void remove() { throw new UnsupportedOperationException("Collection is read-only"); } public K next() { synchronized (CompactHashMap.this) { if (ix >= tableSize()) throw new NoSuchElementException(); K key = (K) key(ix++); for (; ix < tableSize(); ix++) if (key(ix) != null && key(ix) != deletedObject) break; return key; } } } public class EntrySet extends AbstractSet> { public int size() { synchronized (CompactHashMap.this) { return elements; } } public boolean contains(Object o) { synchronized (CompactHashMap.this) { if (o instanceof Map.Entry) { Object key = ((Map.Entry) o).getKey(); if (!containsKey((Map.Entry) o)) return false; return eq(((Map.Entry) o).getValue(), get(key)); } return false; } } public Iterator> iterator() { return new EntryIterator(); } } public class EntryIterator implements Iterator> { public int ix; public EntryIterator() { synchronized (CompactHashMap.this) { for (; ix < tableSize(); ix++) if (value(ix) != null && key(ix) != deletedObject) break; } } public boolean hasNext() { synchronized (CompactHashMap.this) { return ix < tableSize(); } } public void remove() { throw new UnsupportedOperationException("Collection is read-only"); } public Map.Entry next() { synchronized (CompactHashMap.this) { if (ix >= tableSize()) throw new NoSuchElementException(); K key = key(ix); V val = value(ix); ++ix; for (; ix < tableSize(); ix++) if (key(ix) != null && key(ix) != deletedObject) break; return simpleMapEntry(key, val); } } } public class ValueCollection extends AbstractCollection { public int size() { synchronized (CompactHashMap.this) { return elements; } } public Iterator iterator() { return new ValueIterator(); } public boolean contains(Object v) { return containsValue(v); } } public class ValueIterator implements Iterator { public int ix; public ValueIterator() { synchronized (CompactHashMap.this) { for (; ix < table.length / 2; ix++) if (value(ix) != null && value(ix) != deletedObject) break; } } public boolean hasNext() { synchronized (CompactHashMap.this) { return ix < tableSize(); } } public void remove() { throw new UnsupportedOperationException("Collection is read-only"); } public V next() { synchronized (CompactHashMap.this) { if (ix >= tableSize()) throw new NoSuchElementException(); V value = (V) value(ix++); for (; ix < tableSize(); ix++) if (value(ix) != null && value(ix) != deletedObject) break; return value; } } } public K key(int i) { return (K) table[i * 2]; } public void key(int i, Object key) { table[i * 2] = key; } public V value(int i) { return (V) table[i * 2 + 1]; } public void value(int i, Object value) { table[i * 2 + 1] = value; } public int tableSize() { return table.length / 2; } } static public class Best_comparable { public A best; public Comparable score; public boolean verboseNewBest, replaceIfSameScore; transient public Object onChange; transient public Object stringifier; synchronized public boolean isNewBest(Comparable score) { return this.score == null || (replaceIfSameScore ? cmp(score, this.score) >= 0 : cmp(score, this.score) > 0); } synchronized public Comparable bestScore() { return score; } public Comparable score() { return bestScore(); } public Comparable getScore() { return bestScore(); } synchronized public float floatScoreOr(float defaultValue) { return best == null ? defaultValue : (float) score; } public boolean put(Pair p) { return p != null && put(p.a, p.b); } public boolean put(Best b) { return b != null && put(b.get(), b.score); } public boolean put(A a, Comparable score) { ping(); boolean change = false; if (a != null) synchronized (this) { if (isNewBest(score)) { best = a; this.score = score; change = true; } } if (change) { if (verboseNewBest) print("New best! " + this); pcallF(onChange); } return change; } synchronized public A get() { return best; } synchronized public boolean has() { return best != null; } synchronized public Pair pair() { return main.pair(best, bestScore()); } synchronized public A getIfScoreAbove(Comparable x) { return cmp(x, score()) >= 0 ? best : null; } public String toString() { return !has() ? "-" : "Score " + score + ": " + callStringifier(stringifier, best); } public boolean putAndPrintIfNewBest(A a, Comparable score) { if (!put(a, score)) return false; { print(this); return true; } } synchronized public void clear() { best = null; score = 0; } } static public class G22Challenge extends G22LeftArrowScript { static final public String _fieldOrder = "type usesRNG type_singleImage type_animation types lvType lvUsesRNG"; public String type = "Single Image"; public boolean usesRNG = false; static public String type_singleImage = "Single Image"; static public String type_animation = "Animation"; static public List types = ll(type_singleImage, type_animation); public void _onChange() { super._onChange(); { if (lvType != null) lvType.set(type); } { if (lvUsesRNG != null) lvUsesRNG.set(usesRNG); } } transient public SimpleLiveValue lvType; synchronized public SimpleLiveValue lvType() { { if (lvType == null) lvType = new SimpleLiveValue(String.class, type).onChange(new Runnable() { public void run() { try { setField("type", lvType.get()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setField(type := lvType!);"; } }); return lvType; } } transient public SimpleLiveValue lvUsesRNG; synchronized public SimpleLiveValue lvUsesRNG() { { if (lvUsesRNG == null) lvUsesRNG = new SimpleLiveValue(Boolean.class, usesRNG).onChange(new Runnable() { public void run() { try { setField("usesRNG", lvUsesRNG.get()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setField(usesRNG := lvUsesRNG!);"; } }); return lvUsesRNG; } } } static public class DefunctClassLoader { } static public class TimedCache { public long timeout; volatile public A value; public Object function; public long set; public Lock lock = lock(); public boolean keepValueWhileCalculating = false; public int stores, fails, hits; public TimedCache(double timeoutSeconds, IF0 function) { this(function, timeoutSeconds); } public TimedCache(double timeoutSeconds, Object function) { this(function, timeoutSeconds); } public TimedCache(IF0 function, double timeoutSeconds) { this((Object) function, timeoutSeconds); } public TimedCache(Object function, double timeoutSeconds) { this(timeoutSeconds); this.function = function; } public TimedCache(double timeoutSeconds) { timeout = toMS(timeoutSeconds); } public A set(A a) { Lock __0 = lock; lock(__0); try { ++stores; value = a; set = now(); return a; } finally { unlock(__0); } } public boolean has() { Lock __1 = lock; lock(__1); try { clean(); if (set != 0) { ++hits; return true; } ++fails; return false; } finally { unlock(__1); } } public A get() { Lock __2 = lock; lock(__2); try { if (function != null) return get(function); clean(); if (set != 0) ++hits; else ++fails; return value; } finally { unlock(__2); } } public A get(Object makerFunction) { Lock __3 = lock; lock(__3); try { if (keepValueWhileCalculating) { if (value == null || shouldClean()) set((A) callF(makerFunction)); return value; } else { return this.has() ? getNoClean() : set((A) callF(makerFunction)); } } finally { unlock(__3); } } public A getNoClean() { Lock __4 = lock; lock(__4); try { return value; } finally { unlock(__4); } } public void clean() { Lock __5 = lock; lock(__5); try { if (shouldClean()) clear(); } finally { unlock(__5); } } public boolean shouldClean() { return timeout > 0 && now() > set + timeout; } public void clear() { Lock __6 = lock; lock(__6); try { set = 0; value = null; } finally { unlock(__6); } } public String stats() { return "Stores: " + stores + ", hits: " + hits + ", fails: " + fails; } public A peek() { return value; } } static public class WidthAndHeightImpl extends Meta implements WidthAndHeight, IFieldsToList { public int width; public int height; public WidthAndHeightImpl() { } public WidthAndHeightImpl(int width, int height) { this.height = height; this.width = width; } public Object[] _fieldsToList() { return new Object[] { width, height }; } public int getWidth() { return width; } public int getHeight() { return height; } public String toString() { return n2(width) + "*" + n2(height) + " px"; } } static public interface ITokCondition { public boolean get(List tok, int i); } static public interface ISetAndGet extends ISetter, IF0 { } static abstract public class TokCondition implements ITokCondition { public abstract boolean get(List tok, int i); } static abstract public class LiveValue implements IF0WithChangeListeners { abstract public Class getType(); public abstract A get(); } static public class ToJava { public Object get(Object o) { { var __1 = getOpt(o); if (__1 != null) return __1; } throw fail("Can't ToJava: " + className(o)); } public Object getOpt(Object o) { if (o == null) return "null"; if (o instanceof String) return quote(o); if (o instanceof Number) return str(o); if (o instanceof IFieldsToList) return formatFunctionCall("new " + shortName((IFieldsToList) o), map(__83 -> get(__83), ((IFieldsToList) o)._fieldsToList())); if (o instanceof List) return functionCall_list("ll", map(__84 -> get(__84), (List) o)); if (o instanceof Class) return shortClassName((Class) o) + ".class"; if (o instanceof int[]) return "new int[] {" + joinWithComma(toList((int[]) o)) + "}"; return null; } } 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); } } public String toString() { return str(this.get()); } } static public class RightAlignedLine extends JPanel { public RightAlignedLine(int spacing, Component... components) { this(components); setSpacing(spacing); } public RightAlignedLine(Component... components) { setLayout(LetterLayout.rightAlignedRow()); for (Component component : components) if (component != null) add(component); } public void setSpacing(int spacing) { ((LetterLayout) getLayout()).setSpacing(spacing, spacing); } public void add(String text) { add(new JLabel(text)); } } static public class DoubleRect { public double x, y, w, h; public DoubleRect() { } public DoubleRect(Rectangle r) { x = r.x; y = r.y; w = r.width; h = r.height; } public DoubleRect(double x, double y, double w, double h) { this.h = h; this.w = w; this.y = y; this.x = x; } public boolean eq(Object o) { if (!(o instanceof DoubleRect)) return false; if (o == this) return true; DoubleRect r = (DoubleRect) o; return x == r.x && y == r.y && w == r.w && h == r.h; } public String toString() { return x + "," + y + " / " + w + "," + h; } public double x1() { return x; } public double y1() { return y; } public double x2() { return x + w; } public double y2() { return y + h; } public boolean contains(Pt p) { return contains(p.x, p.y); } public boolean contains(double _x, double _y) { return _x >= x && _y >= y && _x < x + w && _y < y + h; } public boolean empty() { return w <= 0 || h <= 0; } } 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 class SimpleLiveValue extends LiveValue implements IVarWithNotify { transient public Set onChange; public SimpleLiveValue onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public SimpleLiveValue removeChangeListener(Runnable r) { main.remove(onChange, r); return this; } public void change() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public Class type; volatile public A value; 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 fireChanged() { change(); } public void set(A a) { if (neq(value, a)) { value = a; fireChanged(); } } } static public class CountingOutputStream extends FilterOutputStream { public long counter; public CountingOutputStream(OutputStream out) { super(out); } @Override public void write(int b) throws IOException { ++counter; out.write(b); } @Override public void write(byte[] b) throws IOException { counter += b.length; out.write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { if (len == 0) return; counter += len; out.write(b, off, len); } public long getFilePointer() { return counter; } } static public class BetterThreadLocal { public Map map = newWeakHashMap(); public BetterThreadLocal() { } public BetterThreadLocal(A value) { set(value); } public boolean isSet() { return map.containsKey(currentThread()); } public A get() { if (map.containsKey(currentThread())) return map.get(currentThread()); A value = initialValue(); set(value); return value; } public A get(Thread thread) { return thread == null ? null : map.get(thread); } public void set(A a) { map.put(currentThread(), a); } public A initialValue() { return null; } } static public class WeakIdentityHashMap implements Map { final public ReferenceQueue queue = new ReferenceQueue(); public Map backingStore = new HashMap(); public WeakIdentityHashMap() { _registerWeakMap(this); } public synchronized void clear() { backingStore.clear(); reap(); } public synchronized boolean containsKey(Object key) { reap(); return backingStore.containsKey(new IdentityWeakReference(key)); } public synchronized boolean containsValue(Object value) { reap(); return backingStore.containsValue(value); } public synchronized Set> entrySet() { reap(); Set> ret = new HashSet>(); for (Map.Entry ref : backingStore.entrySet()) { final K key = ref.getKey().get(); final V value = ref.getValue(); Map.Entry entry = new Map.Entry() { public synchronized K getKey() { return key; } public synchronized V getValue() { return value; } public synchronized V setValue(V value) { throw new UnsupportedOperationException(); } }; ret.add(entry); } return Collections.unmodifiableSet(ret); } public synchronized Set keySet() { reap(); IdentityHashMap map = new IdentityHashMap(); for (IdentityWeakReference ref : backingStore.keySet()) { K k = ref.get(); if (k != null) map.put(k, Boolean.TRUE); } return map.keySet(); } public synchronized boolean equals(Object o) { if (!(o instanceof WeakIdentityHashMap)) { return false; } return backingStore.equals(((WeakIdentityHashMap) o).backingStore); } public synchronized V get(Object key) { reap(); return backingStore.get(new IdentityWeakReference(key)); } public synchronized V put(K key, V value) { reap(); return backingStore.put(new IdentityWeakReference(key), value); } public synchronized int hashCode() { reap(); return backingStore.hashCode(); } public synchronized boolean isEmpty() { reap(); return backingStore.isEmpty(); } public synchronized void putAll(Map t) { throw new UnsupportedOperationException(); } public synchronized V remove(Object key) { reap(); return backingStore.remove(new IdentityWeakReference(key)); } public synchronized int size() { reap(); return backingStore.size(); } public synchronized Collection values() { reap(); return backingStore.values(); } synchronized final public void reap() { Object zombie = queue.poll(); while (zombie != null) { IdentityWeakReference victim = (IdentityWeakReference) zombie; backingStore.remove(victim); zombie = queue.poll(); } } public class IdentityWeakReference extends WeakReference { public int hash; @SuppressWarnings("unchecked") public IdentityWeakReference(Object obj) { super((K) obj, queue); hash = System.identityHashCode(obj); } public synchronized int hashCode() { return hash; } public synchronized boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof WeakIdentityHashMap.IdentityWeakReference)) { return false; } IdentityWeakReference ref = (IdentityWeakReference) o; if (this.get() == ref.get()) { return true; } return false; } } } 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 public class InstantNeverHideToolTip extends MouseAdapter { public JComponent component; public JToolTip toolTip; public Popup popup; public int x, y; public String text; public IF0 calculateText; public InstantNeverHideToolTip(IF0 calculateText, JComponent component) { this(component); this.calculateText = calculateText; } public InstantNeverHideToolTip(String text, JComponent component) { this(component); this.text = text; } public InstantNeverHideToolTip(JComponent component) { this.component = component; { swing(() -> { component.addMouseListener(InstantNeverHideToolTip.this); toolTip = component.createToolTip(); bindToComponent(component, null, () -> hideToolTip()); }); } } @Override public void mouseEntered(MouseEvent e) { x = e.getXOnScreen() + 2; y = e.getYOnScreen() + 2; showToolTip(); } public void updateText() { swing(() -> { if (calculateText != null) setText(calculateText.get()); }); } public void showToolTip() { updateText(); if (empty(text)) return; toolTip.setTipText(text); popup = PopupFactory.getSharedInstance().getPopup(component, toolTip, x, y); popup.show(); } public void mouseExited(MouseEvent e) { hideToolTip(); } public boolean toolTipShowing() { return popup != null; } public void hideToolTip() { if (popup != null) { popup.hide(); popup = null; } } public String getText() { return text; } public void setText(String text) { swing(() -> { if (eq(text, getText())) return; InstantNeverHideToolTip.this.text = text; if (toolTipShowing()) { hideToolTip(); showToolTip(); } }); } } static public class CompactLinkedHashSet extends AbstractSet { public UnsynchronizedCompactHashSet> entries = new UnsynchronizedCompactHashSet(); public Entry head, tail; static public class Entry { public A value; public Entry prev, next; public int hashCode() { return _hashCode(value); } public boolean equals(Object o) { return o == this || eq(value, o); } } public boolean add(A a) { if (entries.contains(a)) return false; Entry n = new Entry(); n.value = a; n.prev = tail; if (tail != null) tail.next = n; tail = n; if (head == null) head = n; entries.add(n); return true; } public boolean remove(Object a) { return remove(entries.find(a)); } public boolean remove(Entry node) { if (node == null) return false; if (node.next != null) node.next.prev = node.prev; else tail = node.prev; if (node.prev != null) node.prev.next = node.next; else head = node.next; entries.remove(node); return true; } public int size() { return entries.size(); } public IterableIterator iterator() { return new IterableIterator() { public Entry entry = head, prev = null; public boolean hasNext() { return entry != null; } public A next() { A a = entry.value; prev = entry; entry = entry.next; return a; } public void remove() { if (prev == null) throw new IllegalStateException(); CompactLinkedHashSet.this.remove(prev); prev = null; } }; } public void clear() { entries.clear(); head = tail = null; } public boolean contains(Object a) { return entries.contains(a); } public A find(Object o) { Entry e = entries.find(o); return e == null ? null : e.value; } public A prevElement(A a) { Entry e = entries.find(a); if (e == null || e.prev == null) return null; return e.prev.value; } public A nextElement(A a) { Entry e = entries.find(a); if (e == null || e.next == null) return null; return e.next.value; } public A first() { return head == null ? null : head.value; } public A last() { return tail == null ? null : tail.value; } public boolean removeIfSame(Object o) { A value = find(o); if (value == o) { remove(value); return true; } return false; } } 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 T3 { public A a; public B b; public C c; public T3() { } public T3(A a, B b, C c) { this.c = c; this.b = b; this.a = a; } public T3(T3 t) { a = t.a; b = t.b; c = t.c; } public int hashCode() { return _hashCode(a) + 2 * _hashCode(b) - 4 * _hashCode(c); } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof T3)) return false; T3 t = (T3) o; return eq(a, t.a) && eq(b, t.b) && eq(c, t.c); } public String toString() { return "(" + quoteBorderless(a) + ", " + quoteBorderless(b) + ", " + quoteBorderless(c) + ")"; } } static public class ProgramScan { static public int threads = isWindows() ? 500 : 10; static public int timeout = 5000; static public String ip = "127.0.0.1"; static public int quickScanFrom = 10000, quickScanTo = 10999; static public int maxNumberOfVMs_android = 4; static public int maxNumberOfVMs_nonAndroid = 50; static public int maxNumberOfVMs; static public boolean verbose = false; static public class Program { public int port; public String helloString; public Program(int port, String helloString) { this.helloString = helloString; this.port = port; } } static public List scan() { try { return scan(1, 65535); } catch (Exception __e) { throw rethrow(__e); } } static public List scan(int fromPort, int toPort) { return scan(fromPort, toPort, new int[0]); } static public List scan(int fromPort, int toPort, int[] preferredPorts) { try { Set preferredPortsSet = new HashSet(asList(preferredPorts)); int scanSize = toPort - fromPort + 1; String name = toPort < 10000 ? "bot" : "program"; int threads = isWindows() ? min(500, scanSize) : min(scanSize, 10); final ExecutorService es = Executors.newFixedThreadPool(threads); if (verbose) print(firstToUpper(name) + "-scanning " + ip + " with timeout " + timeout + " ms in " + threads + " threads."); startTiming(); List> futures = new ArrayList(); List ports = new ArrayList(); for (int port : preferredPorts) { futures.add(checkPort(es, ip, port, timeout)); ports.add(port); } for (int port = fromPort; port <= toPort; port++) if (!preferredPortsSet.contains(port) && !forbiddenPort(port)) { futures.add(checkPort(es, ip, port, timeout)); ports.add(port); } es.shutdown(); List programs = new ArrayList(); long time = now(); int i = 0; for (final Future f : futures) { if (verbose) print("Waiting for port " + get(ports, i++) + " at time " + (now() - time)); Program p = f.get(); if (p != null) programs.add(p); } if (verbose) print("Found " + programs.size() + " " + name + "(s) on " + ip); return programs; } catch (Exception __e) { throw rethrow(__e); } } static public Future checkPort(final ExecutorService es, final String ip, final int port, final int timeout) { return es.submit(new Callable() { @Override public Program call() { try { Socket socket = new Socket(); try { socket.setSoTimeout(timeout); socket.connect(new InetSocketAddress(ip, port), timeout); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); String hello = or(in.readLine(), "?"); return new Program(port, hello); } finally { socket.close(); } } catch (Exception ex) { return null; } } }); } static public List quickScan() { return scan(quickScanFrom, quickScanTo); } static public List quickBotScan() { return quickBotScan(new int[0]); } static public List quickBotScan(int[] preferredPorts) { if (maxNumberOfVMs == 0) maxNumberOfVMs = isAndroid() ? maxNumberOfVMs_android : maxNumberOfVMs_nonAndroid; return scan(4999, 5000 + maxNumberOfVMs - 1, preferredPorts); } } static public class TimeoutException_Inner extends RuntimeExceptionWithCustomStackTrace { public Thread thread; public double timeoutSeconds; public Object function; public TimeoutException_Inner(double timeoutSeconds, Object function, Thread thread) { super("Timeout after " + iceil(timeoutSeconds) + "s by " + shorten_str(function), new Throwable("Caller"), thread.getStackTrace()); this.thread = thread; this.function = function; this.timeoutSeconds = timeoutSeconds; } } static public class RSTOverQ implements Runnable { public boolean _isTransient() { return true; } public Runnable runnable; public Q q = startQ(); public F0 enter; public boolean trigger, running; public RSTOverQ(Runnable runnable) { this.runnable = runnable; } public RSTOverQ(Runnable runnable, Q q) { this.q = q; this.runnable = runnable; assertNotNull(q); } public RSTOverQ(Q q, Runnable runnable) { this(runnable, q); } public void trigger() { go(); } synchronized public void go() { if (trigger) return; trigger = true; q.add(new Runnable() { public void run() { try { _run(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_run();"; } }); } public void run() { go(); } public void get() { go(); } synchronized public boolean running() { return running; } public void _run() { synchronized (this) { if (!trigger) return; running = true; trigger = false; } try { AutoCloseable __1 = callF(enter); try { pcallF(runnable); } finally { _close(__1); } } finally { synchronized (this) { running = false; } } } synchronized public boolean triggered() { return trigger; } public void waitUntilDone() { while (running()) sleep(1); } public String stats() { return renderVars("trigger", trigger, "running", running, "q", q, "runnable", runnable); } } static public class BufferedImageWithMeta extends BufferedImage implements IMeta { public BufferedImageWithMeta(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties) { super(cm, raster, isRasterPremultiplied, properties); } volatile public Object meta; public void _setMeta(Object meta) { this.meta = meta; } public Object _getMeta() { return meta; } final public boolean scaffolding() { return scaffoldingEnabled(); } public boolean scaffoldingEnabled() { return main.scaffoldingEnabled(this); } public boolean scaffoldingEnabled(Object o) { return main.scaffoldingEnabled(o); } } static public class MapI extends IterableIterator { public IF1 f; public Iterator it; public MapI(IF1 f, Iterator it) { this.it = it; this.f = f; } public boolean hasNext() { return it.hasNext(); } public B next() { return f.get(it.next()); } } abstract static public class RandomAccessAbstractList extends AbstractList implements RandomAccess { } static public class GrabbableIntPixels implements IFieldsToList { static final public String _fieldOrder = "data w h offset scanlineStride"; public int[] data; public int w; public int h; public int offset; public int scanlineStride; public GrabbableIntPixels() { } public GrabbableIntPixels(int[] data, int w, int h, int offset, int scanlineStride) { this.scanlineStride = scanlineStride; this.offset = offset; this.h = h; this.w = w; this.data = data; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + data + ", " + w + ", " + h + ", " + offset + ", " + scanlineStride + ")"; } public boolean equals(Object o) { if (!(o instanceof GrabbableIntPixels)) return false; GrabbableIntPixels __1 = (GrabbableIntPixels) o; return eq(data, __1.data) && w == __1.w && h == __1.h && offset == __1.offset && scanlineStride == __1.scanlineStride; } public int hashCode() { int h = -1183022196; h = boostHashCombine(h, _hashCode(data)); h = boostHashCombine(h, _hashCode(w)); h = boostHashCombine(h, _hashCode(h)); h = boostHashCombine(h, _hashCode(offset)); h = boostHashCombine(h, _hashCode(scanlineStride)); return h; } public Object[] _fieldsToList() { return new Object[] { data, w, h, offset, scanlineStride }; } public int[] asPackedArray() { if (offset == 0 && data.length == w * h) return data; int[] pixels = new int[w * h]; for (int y = 0; y < h; y++) arrayCopy(data, offset + y * scanlineStride, pixels, y * h, w); return pixels; } } static public class TransferableImage implements Transferable { public Image i; public TransferableImage(Image i) { this.i = i; } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (flavor.equals(DataFlavor.imageFlavor) && i != null) { return i; } else { throw new UnsupportedFlavorException(flavor); } } public DataFlavor[] getTransferDataFlavors() { DataFlavor[] flavors = new DataFlavor[1]; flavors[0] = DataFlavor.imageFlavor; return flavors; } public boolean isDataFlavorSupported(DataFlavor flavor) { DataFlavor[] flavors = getTransferDataFlavors(); for (int i = 0; i < flavors.length; i++) { if (flavor.equals(flavors[i])) { return true; } } return false; } } final static public class DoubleRange implements Comparable { final public double getStart() { return start(); } public double start() { return start; } public double start; final public double getEnd() { return end(); } public double end() { return end; } public double end; public DoubleRange() { } public DoubleRange(double start, double end) { this.end = end; this.start = start; } public boolean equals(Object o) { return stdEq2(this, o); } public int hashCode() { return stdHash2(this); } public double length() { return end - start; } public boolean isEmpty() { return start >= end; } public double center() { return (start + end) / 2; } static public String _fieldOrder = "start end"; public String toString() { return "[" + start + ";" + end + "]"; } @Override public int compareTo(DoubleRange r) { int c = cmp(start, r.start); if (c != 0) return c; return cmp(end, r.end); } } static public interface Producer { public A next(); } static public class AlphanumComparator implements Comparator { public boolean ignoreCase = false; final public boolean isDigit(char ch) { return ((ch >= 48) && (ch <= 57)); } final public String getChunk(String s, int slength, int marker) { StringBuilder chunk = new StringBuilder(); char c = s.charAt(marker); chunk.append(c); marker++; if (isDigit(c)) while (marker < slength) { c = s.charAt(marker); if (!isDigit(c)) break; chunk.append(c); marker++; } else while (marker < slength) { c = s.charAt(marker); if (isDigit(c)) break; chunk.append(c); marker++; } return chunk.toString(); } public int compare(String s1, String s2) { if (s1 == null) return s2 == null ? 0 : -1; if (s2 == null) return 1; int thisMarker = 0; int thatMarker = 0; int s1Length = s1.length(); int s2Length = s2.length(); while (thisMarker < s1Length && thatMarker < s2Length) { String thisChunk = getChunk(s1, s1Length, thisMarker); thisMarker += thisChunk.length(); String thatChunk = getChunk(s2, s2Length, thatMarker); thatMarker += thatChunk.length(); int result = 0; if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) { int thisChunkLength = thisChunk.length(); result = thisChunkLength - thatChunk.length(); if (result == 0) { for (int i = 0; i < thisChunkLength; i++) { result = thisChunk.charAt(i) - thatChunk.charAt(i); if (result != 0) { return result; } } } } else { result = thisChunk.compareTo(thatChunk); } if (result != 0) return result; } return s1Length - s2Length; } } static public class ReverseChain implements Iterable { public A element; public ReverseChain prev; public int size; public ReverseChain() { } public ReverseChain(ReverseChain prev, A element) { this.element = element; this.prev = prev; if (prev == null) size = 1; else { prev.check(); size = prev.size + 1; } } public void check() { if (size < 1) throw fail("You called the ReverseChain default constructor. Don't do that"); } public String toString() { return str(toList()); } public ArrayList toList() { check(); ArrayList l = emptyList(size); for (int i = 0; i < size; i++) l.add(null); int i = size; ReverseChain c = this; while (c != null) { l.set(--i, c.element); c = c.prev; } return l; } public Iterator iterator() { return toList().iterator(); } } static public class NumPadFixingInputMap extends InputMap { public void put(KeyStroke keyStroke, Object actionMapKey) { super.put(keyStroke, actionMapKey); Integer code = rsyntaxTextArea_fixNumPad_map.get(keyStroke.getKeyCode()); if (code != null) put(KeyStroke.getKeyStroke(code, keyStroke.getModifiers()), actionMapKey); } public void replaceOn(JComponent c) { InputMap im = c.getInputMap(); setParent(im.getParent()); for (KeyStroke key : im.keys()) put(key, im.get(key)); c.setInputMap(JComponent.WHEN_FOCUSED, this); } } static public interface IIntPred { public boolean get(int a); } abstract static public class CompactAbstractMap implements Map { public int size() { return entrySet().size(); } public boolean isEmpty() { return size() == 0; } public boolean containsValue(Object value) { Iterator> i = entrySet().iterator(); if (value == null) { while (i.hasNext()) { Entry e = i.next(); if (e.getValue() == null) return true; } } else { while (i.hasNext()) { Entry e = i.next(); if (value.equals(e.getValue())) return true; } } return false; } public boolean containsKey(Object key) { Iterator> i = entrySet().iterator(); if (key == null) { while (i.hasNext()) { Entry e = i.next(); if (e.getKey() == null) return true; } } else { while (i.hasNext()) { Entry e = i.next(); if (key.equals(e.getKey())) return true; } } return false; } public V get(Object key) { Iterator> i = entrySet().iterator(); if (key == null) { while (i.hasNext()) { Entry e = i.next(); if (e.getKey() == null) return e.getValue(); } } else { while (i.hasNext()) { Entry e = i.next(); if (key.equals(e.getKey())) return e.getValue(); } } return null; } public V put(K key, V value) { throw new UnsupportedOperationException(); } public V remove(Object key) { Iterator> i = entrySet().iterator(); Entry correctEntry = null; if (key == null) { while (correctEntry == null && i.hasNext()) { Entry e = i.next(); if (e.getKey() == null) correctEntry = e; } } else { while (correctEntry == null && i.hasNext()) { Entry e = i.next(); if (key.equals(e.getKey())) correctEntry = e; } } V oldValue = null; if (correctEntry != null) { oldValue = correctEntry.getValue(); i.remove(); } return oldValue; } public void putAll(Map m) { for (Entry e : m.entrySet()) put(e.getKey(), e.getValue()); } public void clear() { entrySet().clear(); } public Set keySet() { return new AbstractSet() { public Iterator iterator() { return new Iterator() { public Iterator> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public K next() { return i.next().getKey(); } public void remove() { i.remove(); } }; } public int size() { return CompactAbstractMap.this.size(); } public boolean isEmpty() { return CompactAbstractMap.this.isEmpty(); } public void clear() { CompactAbstractMap.this.clear(); } public boolean contains(Object k) { return CompactAbstractMap.this.containsKey(k); } }; } public Collection values() { return new AbstractCollection() { public Iterator iterator() { return new Iterator() { public Iterator> i = entrySet().iterator(); public boolean hasNext() { return i.hasNext(); } public V next() { return i.next().getValue(); } public void remove() { i.remove(); } }; } public int size() { return CompactAbstractMap.this.size(); } public boolean isEmpty() { return CompactAbstractMap.this.isEmpty(); } public void clear() { CompactAbstractMap.this.clear(); } public boolean contains(Object v) { return CompactAbstractMap.this.containsValue(v); } }; } public abstract Set> entrySet(); public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Map)) return false; Map m = (Map) o; if (m.size() != size()) return false; try { for (Entry e : entrySet()) { K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key) == null && m.containsKey(key))) return false; } else { if (!value.equals(m.get(key))) return false; } } } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } return true; } public int hashCode() { int h = 0; for (Entry entry : entrySet()) h += entry.hashCode(); return h; } public String toString() { Iterator> i = entrySet().iterator(); if (!i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append('{'); for (; ; ) { Entry e = i.next(); K key = e.getKey(); V value = e.getValue(); sb.append(key == this ? "(this Map)" : key); sb.append('='); sb.append(value == this ? "(this Map)" : value); if (!i.hasNext()) return sb.append('}').toString(); sb.append(',').append(' '); } } public Object clone() throws CloneNotSupportedException { CompactAbstractMap result = (CompactAbstractMap) super.clone(); return result; } public static class SimpleEntry implements Entry, java.io.Serializable { @java.io.Serial static final public long serialVersionUID = -8499721149061103585L; @SuppressWarnings("serial") final public K key; @SuppressWarnings("serial") public V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Entry entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Entry e = (Entry) o; return eq(key, e.getKey()) && eq(value, e.getValue()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } } public static class SimpleImmutableEntry implements Entry, java.io.Serializable { @java.io.Serial static final public long serialVersionUID = 7138329143949025153L; @SuppressWarnings("serial") final public K key; @SuppressWarnings("serial") final public V value; public SimpleImmutableEntry(K key, V value) { this.key = key; this.value = value; } public SimpleImmutableEntry(Entry entry) { this.key = entry.getKey(); this.value = entry.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { throw new UnsupportedOperationException(); } public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Entry e = (Entry) o; return eq(key, e.getKey()) && eq(value, e.getValue()); } public int hashCode() { return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); } public String toString() { return key + "=" + value; } } } static public class UnsynchronizedCompactHashSet extends java.util.AbstractSet { final static public int INITIAL_SIZE = 3; public final static double LOAD_FACTOR = 0.75; final static public Object nullObject = new Object(); final static public Object deletedObject = new Object(); public int elements; public int freecells; public A[] objects; public int modCount; public UnsynchronizedCompactHashSet() { this(INITIAL_SIZE); } public UnsynchronizedCompactHashSet(int size) { objects = (A[]) new Object[(size == 0 ? 1 : size)]; elements = 0; freecells = objects.length; modCount = 0; } public UnsynchronizedCompactHashSet(Collection c) { this(c.size()); addAll(c); } @Override public Iterator iterator() { return new CompactHashIterator(); } @Override public int size() { return elements; } @Override public boolean isEmpty() { return elements == 0; } @Override public boolean contains(Object o) { return find(o) != null; } public A find(Object o) { if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } return objects[index]; } public boolean removeIfSame(Object o) { A value = find(o); if (value == o) { remove(value); return true; } return false; } @Override public boolean add(Object o) { if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; int deletedix = -1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { if (objects[index] == deletedObject) deletedix = index; index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] == null) { if (deletedix != -1) index = deletedix; else freecells--; modCount++; elements++; objects[index] = (A) o; if (1 - (freecells / (double) objects.length) > LOAD_FACTOR) rehash(); return true; } else return false; } @Override public boolean remove(Object o) { if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] != null) { objects[index] = (A) deletedObject; modCount++; elements--; return true; } else return false; } @Override public void clear() { elements = 0; for (int ix = 0; ix < objects.length; ix++) objects[ix] = null; freecells = objects.length; modCount++; } @Override public Object[] toArray() { Object[] result = new Object[elements]; Object[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) result[pos++] = null; else result[pos++] = objects[i]; } return result; } @Override public T[] toArray(T[] a) { int size = elements; if (a.length < size) a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); A[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) a[pos++] = null; else a[pos++] = (T) objects[i]; } return a; } public void rehash() { int garbagecells = objects.length - (elements + freecells); if (garbagecells / (double) objects.length > 0.05) rehash(objects.length); else rehash(objects.length * 2 + 1); } public void rehash(int newCapacity) { int oldCapacity = objects.length; @SuppressWarnings("unchecked") A[] newObjects = (A[]) new Object[newCapacity]; for (int ix = 0; ix < oldCapacity; ix++) { Object o = objects[ix]; if (o == null || o == deletedObject) continue; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % newCapacity; int offset = 1; while (newObjects[index] != null) { index = ((index + offset) & 0x7FFFFFFF) % newCapacity; offset = offset * 2 + 1; if (offset == -1) offset = 2; } newObjects[index] = (A) o; } objects = newObjects; freecells = objects.length - elements; } public class CompactHashIterator implements Iterator { public int index; public int lastReturned = -1; public int expectedModCount; @SuppressWarnings("empty-statement") public CompactHashIterator() { for (index = 0; index < objects.length && (objects[index] == null || objects[index] == deletedObject); index++) ; expectedModCount = modCount; } @Override public boolean hasNext() { return index < objects.length; } @SuppressWarnings("empty-statement") @Override public T next() { int length = objects.length; if (index >= length) { lastReturned = -2; throw new NoSuchElementException(); } lastReturned = index; for (index += 1; index < length && (objects[index] == null || objects[index] == deletedObject); index++) ; if (objects[lastReturned] == nullObject) return null; else return (T) objects[lastReturned]; } @Override public void remove() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (lastReturned == -1 || lastReturned == -2) throw new IllegalStateException(); if (objects[lastReturned] != null && objects[lastReturned] != deletedObject) { objects[lastReturned] = (A) deletedObject; elements--; modCount++; expectedModCount = modCount; } } } public int capacity() { return objects.length; } public boolean shrinkToFactor(double factor) { if (factor > LOAD_FACTOR) throw fail("Shrink factor must be equal to or smaller than load factor: " + factor + " / " + LOAD_FACTOR); int newCapacity = max(INITIAL_SIZE, iround(size() / factor)); if (newCapacity >= capacity()) return false; rehash(newCapacity); return true; } } static public class RuntimeExceptionWithCustomStackTrace extends RuntimeException { public RuntimeExceptionWithCustomStackTrace(String msg, Throwable cause, StackTraceElement[] stackTrace) { super(msg, cause, false, true); setStackTrace(stackTrace); } } static public class Best { public A best; public double score; public boolean verboseNewBest, replaceIfSameScore; final public Best setLowerIsBetter(boolean lowerIsBetter) { return lowerIsBetter(lowerIsBetter); } public Best lowerIsBetter(boolean lowerIsBetter) { this.lowerIsBetter = lowerIsBetter; return this; } final public boolean getLowerIsBetter() { return lowerIsBetter(); } public boolean lowerIsBetter() { return lowerIsBetter; } public boolean lowerIsBetter = false; transient public Object onChange; transient public Object stringifier; synchronized public boolean isNewBest(double score) { return best == null || !isNaN(score) && (replaceIfSameScore ? compareScores(score, this.score) >= 0 : compareScores(score, this.score) > 0); } public double worstScore() { return lowerIsBetter ? infinity() : minusInfinity(); } public int compareScores(double a, double b) { return lowerIsBetter ? -cmp(a, b) : cmp(a, b); } synchronized public double bestScore() { return best == null ? worstScore() : score; } public double score() { return bestScore(); } public double getScore() { return bestScore(); } synchronized public float floatScoreOr(float defaultValue) { return best == null ? defaultValue : (float) score; } public boolean put(Pair p) { return p != null && put(p.a, p.b); } public boolean put(Best b) { return b != null && put(b.get(), b.score); } public boolean put(A a, double score) { ping(); boolean change = false; if (a != null) synchronized (this) { if (isNewBest(score)) { best = a; this.score = score; change = true; } } if (change) { if (verboseNewBest) print("New best! " + this); pcallF(onChange); } return change; } synchronized public A get() { return best; } synchronized public boolean has() { return best != null; } synchronized public Pair pair() { return main.pair(best, bestScore()); } synchronized public Scored scored() { return best == null ? null : new Scored(best, bestScore()); } synchronized public A getIfScoreAbove(double x) { return compareScores(score(), x) >= 0 ? best : null; } public String toString() { return "Score " + formatDouble_significant2(score, 4) + ": " + callStringifier(stringifier, best); } public boolean putAndPrintIfNewBest(A a, double score) { if (!put(a, score)) return false; { print(this); return true; } } synchronized public void clear() { best = null; score = 0; } } static public GlobalID aGlobalIDObjUnlessLoading() { return dynamicObjectIsLoading() ? null : aGlobalIDObj(); } static public Border getBorder(final JComponent c) { return c == null ? null : swing(new F0() { public Border get() { try { return c.getBorder(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return c.getBorder();"; } }); } static public Map.Entry firstEntry(Map map) { return empty(map) ? null : first(map.entrySet()); } static public List javaTokForStructure(String s) { return javaTok_noMLS(s); } static public Map getBracketMap(List tok) { return getBracketMap(tok, getBracketMap_opening, getBracketMap_closing); } static public Map getBracketMap(List tok, Collection opening, Collection closing) { return getBracketMap(tok, opening, closing, 0, l(tok)); } static public Map getBracketMap(List tok, Collection opening, Collection closing, int from, int to) { TreeMap map = new TreeMap(); List stack = new ArrayList(); for (int i = from | 1; i < to; i += 2) { Object t = tok.get(i); if (opening.contains(t)) stack.add(i); else if (closing.contains(t)) if (!empty(stack)) map.put(liftLast(stack), i); } return map; } static public Map getBracketMap(List tok, IF1 opening, IF1 closing) { return getBracketMap(tok, opening, closing, 0, l(tok)); } static public Map getBracketMap(List tok, IF1 opening, IF1 closing, int from, int to) { TreeMap map = new TreeMap(); List stack = new ArrayList(); for (int i = from | 1; i < to; i += 2) { String t = tok.get(i); if (opening.get(t)) stack.add(i); else if (closing.get(t)) if (!empty(stack)) map.put(liftLast(stack), i); } return map; } static public Set getBracketMap_opening = lithashset("{", "("); static public Set getBracketMap_closing = lithashset("}", ")"); static public boolean isOpeningBracket(String s) { return eqOneOf(s, "(", "{", "["); } static public boolean isClosingBracket(String s) { return eqOneOf(s, ")", "}", "]"); } static public int clampToInt(long l) { return (int) clamp(l, Integer.MIN_VALUE, Integer.MAX_VALUE); } static public boolean tokenRangeLongerThanNChars(List tok, int iStart, int iEnd, int maxChars) { int nChars = 0, n = l(tok); iStart = Math.max(0, iStart); iEnd = Math.min(n, iEnd); for (int i = iStart; i < iEnd; i++) { nChars += l(tok.get(i)); if (nChars > maxChars) return true; } return false; } static public String shortenJoinSubList(int max, List l, int i, int j) { return shortenJoin(max, subList(l, i, j)); } static public String shortenJoinSubList(int max, List l, int i) { return shortenJoin(max, subList(l, i)); } static public String spaces(int n) { return rep(' ', n); } static public Map.Entry simpleMapEntry(A key, B value) { return new Map.Entry() { public A getKey() { return key; } public B getValue() { return value; } public B setValue(B newValue) { throw unimplemented(); } }; } static public float getScore(Scored s) { return s == null ? 0 : s.score; } static public String callStringifier(Object stringifier, Object o) { return stringifier != null ? str(callF(stringifier, o)) : str(o); } static public FunctionCall functionCall_list(Object fname, Iterable args) { return new FunctionCall(fname, toObjectArray(args)); } 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 boolean isA(Either e) { return eitherIsA(e); } static public String find(String pattern, String text) { Matcher matcher = Pattern.compile(pattern).matcher(text); if (matcher.find()) return matcher.group(1); return null; } static public A find(Collection c, Object... data) { for (A x : c) if (checkFields(x, data)) return x; return null; } 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 quoteBorderless(Object o) { if (o == null) return "null"; return quoteBorderless(str(o)); } static public String quoteBorderless(String s) { if (s == null) return "null"; StringBuilder out = new StringBuilder((int) (l(s) * 1.5)); quoteBorderless_impl(s, out); return out.toString(); } static public void quoteBorderless_impl(String s, StringBuilder out) { 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 out.append(c); } } static public long stopTiming_defaultMin = 10; static public long startTiming_startTime; static public void startTiming() { startTiming_startTime = now(); } static public void stopTiming() { stopTiming(null); } static public void stopTiming(String text) { stopTiming(text, stopTiming_defaultMin); } static public void stopTiming(String text, long minToPrint) { long time = now() - startTiming_startTime; if (time >= minToPrint) { text = or2(text, "Time: "); print(text + time + " ms"); } } static public String shorten_str(Object o) { return shorten(str(o)); } static public String shorten_str(Object o, int max) { return shorten(str(o), max); } static public String shorten_str(int max, Object o) { return shorten_str(o, max); } static public Q startQ() { return new Q(); } static public Q startQ(String name) { return new Q(name); } static public boolean isNaN(double d) { return Double.isNaN(d); } static public boolean isNaN(float f) { return Float.isNaN(f); } static public double minusInfinity() { return negativeInfinity(); } static public Scored scored(A a, float score) { return new Scored(a, score); } static public Scored scored(A a, double score) { return new Scored(a, (float) score); } static public Scored scored(A a, Scored scored) { return new Scored(a, getScore(scored)); } static public Scored scored(double score, A a) { return scored(a, score); } static public GlobalID aGlobalIDObj() { return asGlobalID(randomID(16)); } static public GlobalID aGlobalIDObj(Random random) { return asGlobalID(randomID(random, 16)); } static public String shortenJoin(int max, Iterable l) { StringBuilder buf = new StringBuilder(); for (String s : unnullForIteration(l)) { buf.append(s); if (l(buf) > max) break; } return shorten(max, str(buf)); } static public RuntimeException unimplemented() { throw fail("TODO"); } static public RuntimeException unimplemented(String msg) { throw fail("TODO: " + msg); } static public RuntimeException unimplemented(Object obj) { throw fail("TODO: implement method in " + className(obj)); } static public double frac_nonNeg(double d) { return mod(d, 1); } static public boolean eitherIsA(Either e) { return e != null && e.isA(); } 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 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 double negativeInfinity() { return Double.NEGATIVE_INFINITY; } static public GlobalID asGlobalID(String id) { return id == null ? null : new GlobalID(id); } }