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 java.lang.invoke.VarHandle; import java.lang.invoke.MethodHandles; import javax.swing.border.*; import javax.swing.event.AncestorListener; import javax.swing.event.AncestorEvent; import javax.swing.Timer; import static x30_pkg.x30_util.DynamicObject; import java.nio.file.*; import static java.nio.file.StandardWatchEventKinds.*; 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 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 java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.datatransfer.StringSelection; import java.util.jar.*; import javax.swing.border.TitledBorder; import java.nio.file.Path; import java.text.*; import org.fife.ui.rsyntaxtextarea.*; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.DataFlavor; import java.awt.geom.*; import javax.swing.undo.UndoManager; import java.text.NumberFormat; import javax.imageio.metadata.*; import javax.imageio.stream.*; import java.nio.charset.Charset; import java.util.TimeZone; import java.text.SimpleDateFormat; import java.awt.datatransfer.UnsupportedFlavorException; import javax.swing.Icon; public class main { static public class G22RegionPanel extends MetaWithChangeListeners implements Swingable, IFieldsToList { public IImageRegion region; public G22RegionPanel() { } public G22RegionPanel(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public G22RegionPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22RegionPanel 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 G22RegionPanel setOriginalImage(BufferedImage originalImage) { return originalImage(originalImage); } public G22RegionPanel originalImage(BufferedImage originalImage) { this.originalImage = originalImage; return this; } final public BufferedImage getOriginalImage() { return originalImage(); } public BufferedImage originalImage() { return originalImage; } public BufferedImage originalImage; public transient FieldVar varShowOriginalColors_cache; public FieldVar varShowOriginalColors() { if (varShowOriginalColors_cache == null) varShowOriginalColors_cache = varShowOriginalColors_load(); return varShowOriginalColors_cache; } public FieldVar varShowOriginalColors_load() { return new FieldVar(this, "showOriginalColors", () -> showOriginalColors(), showOriginalColors -> showOriginalColors(showOriginalColors)); } final public G22RegionPanel setShowOriginalColors(boolean showOriginalColors) { return showOriginalColors(showOriginalColors); } public G22RegionPanel showOriginalColors(boolean showOriginalColors) { if (!eq(this.showOriginalColors, showOriginalColors)) { this.showOriginalColors = showOriginalColors; change(); } return this; } final public boolean getShowOriginalColors() { return showOriginalColors(); } public boolean showOriginalColors() { return showOriginalColors; } public boolean showOriginalColors = true; transient public ImageSurface is; 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() { is = g22utils.stdImageSurface(); imageSurfaceCheckerBoardBackground(is); varShowOriginalColors().onChangeAndNow(() -> updateImage()); return northAndCenterWithMargins(jcenteredline(liveValueCheckBox(varShowOriginalColors(), "Show original colors")), g22utils.wrap(is)); } public void updateImage() { if (showOriginalColors) is.setImage(new CutOutRegionFromImage(region).margin(10).fullImage(originalImage).get()); else is.setImage(regionToBinaryImage(region)); } } static public String shortClassName_dropNumberPrefix(Object o) { return dropNumberPrefix(shortClassName(o)); } static public G22Utils g22utils(Concepts cc) { return (G22Utils) cc.miscMapGet(G22Utils.class); } static public G22Utils g22utils(Concept cc) { return g22utils(concepts(cc)); } 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 void change() { callOpt(getOptMC("mainConcepts"), "allChanged"); } static public A markVisualizer(Object visualizer, A a) { return setMetaSrc(a, visualizer); } static public ImageSurface imageSurfaceCheckerBoardBackground(ImageSurface is) { if (is.drawBackground != null) return is; double pixelsPerSecond = 8; is.drawBackground = (w, h, g) -> { var cb = new CheckerBoard2().w(w).h(h); double time = sysSeconds(); int shift = iround(time * pixelsPerSecond); cb.shiftX(shift).shiftY(shift); cb.drawOn(g); }; setDoubleBuffered(is); repaintEvery(1.0 / pixelsPerSecond, is); return is; } static public JPanel northAndCenterWithMargins(Swingable n, Swingable c) { return northAndCenterWithMargins(n, toComponent(c)); } static public JPanel northAndCenterWithMargins(Swingable n, Component c) { return northAndCenterWithMargins(toComponent(n), c); } static public JPanel northAndCenterWithMargins(Component n, Swingable c) { return northAndCenterWithMargins(n, toComponent(c)); } static public JPanel northAndCenterWithMargins(Component n, Component c) { return applyDefaultMargin(northAndCenter(withBottomMargin(n), c)); } static public JPanel northAndCenterWithMargins(int margin, Swingable n, Swingable c) { return northAndCenterWithMargins(margin, n, toComponent(c)); } static public JPanel northAndCenterWithMargins(int margin, Swingable n, Component c) { return northAndCenterWithMargins(margin, toComponent(n), c); } static public JPanel northAndCenterWithMargins(int margin, Component n, Swingable c) { return northAndCenterWithMargins(margin, n, toComponent(c)); } static public JPanel northAndCenterWithMargins(int margin, Component n, Component c) { return applyMargin(margin, northAndCenter(withBottomMargin(margin, n), c)); } 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 JCheckBox liveValueCheckBox(String text, IVarWithNotify lv) { return jLiveValueCheckBox(text, lv); } static public JCheckBox liveValueCheckBox(IVarWithNotify lv, String text) { return jLiveValueCheckBox(text, lv); } static public Image2B regionToBinaryImage(IImageRegion region) { return new RegionToImage2B(region).get(); } static public String dropNumberPrefix(String s) { return dropFirst(s, indexOfNonDigit(s)); } static public String shortClassName(Object o) { if (o == null) return null; Class c = o instanceof Class ? (Class) o : o.getClass(); String name = c.getName(); return shortenClassName(name); } static public Concepts concepts(Concept c) { return c == null ? null : c._concepts; } 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 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 Object getOptMC(String field) { return getOpt(mc(), field); } 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 double sysSeconds() { return nanosToSeconds(nanoTime()); } static public int iround(double d) { return (int) Math.round(d); } static public int iround(Number n) { return iround(toDouble(n)); } static public A setDoubleBuffered(A c) { return setDoubleBuffered(c, true); } static public A setDoubleBuffered(A c, boolean b) { { swing(() -> { { if (c != null) c.setDoubleBuffered(b); } }); } return c; } static public A repaintEvery(int ms, A c) { return awtDoEvery(c, ms, () -> c.repaint()); } static public A repaintEvery(double seconds, A c) { return awtDoEvery(c, seconds, () -> c.repaint()); } static public A repaintEvery(A c, int ms) { return repaintEvery(ms, c); } static public A toComponent(A c) { return c; } static public Component toComponent(Swingable c) { return c == null ? null : c.visualize(); } static public A applyDefaultMargin(final A c) { if (c != null) { swing(() -> { c.setBorder(BorderFactory.createEmptyBorder(withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth)); }); } return c; } static public JPanel northAndCenter(Component n, Component c) { return centerAndNorth(c, n); } 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 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 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 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 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 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 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 JCheckBox jLiveValueCheckBox(String text, SimpleLiveValue lv) { JCheckBox cb = jCheckBox(text); bindCheckBoxToLiveValue(cb, lv); return cb; } static public JCheckBox jLiveValueCheckBox(String text, IVarWithNotify lv) { JCheckBox cb = jCheckBox(text); bindCheckBoxToLiveValue(cb, lv); return cb; } 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 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 indexOfNonDigit(String s) { int n = l(s); for (int i = 0; i < n; i++) if (!isDigit(s.charAt(i))) return i; return -1; } static public String shortenClassName(String name) { if (name == null) return null; int i = lastIndexOf(name, "$"); if (i < 0) i = lastIndexOf(name, "."); return i < 0 ? name : substring(name, i + 1); } static public Map> 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(F2 f, A a, B b) { return f == null ? null : f.get(a, b); } 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 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 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 Class mc() { return main.class; } 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 double nanosToSeconds(double nanos) { return nanoSecondsToSeconds(nanos); } static public long nanoTime() { return System.nanoTime(); } 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 awtDoEvery(A component, long delay, Runnable r) { return awtEvery(component, delay, r); } static public A awtDoEvery(A component, long delay, long firstDelay, Runnable r) { return awtEvery(component, delay, firstDelay, r); } static public void awtDoEvery(RootPaneContainer frame, long delay, Runnable r) { awtEvery(frame, delay, r); } static public A awtDoEvery(A component, double delaySeconds, Runnable r) { return awtEvery(component, delaySeconds, r); } 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 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 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 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(IntBuffer b) { return b == null ? 0 : b.size(); } static public int l(LongBuffer b) { return b == null ? 0 : b.size(); } static public int l(IntSize o) { return o == null ? 0 : o.size(); } 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 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 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 int first(IntBuffer buf) { return buf.get(0); } static public byte first(ByteBuffer buf) { return buf.get(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 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 Component wrapForSmartAdd(Object o) { if (o == null) return jpanel(); if (o instanceof String) return jlabel((String) o); return wrap(o); } static public Component jrigid() { return javax.swing.Box.createRigidArea(new Dimension(0, 0)); } static public void _handleError(Error e) { } 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 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 JPanel marginPanel() { return jtransparent(borderLayoutPanel()); } static public String[] drop(int n, String[] a) { n = Math.min(n, a.length); String[] b = new String[a.length - n]; System.arraycopy(a, n, b, 0, b.length); return b; } static public Object[] drop(int n, Object[] a) { n = Math.min(n, a.length); Object[] b = new Object[a.length - n]; System.arraycopy(a, n, b, 0, b.length); return b; } static public ArrayList toList(A[] a) { return asList(a); } static public ArrayList toList(int[] a) { return asList(a); } static public ArrayList toList(short[] a) { return asList(a); } static public ArrayList toList(Set s) { return asList(s); } static public ArrayList toList(Iterable s) { return asList(s); } 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 isDigit(char c) { return Character.isDigit(c); } static public int lastIndexOf(String a, String b) { return a == null || b == null ? -1 : a.lastIndexOf(b); } static public int lastIndexOf(String a, char b) { return a == null ? -1 : a.lastIndexOf(b); } static public int lastIndexOf(List l, int i, A a) { if (l == null) return -1; for (i = min(l(l), i) - 1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } static public int lastIndexOf(List l, A a) { if (l == null) return -1; for (int i = l(l) - 1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } static public Map newDangerousWeakHashMap() { return _registerDangerousWeakMap(synchroMap(new WeakHashMap())); } static public Map newDangerousWeakHashMap(Object initFunction) { return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction); } 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 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 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 class getOpt_Map extends WeakHashMap { public getOpt_Map() { if (getOpt_special == null) getOpt_special = new HashMap(); clear(); } public void clear() { super.clear(); put(Class.class, getOpt_special); put(String.class, getOpt_special); } } static final public Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map())); static public HashMap getOpt_special; static public Map getOpt_getFieldMap(Object o) { Class c = _getClass(o); HashMap map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); return map; } static public Object getOpt_cached(Object o, String field) { try { if (o == null) return null; Map map = getOpt_getFieldMap(o); if (map == getOpt_special) { if (o instanceof Class) return getOpt((Class) o, field); if (o instanceof Map) return ((Map) o).get(field); } Field f = map.get(field); if (f != null) return f.get(o); if (o instanceof DynamicObject) return syncMapGet2(((DynamicObject) o).fieldValues, field); return null; } catch (Exception __e) { throw rethrow(__e); } } static public HashMap getOpt_makeCache(Class c) { HashMap map; if (isSubtypeOf(c, Map.class)) map = getOpt_special; else { map = new HashMap(); if (!reflection_classesNotToScan().contains(c.getName())) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) { makeAccessible(f); String name = f.getName(); if (!map.containsKey(name)) map.put(name, f); } _c = _c.getSuperclass(); } while (_c != null); } } if (getOpt_cache != null) getOpt_cache.put(c, map); return map; } static public void 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 double nanoSecondsToSeconds(double nanos) { return nanos * 1e-9; } static public double parseDouble(String s) { return empty(s) ? 0.0 : Double.parseDouble(s); } static public A awtEvery(A component, long delay, Object r) { swingEvery(component, delay, r); return component; } static public A awtEvery(A component, long delay, Runnable r) { return awtEvery(component, delay, delay, r); } static public A awtEvery(A component, long delay, long firstDelay, Runnable r) { return awtEvery(component, delay, firstDelay, (Object) r); } static public A awtEvery(A component, long delay, long firstDelay, Object r) { swingEvery(component, delay, firstDelay, r); return component; } static public void awtEvery(RootPaneContainer frame, long delay, Object r) { swingEvery(frame, delay, r); } static public A awtEvery(A component, double delaySeconds, Object r) { return awtEvery(component, toMS(delaySeconds), r); } 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 Border jCompoundBorder(Border inner, Border outer) { if (inner == null) return outer; if (outer == null) return inner; return BorderFactory.createCompoundBorder(inner, outer); } 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 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 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 ArrayList asList(A[] a) { return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a)); } static public ArrayList asList(byte[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (var i : a) l.add(i); return l; } 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 Object[] asObjectArray(Collection l) { return toObjectArray(l); } 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(IntBuffer b) { return b == null || b.isEmpty(); } static public boolean empty(LongBuffer b) { return b == null || b.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 Pair mapEntryToPair(Map.Entry e) { return e == null ? null : pair(e.getKey(), e.getValue()); } static public Set> entrySet(Map map) { return _entrySet(map); } static public Pair pair(A a, B b) { return new Pair(a, b); } static public Pair pair(A a) { return new Pair(a, a); } static public A firstThat(Iterable l, IF1 pred) { for (A a : unnullForIteration(l)) if (pred.get(a)) return a; return null; } static public A firstThat(A[] l, IF1 pred) { for (A a : unnullForIteration(l)) if (pred.get(a)) return a; return null; } static public A firstThat(IF1 pred, Iterable l) { return firstThat(l, pred); } static public A firstThat(IF1 pred, A[] l) { return firstThat(l, pred); } static public 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 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 JLabel jlabel(final String text) { return swingConstruct(BetterLabel.class, text); } static public JLabel jlabel() { return jlabel(" "); } static public A swingNu(final Class c, final Object... args) { return swingConstruct(c, args); } 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 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 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 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 void setChecked(JCheckBox checkBox, boolean b) { if (checkBox != null) { swing(() -> { if (isChecked(checkBox) != b) checkBox.setSelected(b); }); } } static public void setChecked(JCheckBoxMenuItem mi, boolean b) { if (mi != null) { swing(() -> { mi.setSelected(b); }); } } static public boolean 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 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 A onChange(A b, Runnable 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 void onChange(IHasChangeListeners a, Runnable r) { if (a != null && r != null) a.onChange(r); } static public A jtransparent(final A a) { { swing(() -> { a.setOpaque(false); }); } return a; } static public JPanel borderLayoutPanel() { return jpanel(new BorderLayout()); } static public int strL(String s) { return s == null ? 0 : s.length(); } static public int lCharSequence(CharSequence s) { return s == null ? 0 : s.length(); } static public 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 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 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 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 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 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 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 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 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 void swingEvery(JComponent component, long delay, Object r) { installTimer(component, delay, r); } static public void swingEvery(JComponent component, long delay, long firstDelay, Object r) { installTimer(component, r, delay, firstDelay); } static public void swingEvery(RootPaneContainer frame, long delay, Object r) { installTimer(frame, delay, r); } static public void swingEvery(RootPaneContainer frame, long delay, long firstDelay, Object r) { installTimer(frame, delay, firstDelay, r); } static public long toMS(double seconds) { return (long) (seconds * 1000); } 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 JScrollPane jscroll(Component c) { return swing(() -> { return c instanceof JScrollPane ? ((JScrollPane) c) : new JScrollPane(c); }); } 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 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 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 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 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 List ll(A... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (A x : a) l.add(x); return l; } static public String 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 Set> _entrySet(Map map) { return map == null ? Collections.EMPTY_SET : map.entrySet(); } 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 byte[] unnullForIteration(byte[] l) { return l == null ? emptyByteArray() : l; } static public int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; } static public char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; } static public double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; } static public short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; } static public Map unnullForIteration(Map l) { return l == null ? immutableEmptyMap() : l; } static public Iterable unnullForIteration(Iterable i) { return i == null ? immutableEmptyList() : i; } static public A[] unnullForIteration(A[] a) { return a == null ? (A[]) emptyObjectArray() : a; } static public BitSet unnullForIteration(BitSet b) { return b == null ? new BitSet() : b; } static public Pt unnullForIteration(Pt p) { return p == null ? new Pt() : p; } static public Symbol unnullForIteration(Symbol s) { return s == null ? emptySymbol() : s; } static public Pair unnullForIteration(Pair p) { return p != null ? p : new Pair(null, null); } static public long unnullForIteration(Long l) { return l == null ? 0L : l; } static public boolean emptyString(String s) { return s == null || s.length() == 0; } 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 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 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 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 A getSelectedItem_typed(JList l) { return swing(() -> l.getSelectedValue()); } static public A getSelectedItem_typed(JComboBox cb) { return swing(() -> (A) cb.getSelectedItem()); } 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 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 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 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 AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) { return print_byThread().get() == null ? tempInterceptPrint(f) : null; } 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 Class javax() { return getJavaX(); } static public List synchroList() { return synchroList(new ArrayList()); } static public List synchroList(List l) { return Collections.synchronizedList(l); } 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 A assertNotNull(A a) { assertTrue(a != null); return a; } static public A assertNotNull(String msg, A a) { assertTrue(msg, a != null); return a; } static public Map synchroHashMap() { return synchronizedMap(new HashMap()); } 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 String combinePrintParameters(String s, Object o) { return (endsWithLetterOrDigit(s) ? s + ": " : s) + o; } static public void ping_okInCleanUp() { if (ping_pauseAll || ping_anyActions) ping_impl(true); } static public Object getThreadLocal(Object o, String name) { ThreadLocal t = (ThreadLocal) (getOpt(o, name)); return t != null ? t.get() : null; } static public A getThreadLocal(ThreadLocal tl) { return tl == null ? null : tl.get(); } static public A getThreadLocal(ThreadLocal tl, A defaultValue) { return or(getThreadLocal(tl), defaultValue); } static public ThreadLocal print_byThread_dontCreate() { return print_byThread; } static public boolean isFalse(Object o) { return eq(false, o); } static public String getStackTrace(Throwable throwable) { lastException(throwable); return getStackTrace_noRecord(throwable); } static public String getStackTrace_noRecord(Throwable throwable) { StringWriter writer = new StringWriter(); throwable.printStackTrace(new PrintWriter(writer)); return hideCredentials(writer.toString()); } static public String getStackTrace() { return getStackTrace_noRecord(new Throwable()); } static public String getStackTrace(String msg) { return getStackTrace_noRecord(new Throwable(msg)); } static public String fixNewLines(String s) { int i = indexOf(s, '\r'); if (i < 0) return s; int l = s.length(); StringBuilder out = new StringBuilder(l); out.append(s, 0, i); for (; i < l; i++) { char c = s.charAt(i); if (c != '\r') out.append(c); else { out.append('\n'); if (i + 1 < l && s.charAt(i + 1) == '\n') ++i; } } return out.toString(); } static public void print_append(Appendable buf, String s, int max) { try { synchronized (buf) { buf.append(s); if (buf instanceof StringBuffer) rotateStringBuffer(((StringBuffer) buf), max); else if (buf instanceof StringBuilder) rotateStringBuilder(((StringBuilder) buf), max); } } catch (Exception __e) { throw rethrow(__e); } } static public 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 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 HashSet litset(A... items) { return lithashset(items); } 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 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 Object vm_generalMap_get(Object key) { return vm_generalMap().get(key); } 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 List> _threadInheritInfo_retrievers = synchroList(); static public void _threadInheritInfo(Object info) { if (info == null) return; pcallFAll(_threadInheritInfo_retrievers, (Map) info); } 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 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 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 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 List immutableEmptyList() { return Collections.emptyList(); } static public byte[] emptyByteArray_a = new byte[0]; static public byte[] emptyByteArray() { return emptyByteArray_a; } 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 short[] emptyShortArray = new short[0]; static public short[] emptyShortArray() { return emptyShortArray; } static public Map immutableEmptyMap() { return Collections.emptyMap(); } 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 void addToContainer(Container a, Component... b) { if (a == null) return; { swing(() -> { for (Component c : unnullForIteration(b)) if (c != null) a.add(c); }); } } 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 Object callFunction(Object f, Object... args) { return callF(f, args); } 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 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 ActionListener actionListener(final Object runnable) { return actionListener(runnable, null); } static public ActionListener actionListener(final Object runnable, final Object instanceToHold) { if (runnable instanceof ActionListener) return (ActionListener) runnable; final Object info = _threadInfo(); return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { _threadInheritInfo(info); AutoCloseable __1 = holdInstance(instanceToHold); try { pcallF(runnable); } finally { _close(__1); } } catch (Throwable __e) { messageBox(__e); } } }; } static public String selectedItem(JList l) { return getSelectedItem(l); } static public String selectedItem(JComboBox cb) { return getSelectedItem(cb); } 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 String joinWithComma(Collection c) { return join(", ", c); } static public String joinWithComma(Object... c) { return join(", ", c); } static public String joinWithComma(String... c) { return join(", ", c); } static public String joinWithComma(Pair p) { return p == null ? "" : joinWithComma(str(p.a), str(p.b)); } static public List getClasses(Object[] array) { List l = emptyList(l(array)); for (Object o : array) l.add(_getClass(o)); return l; } 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 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 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 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 public Map synchronizedMap() { return synchroMap(); } static public Map synchronizedMap(Map map) { return synchroMap(map); } static public boolean endsWithLetterOrDigit(String s) { return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length() - 1)); } static public A or(A a, A b) { return a != null ? a : b; } 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 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 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 HashSet lithashset(A... items) { HashSet set = new HashSet(); for (A a : items) set.add(a); return set; } 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 A optCast(Class c, Object o) { return isInstance(c, o) ? (A) o : null; } 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 AutoCloseable tempActivity(Object r) { return null; } static public boolean allPaused() { return ping_pauseAll; } 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 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 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 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 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 Map newWeakHashMap() { return _registerWeakMap(synchroMap(new WeakHashMap())); } static public void newPing() { var tl = newPing_actionTL(); Runnable action = tl == null ? null : tl.get(); { if (action != null) action.run(); } } static public void failIfUnlicensed() { assertTrue("license off", licensed()); } static public Thread currentThread() { return Thread.currentThread(); } static public Throwable _storeException_value; static public void _storeException(Throwable e) { _storeException_value = e; } static public Object vm_generalMap_put(Object key, Object value) { return mapPutOrRemove(vm_generalMap(), key, value); } static public Set syncIdentityHashSet() { return (Set) synchronizedSet(identityHashSet()); } static public Map syncHashMap() { return synchroHashMap(); } 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 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 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 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 AbstractAction abstractAction(String name, final Object runnable) { return new AbstractAction(name) { public void actionPerformed(ActionEvent evt) { pcallF(runnable); } }; } 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 String getSelectedItem(JList l) { return (String) l.getSelectedValue(); } static public String getSelectedItem(JComboBox cb) { return strOrNull(cb.getSelectedItem()); } 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 void _onJavaXSet() { } static public boolean isStaticMethod(Method m) { return methodIsStatic(m); } static public PersistableThrowable persistableThrowable(Throwable e) { return e == null ? null : new PersistableThrowable(e); } 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 boolean isInstance(Class type, Object arg) { return type.isInstance(arg); } 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 String strOrNull(Object o) { return o == null ? null : str(o); } 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(IntBuffer b) { return b != null && !b.isEmpty(); } static public boolean nempty(LongBuffer b) { return b != null && !b.isEmpty(); } 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 Throwable innerException2(Throwable e) { if (e == null) return null; while (empty(e.getMessage()) && e.getCause() != null) e = e.getCause(); return 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 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 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 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 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 Iterator emptyIterator() { return Collections.emptyIterator(); } 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 boolean methodIsStatic(Method m) { return (m.getModifiers() & Modifier.STATIC) != 0; } 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 boolean domainIsUnder(String domain, String mainDomain) { return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain); } static public String theAGIBlueDomain() { return "agi.blue"; } static public Map emptyMap() { return new HashMap(); } static public A printException(A e) { printStackTrace(e); return 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 callF_gen(F0 f) { return f == null ? null : f.get(); } static public B callF_gen(F1 f, A a) { return f == null ? null : f.get(a); } static public A callF_gen(IF0 f) { return f == null ? null : f.get(); } static public B callF_gen(IF1 f, A a) { return f == null ? null : f.get(a); } static public B callF_gen(A a, IF1 f) { return f == null ? null : f.get(a); } static public C callF_gen(F2 f, A a, B b) { return f == null ? null : f.get(a, b); } static public C callF_gen(IF2 f, A a, B b) { return f == null ? null : f.get(a, b); } static public void callF_gen(VF1 f, A a) { { if (f != null) f.get(a); } } static public void callF_gen(A a, IVF1 f) { { if (f != null) f.get(a); } } static public void callF_gen(IVF1 f, A a) { { if (f != null) f.get(a); } } static public Object callF_gen(Runnable r) { { if (r != null) r.run(); } return null; } static public Object callF_gen(Object f, Object... args) { return callF(f, args); } static public Set synchroHashSet() { return synchronizedSet(new HashSet()); } static public A popLast(List l) { return liftLast(l); } static public List popLast(int n, List l) { return liftLast(n, l); } static public boolean nemptyString(String s) { return s != null && s.length() > 0; } static public int listL(Collection l) { return l == null ? 0 : l.size(); } static public boolean neq(Object a, Object b) { return !eq(a, b); } 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 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 IF0 f0ToIF0(F0 f) { return f == null ? null : () -> f.get(); } 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 String asString(Object o) { return o == null ? null : o.toString(); } 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 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 boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) { return a != null && a.regionMatches(true, offsetA, b, offsetB, len); } static public List 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 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); } 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); } 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 CutOutRegionFromImage implements IFieldsToList { public IImageRegion region; public CutOutRegionFromImage() { } public CutOutRegionFromImage(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public CutOutRegionFromImage setAlphaNonContained(double alphaNonContained) { return alphaNonContained(alphaNonContained); } public CutOutRegionFromImage alphaNonContained(double alphaNonContained) { this.alphaNonContained = alphaNonContained; return this; } final public double getAlphaNonContained() { return alphaNonContained(); } public double alphaNonContained() { return alphaNonContained; } public double alphaNonContained = 0.5; final public CutOutRegionFromImage setFullImage(BufferedImage fullImage) { return fullImage(fullImage); } public CutOutRegionFromImage fullImage(BufferedImage fullImage) { this.fullImage = fullImage; return this; } final public BufferedImage getFullImage() { return fullImage(); } public BufferedImage fullImage() { return fullImage; } public BufferedImage fullImage; final public CutOutRegionFromImage setMargin(int margin) { return margin(margin); } public CutOutRegionFromImage margin(int margin) { this.margin = margin; return this; } final public int getMargin() { return margin(); } public int margin() { return margin; } public int margin; final public CutOutRegionFromImage setRect(Rect rect) { return rect(rect); } public CutOutRegionFromImage rect(Rect rect) { this.rect = rect; return this; } final public Rect getRect() { return rect(); } public Rect rect() { return rect; } public Rect rect; public BufferedImage get() { if (region == null) return null; if (fullImage == null) fullImage = toBufferedImage(region.image()); if (fullImage == null) return null; rect = region.bounds(); rect = intersectRects(growRect(rect, margin), imageRect(fullImage)); var clipped = clipBufferedImage(fullImage, rect); int[] pixels = pixelsOfBufferedImage(clipped); int w = rect.w, h = rect.h, i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (!region.contains(rect.x + x, rect.y + y)) pixels[i] = withAlpha(alphaNonContained, pixels[i]); ++i; } return bufferedImageWithAlpha(w, h, pixels); } } 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); } public String toString_base() { return super.toString(); } public String toString() { Object o = metaGet("toString", this); if (o instanceof String) return ((String) o); if (o instanceof IF1) return str(((IF1) o).get(this)); return toString_base(); } } 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 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 synchronized A getAndSet(A a) { var value = v; set(a); return value; } public IF0 getter() { return () -> get(); } public IVF1 setter() { return __47 -> set(__47); } public String toString() { return str(this.get()); } } 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); } } public interface IImageRegion extends INumberOfPixels, IPixelSet { public Rect bounds(); public IterableIterator pixelIterator(); public boolean contains(int x, int y); public default Img image() { return null; } public default Object creator() { return null; } public default int indexInCreator() { return 0; } public default Boolean createdWithDiagonals() { return null; } public default int numberOfPixels() { return l(pixelIterator()); } public default Pt firstPixel() { return first(pixelIterator()); } public default Color color() { return null; } public default int brightness() { return -1; } public default OnePathWithOrigin outline() { return g22_regionOutline(this); } default public Image2B toImage2B() { return new RegionToImage2B(this).get(); } default public int[] pixelsAsIntArray() { throw unimplemented(); } } 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 stdImageSurface(File file) { var is = stdImageSurface(); is.setImage(file); return is; } public ImageSurface stdImageSurface(G22GalleryImage img) { return stdImageSurface(img == null ? null : img.path); } 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"); parser.addClassAlias("MRUAndAllTimeTop", "MRUAndAllTimeTop_optimized"); return parser; } public Object leftArrow(String script) { return leftArrowParser().parse(script).get(); } 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 recentlyOpenedDBsFile() { return newFile(databasesMotherDir(), "Recently 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() { return loadRecentProjectsFile(lastOpenedDBsFile()); } public List dbNamesRecentlyOpened() { return loadRecentProjectsFile(recentlyOpenedDBsFile()); } public void addToRecentDBNames(String dbName, boolean hidden) { List list = dbNamesRecentlyOpened(); List list2 = cloneList(list); removeAll(list2, dbName, "*" + dbName); list2.add(0, hidden ? "*" + dbName : dbName); truncateList(list2, 100); if (!eq(list, list2)) saveTextFile(recentlyOpenedDBsFile(), lines(list2)); } public List loadRecentProjectsFile(File file) { List dbNames = new ArrayList(); for (String name : tlft(loadTextFile(file))) { 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 void setupScriptCRUD(SimpleCRUD_v2 crud) { setupScriptCRUD(crud, false); } public void setupScriptCRUD(SimpleCRUD_v2 crud, boolean allowRunOnProjectOpen) { crud.useNewChangeHandler(true); crud.editableFieldsForItem = x -> llNonNulls("description", allowRunOnProjectOpen ? "runOnProjectOpen" : null, allowRunOnProjectOpen ? "runOrder" : null); crud.multiLineField("text"); crud.multiLineField("editingText"); crud.makeTextArea = text -> jMinHeight(200, crud.makeTextArea_base(text)); crud.humanizeFieldNames = false; crud.iconButtons(true); crud.itemToMap_inner2 = c -> scriptToMap(c, allowRunOnProjectOpen); crud.dontDuplicateFields = litset("runOnProjectOpen", "runOrder", "runCount", "lastResultByMode"); } 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(__61 -> linesOfCode_javaTok(__61), 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(__62 -> getLabel(__62), 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 List getVarFromAnyProject(String name) { return nonNulls(masterStuff().openProjects(), project -> project.g22utils().getProjectVar(name)); } public G22Variable projectVarConcept(String name) { return optimizedUniq(concepts, G22Variable.class, "name", name); } public Object waitForProjectVar(String name) { G22Variable var = projectVarConcept(name); return waitForCalculatedValueUsingChangeListener(() -> var.value(), var); } public void setBigProjectVar(boolean persistent, String name, Object value) { if (persistent) setBigProjectVar(name, value); else setTransientProjectVar(name, value); } public G22Variable setProjectVar(boolean persistent, String name, Object value) { G22Variable var = projectVarConcept(name); if (!persistent) var.persistent(persistent); var.value(value); if (persistent) var.persistent(persistent); return var; } public void unloadProjectVar(String name) { var var = findProjectVar(name); { if (var != null) var.unload(); } } public void setBigProjectVar(String name, Object value) { setPersistentProjectVar(name, value); G22Variable var = projectVarConcept(name); var.makeBig(); } public Object getCachedProjectVar(String name) { var var = findProjectVar(name); return var == null ? null : var.cachedValue(); } public boolean isBigProjectVar(String name) { var v = findProjectVar(name); return v != null && v.big(); } public void setPersistentProjectVar(String name, Object value) { setProjectVar(true, name, value); } public G22Variable setTransientProjectVar(String name, Object value) { return setProjectVar(false, name, value); } public void setAutoClosingProjectVar(String name, Object value) { setTransientProjectVar(name, value).autoClose(true); } public void deleteProjectVar(String name) { deleteConcept(findProjectVar(name)); } public Object getOrCreateProjectVar(String name, IF0 maker) { return getOrCreateProjectVar(projectVarConcept(name), maker); } public Object getOrCreatePersistentProjectVar(String name, IF0 maker) { var var = projectVarConcept(name); Object value = getOrCreateProjectVar(var, maker); var.persistent(true); return value; } public Object getOrCreateProjectVar(G22Variable var, IF0 maker) { if (!var.has()) { Object value = maker.get(); if (value != null) var.setValueIfNull(value); } return var.get(); } public IVarWithNotify liveProjectVar(String name) { return liveProjectVar(name, null); } public IVarWithNotify liveProjectVar(String name, Object defaultValue) { G22Variable var = projectVarConcept(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 = projectVarConcept(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 void projectVarChanged(String name) { var var = findProjectVar(name); { if (var != null) var.changeInsideOfValue(); } } public Collection projectVarChanged(Object value) { var vars = conceptsWhere(concepts, G22Variable.class, "value", value); for (var var : vars) var.change(); return vars; } 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 __2 = 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(__2); } }); } public Object host() { AutoCloseable __3 = enter(); try { return dm_os(); } finally { _close(__3); } } 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(), __4 -> projectFileChanged(__4)); } 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); } public IF1 classFinder() { return masterStuff.makeClassFinder(); } public Object restructure(Object o) { return unstructure(structure(o), false, concepts.classFinder); } public G22ProjectActions project() { return projectActions(); } public boolean openPathInProject(String path) { return projectActions().openPathInProject(path); } final public boolean showUIURL(String url) { return openUIURL(url); } public boolean openUIURL(String url) { return projectActions().openUIURL(url); } public BufferedImage loadProjectImage(String fileName) { return loadImage2(projectFile(fileName)); } public IG22LoadedDB openDB(String name) { return openDB(name, false); } public IG22LoadedDB openDB(String name, boolean hidden) { return masterStuff().openDB(name, hidden); } public G22Utils getProject(String name) { return openDB(name, true).g22utils(); } public G22JavaObjectVisualizer visualizeObject(Object o) { return new G22JavaObjectVisualizer(this, o); } transient public IF0 makeVariablesPanel; public G22VariablesPanel makeVariablesPanel() { return makeVariablesPanel != null ? makeVariablesPanel.get() : makeVariablesPanel_base(); } final public G22VariablesPanel makeVariablesPanel_fallback(IF0 _f) { return _f != null ? _f.get() : makeVariablesPanel_base(); } public G22VariablesPanel makeVariablesPanel_base() { return new G22VariablesPanel().g22utils(this); } transient public IF0 jGazelleLogo; public JComponent jGazelleLogo() { return jGazelleLogo != null ? jGazelleLogo.get() : jGazelleLogo_base(); } final public JComponent jGazelleLogo_fallback(IF0 _f) { return _f != null ? _f.get() : jGazelleLogo_base(); } public JComponent jGazelleLogo_base() { return main.jGazelleLogo(); } public boolean devMode() { return masterStuff().devMode(); } public G22GalleryImage galleryImageForMD5(String md5) { return firstThat(list(concepts, G22GalleryImage.class), img -> cic(fileName(img.path), md5)); } public JComponent wrapImageSurface(ImageSurface is) { return is == null ? null : jscroll_centered_borderless(is); } public JComponent wrap(Object o) { var c = main.wrap(o); if (c instanceof ImageSurface) return wrapImageSurface((ImageSurface) c); return c; } transient public IF0 byUser; public String byUser() { return byUser != null ? byUser.get() : byUser_base(); } final public String byUser_fallback(IF0 _f) { return _f != null ? _f.get() : byUser_base(); } public String byUser_base() { return ""; } } 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(File file) { setImage(file); } public ImageSurface(MakesBufferedImage image) { this(image != null ? image.getBufferedImage() : dummyImage()); } public ImageSurface(BufferedImage image) { setImage(image); clearSurface = false; bindToComponent(this, () -> performAutoZoom(), null); onResize(this, () -> performAutoZoom()); onEnclosingScrollPaneResize(this, () -> performAutoZoom()); 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); } transient public IVF3 drawBackground; public void drawBackground(int w, int h, Graphics2D g) { if (drawBackground != null) drawBackground.get(w, h, g); else drawBackground_base(w, h, g); } final public void drawBackground_fallback(IVF3 _f, int w, int h, Graphics2D g) { if (_f != null) _f.get(w, h, g); else drawBackground_base(w, h, g); } public void drawBackground_base(int w, int h, Graphics2D g) { g.setColor(or(getBackground(), Color.white)); g.fillRect(0, 0, w, h); } public void render(int w, int h, Graphics2D g) { if (verbose) _print("render"); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationMode); drawBackground(w, h, g); BufferedImage image = or(imageToDraw, this.image); if (!hasImage()) drawBackground(w, h, g); else { boolean alpha = !noAlpha && hasTransparency(image); if (alpha) drawBackground(w, h, g); 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(cloneGraphics(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(File file) { setFile(file); setImage(loadImage2(file)); } 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(); }); } private 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(); } final public void pixelate(boolean b) { setPixelated(b); } public void setPixelated(boolean b) { assertTrue(b); imageSurface_pixelated(this); } final public ImageSurface autoZoomToDisplay(boolean b) { return setAutoZoomToDisplay(b); } 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 void standardZoom() { setZoom(1.0); } 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 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 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); } } 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(); } } } 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 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 final public class WeakHasherMap extends AbstractMap implements Map { public Hasher hasher = null; private boolean keyEquals(Object k1, Object k2) { return (hasher == null ? k1.equals(k2) : hasher.equals(k1, k2)); } private int keyHashCode(Object k1) { return (hasher == null ? k1.hashCode() : hasher.hashCode(k1)); } private WeakKey WeakKeyCreate(K k) { if (k == null) return null; else return new WeakKey(k); } private 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); } private 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); } private 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") private 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); } private boolean keyvalEquals(K o1, K o2) { return (o1 == null) ? (o2 == null) : keyEquals(o1, o2); } private 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 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 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", getMessage()); } public String getMessage() { return commaCombine(getCause(), objects); } } static public interface Swingable { public JComponent visualize(); } static public class Image2B implements IBinaryImage { public Image2B() { } public int w, h; public byte[] pixels; public Image2B(int w, int h, byte[] pixels) { this.pixels = pixels; this.h = h; this.w = w; cleanPixelArray(); } public Image2B(Image2B img) { w = img.getWidth(); h = img.getHeight(); pixels = cloneByteArray(img.pixels); } public Image2B(RGBImage img) { w = img.getWidth(); h = img.getHeight(); pixels = new byte[(w * h + 7) / 8]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) if (img.getPixel(x, y).getBrightness() >= 0.5f) { int i = y * w + x; pixels[i / 8] |= 1 << (i & 7); } } public Image2B(BWImage img) { this(img, 128); } public Image2B(BWImage img, int threshold) { w = img.w(); h = img.h(); int n = w * h; int nOut = (n + 7) / 8; byte[] pixels = this.pixels = new byte[nOut]; byte[] bwPixels = img.pixels; int iIn = 0; for (int iOut = 0; iOut < nOut - 1; iOut++) { int value = 0; for (int bit = 0; bit < 8; bit++) { value >>= 1; if (ubyteToInt(bwPixels[iIn++]) >= threshold) value |= 0x80; } pixels[iOut] = (byte) value; } for (; iIn < n; iIn++) if (ubyteToInt(bwPixels[iIn]) >= threshold) pixels[nOut - 1] |= 1 << (iIn & 7); } public Image2B(BufferedImage img) { this(img, 128); } public Image2B(BufferedImage img, int threshold) { this(new BWImage(img), threshold); } public Image2B(int w, int h) { this.h = h; this.w = w; pixels = new byte[(w * h + 7) / 8]; } public RGBImage toRGB() { RGBImage img = new RGBImage(w, h, Color.black); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 8] & (1 << (i & 7))) != 0) img.setPixel(x, y, Color.white); } return img; } public BWImage toBW() { BWImage img = new BWImage(w, h, 0f); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 8] & (1 << (i & 7))) != 0) img.setPixel(x, y, 1f); } return img; } public BufferedImage getBufferedImage() { return toBW().getBufferedImage(); } final public boolean getBoolPixel(int x, int y) { return getPixel(x, y); } public boolean getPixel(int x, int y) { int i = y * w + x; return (pixels[i / 8] & (1 << (i & 7))) != 0; } final public boolean getBoolPixel(int x, int y, boolean defaultColor) { return getPixel(x, y, defaultColor); } public boolean getPixel(int x, int y, boolean defaultColor) { if (x < 0 || y < 0 || x >= w || y >= h) return defaultColor; return getPixel(x, y); } public void setPixel(int x, int y, boolean b) { int i = y * w + x; byte val = pixels[i / 8], shifted = (byte) (1 << (i & 7)); val = (byte) (b ? val | shifted : val & ~shifted); pixels[i / 8] = val; } public void setPixel(int x, int y) { int i = y * w + x; pixels[i / 8] |= 1 << (i & 7); } public int getWidth() { return w; } public int getHeight() { return h; } public String toString() { return "Image2B " + str_px(w, h); } public void cleanPixelArray() { int n = w * h; if ((n & 7) != 0) pixels[n / 8] &= (1 << (n & 7)) - 1; } } static public class RegionToImage2B implements IFieldsToList { public IPixelSet region; public RegionToImage2B() { } public RegionToImage2B(IPixelSet region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public RegionToImage2B setBounds(Rect bounds) { return bounds(bounds); } public RegionToImage2B bounds(Rect bounds) { this.bounds = bounds; return this; } final public Rect getBounds() { return bounds(); } public Rect bounds() { return bounds; } public Rect bounds; public Image2B image; public void run() { try { if (bounds == null) bounds = region.bounds(); int x1 = bounds.x, y1 = bounds.y, w = bounds.w, h = bounds.h, i = 0; byte[] pixels = new byte[(w * h + 7) / 8]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (!region.contains(x1 + x, y1 + y)) pixels[i / 8] |= 1 << (i & 7); i++; } image = new Image2B(w, h, pixels); } catch (Exception __e) { throw rethrow(__e); } } public Image2B get() { if (image == null) run(); return image; } } static abstract public class F0 { abstract public A get(); } 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(); } } 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 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; final public Concepts setGrabThroughSocket(boolean grabThroughSocket) { return grabThroughSocket(grabThroughSocket); } public Concepts grabThroughSocket(boolean grabThroughSocket) { this.grabThroughSocket = grabThroughSocket; return this; } final public boolean getGrabThroughSocket() { return grabThroughSocket(); } public boolean grabThroughSocket() { return grabThroughSocket; } transient public boolean grabThroughSocket = 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; final public Concepts setCloseConceptsOnExit(boolean closeConceptsOnExit) { return closeConceptsOnExit(closeConceptsOnExit); } public Concepts closeConceptsOnExit(boolean closeConceptsOnExit) { this.closeConceptsOnExit = closeConceptsOnExit; return this; } final public boolean getCloseConceptsOnExit() { return closeConceptsOnExit(); } public boolean closeConceptsOnExit() { return closeConceptsOnExit; } transient public boolean closeConceptsOnExit = false; 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 (grabThroughSocket && 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 { if (closeConceptsOnExit) closeAllOpt(allConcepts()); 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 first(allIndicesForClass(c)); } synchronized public Collection allIndicesForClass(Class c) { return concatLists(values(fieldIndices == null ? null : fieldIndices.get(c)), values(ciFieldIndices == null ? null : ciFieldIndices.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 void addAndChange(LongBuffer buf, long a) { if (buf == null) return; buf.add(a); change(); } public void clearAndChange(LongBuffer buf) { if (buf == null) return; buf.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; } public static interface IF0 { public A get(); } static public interface Hasher { public int hashCode(A a); public boolean equals(A a, A b); } static public interface IFieldsToList { public Object[] _fieldsToList(); } static public interface IF1 { public B get(A a); } 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); } } 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 CheckerBoard2 implements G2Drawable { final public CheckerBoard2 setW(int w) { return w(w); } public CheckerBoard2 w(int w) { this.w = w; return this; } final public int getW() { return w(); } public int w() { return w; } public int w = 256; final public CheckerBoard2 setH(int h) { return h(h); } public CheckerBoard2 h(int h) { this.h = h; return this; } final public int getH() { return h(); } public int h() { return h; } public int h = 256; final public CheckerBoard2 setShiftX(double shiftX) { return shiftX(shiftX); } public CheckerBoard2 shiftX(double shiftX) { this.shiftX = shiftX; return this; } final public double getShiftX() { return shiftX(); } public double shiftX() { return shiftX; } public double shiftX; final public CheckerBoard2 setShiftY(double shiftY) { return shiftY(shiftY); } public CheckerBoard2 shiftY(double shiftY) { this.shiftY = shiftY; return this; } final public double getShiftY() { return shiftY(); } public double shiftY() { return shiftY; } public double shiftY; final public CheckerBoard2 setCellW(double cellW) { return cellW(cellW); } public CheckerBoard2 cellW(double cellW) { this.cellW = cellW; return this; } final public double getCellW() { return cellW(); } public double cellW() { return cellW; } public double cellW = 8; final public CheckerBoard2 setCellH(double cellH) { return cellH(cellH); } public CheckerBoard2 cellH(double cellH) { this.cellH = cellH; return this; } final public double getCellH() { return cellH(); } public double cellH() { return cellH; } public double cellH = 8; final public CheckerBoard2 setColor1(Color color1) { return color1(color1); } public CheckerBoard2 color1(Color color1) { this.color1 = color1; return this; } final public Color getColor1() { return color1(); } public Color color1() { return color1; } public Color color1 = Color.lightGray; final public CheckerBoard2 setColor2(Color color2) { return color2(color2); } public CheckerBoard2 color2(Color color2) { this.color2 = color2; return this; } final public Color getColor2() { return color2(); } public Color color2() { return color2; } public Color color2 = Color.gray; public CheckerBoard2 cellSize(double cellSize) { return cellW(cellSize).cellH(cellSize); } public int getWidth() { return w; } public int getHeight() { return h; } public void drawOn(Graphics2D g) { int xofs = idiv_floor(shiftX, cellW); int yofs = idiv_floor(shiftY, cellH); double x1 = mod(shiftX, cellW) - cellW; double y1 = mod(shiftY, cellH) - cellH; boolean bRow = odd(yofs ^ xofs); for (double y = y1; y < h; y += cellH) { bRow = !bRow; boolean b = bRow; for (double x = x1; x < w; x += cellW) { b = !b; g.setColor(b ? color1 : color2); g.fill(new Rectangle2D.Double(x, y, cellW, cellH)); } } } } static public interface IVF1 { public void get(A a); } static abstract public class VF2 { abstract public void get(A a, B b); } 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 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 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 boolean openPathInProject(String path); public void editProjectStory(); public void editScripts(); public void editScript(G22LeftArrowScript script); public boolean openUIURL(String url); public IVarWithNotify varShowCasedScript(); } 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 final public class BWImage extends Meta implements MakesBufferedImage, IBWImage { public int width, height; public byte[] pixels; public float borderColor = 0.0f; public BWImage() { } public BWImage(int width, int height) { this.height = height; this.width = width; pixels = new byte[width * height]; } public BWImage(int width, int height, float brightness) { this.height = height; this.width = width; pixels = new byte[width * height]; fillArrayUnlessZero(pixels, _toByte(brightness)); } public BWImage(int width, int height, float[] pixels) { this.pixels = new byte[pixels.length]; this.height = height; this.width = width; for (int i = 0; i < pixels.length; i++) this.pixels[i] = _toByte(pixels[i]); } public BWImage(int width, int height, byte[] pixels) { this.height = height; this.width = width; this.pixels = pixels; } public BWImage(BWImage image) { width = image.getWidth(); height = image.getHeight(); byte[] pixels = this.pixels = new byte[width * height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) pixels[y * width + x] = image.getByte(x, y); } public BWImage(RGBImage image) { width = image.getWidth(); height = image.getHeight(); byte[] pixels = this.pixels = new byte[height * width]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { RGB rgb = image.getRGB(x, y); pixels[y * width + x] = BWImage._toByte(rgb.getBrightness()); } } public BWImage(BufferedImage image) { try { width = image.getWidth(); height = image.getHeight(); int[] pixels = new int[width * height]; byte[] bytePixels = this.pixels = new byte[width * height]; PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); if (!pixelGrabber.grabPixels()) throw fail("Could not grab pixels"); int n = width * height; for (int i = 0; i < n; i++) { int packed = pixels[i]; int r = ((packed >> 16) & 0xFF); int g = ((packed >> 8) & 0xFF); int b = (packed & 0xFF); bytePixels[i] = (byte) ((r + g + b + 1) / 3); } } catch (Exception __e) { throw rethrow(__e); } } static public byte pixelToByte(int packed) { float r = ((packed >> 16) & 0xFF) / 255f; float g = ((packed >> 8) & 0xFF) / 255f; float b = (packed & 0xFF) / 255f; return (byte) ((r + g + b) / 3.0f * 255f); } public byte getByte(int x, int y) { return inRange(x, y) ? getByte_noRangeCheck(x, y) : _toByte(borderColor); } public int getInt(int x, int y) { return ubyteToInt(getByte(x, y)); } public int getInt_noRangeCheck(int idx) { return ubyteToInt(pixels[idx]); } public int getInt(int x, int y, int defaultValue) { return inRange(x, y) ? getInt(x, y) : defaultValue; } public double averageBrightness() { double sum = 0; int n = width * height; for (int i = 0; i < n; i++) sum += getInt_noRangeCheck(i); return sum / n; } public float minimumBrightness() { float min = 1; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) min = Math.min(min, getPixel(x, y)); return min; } public float maximumBrightness() { float max = 0; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) max = Math.max(max, getPixel(x, y)); return max; } public float getPixel(int x, int y) { return inRange(x, y) ? _toFloat(getByte(x, y)) : borderColor; } public float getFloatPixel(int x, int y) { return getPixel(x, y); } public float getPixel(Pt p) { return getPixel(p.x, p.y); } static public byte _toByte(float pixel) { return (byte) (pixel * 255f); } static public float _toFloat(byte pixel) { return (((int) pixel) & 255) / 255f; } private boolean inRange(int x, int y) { return x >= 0 && x < width && y >= 0 && y < height; } public int getWidth() { return width; } public int getHeight() { return height; } public RGBImage toRGB() { int[] rgbs = new int[width * height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { int b = getByte(x, y) & 0xFF; rgbs[y * width + x] = 0xFF000000 | b * 0x010101; } return new RGBImage(width, height, rgbs); } public RGBImage toRGB_slow() { RGB[] rgbs = new RGB[width * height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { float p = getPixel(x, y); rgbs[y * width + x] = new RGB(p, p, p); } return new RGBImage(width, height, rgbs); } public BWImage clip(int x, int y, int w, int h) { return clip(new Rectangle(x, y, w, h)); } private Rectangle fixClipRect(Rectangle r) { return r.intersection(new Rectangle(0, 0, width, height)); } public BWImage clip(Rect r) { return clip(r.getRectangle()); } public BWImage clip(Rectangle r) { r = fixClipRect(r); byte[] newPixels = new byte[r.height * r.width]; for (int y = 0; y < r.height; y++) for (int x = 0; x < r.width; x++) newPixels[y * r.width + x] = getByte(r.x + x, r.y + y); return new BWImage(r.width, r.height, newPixels); } public void setPixel(int x, int y, float brightness) { setByte(x, y, _toByte(fixPixel(brightness))); } public void setInt(int x, int y, int i) { setByte(x, y, (byte) limitToUByte(i)); } public void setInt(Pt p, int i) { setInt(p.x, p.y, i); } public void setByte(int x, int y, byte b) { if (x >= 0 && x < width && y >= 0 && y < height) pixels[y * width + x] = b; } public byte getByte_noRangeCheck(int x, int y) { return pixels[y * width + x]; } public void setByte(int x, int y, int brightness) { setByte(x, y, (byte) brightness); } private float fixPixel(float pixel) { return Math.max(0, Math.min(1, pixel)); } public float getBorderColor() { return borderColor; } public void setBorderColor(float borderColor) { this.borderColor = borderColor; } public boolean anyPixelBrighterThan(double threshold) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) if (getPixel(x, y) > threshold) return true; return false; } public int[] getRGBPixels() { int n = width * height; int[] out = new int[n]; for (int i = 0; i < n; i++) { var b = ubyteToInt(pixels[i]); b |= (b << 8) | (b << 16); out[i] = b | 0xFF000000; } return out; } public BufferedImage getBufferedImage() { return bufferedImage(getRGBPixels(), width, height); } public byte[] getBytes() { return pixels; } } public interface INumberOfPixels { public int numberOfPixels(); } static public class OnePathWithOrigin extends OnePath { final public OnePathWithOrigin setOrigin(Pt origin) { return origin(origin); } public OnePathWithOrigin origin(Pt origin) { this.origin = origin; return this; } final public Pt getOrigin() { return origin(); } public Pt origin() { return origin; } public Pt origin = pt(0, 0); public OnePathWithOrigin() { } public OnePathWithOrigin(String path) { super(path); } public OnePathWithOrigin(Pt origin, String path) { super(path); this.origin = origin; } public OnePathWithOrigin(int originX, int originY, String path) { super(path); origin = pt(originX, originY); } public OnePathWithOrigin(Iterable points, boolean close) { var l = asList(points); origin = first(l); fromPoints(l, close); } public OnePathWithOrigin(OnePathWithOrigin path) { super(path); origin = path.origin; } public String toString() { return "Origin (" + origin + "), path: " + super.toString(); } public OnePathWithOrigin reversed() { return new OnePathWithOrigin(reversedList(pointList()), false); } } public interface IMultiMap { public Set keySet(); public Collection get(A a); public int size(); public int keyCount(); } 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; } } 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; } final public int x() { return x; } final public int y() { return y; } public WidthAndHeight widthAndHeight() { return main.widthAndHeight(w, h); } } 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 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 public interface ISetter { public void set(A a); } static public interface IRef extends IF0 { public default void replaceValue(A oldValue, A newValue) { } } 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 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 = 3; 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; transient public Set onDone; public G22AutoStarter onDone(Runnable r) { onDone = createOrAddToSyncLinkedHashSet(onDone, r); return this; } public G22AutoStarter removeDoneListener(Runnable r) { main.remove(onDone, r); return this; } public void fireDone() { if (onDone != null) for (var listener : onDone) pcallF_typed(listener); } 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(); } fireDone(); change(); close(); } finally { _close(__1); } } public boolean done() { return nScriptsRun >= l(scripts); } public boolean waitedAndDone() { return waited.get() && done(); } 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; } public boolean cancelled() { return !enabled; } } 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); } } public synchronized boolean getAndSet(boolean b) { var value = a; set(b); return value; } public synchronized boolean waitUntilTrueAndClear() { if (!waitUntilTrue()) return false; set(false); return true; } public Object mutex() { return this; } } 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 interface IPixelSet extends HasBounds { public boolean contains(int x, int y); default public boolean contains(Pt p) { return contains(p.x, p.y); } default public IterableIterator pixelIterator() { return filterI(main.pixelIterator(bounds()), p -> contains(p)); } } static public interface IVF3 { public void get(A a, B b, C c); } 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 interface IVar extends IF0 { public void set(A a); public A get(); default public Class getType() { return null; } default public IF0 getter() { return () -> get(); } default public IVF1 setter() { return __1 -> set(__1); } default public boolean has() { return get() != null; } default public void clear() { set(null); } } 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); default public IG22LoadedDB openDB(String dbName) { return openDB(dbName, false); } public IG22LoadedDB openDB(String dbName, 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); default public Collection openProjects() { return getLoadedDBs(); } public Collection getLoadedDBs(); public G22MasterStuff onLoadedDBsChange(Runnable r); public G22MasterStuff removeLoadedDBsChangeListener(Runnable r); public IF1 makeClassFinder(); public IF0WithChangeListeners lvGazelleUserCount(); public ILASClassLoader lasClassLoader(); public boolean devMode(); default public boolean isConceptDirLoaded(File dir) { return getLoadedDBForConceptDir(dir) != null; } } 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 G22VariablesPanel implements Swingable, IFieldsToList { public G22VariablesPanel() { } public String toString() { return shortClassName_dropNumberPrefix(this); } public Object[] _fieldsToList() { return null; } final public G22VariablesPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22VariablesPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; final public G22VariablesPanel setCompactView(boolean compactView) { return compactView(compactView); } public G22VariablesPanel compactView(boolean compactView) { this.compactView = compactView; return this; } final public boolean getCompactView() { return compactView(); } public boolean compactView() { return compactView; } public boolean compactView = false; final public G22VariablesPanel setUpdateInterval(double updateInterval) { return updateInterval(updateInterval); } public G22VariablesPanel updateInterval(double updateInterval) { this.updateInterval = updateInterval; return this; } final public double getUpdateInterval() { return updateInterval(); } public double updateInterval() { return updateInterval; } public double updateInterval = 1.0; transient public SimpleCRUD_v2 crud; transient public SingleComponentPanel scpDetail; transient public ReliableSingleThread rstUpdateDetail = rst(() -> _updateDetail()); public SimpleCRUD_v2 crud() { if (crud == null) { crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22Variable.class); crud.updateInterval(updateInterval); } return crud; } 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() { crud().iconButtons(true); crud.entityName = () -> "Variable"; crud.renderValue = __1 -> strOrNull(__1); var vis = jCenteredSection("Project Variables", crud.visualize()); if (compactView) return vis; crud.onSingleSelectionChanged(() -> { print("Selection: " + crud.selected()); rstUpdateDetail.get(); }); scpDetail = scp(); return jvsplit(vis, scpDetail); } public void updateCount() { crud().update(); } public void setSelected(G22Variable var) { crud().setSelected(var); } public void _updateDetail() { var var = crud.selected(); if (var == null) { scpDetail.clear(); return; } Object value = var.value(); var vis = new G22JavaObjectVisualizer(g22utils, value).visualize(); bindChangeListenerToComponent(vis, var.varValue(), () -> { if (!eq(var.value(), value)) rstUpdateDetail.get(); }); scpDetail.set(jCenteredSection("Variable " + var.name, vis)); } } 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)); } private 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 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 abstract public class LiveValue implements IF0WithChangeListeners { abstract public Class getType(); public abstract A get(); } public interface ILASClassLoader { public Class defineLASClass(String name, IF0 generateClass); public Object rememberClassBytes(boolean rememberClassBytes); } static public class GazelleV_LeftArrowScriptParser extends SimpleLeftToRightParser { final public GazelleV_LeftArrowScriptParser setMagicSwitch(boolean magicSwitch) { return magicSwitch(magicSwitch); } public GazelleV_LeftArrowScriptParser magicSwitch(boolean magicSwitch) { this.magicSwitch = magicSwitch; return this; } final public boolean getMagicSwitch() { return magicSwitch(); } public boolean magicSwitch() { return magicSwitch; } public boolean magicSwitch = true; 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 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 __15 = (EvaluableWrapper) o; return eq(expr, __15.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("will") && is(1, "return")) { consume(2); GazelleV_LeftArrowScript.Evaluable exp = parseAssignmentOrExpr(); GazelleV_LeftArrowScript.Evaluable body = parseScript(new BuildingScript()); return new GazelleV_LeftArrowScript.WillReturn(exp, 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("{", ",", "then")) 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.CallOnTarget parseThenCall(GazelleV_LeftArrowScript.CallOnTarget expr) { consume("then"); GazelleV_LeftArrowScript.CallOnTarget secondCall = (GazelleV_LeftArrowScript.CallOnTarget) (parseCall(null)); return new GazelleV_LeftArrowScript.Then(expr, secondCall); } 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, "(")) { consume(); GazelleV_LeftArrowScript.Evaluable e = parseExpr_inParens(); consume(")"); 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 parseExpr_inParens() { boolean inParensOld = inParens; inParens = true; try { return parseExpr(); } finally { inParens = inParensOld; } } 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 parseNewExpr() { 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); } 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")) return parseNewExpr(); if (eq(t, "list") && is("{")) { GazelleV_LeftArrowScript.Script block = parseReturnableCurlyBlock(); GazelleV_LeftArrowScript.Evaluable e = new GazelleV_LeftArrowScript.ListFromScript(block); return inner ? e : parseCall(e); } 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) { if (!isInterface(c)) return null; var ptr = ptr(); var parameterized = parseTypeArgumentsOpt(c); if (is("{")) return finishLambdaDef(c, null); if (consumeOpt("_")) { String methodName = consumeIdentifier(); return new GazelleV_LeftArrowScript.LambdaMethodOnArgument(c, methodName, parseArguments()); } int nArgs = 0; while (isIdentifier(token(nArgs))) nArgs++; if (!(is(nArgs, "-") && is(nArgs + 1, ">"))) { ptr(ptr); return null; } String[] argNames = consumeArray(nArgs); skip(2); return finishLambdaDef(c, argNames); } public GazelleV_LeftArrowScript.Evaluable finishLambdaDef(Class c, String[] argNames) { AutoCloseable __8 = tempAddKnownVars(argNames); try { GazelleV_LeftArrowScript.Evaluable body; if (is("{")) body = parseReturnableCurlyBlock(); else body = parseExpr(); var lambda = new GazelleV_LeftArrowScript.LambdaDef(c, argNames, body); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("finishLambdaDef 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) { var start = ptr(); if (isIdentifier()) { 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(); return finalizeCall(start, target, name, args); } if (consumeOpt("~")) { if (isIdentifier()) { String key = consumeIdentifier(); return parseCall(finalizeCall(start, target, "getOpt", _const(key))); } else { int idx = consumeInteger(); return parseCall(finalizeCall(start, target, "listGet", _const(idx))); } } return target; } public GazelleV_LeftArrowScript.Evaluable finalizeCall(ListAndIndex start, GazelleV_LeftArrowScript.Evaluable target, String name, GazelleV_LeftArrowScript.Evaluable... args) { return finalizeCall2(finalizeCall1(start, target, name, args)); } public GazelleV_LeftArrowScript.Evaluable finalizeCall2(GazelleV_LeftArrowScript.CallOnTarget call) { while (is("then")) call = parseThenCall(call); return call; } public GazelleV_LeftArrowScript.CallOnTarget finalizeCall1(ListAndIndex start, GazelleV_LeftArrowScript.Evaluable target, String name, GazelleV_LeftArrowScript.Evaluable... args) { if (magicSwitch) { Object ext = findExternalObject(name); if (ext instanceof MethodOnObject) { if (nempty(args)) return new GazelleV_LeftArrowScript.CallMethodOrGlobalFunction(target, name, ((MethodOnObject) ext), args); else return new GazelleV_LeftArrowScript.CallMethodOrGetFieldOrGlobalFunction(target, name, ((MethodOnObject) ext)); } } 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 fd = new GazelleV_LeftArrowScript.FunctionDef(functionName, keysList(args), null); { if (functionDefsToAddTo != null) functionDefsToAddTo.put(functionName, fd); } 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"); fd.body = parseReturnableCurlyBlock(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Defined function " + functionName + ", added to " + functionDefsToAddTo); fd.scope(scope); if (returnType != null) fd.returnType(returnType); 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_inParens(); 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 new ClassNotFound(typeName); return parseArrayType(parseTypeArguments((Type) type)); } public Type parseArrayType(Type type) { while (is("[") && is(1, "]")) { consume(2); type = new GenericArrayTypeImpl(type); } return type; } final public Type parseTypeArgumentsOpt(Type type) { return parseTypeArguments(type); } public Type parseTypeArguments(Type type) { if (is("<") && empty(nextSpace()) && 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())); } } 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 String toString_base() { return super.toString(); } public String toString() { Object o = metaGet("toString", this); if (o instanceof String) return ((String) o); if (o instanceof IF1) return str(((IF1) o).get(this)); return toString_base(); } 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 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 void discardEdit() { String text = editedText(); if (text == null) return; saveFieldToHistory("discardingEdit", text); editingText(null); } 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 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) { Pt p = getPt(e); String s = str(p); var img = is.getImage(); if (img != null && p.x >= 0 && p.y >= 0 && p.x < img.getWidth() && p.y < img.getHeight()) s += " - " + intToHex_fullLength(img.getRGB(p.x, p.y)); setToolTip(is, s); } } public interface TransientObject { } 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(); } final public A mostPopular() { return getMostPopularEntry(); } 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); } } public interface G2Drawable { public void drawOn(Graphics2D g); default public void drawOn(BufferedImage img) { drawOn(img.createGraphics()); } } 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; } } static public class G22Variable extends ConceptWithChangeListeners implements IPersistenceInfo, AutoCloseable { static final public String _fieldOrder = "name value persistent autoClose big"; 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 G22Variable setName(String name) { return name(name); } public G22Variable 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; volatile public Object value; public transient FieldVar varPersistent_cache; public FieldVar varPersistent() { if (varPersistent_cache == null) varPersistent_cache = varPersistent_load(); return varPersistent_cache; } public FieldVar varPersistent_load() { return new FieldVar(this, "persistent", () -> persistent(), persistent -> persistent(persistent)); } final public G22Variable setPersistent(boolean persistent) { return persistent(persistent); } public G22Variable persistent(boolean persistent) { if (!eq(this.persistent, persistent)) { this.persistent = persistent; change(); } return this; } final public boolean getPersistent() { return persistent(); } public boolean persistent() { return persistent; } public boolean persistent = false; final public G22Variable setAutoClose(boolean autoClose) { return autoClose(autoClose); } public G22Variable autoClose(boolean autoClose) { this.autoClose = autoClose; return this; } final public boolean getAutoClose() { return autoClose(); } public boolean autoClose() { return autoClose; } public boolean autoClose = false; public transient FieldVar varBig_cache; public FieldVar varBig() { if (varBig_cache == null) varBig_cache = varBig_load(); return varBig_cache; } public FieldVar varBig_load() { return new FieldVar(this, "big", () -> big(), big -> big(big)); } final public G22Variable setBig(boolean big) { return big(big); } public G22Variable big(boolean big) { if (!eq(this.big, big)) { this.big = big; change(); } return this; } final public boolean getBig() { return big(); } public boolean big() { return big; } public boolean big = false; public Map _persistenceInfo() { return litmap("value", persistent && !big); } 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)); } public void setValueIfNull(Object defaultValue) { if (defaultValue != null && value == null) value(defaultValue); } public Object cachedValue() { return value; } final public Object value() { return get(); } public Object get() { if (value != null) return value; if (big) return getBigValue(); return value; } public G22Utils g22utils() { return main.g22utils(_concepts()); } public File bigFile() { return newFile(assertNotNull(g22utils().projectDir()), id + "-" + sanitizeFileName(name) + ".structgz"); } public Object getBigValue() { File f = bigFile(); return setValueField(unstructureGZFile(f, g22utils().classFinder())); } public void setBigValue(Object value) { if (value == null) { if (hasBigValue()) { deleteBigValue(); change(); } } else { File f = bigFile(); saveGZStructureToFile(f, value); change(); } } public void deleteBigValue() { deleteFile(bigFile()); } public boolean hasBigValue() { return fileExists(bigFile()); } public void makeBig() { if (big) return; setBigValue(value); big(true); persistent(true); } public void makeSmall() { if (!big) return; get(); big(false); deleteBigValue(); } final public G22Variable setValue(Object o) { return value(o); } public G22Variable value(Object o) { if (big) setBigValue(o); else if (!eq(value, o)) { setValueField(o); change(); } return this; } final public boolean has() { return notNull(); } public boolean notNull() { return big ? hasBigValue() : value != null; } public void unload() { if (big) setValueField(null); } public Object setValueField(Object o) { if (autoClose && o != value) { cleanUp(value); value = null; } return value = o; } public void close() { try { if (autoClose) { cleanUp(value); value = null; } } catch (Exception __e) { throw rethrow(__e); } } public void delete() { close(); super.delete(); } public void changeInsideOfValue() { if (big) value(value); change(); } } 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 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; final public ConceptsComboBox setItemFilter(IF1 itemFilter) { return itemFilter(itemFilter); } public ConceptsComboBox itemFilter(IF1 itemFilter) { this.itemFilter = itemFilter; return this; } final public IF1 getItemFilter() { return itemFilter(); } public IF1 itemFilter() { return itemFilter; } public IF1 itemFilter; 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(filterTheList(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); } public List filterTheList(Collection l) { return itemFilter == null ? asList(l) : filter(itemFilter, l); } 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 interface IConceptCounter { public Class conceptClass(); public int countConcepts(); public Collection allConcepts(); } static public interface IAutoCloseableF0 extends IF0, AutoCloseable { } public interface IG22LoadedDB { public boolean hidden(); public Concepts concepts(); public JFrame mainWindow(); public G22Utils g22utils(); public void activate(); } 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(); object = arrayToList(object); 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 (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))); } public Object arrayToList(Object object) { if (isArray(object)) object = wrapArrayAsImmutableList(object); return object; } } public G22JavaObjectVisualizer withType(boolean b) { return withTypeAndTime(b); } } 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 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); } private 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)); } private static 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); } private 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 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(); } default public int width() { return getWidth(); } public int getWidth(); default public int h() { return getHeight(); } default public int height() { 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()); } } static public interface IBinaryImage extends MakesBufferedImage { public boolean getBoolPixel(int x, int y); default public void setPixel(int x, int y, boolean b) { throw unimplemented(); } default public boolean getBoolPixel(Pt p) { return getBoolPixel(p.x, p.y); } public default BufferedImage getBufferedImage() { return toImage2B().getBufferedImage(); } default public Image2B toImage2B() { return this instanceof Image2B ? (Image2B) this : iBinaryImageToImage2B(this); } } public interface IBackgroundProcess extends AutoCloseable { public IBackgroundProcess setInterruptAction(Runnable action); } 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 interface IMultiSet { public int add(A key); public int get(A key); } 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)); } } 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(jMinWidth0(mainComponent)); scp.set(splitPane()); } else { splitPane().setRightComponent(jMinWidth0(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_minZero(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 SimpleCRUD_v2 extends JConceptsTable { public JPanel buttons, panel; public Set unshownFields; public Set excludeFieldsFromEditing; public String modifiedField; public TableSearcher tableSearcher; public Set multiLineFields; public Set dontDuplicateFields; public int formFixer = 12; public boolean showBackRefs = false; public int maxRefsToShow = 3; public boolean showClassNameSelectors = false; public boolean allowNewFields = false; public int newFieldsToShow = 3; public boolean emptyStringsToNull = false; public int formLabelsWidth = 100; final public SimpleCRUD_v2 setShowSearchBar(boolean showSearchBar) { return showSearchBar(showSearchBar); } public SimpleCRUD_v2 showSearchBar(boolean showSearchBar) { this.showSearchBar = showSearchBar; return this; } final public boolean getShowSearchBar() { return showSearchBar(); } public boolean showSearchBar() { return showSearchBar; } public boolean showSearchBar = true; final public SimpleCRUD_v2 setShowAddButton(boolean showAddButton) { return showAddButton(showAddButton); } public SimpleCRUD_v2 showAddButton(boolean showAddButton) { this.showAddButton = showAddButton; return this; } final public boolean getShowAddButton() { return showAddButton(); } public boolean showAddButton() { return showAddButton; } public boolean showAddButton = true; final public SimpleCRUD_v2 setShowEditButton(boolean showEditButton) { return showEditButton(showEditButton); } public SimpleCRUD_v2 showEditButton(boolean showEditButton) { this.showEditButton = showEditButton; return this; } final public boolean getShowEditButton() { return showEditButton(); } public boolean showEditButton() { return showEditButton; } public boolean showEditButton = true; final public SimpleCRUD_v2 setShowDuplicateButton(boolean showDuplicateButton) { return showDuplicateButton(showDuplicateButton); } public SimpleCRUD_v2 showDuplicateButton(boolean showDuplicateButton) { this.showDuplicateButton = showDuplicateButton; return this; } final public boolean getShowDuplicateButton() { return showDuplicateButton(); } public boolean showDuplicateButton() { return showDuplicateButton; } public boolean showDuplicateButton = true; final public SimpleCRUD_v2 setIconButtons(boolean iconButtons) { return iconButtons(iconButtons); } public SimpleCRUD_v2 iconButtons(boolean iconButtons) { this.iconButtons = iconButtons; return this; } final public boolean getIconButtons() { return iconButtons(); } public boolean iconButtons() { return iconButtons; } public boolean iconButtons = false; public SingleComponentPanel scpButtonFiller; public SimpleCRUD_v2(Class conceptClass) { super(conceptClass); } public SimpleCRUD_v2(Concepts concepts, Class conceptClass) { super(concepts, conceptClass); } public SimpleCRUD_v2 show(String frameTitle) { make(); showFrame(frameTitle, panel); return this; } public SimpleCRUD_v2 show() { return show(entityNamePlural()); } public SimpleCRUD_v2 showMaximized() { show(); maximizeFrame(panel); return this; } public JPanel makePanel() { return make(); } public JPanel make() { db(); framesBot(); return make_dontStartBots(); } transient public IF1> itemToMap_inner; public Map itemToMap_inner(A a) { return itemToMap_inner != null ? itemToMap_inner.get(a) : itemToMap_inner_base(a); } final public Map itemToMap_inner_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : itemToMap_inner_base(a); } public Map itemToMap_inner_base(A a) { return super.itemToMap_base(a); } public Map itemToMap_base(A a) { Map map = itemToMap_inner(a); if (map == null) return null; return putAll(map, moreSpecialFieldsForItem(a)); } transient public IF1> moreSpecialFieldsForItem; public Map moreSpecialFieldsForItem(A a) { return moreSpecialFieldsForItem != null ? moreSpecialFieldsForItem.get(a) : moreSpecialFieldsForItem_base(a); } final public Map moreSpecialFieldsForItem_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : moreSpecialFieldsForItem_base(a); } public Map moreSpecialFieldsForItem_base(A a) { Map map = litorderedmap(); if (showBackRefs) { Collection refs = allBackRefs(a); if (nempty(refs)) { refs = sortedByConceptID(refs); int more = l(refs) - maxRefsToShow; map.put("Referenced by", joinWithComma(takeFirst(maxRefsToShow, refs)) + (more > 0 ? ", " + more + " more" : "")); } } return map; } public JPanel make_dontStartBots() { return (JPanel) visualize(); } 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() { dropFields = asList(unshownFields); makeTable(); { swing(() -> { buttons = jRightAlignedLine(flattenToList(!showAddButton ? null : makeAddButton(new Runnable() { public void run() { try { newConcept(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newConcept();"; } }), !showEditButton || !showDuplicateButton ? null : tableDependButton(table, makeDuplicateButton(new Runnable() { public void run() { try { duplicateConcept(selectedConcept()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "duplicateConcept(selectedConcept())"; } })), !showEditButton ? null : tableDependButton(table, makeEditButton(new Runnable() { public void run() { try { editConcept(selectedConcept()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "editConcept(selectedConcept())"; } })), tableDependButton(table, makeDeleteButton(new Runnable() { public void run() { try { List l = selectedConcepts(); withDBLock(concepts, new Runnable() { public void run() { try { for (A c : l) c.delete(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "for (A c : l) c.delete()"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "List l = selectedConcepts();\r\n withDBLock(concepts, r { for (A c ..."; } })))); var buttonBar = centerAndEastWithMargin(scpButtonFiller = singleComponentPanel(), buttons); if (showSearchBar) { tableSearcher = tableWithSearcher2(table, "withMargin", true); panel = centerAndSouthWithMargin(tableSearcher.panel, buttonBar); } else panel = centerAndSouthWithMargin(table, buttonBar); var fEdit = new VF1() { public void get(Integer row) { try { editConcept(getItem(row)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "editConcept(getItem(row))"; } }; tablePopupMenuItem(table, "Edit", fEdit); onDoubleClick(table, fEdit); tablePopupMenuFirst(table, (menu, row) -> { Concept c = getItem(row); if (c != null) addMenuItem(menu, "Delete " + quote(shorten(str(c))), runnableThread(new Runnable() { public void run() { try { deleteConcept(c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "deleteConcept(c);"; } })); }); }); } return panel; } transient public Runnable newConcept; public void newConcept() { if (newConcept != null) newConcept.run(); else newConcept_base(); } final public void newConcept_fallback(Runnable _f) { if (_f != null) _f.run(); else newConcept_base(); } public void newConcept_base() { duplicateConcept(null); } transient public IF1 createDuplicate; public A createDuplicate(A c) { return createDuplicate != null ? createDuplicate.get(c) : createDuplicate_base(c); } final public A createDuplicate_fallback(IF1 _f, A c) { return _f != null ? _f.get(c) : createDuplicate_base(c); } public A createDuplicate_base(A c) { A clone = (A) unlisted(_getClass(c)); ccopyFieldsExcept(c, clone, dontDuplicateFields); return clone; } public void duplicateConcept(A oldConcept) { EditWindow ew = new EditWindow(); if (oldConcept == null) ew.item = unlisted(conceptClass); else ew.item = createDuplicate(oldConcept); csetAll(ew.item, filters); makeComponents(ew); F0 r = new F0() { public Boolean get() { try { try { selectAfterUpdate(ew.item); concepts.register(ew.item); saveData(ew); } catch (Throwable e) { printStackTrace(e); infoBox(e); return false; } return true; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n selectAfterUpdate(ew.item);\r\n concepts.register(ew.item..."; } }; AutoCloseable __2 = tempSetMCOpt("formLayouter1_fixer2", formFixer); try { renameSubmitButton("Create", showAForm("New " + entityName(), toObjectArray(listPlus(ew.matrix, r)))); } finally { _close(__2); } } public void editConcept(A c) { if (c == null) return; EditWindow ew = new EditWindow(); ew.item = c; makeComponents(ew); F0 r = new F0() { public Boolean get() { try { try { if (ew.item != c) { print("Replacing object: " + c + " => " + ew.item); replaceConceptAndUpdateRefs(c, ew.item); } saveData(ew); } catch (Throwable e) { printStackTrace(e); infoBox(e); return false; } return true; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try {\r\n // concept class was changed, replace object\r\n if (ew.i..."; } }; AutoCloseable __3 = tempSetMCOpt("formLayouter1_fixer2", formFixer); try { renameSubmitButton("Save", showAForm("Edit " + entityName() + " #" + c.id, toObjectArray(listPlus(ew.matrix, r)))); } finally { _close(__3); } } public JComponent fieldComponent(A c, String field) { Class type = getFieldType(conceptClass, field); Type genericType = genericFieldType(conceptClass, field); if (type == Concept.Ref.class) type = getTypeArgumentAsClass(genericType); Object value = cget(c, field); if (type == null) type = _getClass(value); print("Field type: " + field + " => " + type); if (type == boolean.class) return jCenteredCheckBox(isTrue(value)); else if (contains(multiLineFields, field) || containsNewLines(optCast(String.class, value))) return makeTextArea((String) value); else if (isSubtype(type, Concept.class)) return jcomboboxFromConcepts_str(concepts, type, (Concept) value); else if (isUneditableFieldType(type)) return jlabel(structureOrText_crud(value)); else try { return autoComboBox(structureOrText_crud(value), new TreeSet(map(__63 -> structureOrText_crud(__63), collect(list(concepts, conceptClass), field)))); } catch (Throwable e) { printException(e); return jTextField(structureOrText_crud(value)); } } public void saveComponent(A c, String field, JComponent comp) { comp = unwrap(comp); Class type = fieldType(c, field); Type genericType = genericFieldType(conceptClass, field); if (type == Concept.Ref.class) type = getTypeArgumentAsClass(genericType); if (comp instanceof JTextComponent) { String text = trimIf(!(comp instanceof JTextArea), getText((JTextComponent) comp)); Object value = postProcessValue(text); Object converted = convertToField(value, conceptClass, field); cset(c, field, converted); } else if (comp instanceof JComboBox) { String text = getTextTrim((JComboBox) comp); if (isSubtype(type, Concept.class)) cset(c, field, getConcept(concepts, parseFirstLong(text))); else { Object value = postProcessValue(text); cset(c, field, convertToField(value, conceptClass, field)); } } else if (comp instanceof JCheckBox) cset(c, field, isChecked((JCheckBox) comp)); } transient public IF1> editableFieldsForItem; public Collection editableFieldsForItem(A c) { return editableFieldsForItem != null ? editableFieldsForItem.get(c) : editableFieldsForItem_base(c); } final public Collection editableFieldsForItem_fallback(IF1> _f, A c) { return _f != null ? _f.get(c) : editableFieldsForItem_base(c); } public Collection editableFieldsForItem_base(A c) { if (excludeFieldsFromEditing != null && modifiedField != null) excludeFieldsFromEditing.add(modifiedField); return listWithoutSet(conceptFieldsInOrder(c), joinSets(excludeFieldsFromEditing, unshownFields, keys(filters))); } public void excludeFieldsFromEditing(String... fields) { excludeFieldsFromEditing = setPlus(excludeFieldsFromEditing, fields); } public Collection> possibleClasses() { return (Collection) moveItemFirst(conceptClass, dropTypeParameter(sortClassesByNameIC(myNonAbstractClassesImplementing(conceptClass)))); } public JComboBox> classSelectorComponent(A c) { return setComboBoxRenderer(jTypedComboBox(possibleClasses(), _getClass(c)), customToStringListCellRenderer(__64 -> shortClassName(__64))); } public class NewField { public JTextField tfName = jtextfield(); public JTextField tfValue = jtextfield(); public JComboBox cbRef = jcomboboxFromConcepts_str(concepts, conceptClass); public JComboBox cbType = jcombobox("String", "Reference"); public SingleComponentPanel scpValue = singleComponentPanel(); public JPanel panel() { onChangeAndNow(cbType, new Runnable() { public void run() { try { updateSCP(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateSCP();"; } }); return jhgridWithSpacing(withToolTip("Name for new field", withLabel("Name", tfName)), withLabel("Value", westAndCenterWithMargin(cbType, scpValue))); } public String typeStr() { return getText(cbType); } public void updateSCP() { scpValue.setComponent(eqic(typeStr(), "Reference") ? cbRef : withToolTip("Contents of new field", tfValue)); } public String field() { return gtt(tfName); } public Object value() { return eqic(typeStr(), "Reference") ? getConcept(concepts, parseFirstLong(getText(cbRef))) : gtt(tfValue); } } public class EditWindow { public A item; public Map componentsByField = litorderedmap(); public List matrix = new ArrayList(); public JComboBox> classSelector; public List newFields = new ArrayList(); } public void makeComponents(EditWindow ew) { if (showClassNameSelectors) { addAll(ew.matrix, makeLabel("Java Class"), ew.classSelector = classSelectorComponent(ew.item)); onChange(ew.classSelector, new Runnable() { public void run() { try { Class oldClass = _getClass(ew.item); Class newClass = getSelectedItem_typed(ew.classSelector); if (oldClass == newClass) return; A oldItem = ew.item; ew.item = unlisted(newClass); ccopyFields(oldItem, ew.item); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Class oldClass = _getClass(ew.item);\r\n Class..."; } }); } for (String field : editableFieldsForItem(ew.item)) { JComponent c = fieldComponent(ew.item, field); ew.componentsByField.put(field, c); addAll(ew.matrix, makeLabel(field), c); } if (allowNewFields && newFieldsToShow > 0) { addAll(ew.matrix, " ", jlabel()); for (int i = 0; i < newFieldsToShow; i++) { NewField nf = new NewField(); ew.newFields.add(nf); addAll(ew.matrix, makeLabel(""), nf.panel()); } } } public void saveData(EditWindow ew) { for (Map.Entry __0 : _entrySet(ew.componentsByField)) { String field = __0.getKey(); JComponent component = __0.getValue(); if (isIdentifier(field)) saveComponent(ew.item, field, component); } for (NewField nf : ew.newFields) { String field = nf.field(); Object value = nf.value(); if (nempty(field) && notNullOrEmptyString(value)) cset(ew.item, field, value); } if (modifiedField != null) cset(ew.item, modifiedField, now()); } public Object postProcessValue(Object o) { if (emptyStringsToNull && eq(o, "")) return null; return o; } public JComponent makeLabel(String label) { return jMinWidthAtLeast(formLabelsWidth, jlabel(label)); } transient public IF2 showAForm; public JComponent showAForm(String title, Object... parts) { return showAForm != null ? showAForm.get(title, parts) : showAForm_base(title, parts); } final public JComponent showAForm_fallback(IF2 _f, String title, Object... parts) { return _f != null ? _f.get(title, parts) : showAForm_base(title, parts); } public JComponent showAForm_base(String title, Object... parts) { return showFormTitled3(title, parts).visualize(); } public boolean isUneditableFieldType(Class type) { return isSubclassOfAny(type, Map.class, Collection.class, Pair.class); } public void hideField(String field) { hideFields(field); } public void hideFields(String... fields) { unshownFields = createOrAddToSet(unshownFields, fields); } transient public IF0 entityName; public String entityName() { return entityName != null ? entityName.get() : entityName_base(); } final public String entityName_fallback(IF0 _f) { return _f != null ? _f.get() : entityName_base(); } public String entityName_base() { return shortClassName(conceptClass); } transient public IF0 entityNamePlural; public String entityNamePlural() { return entityNamePlural != null ? entityNamePlural.get() : entityNamePlural_base(); } final public String entityNamePlural_fallback(IF0 _f) { return _f != null ? _f.get() : entityNamePlural_base(); } public String entityNamePlural_base() { return plural(entityName()); } transient public IF0 entityNameLower; public String entityNameLower() { return entityNameLower != null ? entityNameLower.get() : entityNameLower_base(); } final public String entityNameLower_fallback(IF0 _f) { return _f != null ? _f.get() : entityNameLower_base(); } public String entityNameLower_base() { return firstToLower(entityName()); } transient public IF0 entityNamePluralLower; public String entityNamePluralLower() { return entityNamePluralLower != null ? entityNamePluralLower.get() : entityNamePluralLower_base(); } final public String entityNamePluralLower_fallback(IF0 _f) { return _f != null ? _f.get() : entityNamePluralLower_base(); } public String entityNamePluralLower_base() { return firstToLower(entityNamePlural()); } public void addButton(String text, Runnable r) { addButton(jbutton(text, r)); } public void addButton(JComponent c) { visualize(); buttons.add(c); } public JButton makeAddButton(Runnable r) { return makeButton("Add...", "Create a new " + entityNameLower(), "#1103069", r); } public JButton makeDeleteButton(Runnable r) { return makeButton("Delete", "Delete selected " + entityNamePluralLower(), "#1103067", r); } public JButton makeEditButton(Runnable r) { return makeButton("Edit...", "Edit selected " + entityNameLower(), "#1103068", r); } public JButton makeDuplicateButton(Runnable r) { return makeButton("Duplicate...", "Duplicate selected " + entityNameLower(), "#1103070", r); } public JButton makeButton(String text, String iconID, Runnable r) { return makeButton(text, null, iconID, r); } public JButton makeButton(String text, String toolTip, String iconID, Runnable r) { if (iconButtons) return toolTip(or2(toolTip, text), jimageButtonScaledToWidth(16, iconID, text, r)); else return toolTip(toolTip, jbutton(text, r)); } public void multiLineField(String field) { multiLineFields = addOrCreate(multiLineFields, field); } transient public IF1 makeTextArea; public JComponent makeTextArea(String text) { return makeTextArea != null ? makeTextArea.get(text) : makeTextArea_base(text); } final public JComponent makeTextArea_fallback(IF1 _f, String text) { return _f != null ? _f.get(text) : makeTextArea_base(text); } public JComponent makeTextArea_base(String text) { return typeWriterTextArea(text); } public void setButtonFiller(JComponent c) { scpButtonFiller.set(c); } } static public class GenericArrayTypeImpl implements GenericArrayType { final public Type genericComponentType; public GenericArrayTypeImpl(Type ct) { genericComponentType = ct; } public static GenericArrayTypeImpl make(Type ct) { return new GenericArrayTypeImpl(ct); } public Type getGenericComponentType() { return genericComponentType; } public String toString() { return getGenericComponentType().getTypeName() + "[]"; } @Override public boolean equals(Object o) { if (o instanceof GenericArrayType) { GenericArrayType that = (GenericArrayType) o; return Objects.equals(genericComponentType, that.getGenericComponentType()); } else return false; } @Override public int hashCode() { return Objects.hashCode(genericComponentType); } } public interface IStringifier { public String toString(A o); } 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, IntSize { public MinimalChain last; final public int getSize() { return size(); } public int size() { return size; } 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 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 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 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; } } 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 int consumeInteger() { return parseInt(assertInteger(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); } final public void consume(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 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 interface IRGBImage extends MakesBufferedImage { public int getIntPixel(int x, int y); } static public interface IBWImage extends MakesBufferedImage, IRGBImage { public float getFloatPixel(int x, int y); default public int getInt(int x, int y) { return iround(getFloatPixel(x, y) * 255f); } default public int getIntPixel(int x, int y) { return rgbIntFromGrayscale(getInt(x, y)); } default public float getFloatPixel(Pt p) { return getFloatPixel(p.x, p.y); } default public float getFloatPixel(int index) { int w = w(); return getFloatPixel(index % w, index / w); } default public float[] toFloatArray() { float[] data = new float[w() * h()]; for (int i = 0; i < l(data); i++) data[i] = getFloatPixel(i); return data; } public default BufferedImage getBufferedImage() { return grayImageFromIBWImage(this); } default public BWImage toBWImage() { return this instanceof BWImage ? (BWImage) this : iBWImageToBWImage(this); } } 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(__65 -> methodNames(__65), 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 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); } } 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) { r = rgbRed(rgb) / 255f; g = rgbGreen(rgb) / 255f; b = rgbBlue(rgb) / 255f; } public RGB(double brightness) { this.r = this.g = this.b = max(0f, min(1f, (float) brightness)); } public RGB(Color color) { r = color.getRed() / 255f; g = color.getGreen() / 255f; 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; } public RGB cloneMe() { return new RGB(r, g, b); } } static public class Flag implements Runnable { volatile public boolean up = false; public boolean raise() { if (up) return false; synchronized (this) { if (up) return false; up = true; notifyAll(); return true; } } public void run() { try { raise(); } catch (Exception __e) { throw rethrow(__e); } } public void waitUntilUp() { try { if (up) return; synchronized (this) { 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 boolean waitUntilUp(long timeout) { try { if (up) return true; synchronized (this) { if (!up) wait(timeout); } return isUp(); } catch (Exception __e) { throw rethrow(__e); } } final public boolean get() { return isUp(); } public boolean isUp() { return up; } public String toString() { return isUp() ? "up" : "down"; } } 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 __1 = (MethodOnObject) o; return eq(object, __1.object) && eq(method, __1.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 List _stickyLibs_1400546 = ll("#1400546", "#1400547", "#1400548"); 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 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 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 String indented() { return indentedScriptStruct(this); } } 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 ListFromScript extends EvaluableBase implements IFieldsToList { public Script script; public ListFromScript() { } public ListFromScript(Script script) { this.script = script; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + script + ")"; } public Object[] _fieldsToList() { return new Object[] { script }; } public Object get(VarContext ctx) { return script.getAsList(ctx); } } 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 Object getAsList(VarContext ctx) { Object result = null; var pingSource = pingSource(); List list = new ArrayList(); for (var step : steps) { ping(pingSource); list.add(step.get(ctx)); var exiting = ctx.exitFromScript; if (exiting != null) { if (exiting == this) { ctx.exitFromScript = null; result = ctx.returnValue; ctx.returnValue(null); list.add(result); return list; } return null; } } return list; } 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, evalArgs(args, 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, evalArgs(args, 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 = evalArgs(args, 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); } } abstract static public class CallOnTarget extends EvaluableBase implements IFieldsToList { public Evaluable target; public CallOnTarget() { } public CallOnTarget(Evaluable target) { this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ")"; } public Object[] _fieldsToList() { return new Object[] { target }; } final public CallOnTarget setAllowNullReference(boolean allowNullReference) { return allowNullReference(allowNullReference); } public CallOnTarget 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(); } abstract public Object evalOnTarget(VarContext ctx, Object object); public Object get(VarContext ctx) { Object object = target.get(ctx); if (object == null) return handleNullReference(); return evalOnTarget(ctx, object); } } static public class CallMethodOrGetField extends CallOnTarget { public CallMethodOrGetField() { } public String name; public CallMethodOrGetField(Evaluable target, String name) { this.name = name; this.target = target; } public Object evalOnTarget(VarContext ctx, Object object) { try { 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 CallOnTarget { public CallMethod() { } public String methodName; public Evaluable[] args; public CallMethod(Evaluable target, String methodName, Evaluable[] args) { this.args = args; this.methodName = methodName; this.target = target; } public Object evalOnTarget(VarContext ctx, Object object) { return newPreciseCall(object, methodName, evalArgs(args, 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 allowNullReference ? _const(null) : 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 Object[] evalArgs(Evaluable[] args, VarContext ctx) { return mapToArrayOrNull(args, arg -> arg.get(ctx)); } static public class CallMethodOrGlobalFunction extends CallMethod { public CallMethodOrGlobalFunction() { } public MethodOnObject globalFunction; static final public Object methodNotFoundSentinel = new Object(); public CallMethodOrGlobalFunction(Evaluable target, String methodName, MethodOnObject globalFunction, Evaluable[] args) { this.args = args; this.globalFunction = globalFunction; this.methodName = methodName; this.target = target; } public String toString() { return target + "." + formatFunctionCall(methodName + "+", args); } public Object evalOnTarget(VarContext ctx, Object o) { Object[] realArgs = evalArgs(args, ctx); Object result = newPreciseCall_sentinel(o, methodName, methodNotFoundSentinel, realArgs); if (result != methodNotFoundSentinel) return result; return newPreciseCall(globalFunction.object, globalFunction.method, itemPlusArray(o, realArgs)); } } static public class CallMethodOrGetFieldOrGlobalFunction extends CallMethodOrGetField { public CallMethodOrGetFieldOrGlobalFunction() { } public MethodOnObject globalFunction; static final public Object notFoundSentinel = new Object(); public CallMethodOrGetFieldOrGlobalFunction(Evaluable target, String name, MethodOnObject globalFunction) { this.globalFunction = globalFunction; this.name = name; this.target = target; } public String toString() { return target + "." + name + "+"; } public Object evalOnTarget(VarContext ctx, Object o) { Object result = preciseGetOrCallMethod_sentinel(o, name, notFoundSentinel); if (result != notFoundSentinel) return result; return newPreciseCall(globalFunction.object, globalFunction.method, o); } } abstract static public class LambdaBase extends EvaluableBase implements IFieldsToList { public Class intrface; public LambdaBase() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface }; } public Method implementedMethod; public LambdaBase(Class intrface) { this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); } } static public class LambdaMethodOnArgument extends LambdaBase { public String methodName; public Evaluable[] args; public LambdaMethodOnArgument(Class intrface, String methodName, Evaluable[] args) { super(intrface); this.args = args; this.methodName = methodName; } public Object get(VarContext ctx) { return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { if (method.getDeclaringClass() == intrface) return forwardCall(actualArgs[0], ctx); else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); }); } public Object forwardCall(Object target, VarContext ctx) { return call(target, methodName, evalArgs(args, ctx)); } } 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 = evalArgs(curriedArgs, 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 = evalArgs(args, 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 == null) out = new ArrayList(); else if (coll.getClass().isArray()) { if (coll instanceof Object[]) { var array = (Object[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof byte[]) { var array = (byte[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else throw fail("todo: " + coll); } else if (coll instanceof Iterable) { out = emptyList((Iterable) coll); for (var element : ((Iterable) coll)) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } 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 WillReturn extends EvaluableBase implements IFieldsToList { public Evaluable exp; public Evaluable body; public WillReturn() { } public WillReturn(Evaluable exp, Evaluable body) { this.body = body; this.exp = exp; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + exp + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { exp, body }; } public Object get(VarContext ctx) { body.get(ctx); return exp.get(ctx); } } 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 Evaluable _const(Object o) { return new Const(o); } static public class Then extends CallOnTarget { public CallOnTarget call1, call2; public Then(CallOnTarget call1, CallOnTarget call2) { this.call2 = call2; this.call1 = call1; target = call1.target; call1.target = null; } public Object evalOnTarget(VarContext ctx, Object object) { call1.evalOnTarget(ctx, object); return call2.evalOnTarget(ctx, object); } } } 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)); } } public interface HasBounds extends WidthAndHeight { public Rect bounds(); default public int getWidth() { return bounds().h; } default public int getHeight() { return bounds().w; } } 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 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 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 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 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 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(__66 -> convert(__66), c.fields)), lines_rtrim(map(__67 -> convert(__67), 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 != null && 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(__68 -> convertWithLeadingSpace2(__68), ((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(__69 -> convert(__69), ((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(__70 -> convert(__70), ((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 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; } public JPopDownButton content(Object... items) { onFillingMenu(menu -> fillJPopupMenu(menu, items)); return this; } 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()); } public JComponent visualize() { return this; } } 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(); } } 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 Timestamp(Date date) { if (date != null) this.date = date.getTime(); } public long unixDate() { return date; } public long unixSeconds() { return unixDate() / 1000; } 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 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); } } } 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 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); } } } public enum G22ScriptMode { edit, saved, autoRunnable } public interface RunnableWithExceptions { public void run() throws Exception; } 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 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); }); } } public interface IPersistenceInfo { public Map _persistenceInfo(); } 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 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 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); } } 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()); } } 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 OnePath { public ByteBuffer steps = new ByteBuffer(); public OnePath() { } public OnePath(String path) { int n = l(path); steps.allocate(n); for (int i = 0; i < n; i++) steps.add(parseDigit(path, i)); } public OnePath(OnePath path) { steps = new ByteBuffer(path.steps); } public OnePath(Iterable points, boolean close) { fromPoints(points, close); } public void fromPoints(Iterable points, boolean close) { var it = iterator(points); if (empty(it)) return; Pt firstPoint = it.next(), p = firstPoint; while (it.hasNext()) { Pt p2 = it.next(); steps.add(ptToDigit(ptMinus(p2, p))); p = p2; } if (close) steps.add(ptToDigit(ptMinus(firstPoint, p))); } final public int length() { return size(); } final public int nSteps() { return size(); } public int size() { return steps.size(); } public String toString() { return pathString(); } public String pathString() { return singleDigitBytesToString(steps); } public IterableIterator pointIterator() { return pointIterator(origin()); } public IterableIterator pointIterator(Pt startPt) { return new IterableIterator() { public int i = 0, n = length(); public Pt p = startPt; public boolean hasNext() { return i <= n; } public Pt next() { var p = this.p; if (i < n) this.p = translatePt(this.p, getStepAsPt(i)); ++i; return p; } }; } final public List pointsList() { return pointList(); } public List pointList() { return ptBuffer(pointIterator()); } public int getStep(int i) { return steps.get(i); } public Pt getStepAsPt(int i) { return onePathDirections()[steps.get(i)]; } static public int ptToDigit(Pt p) { return p.y < 0 ? p.x < 0 ? 1 : p.x == 0 ? 2 : 3 : p.y == 0 ? p.x < 0 ? 8 : p.x == 0 ? 0 : 4 : p.x < 0 ? 7 : p.x == 0 ? 6 : 5; } public Pt origin() { return main.origin(); } public Pt endPoint() { return last(pointIterator()); } public Pt drift() { return ptMinus(endPoint(), origin()); } public void addStep(int p_x, int p_y) { addStep(pt(p_x, p_y)); } public void addStep(Pt p) { int step = onePathLookupDirection(p); if (step < 0) throw fail("Invalid one path step: " + p); addStep(step); } public void addStep(int step) { assertBetween(0, 8, step); steps.add(step); } public void insertStep(int idx, int p_x, int p_y) { insertStep(idx, pt(p_x, p_y)); } public void insertStep(int idx, Pt p) { int step = onePathLookupDirection(p); if (step < 0) throw fail("Invalid one path step: " + p); insertStep(idx, step); } public void insertStep(int idx, int step) { assertBetween(0, 8, step); steps.add(idx, step); } public Rect bounds() { return boundsOfPts(pointIterator()); } } public enum JVMStackCellType { none, objValue, intValue, longValue, floatValue, doubleValue } 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)); } } public interface IntSize { public int size(); } 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 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 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 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 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 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 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 int 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 class JConceptsTable implements Swingable { public Class conceptClass; public Concepts concepts; public JTable table; public Map filters; public String hID = "ID"; final public JConceptsTable setDropFields(List dropFields) { return dropFields(dropFields); } public JConceptsTable dropFields(List dropFields) { this.dropFields = dropFields; return this; } final public List getDropFields() { return dropFields(); } public List dropFields() { return dropFields; } public List dropFields; final public JConceptsTable setNoSubclasses(boolean noSubclasses) { return noSubclasses(noSubclasses); } public JConceptsTable noSubclasses(boolean noSubclasses) { this.noSubclasses = noSubclasses; return this; } final public boolean getNoSubclasses() { return noSubclasses(); } public boolean noSubclasses() { return noSubclasses; } public boolean noSubclasses = false; public IF1 postProcess; public Runnable afterUpdate; public boolean latestFirst = false; public IF1, Collection> sorter = __1 -> defaultSort(__1); public int idWidth = 50; final public JConceptsTable setUpdateInterval(int updateInterval) { return updateInterval(updateInterval); } public JConceptsTable updateInterval(int updateInterval) { this.updateInterval = updateInterval; return this; } final public int getUpdateInterval() { return updateInterval(); } public int updateInterval() { return updateInterval; } public int updateInterval = 100; public int firstUpdateInterval = 100; public boolean humanizeFieldNames = true; public Float tableFontSize; public Integer tableRowHeight; final public JConceptsTable setAddCountToEnclosingTab(boolean addCountToEnclosingTab) { return addCountToEnclosingTab(addCountToEnclosingTab); } public JConceptsTable addCountToEnclosingTab(boolean addCountToEnclosingTab) { this.addCountToEnclosingTab = addCountToEnclosingTab; return this; } final public boolean getAddCountToEnclosingTab() { return addCountToEnclosingTab(); } public boolean addCountToEnclosingTab() { return addCountToEnclosingTab; } public boolean addCountToEnclosingTab = false; final public JConceptsTable setUseNewChangeHandler(boolean useNewChangeHandler) { return useNewChangeHandler(useNewChangeHandler); } public JConceptsTable useNewChangeHandler(boolean useNewChangeHandler) { this.useNewChangeHandler = useNewChangeHandler; return this; } final public boolean getUseNewChangeHandler() { return useNewChangeHandler(); } public boolean useNewChangeHandler() { return useNewChangeHandler; } public boolean useNewChangeHandler = false; final public JConceptsTable setDefaultAction(IVF1 defaultAction) { return defaultAction(defaultAction); } public JConceptsTable defaultAction(IVF1 defaultAction) { this.defaultAction = defaultAction; return this; } final public IVF1 getDefaultAction() { return defaultAction(); } public IVF1 defaultAction() { return defaultAction; } public IVF1 defaultAction; public int count; transient public Set onSelectionChanged; public JConceptsTable onSelectionChanged(Runnable r) { onSelectionChanged = createOrAddToSyncLinkedHashSet(onSelectionChanged, r); return this; } public JConceptsTable removeSelectionChangedListener(Runnable r) { main.remove(onSelectionChanged, r); return this; } public void selectionChanged() { if (onSelectionChanged != null) for (var listener : onSelectionChanged) pcallF_typed(listener); } transient public Set onSingleSelectionChanged; public JConceptsTable onSingleSelectionChanged(Runnable r) { onSingleSelectionChanged = createOrAddToSyncLinkedHashSet(onSingleSelectionChanged, r); return this; } public JConceptsTable removeSingleSelectionChangedListener(Runnable r) { main.remove(onSingleSelectionChanged, r); return this; } public void singleSelectionChanged() { if (onSingleSelectionChanged != null) for (var listener : onSingleSelectionChanged) pcallF_typed(listener); } public AWTOnConceptChanges changeHandler; public AWTOnConceptChangesByClass newChangeHandler; public boolean updatingList = false; final public JConceptsTable setSelectAfterUpdate(A selectAfterUpdate) { return selectAfterUpdate(selectAfterUpdate); } public JConceptsTable selectAfterUpdate(A selectAfterUpdate) { this.selectAfterUpdate = selectAfterUpdate; return this; } final public A getSelectAfterUpdate() { return selectAfterUpdate(); } public A selectAfterUpdate() { return selectAfterUpdate; } public A selectAfterUpdate; public A lastSelected; public JConceptsTable() { } public JConceptsTable(Class conceptClass) { this.conceptClass = conceptClass; } public JConceptsTable(Concepts concepts, Class conceptClass) { this.conceptClass = conceptClass; this.concepts = concepts; } transient public IF1> itemToMap; public Map itemToMap(A a) { return itemToMap != null ? itemToMap.get(a) : itemToMap_base(a); } final public Map itemToMap_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : itemToMap_base(a); } public Map itemToMap_base(A a) { return putAll(specialFieldsForItem(a), mapValues(__71 -> renderValue(__71), itemToMap_inner2(a))); } transient public IF1 renderValue; public Object renderValue(Object o) { return renderValue != null ? renderValue.get(o) : renderValue_base(o); } final public Object renderValue_fallback(IF1 _f, Object o) { return _f != null ? _f.get(o) : renderValue_base(o); } public Object renderValue_base(Object o) { return renderForTable_noStruct(o); } transient public IF1> itemToMap_inner2; public Map itemToMap_inner2(A a) { return itemToMap_inner2 != null ? itemToMap_inner2.get(a) : itemToMap_inner2_base(a); } final public Map itemToMap_inner2_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : itemToMap_inner2_base(a); } public Map itemToMap_inner2_base(A a) { return allConceptFieldsAsMapExcept(a, dropFields); } transient public IF1> specialFieldsForItem; public Map specialFieldsForItem(A a) { return specialFieldsForItem != null ? specialFieldsForItem.get(a) : specialFieldsForItem_base(a); } final public Map specialFieldsForItem_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : specialFieldsForItem_base(a); } public Map specialFieldsForItem_base(A a) { Map map = litorderedmap(hID, str(a.id)); mapPut(map, "Java Class", javaClassDescForItem(a)); return map; } public String javaClassDescForItem(A a) { String className = dynShortClassName(a); if (neq(className, shortClassName(conceptClass))) { String text = className; String realClass = shortClassName(a); if (neq(className, realClass)) text += " as " + realClass; return text; } return null; } public String defaultTitle() { return plural(shortClassName(conceptClass)); } public void showAsFrame() { showAsFrame(defaultTitle()); } public void showAsFrame(String title) { makeTable(); showFrame(title, table); } public void makeTable() { if (table != null) return; if (concepts == null) concepts = db_mainConcepts(); table = sexyTable(); if (tableFontSize != null) { setTableFontSizes(tableFontSize, table); if (tableRowHeight == null) tableRowHeight = iround(tableFontSize * 1.5); } if (tableRowHeight != null) setRowHeight(table, tableRowHeight); if (useNewChangeHandler) { newChangeHandler = new AWTOnConceptChangesByClass(concepts, conceptClass, table, () -> _update()).delay(updateInterval).firstDelay(firstUpdateInterval); newChangeHandler.install(); } else { changeHandler = new AWTOnConceptChanges(concepts, table, () -> _update()).delay(updateInterval).firstDelay(firstUpdateInterval); changeHandler.install(); } onTableSelectionChanged(table, () -> { if (updatingList) return; selectionChanged(); }); onSelectionChanged(() -> { var a = selected(); if (a != lastSelected) { lastSelected = a; singleSelectionChanged(); } }); onDoubleClickOrEnter(table, () -> { A a = selected(); if (a != null && defaultAction != null) pcallF(defaultAction, a); }); } public void update() { { swing(() -> { _update(); }); } } public void _update() { if (table == null) return; updatingList = true; boolean allRestored = false; A selectAfterUpdate = selectAfterUpdate(); try { List data = new ArrayList(); Set selection; if (selectAfterUpdate != null) { selection = litset(selectAfterUpdate._conceptID()); selectAfterUpdate(null); } else selection = toSet(selectedConceptIDs()); Collection l = conceptsWhere(concepts, conceptClass, mapToParams(filters)); if (noSubclasses) l = filter(l, x -> x.getClass() == conceptClass); l = postProcess(sorter, l); for (A c : l) addIfNotNull(data, itemToMap(c)); if (latestFirst) reverseInPlace(data); data = (List) postProcess(postProcess, data); count = l(data); dataToTable_uneditable(data, table); if (humanizeFieldNames) humanizeTableColumns(); tableColumnMaxWidth(table, 0, idWidth); allRestored = restoreSelection(selection); if (addCountToEnclosingTab) updateEnclosingTabTitle(); } finally { updatingList = false; } pcallF(afterUpdate); if (!allRestored || selectAfterUpdate != null) selectionChanged(); } public void updateEnclosingTabTitle() { updateEnclosingTabTitleWithCount(table, count); } public void humanizeTableColumns() { int n = tableColumnCount(table); for (int i = 0; i < n; i++) setColumnName(table, i, humanizeFormLabel(getColumnName(table, i))); } public JComponent visualize() { return table(); } public JTable table() { makeTable(); return table; } public A selectedConcept() { return (A) concepts.getConcept(toLong(selectedTableCell(table, 0))); } public A selected() { return selectedConcept(); } public long getItemID(int row) { return toLong(getTableCell(table, row, 0)); } public A getItem(int row) { return (A) concepts.getConcept(getItemID(row)); } public int indexOfConcept(final A c) { if (c == null) return -1; return swing(new F0() { public Integer get() { try { int n = tableRowCount(table); for (int row = 0; row < n; row++) if (toLong(getTableCell(table, row, 0)) == c.id) return row; return -1; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "int n = tableRowCount(table);\r\n for row to n:\r\n if (toLong(getTab..."; } }); } public List selectedConcepts() { return swing(() -> { int[] rows = table.getSelectedRows(); List l = new ArrayList(); for (int row : rows) l.add(getItem(row)); return l; }); } public List selectedConceptIDs() { return swing(() -> { int[] rows = table.getSelectedRows(); List l = emptyList(l(rows)); for (int row : rows) l.add(getItemID(row)); return l; }); } public boolean restoreSelection(Set selection) { return swing(() -> { int n = tableRowCount(table); IntBuffer toSelect = new IntBuffer(); for (int row = 0; row < n; row++) if (selection.contains(getItemID(row))) toSelect.add(row); selectTableRows(table, toSelect.toIntArray()); return toSelect.size() == selection.size(); }); } public void setSelected(A a) { selectRow(table(), indexOfConcept(a)); } public Collection defaultSort(Collection l) { return sortByConceptID(l); } public JConceptsTable addFilter(String field, Object value) { filters = orderedMapPutOrCreate(filters, field, value); return this; } public void onSelectionChangedAndWhenShowing(Runnable r) { bindToComponent(table(), r); onSelectionChanged(r); } public void onSelectionChangedAndNow(Runnable r) { if (r == null) return; onSelectionChanged(r); r.run(); } public JConceptsTable updateInterval(double seconds) { return updateInterval(toMS_int(seconds)); } } 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 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 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 TreeMultiMap extends MultiMap { public TreeMultiMap() { super(true); } public TreeMultiMap(MultiMap map) { this(); putAll(map); } } 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 class ByteBuffer implements Iterable { public byte[] data; public int size; public ByteBuffer() { } public ByteBuffer(int size) { if (size != 0) data = new byte[size]; } public ByteBuffer(Iterable l) { if (l instanceof Collection) allocate(((Collection) l).size()); addAll(l); } public ByteBuffer(byte[] data) { this.data = data; size = l(data); } public void add(int idx, int i) { add(0); arraycopy(data, idx, data, idx + 1, size - (idx + 1)); data[idx] = (byte) i; } public void add(int i) { add((byte) i); } public void add(byte i) { if (size >= lByteArray(data)) { allocate(Math.max(1, toInt(Math.min(maximumSafeArraySize(), lByteArray(data) * 2L)))); if (size >= data.length) throw fail("ByteBuffer too large: " + size); } data[size++] = i; } public void allocate(int n) { data = resizeByteArray(data, max(n, size())); } public void addAll(Iterable l) { if (l != null) for (byte i : l) add(i); } final public byte[] toByteArray() { return toArray(); } public byte[] toArray() { return size == 0 ? null : resizeByteArray(data, size); } public List toList() { return byteArrayToList(data, 0, size); } public List asVirtualList() { return new RandomAccessAbstractList() { public int size() { return size; } public Byte get(int i) { return ByteBuffer.this.get(i); } public Byte set(int i, Byte val) { Byte a = get(i); data[i] = val; return a; } }; } public void reset() { size = 0; } public void clear() { reset(); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public byte get(int idx) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); return data[idx]; } public void set(int idx, byte value) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); data[idx] = value; } public byte popLast() { if (size == 0) throw fail("empty buffer"); return data[--size]; } public byte popFirst() { if (size == 0) throw fail("empty buffer"); byte b = data[0]; arraycopy(data, 1, 0, --size); return b; } public byte last() { return data[size - 1]; } public byte nextToLast() { return data[size - 2]; } public String toString() { return squareBracket(joinWithSpace(toList())); } public Iterator iterator() { return new IterableIterator() { public int i = 0; public boolean hasNext() { return i < size; } public Byte next() { return data[i++]; } }; } public void trimToSize() { data = resizeByteArray(data, size); } public int indexOf(byte b) { for (int i = 0; i < size; i++) if (data[i] == b) return i; return -1; } public byte[] subArray(int start, int end) { return subByteArray(data, start, min(end, size)); } } 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(); } static public interface IF2 { public C get(A a, B b); } static public class TokenRange extends IntRange { public TokenRange() { } public TokenRange(int start, int end) { this.end = end; this.start = start; } } 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 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 AWTOnConceptChangesByClass implements AutoCloseable { final public AWTOnConceptChangesByClass setComponent(JComponent component) { return component(component); } public AWTOnConceptChangesByClass component(JComponent component) { this.component = component; return this; } final public JComponent getComponent() { return component(); } public JComponent component() { return component; } public JComponent component; final public AWTOnConceptChangesByClass setAction(Runnable action) { return action(action); } public AWTOnConceptChangesByClass action(Runnable action) { this.action = action; return this; } final public Runnable getAction() { return action(); } public Runnable action() { return action; } public Runnable action; final public AWTOnConceptChangesByClass setConcepts(Concepts concepts) { return concepts(concepts); } public AWTOnConceptChangesByClass concepts(Concepts concepts) { this.concepts = concepts; return this; } final public Concepts getConcepts() { return concepts(); } public Concepts concepts() { return concepts; } public Concepts concepts; final public AWTOnConceptChangesByClass setConceptClass(Class conceptClass) { return conceptClass(conceptClass); } public AWTOnConceptChangesByClass conceptClass(Class conceptClass) { this.conceptClass = conceptClass; return this; } final public Class getConceptClass() { return conceptClass(); } public Class conceptClass() { return conceptClass; } public Class conceptClass; final public AWTOnConceptChangesByClass setFirstDelay(int firstDelay) { return firstDelay(firstDelay); } public AWTOnConceptChangesByClass firstDelay(int firstDelay) { this.firstDelay = firstDelay; return this; } final public int getFirstDelay() { return firstDelay(); } public int firstDelay() { return firstDelay; } public int firstDelay; final public AWTOnConceptChangesByClass setDelay(int delay) { return delay(delay); } public AWTOnConceptChangesByClass delay(int delay) { this.delay = delay; return this; } final public int getDelay() { return delay(); } public int delay() { return delay; } public int delay = 500; volatile public long changes = -1, changeCounter; public javax.swing.Timer timer; public AutoCloseable closer; public AWTOnConceptChangesByClass(Concepts concepts, Class conceptClass, JComponent component, Runnable action) { this.action = action; this.component = component; this.conceptClass = conceptClass; this.concepts = concepts; } public void install() { assertNotNull(concepts); assertNotNull(conceptClass); assertNotNull(component); bindToComponent(component, () -> closer = onConceptChangeByClass_notOnAllChanged(concepts, conceptClass, () -> ++changeCounter), () -> { { cleanUp(closer); closer = null; } }); 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 = changeCounter; if (changes != c) { changes = c; { if (action != null) action.run(); } } } public void close() { try { { cleanUp(timer); timer = null; } { cleanUp(closer); closer = null; } } catch (Exception __e) { throw rethrow(__e); } } } static public class IntBuffer implements Iterable { public int[] data; public int size; public IntBuffer() { } public IntBuffer(int size) { if (size != 0) data = new int[size]; } public IntBuffer(Iterable l) { if (l instanceof Collection) allocate(((Collection) l).size()); addAll(l); } public void add(int i) { if (size >= lIntArray(data)) { data = resizeIntArray(data, Math.max(1, toInt(Math.min(maximumSafeArraySize(), lIntArray(data) * 2L)))); if (size >= data.length) throw fail("IntBuffer too large: " + size); } data[size++] = i; } public void allocate(int n) { data = resizeIntArray(data, max(n, size())); } public void setSize(int n) { data = resizeIntArray(data, n); size = min(l(data), size); } public void addAll(Iterable l) { if (l != null) for (int i : l) add(i); } public void addAll(int... l) { if (l != null) for (int i : l) add(i); } final public int[] toIntArray() { return toArray(); } public int[] toArray() { return size == 0 ? null : resizeIntArray(data, size); } public int[] subArray(int from, int to) { return subIntArray(data, from, min(to, size)); } public int[] toArrayNonNull() { return unnull(toArray()); } final public List asList() { return toList(); } final public List asVirtualList() { return toList(); } public List toList() { return new RandomAccessAbstractList() { public int size() { return size; } public Integer get(int i) { return IntBuffer.this.get(i); } public Integer set(int i, Integer val) { Integer a = get(i); data[i] = val; return a; } }; } public void reset() { size = 0; } public void clear() { reset(); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public int get(int idx) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); return data[idx]; } public void set(int idx, int value) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); data[idx] = value; } public int popLast() { if (size == 0) throw fail("empty buffer"); return data[--size]; } public int last() { return data[size - 1]; } public int nextToLast() { return data[size - 2]; } public String toString() { return squareBracket(joinWithSpace(toList())); } public Iterator iterator() { return new IterableIterator() { public int i = 0; public boolean hasNext() { return i < size; } public Integer next() { return data[i++]; } }; } public IntegerIterator integerIterator() { return new IntegerIterator() { public int i = 0; public boolean hasNext() { return i < size; } public int next() { return data[i++]; } public String toString() { return "Iterator@" + i + " over " + IntBuffer.this; } }; } public void trimToSize() { data = resizeIntArray(data, size); } } 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 interface Transformable { public Object transformUsing(IF1 f); } static public class VarMatches extends WrappedMap { public VarMatches() { super(new LinkedHashMap()); } public VarMatches(Map map) { this(); main.putAll(this, map); } } abstract static public class RandomAccessAbstractList extends AbstractList implements RandomAccess { } 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 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 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()); } } abstract static public class IntegerIterator { abstract public boolean hasNext(); abstract public int next(); } 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 A listGet(List l, int idx) { return l != null && idx >= 0 && idx < l.size() ? l.get(idx) : null; } 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 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 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 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 BufferedImage toBufferedImage(Object o) { return toBufferedImageOpt(o); } 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 Rect growRect(int pixels, Rect r) { return growRect(r, pixels); } static public Rect growRect(double x, Rect r) { return growRect(x, x, r); } static public Rect growRect(double x, double y, Rect r) { return growRect(r, x, y); } static public Rect growRect(Rect r) { return growRect(r, 1); } static public Rect growRect(Rect r, int pixels) { return new Rect(r.x - pixels, r.y - pixels, r.w + pixels * 2, r.h + pixels * 2); } static public Rect growRect(Rect r, int x, int y) { return new Rect(r.x - x, r.y - y, r.w + x * 2, r.h + y * 2); } static public Rect growRect(Rect r, double x) { return growRect(r, x, x); } static public Rect growRect(Rect r, double x, double y) { return new Rect(iround(r.x - x), iround(r.y - y), r.w + iround(x * 2), r.h + iround(y * 2)); } static public Rect imageRect() { return imageRect(currentImage()); } static public Rect imageRect(BufferedImage img) { return img == null ? null : new Rect(0, 0, img.getWidth(), img.getHeight()); } static public Rect imageRect(MakesBufferedImage img) { return img == null ? null : new Rect(0, 0, img.getWidth(), img.getHeight()); } 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 int[] pixelsOfBufferedImage(BufferedImage image) { try { int width = image.getWidth(); int height = image.getHeight(); int[] pixels = new int[width * height]; PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); if (!pixelGrabber.grabPixels()) throw fail("Could not grab pixels"); return pixels; } catch (Exception __e) { throw rethrow(__e); } } static public Color withAlpha(Color c, double alpha) { return colorWithAlpha(c, alpha); } static public Color withAlpha(double alpha, Color c) { return colorWithAlpha(alpha, c); } static public int withAlpha(double alpha, int rgb) { return rgb & 0xFFFFFF | (iround(clampToZeroOne(alpha) * 255) << 24); } static public BufferedImage bufferedImageWithAlpha(int w, int h, int[] pixels) { return newBufferedImageWithAlpha(w, h, pixels); } static public BufferedImage bufferedImageWithAlpha(int[] pixels, int w, int h) { return newBufferedImageWithAlpha(w, h, pixels); } 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 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 int _hashCode(Object a) { return a == null ? 0 : a.hashCode(); } 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 IterableIterator pixelIterator(Rect r) { return new IterableIterator() { public int x2 = r.x2(), y2 = r.y2(); public int x = r.x, y = r.y; public boolean hasNext() { return y < y2 && x < x2; } public Pt next() { Pt p = pt(x, y); if (++x >= x2) { x = r.x; ++y; } return p; } }; } static public java.awt.Color color(String hex) { return awtColor(hex); } static public OnePathWithOrigin g22_regionOutline(IImageRegion region) { List outlines = g22_allBorderTraces_autoDiagonals(region); return new OnePathWithOrigin(first(outlines), false); } 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 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 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 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 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 createOrRemoveFile(File f, boolean create) { if (create) { if (!fileExists(f)) touchFile(f); } else if (fileExists(f)) removeFile(f); } 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 truncateList(List l, int n) { if (l(l) <= n) return; removeSubList(l, n, l(l)); } 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 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 List tlft(String s) { return toLinesFullTrim(s); } static public List tlft(File f) { return toLinesFullTrim(f); } static public String loadTextFile(String fileName) { return loadTextFile(fileName, null); } static public String loadTextFile(File f, String defaultContents) { return loadTextFile(f, defaultContents, "UTF-8"); } static public String loadTextFile(File f, String defaultContents, String encoding) { try { checkFileNotTooBigToRead(f); if (f == null || !f.exists()) return defaultContents; FileInputStream fileInputStream = new FileInputStream(f); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, encoding); return loadTextFile(inputStreamReader); } catch (Exception __e) { throw rethrow(__e); } } public static String loadTextFile(File fileName) { return loadTextFile(fileName, null); } static public String loadTextFile(String fileName, String defaultContents) { return fileName == null ? defaultContents : loadTextFile(newFile(fileName), defaultContents); } static public String loadTextFile(Reader reader) throws IOException { StringBuilder builder = new StringBuilder(); try { char[] buffer = new char[1024]; int n; while (-1 != (n = reader.read(buffer))) builder.append(buffer, 0, n); } finally { reader.close(); } return str(builder); } static public String dropPrefix(String prefix, String s) { return s == null ? null : s.startsWith(prefix) ? s.substring(l(prefix)) : s; } 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 File dirOfFile(File f) { return f == null ? null : f.getParentFile(); } 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 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 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 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 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 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) { var it = l.iterator(); if (it.hasNext()) { var pingSource = pingSource(); do { ping(pingSource); x.add(f.get(it.next())); } while (it.hasNext()); } } 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 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 boolean containsNewLine(String s) { return contains(s, '\n'); } 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 int boostHashCombine(int a, int b) { return a ^ (b + 0x9e3779b9 + (a << 6) + (a >>> 2)); } 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 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 List nonNulls(Iterable l, IF1 f) { return mapNonNulls(l, f); } 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 waitForCalculatedValueUsingChangeListener(IF0 f, IHasChangeListeners sender) { BoolVar trigger = new BoolVar(); AutoCloseable __2 = tempOnChange(sender, () -> trigger.set(true)); try { while (true) { ping(); { var __1 = f.get(); if (__1 != null) return __1; } trigger.waitUntilTrueAndClear(); } } finally { _close(__2); } } 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 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 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 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 String compilationDateFromClassPath(Object referenceObject) { return loadTextFileResource(classLoader(referenceObject), "compilation-date.txt"); } 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 class Unstructurer { final public Unstructurer setTok(Producer tok) { return tok(tok); } public Unstructurer tok(Producer tok) { this.tok = tok; return this; } final public Producer getTok() { return tok(); } public Producer tok() { return tok; } public Producer tok; final public Unstructurer setAllDynamic(boolean allDynamic) { return allDynamic(allDynamic); } public Unstructurer allDynamic(boolean allDynamic) { this.allDynamic = allDynamic; return this; } final public boolean getAllDynamic() { return allDynamic(); } public boolean allDynamic() { return allDynamic; } public boolean allDynamic = false; public int i = -1; public Object classFinder; public String mcDollar = actualMCDollar(); public Unstructurer classFinder(Object _classFinder) { classFinder = _classFinder != null ? _classFinder : _defaultClassFinder(); return this; } 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 Unstructurer() { 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); handlers.put("shortarray", (unstructure_Handler) (refID, tokIndex, out) -> { consume(); String hex = unquote(tpp()); out.set(shortArrayFromBytes(hexToBytes(hex))); }); } 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());\r..."; } }); } 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 } els..."; } }); } 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\n ..."; } }); } 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(); } } static public Object unstructure_tok(Producer tok, boolean allDynamic, Object classFinder) { boolean debug = unstructure_debug; AutoCloseable __1 = tempSetTL(dynamicObjectIsLoading_threadLocal(), true); try { Var v = new Var(); var unstructurer = new Unstructurer().tok(tok).allDynamic(allDynamic).classFinder(classFinder); unstructurer.parse_initial(new unstructure_Receiver() { public void set(Object o) { v.set(o); } }); unstructure_tokrefs = unstructurer.tokrefs.size(); return v.get(); } finally { _close(__1); } } static public boolean unstructure_debug = false; 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 String toString() { return commaCombine("Class " + className(c), stringIf("special", special), stringIf("customSerializer", customSerializer != null), stringIf("javafy", javafy), stringIf("nullInstances", nullInstances)); } public void nullInstances(boolean b) { this.nullInstances = b; if (b) special = true; } public void javafy(boolean b) { this.javafy = b; if (b) special = true; } public boolean handle(A o) { return false; } } 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_Data app(char c) { out.print(c); return this; } public structure_ClassInfo infoForClass(Class c) { structure_ClassInfo info = infoByClass.get(c); if (info == null) info = newClass(c); return info; } public String realShortName(String name) { return dropPrefix("main$", dropPrefix("loadableUtils.utils$", dropPrefix(mcDollar, name))); } public structure_ClassInfo newClass(Class c) { if (c == File.class) return new structure_ClassInfo() { @Override public boolean handle(File o) { append("File ").append(quote(o.getPath())); return true; } }; structure_ClassInfo info = new structure_ClassInfo(); info.c = c; infoByClass.put(c, info); String name = c.getName(); String shortName = realShortName(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); if (info.handle(o)) return; 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; } 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, d.mcDollar)) { 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 && !isJavaXClassName(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(); class WritingMap implements Runnable { public boolean v = false; public Map.Entry e; public String toString() { return renderVars("WritingMap", "e", mapEntryToPair(e), "v", !v); } public void run() { try { 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); } } } catch (Exception __e) { throw rethrow(__e); } } } d.stack.add(new WritingMap()); 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; } if (o instanceof short[]) { String hex = shortArrayToHex_bigEndian((short[]) o); d.append("shortarray \"").append(hex).app('\"'); 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 = d.realShortName(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 BufferedImage loadImage2(String snippetIDOrURL) { return loadBufferedImage(snippetIDOrURL); } static public BufferedImage loadImage2(File file) { return loadBufferedImage(file); } static public JComponent jGazelleLogo() { return setOpaqueBackground(Color.white, jimage(gazelleLogoImageID())); } 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 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 JScrollPane jscroll_centered_borderless(Component c) { return borderlessScrollPane(jscroll_centered(c)); } 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 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 onEnclosingScrollPaneResize(JComponent c, Runnable r) { new OnEnclosingScrollPaneResize(c, r).install(); } static public class OnEnclosingScrollPaneResize implements IFieldsToList { public JComponent c; public Runnable r; public OnEnclosingScrollPaneResize() { } public OnEnclosingScrollPaneResize(JComponent c, Runnable r) { this.r = r; this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ", " + r + ")"; } public Object[] _fieldsToList() { return new Object[] { c, r }; } final public OnEnclosingScrollPaneResize setDebug(boolean debug) { return debug(debug); } public OnEnclosingScrollPaneResize debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug() { return debug(); } public boolean debug() { return debug; } public boolean debug = false; public ComponentAdapter listener; public JViewport viewport; public void install() { if (r == null) return; bindToComponent(c, () -> { viewport = optCast(JViewport.class, getParent(getParent(c))); if (viewport != null) { listener = new ComponentAdapter() { public void componentResized(ComponentEvent e) { if (debug) print("Viewport resized"); pcallF(r); } }; viewport.addComponentListener(listener); if (debug) print("OnEnclosingScrollPaneResize installed"); } }, () -> { if (listener != null && viewport != null) { viewport.removeComponentListener(listener); if (debug) print("OnEnclosingScrollPaneResize removed"); } }); } } 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 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 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 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 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 = rawClipboardContents(); 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 File getProgramDir() { return programDir(); } static public File getProgramDir(String snippetID) { return programDir(snippetID); } 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 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 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 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 Graphics2D cloneGraphics(Graphics2D g) { return (Graphics2D) g.create(); } static public A repaint(A c) { if (c != null) c.repaint(); return c; } 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 void scaffoldCalled(Object obj, Object function, Object... args) { printShortenedFunctionCall(200, (obj == null ? "" : shorten(20, str(obj)) + " :: ") + function, args); } 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 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 boolean scaffoldingEnabled(Object o) { return metaGet(o, "scaffolding") != null; } static public void printVars(Object... params) { printVars_str(params); } 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 Rectangle toRectangle(Rect r) { return r == null ? null : r.getRectangle(); } 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 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 closeAllAndClear(Collection l) { if (l == null) return; for (AutoCloseable c : cloneList(l)) { try { close(c); } catch (Throwable __e) { printStackTrace(__e); } } l.clear(); } 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 JScrollPane jscroll_center_borderless(Component c) { return jscroll_centered_borderless(c); } 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 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 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 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 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 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 > List allValues(Map map) { List out = new ArrayList(); for (var l : values(map)) addAll(out, l); return out; } 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 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 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 String commaCombine(Object... l) { return joinNemptiesWithComma(flattenCollectionsAndArrays(l)); } static public byte[] cloneByteArray(byte[] a) { if (a == null) return null; byte[] b = new byte[a.length]; System.arraycopy(a, 0, b, 0, a.length); return b; } static public int ubyteToInt(byte b) { return b & 0x0FF; } static public int ubyteToInt(char c) { return c & 0x0FF; } static public BWImage toBW(RGBImage img) { return img == null ? null : new BWImage(img); } 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 String str_px(int w, int h) { return n2(w) + "*" + n2(h) + "px"; } static public String str_px(WidthAndHeight image) { return image == null ? null : str_px(image.getWidth(), image.getHeight()); } static public Class run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } static public UnsupportedOperationException unsupportedOperation() { throw new UnsupportedOperationException(); } 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 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 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 String nullIfEmpty(String s) { return isEmpty(s) ? null : s; } static public Map nullIfEmpty(Map map) { return isEmpty(map) ? null : map; } static public List nullIfEmpty(List l) { return isEmpty(l) ? null : l; } static public String 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 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 long now_virtualTime; static public long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } 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)); try { return unstructure_tok(javaTokC_noMLS_onReader(reader), false, classFinder); } finally { _close(reader); } } 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 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 boolean sameSnippetID(String a, String b) { if (!isSnippetID(a) || !isSnippetID(b)) return false; return parseSnippetID(a) == parseSnippetID(b); } static public RemoteDB connectToDBOpt(String dbNameOrID) { try { return new RemoteDB(dbNameOrID); } catch (Throwable __e) { return null; } } 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 String dynShortName(Object o) { return shortDynamicClassName(o); } 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 A lastKey(SortedMap map) { return empty(map) ? null : map.lastKey(); } 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 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 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 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 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 closeAllOpt(Iterable l) { if (l == null) return; for (Object c : l) { try { if (c instanceof AutoCloseable) close((AutoCloseable) c); } catch (Throwable __e) { printStackTrace(__e); } } } static public void closeAllOpt(Object... l) { if (l == null) return; for (Object c : l) { try { if (c instanceof AutoCloseable) close((AutoCloseable) c); } catch (Throwable __e) { printStackTrace(__e); } } } 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 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 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 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 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 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 loadConceptsStructure(String progID) { return loadTextFilePossiblyGZipped(getProgramFile(progID, "concepts.structure")); } static public String loadConceptsStructure() { return loadConceptsStructure(dbProgramID()); } 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 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 containsKey(Map map, A key) { return map != null && map.containsKey(key); } 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 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 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 void removeLast(StringBuilder buf) { if (buf == null) return; int n = buf.length(); if (n > 0) buf.setLength(n - 1); } 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 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 int idiv_floor(int a, int b) { return a / b; } static public int idiv_floor(double a, double b) { return ifloor(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 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 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", "java.lang.invoke.VarHandle", "java.lang.invoke.MethodHandles"); } 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 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 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 List listPlus(Collection l, A... more) { return concatLists(l, asList(more)); } static public void fillArrayUnlessZero(byte[] a, byte value) { if (value != 0) Arrays.fill(a, value); } static public void fillArrayUnlessZero(int[] a, int value) { if (value != 0) Arrays.fill(a, value); } static public void fillArrayUnlessZero(float[] a, float value) { if (value != 0) Arrays.fill(a, value); } 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 getInt(List c, int i) { return toInt(get(c, i)); } static public int getInt(Map map, Object key) { return toInt(mapGet(map, key)); } static public int getInt(Object o, String field) { return toInt(getOpt(o, (String) field)); } static public int getInt(String field, Object o) { return getInt(o, field); } static public int limitToUByte(int i) { return max(0, min(255, i)); } static public BufferedImage bufferedImage(int[] pixels, int w, int h) { return intArrayToBufferedImage(pixels, w, h); } static public BufferedImage bufferedImage(int[] pixels, WidthAndHeight size) { return bufferedImage(pixels, size.getWidth(), size.getHeight()); } static public BufferedImage bufferedImage(int w, int h, int[] pixels) { return intArrayToBufferedImage(pixels, w, h); } static public BufferedImage bufferedImage(int w, int h) { return newBufferedImage(w, h); } static public BufferedImage bufferedImage(int w, int h, RGB rgb) { return newBufferedImage(w, h, rgb); } static public BufferedImage bufferedImage(int w, Color color) { return bufferedImage(w, w, color); } static public BufferedImage bufferedImage(int w, int h, Color color) { return newBufferedImage(w, h, color); } static public BufferedImage bufferedImage(Pt p, Color color) { return newBufferedImage(p, color); } static public BufferedImage bufferedImage(WidthAndHeight size, Color color) { return newBufferedImage(size.w(), size.h(), color); } static public BufferedImage bufferedImage(Color color, WidthAndHeight size) { return bufferedImage(size, color); } static public Pt origin() { return pt(0, 0); } 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 List reversedList(Iterable l) { List x = cloneList(l); Collections.reverse(x); return x; } 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 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 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 WidthAndHeight widthAndHeight(BufferedImage image) { return image == null ? null : widthAndHeight(image.getWidth(), image.getHeight()); } static public WidthAndHeightImpl widthAndHeight(int w) { return widthAndHeight(w, w); } static public WidthAndHeightImpl widthAndHeight(int w, int h) { return new WidthAndHeightImpl(w, h); } 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 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 BufferedImage render(WidthAndHeight size, G2Drawable drawable) { return drawableToImage(size, drawable); } 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 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); } public static boolean isSnippetID(String s) { try { parseSnippetID(s); return true; } catch (RuntimeException e) { return false; } } 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 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 fsI(String id) { return formatSnippetID(id); } static public String fsI(long id) { return formatSnippetID(id); } 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 ReliableSingleThread rst(Runnable r) { return new ReliableSingleThread(r); } static public Class _run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } 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 void sleepSeconds(double s) { if (s > 0) sleep(round(s * 1000)); } 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 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 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 SimpleLiveValue stringLiveValue() { return new SimpleLiveValue(String.class); } static public SimpleLiveValue stringLiveValue(String value) { return new SimpleLiveValue(String.class, value); } 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 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 A enableScaffolding(A o) { return enableScaffolding(o, true); } static public A enableScaffolding(A o, boolean b) { if (o instanceof IMeta) ((IMeta) o).metaPut("scaffolding", trueOrNull(b)); 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 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 JTextArea showTextWordWrapped(final String title, final String text) { return showWrappedText(title, text); } static public JTextArea showTextWordWrapped(Object text) { return showWrappedText(text); } 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 JScrollPane jBorderlessHigherScrollPane(JComponent c) { return borderlessScrollPane(jHigherScrollPane(c)); } static public JPanel jfullcenter(Component c) { return jFullCenter(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 A toolTip(A c, final Object toolTip) { return setToolTipText(c, toolTip); } static public A toolTip(Object toolTip, A c) { return setToolTipText(toolTip, c); } static public JButton 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 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 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 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 RunResultWithTimestamps runResultWithTimestamps(IF0 f) { return new RunResultWithTimestamps().run(f); } 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 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 JComponent jErrorView(Throwable e) { return jSmallErrorView(e); } 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 quote(Object o) { if (o == null) return "null"; return quote(str(o)); } static public String quote(String s) { if (s == null) return "null"; StringBuilder out = new StringBuilder((int) (l(s) * 1.5 + 2)); quote_impl(s, out); return out.toString(); } static public void quote_impl(String s, StringBuilder out) { out.append('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') out.append('\\').append(c); else if (c == '\r') out.append("\\r"); else if (c == '\n') out.append("\\n"); else if (c == '\t') out.append("\\t"); else if (c == '\0') out.append("\\0"); else out.append(c); } out.append('"'); } static public String 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 IterableIterator filterI(Iterator it, F1 f) { return filterIterator(it, f); } static public IterableIterator filterI(Iterator it, IF1 f) { return filterIterator(it, f); } static public IterableIterator filterI(F1 f, Iterator it) { return filterIterator(f, it); } static public IterableIterator filterI(IF1 f, Iterator it) { return filterIterator(f, it); } static public IterableIterator filterI(IF1 f, Iterable it) { return filterIterator(f, iterator(it)); } static public SingleComponentPanel scp() { return singleComponentPanel(); } static public SingleComponentPanel scp(Component c) { return singleComponentPanel(c); } static public JSplitPane jvsplit(Component n, Component s) { return jvsplit(n, s, 0.5); } static public JSplitPane jvsplit(Component n, Component s, double splitPoint) { return jvsplit(n, s, splitPoint, 0); } static public JSplitPane jvsplit(Component n, Component s, double splitPoint, int delay) { return setSplitPaneOnFirstShowing(swing(() -> new JSplitPane(JSplitPane.VERTICAL_SPLIT, wrap(n), wrap(s))), splitPoint, delay); } static public JSplitPane jvsplit(double splitPoint, Component n, Component s) { return jvsplit(splitPoint, 0, n, s); } static public JSplitPane jvsplit(double splitPoint, int delay, Component n, Component s) { return jvsplit(n, s, splitPoint, delay); } 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(); } 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 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 volatile public int numberOfCores_value; static public int numberOfCores() { if (numberOfCores_value == 0) numberOfCores_value = Runtime.getRuntime().availableProcessors(); return numberOfCores_value; } 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 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 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 String roundBracket(String s) { return "(" + s + ")"; } static public String roundBracket(Object s) { return roundBracket(str(s)); } static public void syncNotifyAll(Object o) { if (o != null) synchronized (o) { o.notifyAll(); } } 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 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 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 int last(IntBuffer buf) { return buf.get(buf.size() - 1); } static public byte last(ByteBuffer buf) { return buf.get(buf.size() - 1); } static public A last(CompactLinkedHashSet set) { return set == null ? null : set.last(); } 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 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 String formatRecordVars(String recordName, Object... params) { return renderRecordVars(recordName, params); } 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 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 isIdentifier(String s) { return isJavaIdentifier(s); } static public boolean startsWithDigit(String s) { return nempty(s) && isDigit(s.charAt(0)); } static public boolean isQuoted(String s) { if (isNormalQuoted(s)) return true; return isMultilineQuoted(s); } static public int parseHexInt(String s) { return hexToInt(s); } 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 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 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 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 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 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 addAndReturn(Collection c, A a) { if (c != null) c.add(a); return a; } static public A addAndReturn(List c, int idx, A a) { if (c != null) c.add(idx, a); return a; } 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 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()); if (type instanceof GenericArrayType) return typeToClass(((GenericArrayType) type).getGenericComponentType()).arrayType(); return null; } 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 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 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 void register(Concept c) { registerConcept(c); } static public String intToHex_fullLength(int i) { return intToHex(i); } 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 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 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 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 Value value(A a) { return new Value(a); } static public String sanitizeFileName(String s) { return nohup_sanitize(s); } static public boolean notNull(Object o) { return o != null; } static public WeakIdentityHashMap weakIdentityMap() { return weakIdentityHashMap(); } 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 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 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 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 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 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 String joinNemptiesWithComma(Object... strings) { return joinNempties(", ", strings); } static public String joinNemptiesWithComma(Iterable strings) { return joinNempties(", ", strings); } 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 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 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 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 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 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 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 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 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 Timestamp tsNow() { return new Timestamp(); } 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, Object dest, int destPos, int n) { arrayCopy(src, 0, dest, destPos, n); } static public void arrayCopy(Object src, int srcPos, Object dest, int destPos, int n) { arraycopy(src, srcPos, dest, destPos, n); } 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 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 String exceptionToStringShort(Throwable e) { try { 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; } catch (Throwable _e) { printStackTrace(_e); return "Error in exceptionToStringShort"; } } 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 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 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 Image2B toImage2B(BufferedImage img) { return img == null ? null : new Image2B(img); } static public Image2B toImage2B(MakesBufferedImage img) { if (img == null) return null; if (img instanceof Image2B) return ((Image2B) img); if (img instanceof BWImage) return new Image2B((BWImage) img); if (img instanceof IBinaryImage) return iBinaryImageToImage2B((IBinaryImage) img); return new Image2B(toBufferedImage(img)); } static public Image2B iBinaryImageToImage2B(IBinaryImage img) { if (img == null) return null; if (img instanceof Image2B) return ((Image2B) img); int w = img.getWidth(), h = img.getHeight(); byte[] pixels = new byte[(w * h + 7) / 8]; int i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (img.getBoolPixel(x, y)) pixels[i / 8] |= 1 << (i & 7); i++; } return new Image2B(w, h, pixels); } 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 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 jMinWidth0(A c) { return jMinWidth_pure(0, c); } 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 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, Swingable n, Swingable c) { return northAndCenterWithMargin(margin, n, toComponent(c)); } static public JPanel northAndCenterWithMargin(int margin, Swingable n, Component c) { return northAndCenterWithMargin(margin, toComponent(n), c); } static public JPanel northAndCenterWithMargin(int margin, Component n, Swingable c) { return northAndCenterWithMargin(margin, n, toComponent(c)); } static public JPanel northAndCenterWithMargin(int margin, Component n, Component c) { return northAndCenter(withBottomMargin(margin, n), c); } static public JPanel northAndCenterWithMargin(Swingable n, Swingable c) { return northAndCenterWithMargin(n, toComponent(c)); } static public JPanel northAndCenterWithMargin(Swingable n, Component c) { return northAndCenterWithMargin(toComponent(n), c); } static public JPanel northAndCenterWithMargin(Component n, Swingable c) { return northAndCenterWithMargin(n, toComponent(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_minZero(Component l, Component r) { return jhsplit_minZero(l, r, 0.5); } static public JSplitPane jhsplit_minZero(Component l, Component r, double splitPoint) { return jhsplit(jMinWidth0(l), jMinWidth0(r), splitPoint); } static public JSplitPane jhsplit_minZero(double splitPoint, Component l, Component r) { return jhsplit_minZero(l, r, splitPoint); } 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 A maximizeFrame(A c) { JFrame f = swing(new F0() { public JFrame get() { try { JFrame f = getFrame(c); if (f != null) f.setExtendedState(JFrame.MAXIMIZED_BOTH); return f; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JFrame f = getFrame(c);\r\n if (f != null)\r\n f.setExtendedState(JFrame...."; } }); if (f != null && !isAWTThread()) { Dimension d = maximumWindowBounds().getSize(); long start = sysNow(); while (licensed()) { try { if (f.getWidth() >= d.getWidth() - 100 && f.getHeight() >= d.getHeight() - 100) break; if (sysNow() >= start + 100) { warn("maximizeFrame timeout"); break; } } catch (Throwable __e) { printStackTrace(__e); } sleep(1); } } return c; } static public void db() { conceptsAndBot(); } static public void db(Integer autoSaveInterval) { conceptsAndBot(autoSaveInterval); } static volatile public boolean framesBot_has = false; static public Android3 framesBot() { if (framesBot_has) return null; framesBot_has = true; Android3 android = new Android3(); android.greeting = programIDPlusHome() + " Frames."; android.console = false; android.responder = new Responder() { public String answer(String s, List history) { if (match("activate frames", s)) { swingLater(new Runnable() { public void run() { try { activateMyFrames(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "// prevent blocking when called from same program's AWT thread\r\n act..."; } }); return "OK, activating " + programName(); } return null; } }; return makeBot(android); } static public List allBackRefs(Concept c) { IdentityHashMap l = new IdentityHashMap(); if (c != null && c.backRefs != null) for (Concept.Ref r : cloneList(c.backRefs)) l.put(r.concept(), true); return keysList(l); } static public List sortedByConceptID(Collection c) { return sortedByCalculatedField(__72 -> conceptID(__72), c); } 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 JPanel jRightAlignedLine(Component... components) { return jrightAlignedLine(components); } static public JPanel jRightAlignedLine(List components) { return jrightAlignedLine(components); } static public List flattenToList(Object... l) { Flattener f = new Flattener(); f.add(l); return f.toList(); } static public JButton tableDependButton(JTable tbl, JButton b) { tableDependButtons(tbl, ll(b)); return b; } static public JButton tableDependButton(JTable tbl, String text, Object action) { return tableDependButton(tbl, jbutton(text, action)); } static public A selectedConcept(JTable table, Class cc) { return (A) getConcept(toLong(selectedTableCell(table, 0))); } static public Object withDBLock(Object r) { Lock __0 = db_mainConcepts().lock; lock(__0); try { return callF(r); } finally { unlock(__0); } } static public A withDBLock(F0 r) { return (A) withDBLock((Object) r); } static public Object withDBLock(Concepts concepts, Object r) { Lock __1 = concepts.lock; lock(__1); try { return callF(r); } finally { unlock(__1); } } static public A withDBLock(Concepts concepts, F0 r) { return (A) withDBLock(concepts, (Object) r); } static public A withDBLock(Concept concept, IF0 r) { return (A) withDBLock(concept._concepts, r); } static public class TableSearcher { public JTable table; public JTextField tfInput; public JComponent searchPanel, panel; public F2 rowTester; public List rowIndices; public String input() { return gtt(tfInput); } } static public TableSearcher tableWithSearcher2(final JTable t, Object... __) { final TableSearcher s = new TableSearcher(); final boolean precise = true; s.table = t; s.tfInput = jtextfield(); s.rowTester = new F2() { public Boolean get(String pat, Map row) { try { return anyValueContainsIgnoreCase(row, pat); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "anyValueContainsIgnoreCase(row, pat)"; } }; onUpdate(s.tfInput, new Runnable() { public List lastFiltered, lastOriginal; public void run() { String pat = s.input(); List> data = rawTableData(t); if (eq(lastFiltered, data)) data = lastOriginal; List data2 = new ArrayList(); List rowIndices = new ArrayList(); for (int i = 0; i < l(data); i++) { Map map = data.get(i); if (isTrue(callF(s.rowTester, pat, map))) { data2.add(map); rowIndices.add(i); } } lastFiltered = data2; lastOriginal = data; dataToTable(t, data2); if (precise) lastFiltered = rawTableData(t); s.rowIndices = rowIndices; } }); s.searchPanel = withLabel("Search:", s.tfInput); JComponent top = s.searchPanel; s.panel = boolOptPar(__, "withMargin") ? northAndCenterWithMargin(top, t) : northAndCenter(top, t); return s; } static public JPanel centerAndSouthWithMargin(Swingable c, Swingable s) { return centerAndSouthWithMargin(c, toComponent(s)); } static public JPanel centerAndSouthWithMargin(Swingable c, Component s) { return centerAndSouthWithMargin(toComponent(c), s); } static public JPanel centerAndSouthWithMargin(Component c, Swingable s) { return centerAndSouthWithMargin(c, toComponent(s)); } static public JPanel centerAndSouthWithMargin(Component c, Component s) { return centerAndSouth(c, withTopMargin(s)); } static public JPanel centerAndSouthWithMargin(int margin, Swingable c, Swingable s) { return centerAndSouthWithMargin(margin, c, toComponent(s)); } static public JPanel centerAndSouthWithMargin(int margin, Swingable c, Component s) { return centerAndSouthWithMargin(margin, toComponent(c), s); } static public JPanel centerAndSouthWithMargin(int margin, Component c, Swingable s) { return centerAndSouthWithMargin(margin, c, toComponent(s)); } static public JPanel centerAndSouthWithMargin(int margin, Component c, Component s) { return centerAndSouth(c, withTopMargin(margin, s)); } static public void tablePopupMenuItem(JTable table, String name, Object action) { tablePopupMenu(table, new VF2() { public void get(JPopupMenu menu, final Integer row) { try { addMenuItem(menu, name, new Runnable() { public void run() { try { pcallF(action, row); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(action, row)"; } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, name, r { pcallF(action, row) });"; } }); } static public void tablePopupMenuItem(JTable table, String name, IVF1 action) { tablePopupMenuItem(table, name, (Object) action); } static public JList onDoubleClick(final JList list, final Object runnable) { { swing(() -> { list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() == 2) { int idx = list.locationToIndex(evt.getPoint()); Object item = list.getModel().getElementAt(idx); list.setSelectedIndex(idx); callF(runnable, item); } } }); }); } return list; } static public JTable onDoubleClick(final JTable table, final Object runnable) { { swing(() -> { table.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() == 2) { int idx = table.rowAtPoint(evt.getPoint()); table.setRowSelectionInterval(idx, idx); callF(runnable, idx); } } }); }); } return table; } static public void onDoubleClick(final JComponent c, final Object runnable) { { swing(() -> { c.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getButton() == 1 && evt.getClickCount() == 2) callF(runnable, evt.getPoint()); } }); }); } } static public void tablePopupMenuFirst(JTable table, final Object menuMaker) { tablePopupMenu_first.set(true); tablePopupMenu(table, menuMaker); } static public void tablePopupMenuFirst(JTable table, IVF2 menuMaker) { tablePopupMenuFirst(table, (Object) menuMaker); } 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 A ccopyFieldsExcept(Concept x, A y, Set dontCopyFields) { if (x == null || y == null) return y; return ccopyFields2(x, y, setMinusSet(conceptFields(x), dontCopyFields)); } 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 AutoCloseable tempSetMCOpt(final String field, Object value) { final Object oldValue = getMCOpt(field); setMCOpt(field, value); return new AutoCloseable() { public String toString() { return "setMCOpt(field, oldValue);"; } public void close() throws Exception { setMCOpt(field, oldValue); } }; } 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 A replaceConceptAndUpdateRefs(Concept a, A b) { assertTrue("object to replace with must be unlisted", isUnlisted(b)); Concepts cc = a.concepts(); assertTrue("object to replace must be listed", cc != null); List refs = allBackRefObjects(a); b.id = a.id; deleteConcept(a); cc.register_phase2(b); cset(a, "meta_migratedTo", b); for (Concept.Ref ref : refs) ref.set(b); return b; } static public Class getFieldType(Object o, String field) { return fieldType(o, field); } static public Type genericFieldType(Object o, String field) { Field f = getField(o, field); return f == null ? null : f.getGenericType(); } static public Class getTypeArgumentAsClass(Type type) { if (type instanceof ParameterizedType) return typeToClass(first(((ParameterizedType) type).getActualTypeArguments())); return null; } static public JCheckBox jCenteredCheckBox() { return centerCheckBox(new JCheckBox()); } static public JCheckBox jCenteredCheckBox(boolean checked) { return centerCheckBox(new JCheckBox("", checked)); } static public JCheckBox jCenteredCheckBox(String text, boolean checked) { return centerCheckBox(new JCheckBox(text, checked)); } static public JCheckBox jCenteredCheckBox(String text) { return centerCheckBox(new JCheckBox(text)); } static public JCheckBox jCenteredCheckBox(String text, boolean checked, final Object onChange) { return centerCheckBox(jCheckBox(text, checked, onChange)); } static public JCheckBox jCenteredCheckBox(boolean checked, final Object onChange) { return centerCheckBox(jCheckBox(checked, onChange)); } static public boolean containsNewLines(String s) { return containsNewLine(s); } static public boolean isSubtype(Class a, Class b) { return isSubclass(a, b); } static public JComboBox jcomboboxFromConcepts_str(Class cc) { return jcomboboxFromConcepts_str(db_mainConcepts(), cc); } static public JComboBox jcomboboxFromConcepts_str(Concepts concepts, Class cc) { return jcomboboxFromConcepts_str(concepts, cc, null); } static public JComboBox jcomboboxFromConcepts_str(Concepts concepts, Class cc, Concept selected) { List items = ll(""); String selectedItem = null; for (Concept c : list(concepts, cc)) { String item = c.id + " - " + c; if (c == selected) selectedItem = item; items.add(item); } return jcombobox(items, selectedItem); } static public JPasswordField jpassword() { return jpassword(""); } static public JPasswordField jpassword(final String pw) { return swing(new F0() { public JPasswordField get() { try { return new JPasswordField(pw); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return new JPasswordField(pw);"; } }); } static public String strOrEmpty(Object o) { return o == null ? "" : str(o); } static public String structureOrText_crud(Object o) { if (o == null) return ""; if (o instanceof Long) return str(o); if (o instanceof File) return ((File) o).getAbsolutePath(); return str(o); } static public AutoComboBox autoComboBox() { return autoComboBox(new ArrayList()); } static public AutoComboBox autoComboBox(final Collection items) { return swing(new F0() { public AutoComboBox get() { try { AutoComboBox cb = new AutoComboBox(); cb.setKeyWord(items); return cb; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "new AutoComboBox cb;\r\n cb.setKeyWord(items);\r\n ret cb;"; } }); } static public AutoComboBox autoComboBox(String value, Collection items) { return setText(autoComboBox(items), value); } 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 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 JComponent unwrap(JComponent c) { return c instanceof JScrollPane ? unwrapScrollPane((JScrollPane) c) : c; } static public Class fieldType(Object o, String field) { Field f = getField(o, field); return f == null ? null : f.getType(); } 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 String trimIf(boolean b, String s) { return b ? trim(s) : s; } static public Object convertToField(Object o, Class c, String field) { Field f = setOpt_findField(c, field); if (f == null) return o; Class t = f.getType(); if (t == Long.class || t == long.class) return toLong(o); else if (t == Integer.class || t == int.class) return toInt(o); else if (t == Float.class || t == float.class) return toFloat(o); else if (t == Double.class || t == double.class) return toDouble(o); else if (t == String.class) return o instanceof String ? ((String) o) : str(o); else if (t == File.class) { if (o instanceof String) return new File((String) o).getAbsoluteFile(); } else if (t == Pt.class) { if (o instanceof String) return parsePt((String) o); } else if (t == GlobalID.class && o instanceof String) return new GlobalID((String) o); return o; } static public long parseFirstLong(String s) { return parseLong(jextract("", s)); } static public void cUpdatePNGFile(Concept c, String field, BufferedImage image, boolean deleteOldFile) { PNGFile png = (PNGFile) (cget(c, field)); if (image == null && png != null) cset(c, field, null); else if (image != null && (png == null || !imagesIdentical(png.getImage(), image))) { if (png != null && deleteOldFile) png.delete(); cset(c, field, new PNGFile(image)); } } static public List listWithoutSet(Collection l, Collection stuff) { return listMinusSet(l, stuff); } static public List conceptFieldsInOrder(Concept c) { return conceptFieldsInOrder(c.getClass()); } static public List conceptFieldsInOrder(Class c) { String order = toStringOpt(getOpt(c, "_fieldOrder")); Set set = asTreeSet(conceptFields(c)); if (order == null) return asList(set); List fields = listIntersectSet(splitAtSpace(order), set); setAddAll(fields, set); return fields; } static public Set joinSets(Collection... l) { Set set = similarEmptySet(first(l)); for (Collection o : l) if (o != null) set.addAll(o); return set; } static public Set setPlus(Collection l, A... more) { Set set = similarEmptySet(l); addAll(set, l); for (A a : more) set.add(a); return set; } static public List moveItemFirst(A item, Collection l) { if (!contains(l, item)) return asList(l); List out = emptyList(l(l)); out.add(item); for (A a : l) if (!eq(a, item)) out.add(a); return out; } static public List dropTypeParameter(List l) { return l; } static public Collection dropTypeParameter(Collection l) { return l; } static public List> sortClassesByNameIC(Collection> l) { return sortedByCalculatedFieldIC(__73 -> shortClassName(__73), l); } static public List> myNonAbstractClassesImplementing(Class base) { List> l = new ArrayList(); for (String name : myInnerClasses()) { Class c = _getClass(mcName() + "$" + name); if (c != null && !isAbstract(c) && isSubtypeOf(c, base)) l.add(c); } return l; } static public JComboBox setComboBoxRenderer(JComboBox cb, ListCellRenderer renderer) { if (cb != null) { swing(() -> { cb.setRenderer(renderer); }); } return cb; } static public JComboBox jTypedComboBox(Collection items) { return swing(() -> new JComboBox(toVector(items))); } static public JComboBox jTypedComboBox(Collection items, A selectedItem) { return selectItem(selectedItem, jTypedComboBox(items)); } static public ListCellRenderer customToStringListCellRenderer(IF1 toString) { return (ListCellRenderer) new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { return super.getListCellRendererComponent(list, toString.get((A) value), index, isSelected, cellHasFocus); } }; } 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 JComboBox jcombobox(final String... items) { return swing(new F0() { public JComboBox get() { try { return new JComboBox(items); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return new JComboBox(items);"; } }); } static public JComboBox jcombobox(Collection items) { return jcombobox(toStringArray(items)); } static public JComboBox jcombobox(Collection items, String selectedItem) { return selectItem(selectedItem, jcombobox(items)); } static public JPanel jhgridWithSpacing(Object... parts) { return hgridWithSpacing(parts); } static public A withToolTip(A c, final Object toolTip) { return setToolTipText(c, toolTip); } static public A withToolTip(Object toolTip, A c) { return setToolTipText(toolTip, c); } static public String gtt(JTextComponent c) { return getTextTrim(c); } static public String gtt(JComboBox cb) { return getTextTrim(cb); } static public A ccopyFields(Concept x, A y, String... fields) { if (x == null || y == null) return y; if (empty(fields)) { for (String field : conceptFields(x)) cset(y, field, cget(x, field)); } else for (String field : fields) { Object o = cget(x, field); if (o != null) cset(y, field, o); } return y; } static public boolean notNullOrEmptyString(Object o) { return o != null && !eq(o, ""); } 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 JForm showFormTitled3(String title, Object... parts) { JForm form = new JForm(parts).disposeFrameOnSubmit(); showFrame(title, form); return form; } static public boolean isSubclassOfAny(Class a, Collection b) { return any(b, x -> isSubclass(a, x)); } static public boolean isSubclassOfAny(Class a, Class... b) { return any(b, x -> isSubclass(a, x)); } static public Set createOrAddToSet(Set set, A a) { if (set == null) set = new HashSet(); set.add(a); return set; } static public Set createOrAddToSet(Set set, A... l) { for (A a : unnullForIteration(l)) set = createOrAddToSet(set, a); return set; } static public String plural(String s) { return getPlural(s); } static public String firstToLower(String s) { if (empty(s)) return s; return Character.toLowerCase(s.charAt(0)) + s.substring(1); } 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 List addOrCreate(List l, A a) { return addDyn(l, a); } static public Set addOrCreate(Set l, A a) { return createOrAddToSet(l, a); } static public JTextArea typeWriterTextArea() { return newTypeWriterTextArea(); } static public JTextArea typeWriterTextArea(String text) { return newTypeWriterTextArea(text); } 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 A firstKey(Map map) { return first(keys(map)); } static public A firstKey(IMultiMap map) { return map == null ? null : first(map.keySet()); } 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 List syncGetAndClear(Collection l) { return syncCloneAndClearList(l); } static public A getWeakRef(Reference ref) { return ref == null ? null : ref.get(); } static public void cancelAndInterruptThread(Thread t) { if (t == null) return; cancelThread(t); t.interrupt(); } 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 eqOrEqic(boolean caseInsensitive, String a, String b) { return caseInsensitive ? eqic(a, b) : eq(a, b); } 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 String assertInteger(String s) { if (!isInteger(s)) throw fail("Not an integer: " + quote(s)); return s; } static public boolean containsLineBreak(String s) { return containsNewLine(s); } 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 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 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 int rgbIntFromGrayscale(int brightness) { brightness = clampToUByte(brightness); return brightness | (brightness << 8) | (brightness << 16); } static public int rgbIntFromGrayscale(double brightness) { return rgbIntFromGrayscale(zeroToOneToZeroTo255(brightness)); } static public BufferedImage grayImageFromIBWImage(IBWImage img) { int w = img.getWidth(), h = img.getHeight(); byte[] pixels = new byte[w * h]; int i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int pixel = iround(img.getFloatPixel(x, y) * 255); pixels[i++] = clampToUByte(pixel); } return newGrayBufferedImage(w, h, pixels); } static public BWImage iBWImageToBWImage(IBWImage img) { int w = img.getWidth(), h = img.getHeight(); BWImage out = new BWImage(w, h); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) out.setPixel(x, y, img.getFloatPixel(x, y)); return out; } 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 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 List cloneKeys(Map map) { return cloneList(keys(map)); } 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 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 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 RuntimeException error() { throw new RuntimeException("fail"); } static public RuntimeException error(String msg) { throw new RuntimeException(msg); } static public String ok(Object o) { return format("ok *", o); } static public int rgbRed(int rgb) { return (rgb >> 16) & 0xFF; } static public int rgbGreen(int rgb) { return (rgb >> 8) & 0xFF; } static public int rgbBlue(int rgb) { return rgb & 0xFF; } 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 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 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 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 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[] toStringArray(Collection c) { String[] a = new String[l(c)]; Iterator it = c.iterator(); for (int i = 0; i < l(a); i++) a[i] = it.next(); return a; } static public String[] toStringArray(Object o) { if (o instanceof String[]) return (String[]) o; else if (o instanceof Collection) return toStringArray((Collection) o); else throw fail("Not a collection or array: " + getClassName(o)); } static public boolean 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(__74 -> _getClass(__74), args))); } catch (Exception __e) { throw rethrow(__e); } } 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 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 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 Object newPreciseCall_sentinel(Object o, String method, Object methodNotFoundSentinel, 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 (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 (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_sentinel(o, method, methodNotFoundSentinel, args); } catch (Exception __e) { throw rethrow(__e); } } static public A[] itemPlusArray(A a, A[] l) { return singlePlusArray(a, l); } static public Object preciseGetOrCallMethod_sentinel(Object object, String name, Object sentinel) { if (object == null) return null; if (canCallWithVarargs(object, name)) return call(object, name); Field f = getField(object, name); if (f != null) return fieldGet(f, object); return sentinel; } 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 replacePrefix(String prefix, String replacement, String s) { if (!startsWith(s, prefix)) return s; return replacement + substring(s, l(prefix)); } 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 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 IVF1 runnableToIVF1(Runnable r) { return r == null ? null : a -> r.run(); } static public void catchError(DoneFlag doneFlag, Runnable r) { try { { if (r != null) r.run(); } } catch (Throwable e) { doneFlag.setError(e); } } 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 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 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 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 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 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 public String unicode_downPointingTriangle() { return charToString(0x25BC); } 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 int getPreferredWidth(Component c) { return preferredWidth(c); } static public Type getRawType(Type t) { if (t instanceof ParameterizedType) return ((ParameterizedType) t).getRawType(); return t; } static public String formatLocalDateWithSeconds(long time) { return localDateWithSeconds(time); } static public String formatLocalDateWithSeconds() { return localDateWithSeconds(); } static public BigInteger plus(BigInteger a, BigInteger b) { return a.add(b); } static public BigInteger plus(BigInteger a, long b) { return a.add(bigint(b)); } static public long plus(long a, long b) { return a + b; } static public int plus(int a, int b) { return a + b; } static public float plus(float a, float b) { return a + b; } static public double plus(double a, double b) { return a + b; } static public long clockTimeToSystemTime(long now) { return now == 0 ? 0 : now + clockToSysTimeDiff(); } static public 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 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 void assertFalse(Object o) { if (!(eq(o, false))) throw fail(str(o)); } static public boolean assertFalse(boolean b) { if (b) throw fail("oops"); return b; } static public boolean assertFalse(String msg, boolean b) { if (b) throw fail(msg); return b; } static public String 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 String md5(String text) { try { if (text == null) return "-"; return bytesToHex(md5AsByteArray(toUtf8(text))); } catch (Exception __e) { throw rethrow(__e); } } static public String md5(byte[] data) { if (data == null) return "-"; return bytesToHex(md5AsByteArray(data)); } 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(__75 -> getRawTypeClass(__75), ((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 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 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 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 int parseDigit(char c) { return c >= '0' && c <= '9' ? c - '0' : 0; } static public int parseDigit(String s, int i) { return parseDigit(s.charAt(i)); } static public String singleDigitBytesToString(ByteBuffer l) { if (l == null) return null; int n = l.size(); char[] data = new char[n]; for (int i = 0; i < n; i++) data[i] = (char) ('0' + ubyteToInt(l.get(i)) % 10); return str(data); } static public int length(Object[] array) { return array == null ? 0 : array.length; } static public int length(List list) { return list == null ? 0 : list.size(); } static public int length(String s) { return s == null ? 0 : s.length(); } static public Pt translatePt(Pt a, Pt b) { return addPts(a, b); } static public Pt translatePt(int x, int y, Pt a) { return addPts(a, pt(x, y)); } static public Pt translatePt(Pt a, int x, int y) { return translatePt(x, y, a); } static public PtBuffer ptBuffer(Iterable l) { return new PtBuffer(l); } static final public Pt[] onePathDirections_directions = { pt(0, 0), pt(-1, -1), pt(0, -1), pt(1, -1), pt(1, 0), pt(1, 1), pt(0, 1), pt(-1, 1), pt(-1, 0) }; static public Pt[] onePathDirections() { return onePathDirections_directions; } static public int onePathLookupDirection(Pt p) { return indexOf(onePathDirections(), p); } static public void assertBetween(long a, long b, long x) { assertBetween("", a, b, x); } static public void assertBetween(String msg, long a, long b, long x) { { if (x >= a && x <= b) return; } throw fail(colonCombine(msg, x + " is not between " + a + " and " + b)); } static public void assertBetween(int a, int b, int x) { assertBetween("", a, b, x); } static public void assertBetween(String msg, int a, int b, int x) { { if (x >= a && x <= b) return; } throw fail(colonCombine(msg, x + " is not between " + a + " and " + b)); } static public Rect boundsOfPts(Iterable l) { BoundsFinder bf = new BoundsFinder(); for (var p : unnullForIteration(l)) bf.add(p); return bf.get(); } 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 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 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 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 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 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 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 void onSelectionChanged(JList list, VF1 f) { onSelectionChanged(list, toIVF1(f)); } static public void onSelectionChanged(JList list, IVF1 f) { if (list != null && f != null) { swing(() -> { list.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { pcallF(f, getSelectedItem(list)); } }); }); } } static public Map mapValues(Object func, Map map) { Map m = similarEmptyMap(map); for (Object key : keys(map)) m.put(key, callF(func, map.get(key))); return m; } static public Map mapValues(Map map, IF1 f) { return mapValues(f, map); } static public Map mapValues(IF1 f, Map map) { Map m = similarEmptyMap(map); for (Map.Entry __0 : _entrySet(map)) { A key = __0.getKey(); B val = __0.getValue(); m.put(key, f.get(val)); } return m; } static public Map mapValues(Map map, Object func) { return mapValues(func, map); } static public MultiMap mapValues(IF1 func, MultiMap mm) { return mapMultiMapValues(func, mm); } static public MultiMap mapValues(MultiMap mm, IF1 func) { return mapValues(func, mm); } static public Object renderForTable_noStruct(Object o) { { var __1 = toBufferedImageOpt(o); if (__1 != null) return __1; } if (o instanceof String && containsNewLine((String) o)) return escapeNewLines(dropTrailingNewLine((String) o)); if (o instanceof Collection) return joinWithComma((Collection) o); return strOrNull(o); } static public Map allConceptFieldsAsMapExcept(Concept c, Collection excludedFields) { Map map = new HashMap(); for (String field : unnullForIteration(listMinusSet(conceptFields(c), excludedFields))) map.put(field, cget(c, field)); return map; } static public String dynShortClassName(Object o) { return shortDynamicClassName(o); } static public boolean sexyTable_drag = false; static public JTable sexyTable() { final JTable table = sexyTableWithoutDrag(); if (sexyTable_drag) tableEnableTextDrag(table); return table; } static public JTable setTableFontSizes(float size, JTable table) { if (table == null) return null; { swing(() -> { setFontSize(table.getTableHeader(), size); setFontSize(table, size); }); } return table; } static public JTable setTableFontSizes(JTable table, float size) { return setTableFontSizes(size, table); } static public JTable setRowHeight(final int h, final JTable t) { if (t != null) { swing(() -> { t.setRowHeight(h); }); } return t; } static public JTable setRowHeight(JTable t, int h) { return setRowHeight(h, t); } static public void onTableSelectionChanged(final JTable table, final Runnable r) { { swing(() -> { table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { callF(r); } }); }); } } static public JTable onDoubleClickOrEnter(JTable table, Runnable runnable) { return onDoubleClickOrEnter(table, (Object) runnable); } static public JTable onDoubleClickOrEnter(final JTable table, Object runnable) { onDoubleClick(table, runnable); onEnter(table, runnable); return table; } static public JList onDoubleClickOrEnter(final JList list, final Object runnable) { onDoubleClick(list, runnable); onEnter(list, runnable); return list; } static public JTable onDoubleClickOrEnter(Object runnable, JTable table) { return onDoubleClickOrEnter(table, runnable); } static public Set toSet(Object[] array) { return asSet(array); } static public Set toSet(String[] array) { return asSet(array); } static public Set toSet(Iterable l) { return asSet(l); } static public Set toSet(MultiSet ms) { return asSet(ms); } static public Object[] mapToParams(Map map) { return mapToObjectArray(map); } static public A postProcess(Object f, A a) { return callPostProcessor(f, a); } static public A postProcess(IF1 f, A a) { return callPostProcessor(f, a); } 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 List reverseInPlace(List l) { return reverseList(l); } static public JTable dataToTable_uneditable(Object data, final JTable table) { return dataToTable_uneditable(table, data); } static public JTable dataToTable_uneditable(final JTable table, final Object data) { if (table != null) { swing(() -> { dataToTable(table, data, true); makeTableUneditable(table); }); } return table; } static public JTable dataToTable_uneditable(final Object data) { return dataToTable_uneditable(showTable(), data); } static public JTable dataToTable_uneditable(Object data, String title) { return dataToTable_uneditable(showTable(title), data); } static public void tableColumnMaxWidth(final JTable table, final int columnIdx, final int width) { { swing(() -> { try { if (inRange(columnIdx, table.getColumnCount())) table.getColumnModel().getColumn(columnIdx).setMaxWidth(width); } catch (Throwable __e) { printStackTrace(__e); } }); } } static public void updateEnclosingTabTitleWithCount(JComponent c, int n) { Pair p = enclosingTab(c); if (p == null) return; setTabTitle(p.a, p.b, appendBracketedCount(dropTrailingBracketedCount(getTabTitle(p.a, p.b)), n)); } static public int tableColumnCount(JTable table) { return tableNumColumns(table); } static public void setColumnName(final JTable table, final int idx, final String name) { if (table != null) { swing(() -> { if (table.getColumnCount() > idx) table.getColumnModel().getColumn(idx).setHeaderValue(name); }); } } 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 String getColumnName(final JTable table, final int idx) { return table == null ? null : swing(new F0() { public String get() { try { return table.getColumnCount() <= idx ? null : str(table.getColumnModel().getColumn(idx).getHeaderValue()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return table.getColumnCount() <= idx ? null\r\n : str(table.getColumnModel..."; } }); } static public Object selectedTableCell(JTable t, int col) { return getTableCell(t, selectedTableRow(t), col); } static public Object selectedTableCell(final JTable t) { return swing(new F0() { public Object get() { try { return selectedTableCell(t, t.getSelectedColumn()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return selectedTableCell(t, t.getSelectedColumn());"; } }); } static public Object selectedTableCell(final JTable t, final String colName) { return swing(new F0() { public Object get() { try { return selectedTableCell(t, tableColumnViewIndex(t, colName)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return selectedTableCell(t, tableColumnViewIndex(t, colName));"; } }); } static public Object getTableCell(JTable tbl, int row, int col) { if (row >= 0 && row < tbl.getModel().getRowCount()) return tbl.getModel().getValueAt(row, col); return null; } static public int tableRowCount(JTable table) { return tableRows(table); } static public void selectTableRows(final JTable table, int[] rows) { if (table != null) { swing(() -> { ListSelectionModel model = table.getSelectionModel(); int n = tableRows(table); model.clearSelection(); if (rows != null) for (int row : rows) if (row < n) model.addSelectionInterval(row, row); }); } } 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 List sortByConceptID(Collection l) { return sortConceptsByID(l); } static public Map orderedMapPutOrCreate(Map map, A key, B value) { if (key != null && value != null) { if (map == null) map = new LinkedHashMap(); map.put(key, value); } return map; } static public int toMS_int(double seconds) { return toInt_checked((long) (seconds * 1000)); } static public A printStackTrace_gen(A e) { if (e instanceof Throwable) printStackTrace((Throwable) e); else print(e); return e; } 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, ITokCondition condition, String out) { return jreplace(tok, in, out, (Object) 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 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 int lByteArray(byte[] a) { return a == null ? 0 : a.length; } static public int maximumSafeArraySize() { return Integer.MAX_VALUE - 8; } static public byte[] resizeByteArray(byte[] a, int n) { if (n == l(a)) return a; byte[] b = new byte[n]; arraycopy(a, 0, b, 0, min(l(a), n)); return b; } static public ArrayList byteArrayToList(byte[] a) { if (a == null) return null; return byteArrayToList(a, 0, a.length); } static public ArrayList byteArrayToList(byte[] a, int from, int to) { if (a == null) return null; ArrayList l = new ArrayList<>(to - from); for (int i = from; i < to; i++) l.add(a[i]); return l; } static public List asVirtualList(A[] a) { return wrapArrayAsList(a); } static public A nextToLast(List l) { return get(l, l(l) - 2); } static public String squareBracket(String s) { return "[" + s + "]"; } 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 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 A newInstance(Class c, Object... args) { return nuObject(c, args); } static public Object newInstance(String className, Object... args) { return nuObject(className, args); } 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 MultiMap descTreeMultiMap() { return new MultiMap(descTreeMap()); } 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 List scoredSearch_prepare(String query) { return map(__76 -> replacePlusWithSpace(__76), 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 public AutoCloseable onConceptChangeByClass_notOnAllChanged(Class type, Runnable r) { return onConceptChangeByClass_notOnAllChanged(db_mainConcepts(), type, r); } static public AutoCloseable onConceptChangeByClass_notOnAllChanged(Concepts cc, Class type, Runnable r) { return tempAddConceptIndex(cc, new IConceptIndex() { public void update(Concept c) { if (instanceOf(c, type)) pcallF(r); } public void remove(Concept c) { if (instanceOf(c, type)) pcallF(r); } }); } static public AutoCloseable onConceptChangeByClass_notOnAllChanged(Class type, IVF1 r) { return onConceptChangeByClass_notOnAllChanged(db_mainConcepts(), type, r); } static public AutoCloseable onConceptChangeByClass_notOnAllChanged(Concepts cc, Class type, IVF1 r) { return tempAddConceptIndex(cc, new IConceptIndex() { public void update(Concept c) { if (instanceOf(c, type)) pcallF(r, (A) c); } public void remove(Concept c) { if (instanceOf(c, type)) pcallF(r, (A) c); } }); } static public int lIntArray(int[] a) { return a == null ? 0 : a.length; } static public int[] resizeIntArray(int[] a, int n) { if (n == lIntArray(a)) return a; int[] b = new int[n]; arraycopy(a, 0, b, 0, Math.min(lIntArray(a), n)); return b; } 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 ?