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 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.util.jar.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.border.TitledBorder;
import java.nio.file.Path;
import java.text.*;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import org.fife.ui.rsyntaxtextarea.*;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.geom.*;
import javax.swing.undo.UndoManager;
import javax.swing.border.*;
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 G22PointOfInterest extends ConceptWithChangeListeners {
static final public String _fieldOrder = "imageMD5 pt bnpSettings source labelsText";
public String imageMD5;
public Pt pt;
public BlurAndPosterizeSettings bnpSettings;
public String source;
public String labelsText;
public String toString() {
return commaCombine("Point of interest " + id, labelsText);
}
public G22Utils g22utils() {
return main.g22utils(this);
}
public BufferedImage image() {
var img = galleryImage();
return img == null ? null : img.image();
}
public G22GalleryImage galleryImage() {
return g22utils().galleryImageForMD5(imageMD5);
}
public G22DataWrangler wrangler() {
G22DataWrangler wrangler = new G22DataWrangler();
wrangler.timings(g22utils().functionTimings());
wrangler.inputImage(image());
wrangler.importSettings(bnpSettings);
return wrangler;
}
public IImageRegion regionAroundPoint() {
return regionAroundPoint(wrangler());
}
public IImageRegion regionAroundPoint(G22DataWrangler wrangler) {
var rm = wrangler.regionMaker();
return rm.getRegion(rm.regionAt(pt));
}
}
static public String commaCombine(Object... l) {
return joinNemptiesWithComma(flattenCollectionsAndArrays(l));
}
static public G22Utils g22utils(Concepts cc) {
return (G22Utils) cc.miscMapGet(G22Utils.class);
}
static public G22Utils g22utils(Concept cc) {
return g22utils(concepts(cc));
}
static public String joinNemptiesWithComma(Object... strings) {
return joinNempties(", ", strings);
}
static public String joinNemptiesWithComma(Iterable strings) {
return joinNempties(", ", strings);
}
static public List flattenCollectionsAndArrays(Iterable a) {
List l = new ArrayList();
for (Object x : a) if (x instanceof Collection)
l.addAll(flattenCollectionsAndArrays((Collection) x));
else if (x instanceof Object[])
l.addAll(flattenCollectionsAndArrays(asList((Object[]) x)));
else
l.add(x);
return l;
}
static public List flattenCollectionsAndArrays(Object... whatever) {
return flattenCollectionsAndArrays(ll(whatever));
}
static public Concepts concepts(Concept c) {
return c == null ? null : c._concepts;
}
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 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 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 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 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 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 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 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 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(ShortBuffer b) {
return b == null ? 0 : b.size();
}
static public int l(IntSize o) {
return o == null ? 0 : o.size();
}
static public int[] emptyIntArray_a = new int[0];
static public int[] emptyIntArray() {
return emptyIntArray_a;
}
static public char[] emptyCharArray = new char[0];
static public char[] emptyCharArray() {
return emptyCharArray;
}
static public double[] emptyDoubleArray = new double[0];
static public double[] emptyDoubleArray() {
return emptyDoubleArray;
}
static public Map emptyMap() {
return new HashMap();
}
static public Object[] emptyObjectArray_a = new Object[0];
static public Object[] emptyObjectArray() {
return emptyObjectArray_a;
}
static public Symbol emptySymbol_value;
static public Symbol emptySymbol() {
if (emptySymbol_value == null)
emptySymbol_value = symbol("");
return emptySymbol_value;
}
static public 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 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 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 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 RuntimeException fail() {
throw new RuntimeException("fail");
}
static public RuntimeException fail(Throwable e) {
throw asRuntimeException(e);
}
static public RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static public RuntimeException fail(Object... objects) {
throw new Fail(objects);
}
static public RuntimeException fail(String msg) {
throw new RuntimeException(msg == null ? "" : msg);
}
static public RuntimeException fail(String msg, Throwable innerException) {
throw new RuntimeException(msg, innerException);
}
static public String getType(Object o) {
return getClassName(o);
}
static public long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static public long getFileSize(File f) {
return f == null ? 0 : f.length();
}
static public Iterator emptyIterator() {
return Collections.emptyIterator();
}
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 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 RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static public String getClassName(Object o) {
return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName();
}
static public void _handleError(Error e) {
}
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 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 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 image() {
return load();
}
final public BufferedImage getImage() {
return load();
}
public BufferedImage load() {
return loadImage2(path);
}
public File imageFile() {
return path;
}
}
static public class G22DataWrangler extends Stages2 implements IHasChangeListeners {
transient public Set onChange;
public G22DataWrangler onChange(Runnable r) {
onChange = createOrAddToSyncLinkedHashSet(onChange, r);
return this;
}
public G22DataWrangler removeChangeListener(Runnable r) {
main.remove(onChange, r);
return this;
}
public void change() {
if (onChange != null)
for (var listener : onChange) pcallF_typed(listener);
}
final public G22DataWrangler setInputImage(BufferedImage inputImage) {
return inputImage(inputImage);
}
public G22DataWrangler inputImage(BufferedImage inputImage) {
this.inputImage = inputImage;
return this;
}
final public BufferedImage getInputImage() {
return inputImage();
}
public BufferedImage inputImage() {
return inputImage;
}
public BufferedImage inputImage;
final public G22DataWrangler setWithDiagonals(boolean withDiagonals) {
return withDiagonals(withDiagonals);
}
public G22DataWrangler withDiagonals(boolean withDiagonals) {
this.withDiagonals = withDiagonals;
return this;
}
final public boolean getWithDiagonals() {
return withDiagonals();
}
public boolean withDiagonals() {
return withDiagonals;
}
public boolean withDiagonals = true;
public transient FieldVar varBlur_cache;
public FieldVar varBlur() {
if (varBlur_cache == null)
varBlur_cache = varBlur_load();
return varBlur_cache;
}
public FieldVar varBlur_load() {
return new FieldVar(this, "blur", () -> blur(), blur -> blur(blur));
}
final public G22DataWrangler setBlur(int blur) {
return blur(blur);
}
public G22DataWrangler blur(int blur) {
if (!eq(this.blur, blur)) {
this.blur = blur;
change();
}
return this;
}
final public int getBlur() {
return blur();
}
public int blur() {
return blur;
}
public int blur = 1;
final public G22DataWrangler setKilobytes(TargetAndActual kilobytes) {
return kilobytes(kilobytes);
}
public G22DataWrangler kilobytes(TargetAndActual kilobytes) {
this.kilobytes = kilobytes;
return this;
}
final public TargetAndActual getKilobytes() {
return kilobytes();
}
public TargetAndActual kilobytes() {
return kilobytes;
}
public TargetAndActual kilobytes = new TargetAndActual<>(250.0);
final public G22DataWrangler setCoveredPixelsPercentage(TargetAndActual coveredPixelsPercentage) {
return coveredPixelsPercentage(coveredPixelsPercentage);
}
public G22DataWrangler coveredPixelsPercentage(TargetAndActual coveredPixelsPercentage) {
this.coveredPixelsPercentage = coveredPixelsPercentage;
return this;
}
final public TargetAndActual getCoveredPixelsPercentage() {
return coveredPixelsPercentage();
}
public TargetAndActual coveredPixelsPercentage() {
return coveredPixelsPercentage;
}
public TargetAndActual coveredPixelsPercentage = new TargetAndActual();
final public G22DataWrangler setDetailLevel(TargetAndActual detailLevel) {
return detailLevel(detailLevel);
}
public G22DataWrangler detailLevel(TargetAndActual detailLevel) {
this.detailLevel = detailLevel;
return this;
}
final public TargetAndActual getDetailLevel() {
return detailLevel();
}
public TargetAndActual detailLevel() {
return detailLevel;
}
public TargetAndActual detailLevel = new TargetAndActual();
final public G22DataWrangler setVectorize(boolean vectorize) {
return vectorize(vectorize);
}
public G22DataWrangler vectorize(boolean vectorize) {
this.vectorize = vectorize;
return this;
}
final public boolean getVectorize() {
return vectorize();
}
public boolean vectorize() {
return vectorize;
}
public boolean vectorize = true;
final public G22DataWrangler setAllowPartialSSIs(boolean allowPartialSSIs) {
return allowPartialSSIs(allowPartialSSIs);
}
public G22DataWrangler allowPartialSSIs(boolean allowPartialSSIs) {
this.allowPartialSSIs = allowPartialSSIs;
return this;
}
final public boolean getAllowPartialSSIs() {
return allowPartialSSIs();
}
public boolean allowPartialSSIs() {
return allowPartialSSIs;
}
public boolean allowPartialSSIs = true;
final public G22DataWrangler setSortMode(SortMode sortMode) {
return sortMode(sortMode);
}
public G22DataWrangler sortMode(SortMode sortMode) {
this.sortMode = sortMode;
return this;
}
final public SortMode getSortMode() {
return sortMode();
}
public SortMode sortMode() {
return sortMode;
}
public SortMode sortMode = SortMode.compressibility;
public enum SortMode {
compressibility, pixels
}
final public G22DataWrangler setPosterizer(IPosterizer posterizer) {
return posterizer(posterizer);
}
public G22DataWrangler posterizer(IPosterizer posterizer) {
this.posterizer = posterizer;
return this;
}
final public IPosterizer getPosterizer() {
return posterizer();
}
public IPosterizer posterizer() {
return posterizer;
}
public IPosterizer posterizer = new SinglePixelPosterizer(4);
public BufferedImage blurredImage;
public int maxLines, maxInts;
public List extends AbstractSSI> currentSSIs;
public List initialSSIs;
public AbstractSSIList sortedSSIs, cutSSIs, vectorizedSSIs, cutVectorizedSSIs;
public CutListToBudget cutter;
public Hi15Image posterizedImage;
public FastRegions_Hi15Image regionMaker;
public List> regions;
public G22DataWrangler() {
}
public G22DataWrangler(BufferedImage inputImage) {
this.inputImage = inputImage;
}
public G22DataWrangler kb(TargetAndActual kb) {
return kilobytes(kb);
}
public TargetAndActual kb() {
return kilobytes;
}
public WidthAndHeight resolution() {
return imageSize(inputImage);
}
public double detailDivisor() {
return areaRoot(inputImage);
}
public G22DataWrangler colorsPerChannel(int perChannel) {
return posterizer(new SinglePixelPosterizer(perChannel));
}
public int colorsPerChannel() {
return ((SinglePixelPosterizer) posterizer).brightnessLevels;
}
public int colors() {
return cubed(colorsPerChannel());
}
transient public FieldVar varColorsPerChannel_cache;
public FieldVar varColorsPerChannel() {
if (varColorsPerChannel_cache == null)
varColorsPerChannel_cache = varColorsPerChannel_load();
return varColorsPerChannel_cache;
}
public FieldVar varColorsPerChannel_load() {
return new FieldVar(this, "colorsPerChannel", () -> colorsPerChannel(), __1 -> colorsPerChannel(__1));
}
transient public FieldVar varColors_cache;
public FieldVar varColors() {
if (varColors_cache == null)
varColors_cache = varColors_load();
return varColors_cache;
}
public FieldVar varColors_load() {
return new FieldVar(this, "colors", () -> colors(), __2 -> colors(__2));
}
public G22DataWrangler colors(int colors) {
int perChannel = iceil(cbrt(colors));
return colorsPerChannel(perChannel);
}
{
stage("Blur", new Runnable() {
public void run() {
try {
blurredImage = blurBufferedImage(blur, inputImage);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "blurredImage = blurBufferedImage(blur, inputImage);";
}
});
}
{
stage("Posterize", new Runnable() {
public void run() {
try {
posterizedImage = posterizeBufferedImageToHi15(blurredImage, posterizer);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "posterizedImage = posterizeBufferedImageToHi15(blurredImage, posterizer);";
}
});
}
public Stage regionsStage = stage("Regions", new Runnable() {
public void run() {
try {
regionMaker = new FastRegions_Hi15Image(posterizedImage);
regionMaker.withDiagonals(withDiagonals);
regions = regionMaker.get();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "regionMaker = new FastRegions_Hi15Image(posterizedImage);\r\n regionMaker.wi...";
}
});
{
stage("Sort regions", new Runnable() {
public void run() {
try {
regions = biggestRegionsFirst(regions);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "regions = biggestRegionsFirst(regions);";
}
});
}
{
stage("SSIs", new Runnable() {
public void run() {
try {
initialSSIs = new ArrayList();
for (var region : regions) initialSSIs.addAll(new G22_RegionToSSIs_v2(region).withDiagonals(withDiagonals).get());
currentSSIs = initialSSIs;
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "initialSSIs = new ArrayList();\r\n for (var region : regions)\r\n initial...";
}
});
}
public int initialSSILines() {
return totalSSILines(initialSSIs);
}
{
stage("Vector-Optimize", new Runnable() {
public void run() {
try {
currentSSIs = vectorizedSSIs = vectorize ? new VectorOptimizedSSIList(currentSSIs) : new GeneralSSIList(currentSSIs);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "currentSSIs = vectorizedSSIs = vectorize\r\n ? new VectorOptimizedSSIList(...";
}
});
}
{
stage("Sort SSIs", new Runnable() {
public void run() {
try {
if (sortMode == SortMode.compressibility)
sortedSSIs = new GeneralSSIList(sortedDesc(currentSSIs, (a, b) -> {
int x = cmp(a.compressibility(), b.compressibility());
if (x != 0)
return x;
return cmp(a.numberOfPixels(), b.numberOfPixels());
}));
else if (sortMode == SortMode.pixels)
sortedSSIs = new GeneralSSIList(biggestSSIsFirst(currentSSIs));
else
throw fail("Unknown sort mode");
currentSSIs = sortedSSIs;
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "if (sortMode == SortMode.compressibility)\r\n sortedSSIs = new GeneralSSIL...";
}
});
}
{
stage("Cut SSI List by detail level", new Runnable() {
public void run() {
try {
maxLines = !detailLevel.hasTarget() ? Integer.MAX_VALUE : iround(detailDivisor() * detailLevel.target());
currentSSIs = cutSSIs = new GeneralSSIList(takeFirstNSSILines(maxLines, currentSSIs));
detailLevel.set(l(cutSSIs) / detailDivisor());
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "maxLines = !detailLevel.hasTarget() ? Integer.MAX_VALUE\r\n : iround(detai...";
}
});
}
{
stage("Cut Vector-Optimized SSIs by file size", new Runnable() {
public void run() {
try {
maxInts = !kilobytes.hasTarget() ? Integer.MAX_VALUE : iround(kilobytes.target() * 512);
cutter = new CutListToBudget(ssi -> (double) ssi.sizeInInts(), maxInts, (List) currentSSIs);
if (allowPartialSSIs)
cutter.allowPartial((ssi, budget) -> ssi.reduceToInts(iround(budget)));
currentSSIs = cutVectorizedSSIs = new GeneralSSIList(cutter.get());
kilobytes.set(totalSizeInInts(cutVectorizedSSIs) / 512.0);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "maxInts = !kilobytes.hasTarget() ? Integer.MAX_VALUE\r\n : iround(kilobyte...";
}
});
}
public List> regions() {
stepUntilStage(regionsStage);
return regions;
}
public List regionsAsIBinaryImages() {
return map(__57 -> regionToIBinaryImage(__57), regions());
}
public BlurAndPosterizeSettings bnpSettings() {
return new BlurAndPosterizeSettings().blur(blur).colors(colors());
}
public void importSettings(BlurAndPosterizeSettings bnp) {
blur(bnp.blur);
colors(bnp.colors);
}
public FastRegions_Hi15Image regionMaker() {
stepUntilStage(regionsStage);
return regionMaker;
}
}
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 extends IG22LoadedDB> 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(__58 -> linesOfCode_javaTok(__58), 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(__59 -> getLabel(__59), 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 IterableIterator peekAllProjectsConcepts() {
var classFinder = masterStuff.makeClassFinder();
return mapI_pcall(gazelleDBs(), db -> {
var cc = newConceptsWithClassFinder(db.conceptsFile(), classFinder);
cc.loadFromDisk();
return cc;
});
}
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 extends AutoCloseable> 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 List list(Class type) {
return list(type, concepts());
}
public List list(Class type, Concepts cc) {
return main.list(cc, type);
}
public List list(Concepts concepts, Class type) {
return main.list(type, concepts);
}
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 "";
}
final public Collection extends IG22LoadedDB> openProjects() {
return getLoadedDBs();
}
public Collection extends IG22LoadedDB> getLoadedDBs() {
return masterStuff().openProjects();
}
public List listInOpenProjects(Class type) {
return concatMap(openProjects(), db -> db.g22utils().list(type));
}
}
static abstract public class IterableIterator implements Iterator, Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
static public class BlurAndPosterizeSettings extends MetaWithChangeListeners {
final public BlurAndPosterizeSettings setBlur(int blur) {
return blur(blur);
}
public BlurAndPosterizeSettings blur(int blur) {
this.blur = blur;
return this;
}
final public int getBlur() {
return blur();
}
public int blur() {
return blur;
}
public int blur = 0;
final public BlurAndPosterizeSettings setColors(int colors) {
return colors(colors);
}
public BlurAndPosterizeSettings colors(int colors) {
this.colors = colors;
return this;
}
final public int getColors() {
return colors();
}
public int colors() {
return colors;
}
public int colors = 64;
final public BlurAndPosterizeSettings setColorDrift(RGB colorDrift) {
return colorDrift(colorDrift);
}
public BlurAndPosterizeSettings colorDrift(RGB colorDrift) {
this.colorDrift = colorDrift;
return this;
}
final public RGB getColorDrift() {
return colorDrift();
}
public RGB colorDrift() {
return colorDrift;
}
public RGB colorDrift = noColorDrift();
static public RGB noColorDrift() {
return new RGB(0, 0, 0);
}
public BlurAndPosterizeSettings cloneMe() {
return shallowClone(this).colorDrift(colorDrift.cloneMe());
}
public String toString() {
if (eq(colorDrift, noColorDrift()))
return stdToStringWithFields(this, "blur", "colors");
else
return stdToString(this);
}
}
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 extends Concept> 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 extends Concept> c1, Class extends Concept> 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 extends Concept> type, Object func) {
for (Concept c : conceptsOfType(type)) callF(func, c);
}
public int deleteAll(Class extends Concept> 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 extends Concept> 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 extends Concept> 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 extends Concept> c, String field, IFieldIndex index) {
Map map = mapGet(fieldIndices, c);
mapRemove(map, field);
}
synchronized public IFieldIndex getFieldIndex(Class extends Concept> 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 extends Concept> c) {
return first(allIndicesForClass(c));
}
synchronized public Collection allIndicesForClass(Class extends Concept> c) {
return concatLists(values(fieldIndices == null ? null : fieldIndices.get(c)), values(ciFieldIndices == null ? null : ciFieldIndices.get(c)));
}
synchronized public void addCIFieldIndex(Class extends Concept> 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 extends Concept> c, String field) {
Map map = mapGet(ciFieldIndices, c);
mapRemove(map, field);
}
synchronized public IFieldIndex getCIFieldIndex(Class extends Concept> 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 extends String, ? extends FieldMigration> __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;
}
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 interface Hasher {
public int hashCode(A a);
public boolean equals(A a, A b);
}
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 super K> 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 super K> q) {
super(k, q);
hash = keyHashCode(k);
}
private WeakKey create(K k, ReferenceQueue super K> 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 super K> 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 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);
}
}
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 public class Hi15Image extends WAndHImpl implements MakesBufferedImage {
public short[] pixels;
public Hi15Image() {
}
public Hi15Image(int w, int h, short[] pixels) {
this.pixels = pixels;
this.h = h;
this.w = w;
}
public Hi15Image(BufferedImage img) {
this(new RGBImage(img));
}
public Hi15Image(RGBImage img) {
w = img.getWidth();
h = img.getHeight();
pixels = new short[w * h];
for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) pixels[y * w + x] = rgbIntToHi15(img.getInt(x, y));
}
public Hi15Image(MakesBufferedImage img) {
this(toBufferedImage(img));
}
public RGBImage toRGB() {
RGBImage img = new RGBImage(w, h);
int i = 0, w = this.w, h = this.h;
for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) img.setPixel(x, y, hi15ToRGBInt(pixels[i++]));
return img;
}
public BufferedImage getBufferedImage() {
return toRGB().getBufferedImage();
}
final public short getHi15Color(int x, int y) {
return getHi15Pixel(x, y);
}
public short getHi15Pixel(int x, int y) {
return pixels[y * w + x];
}
public short getHi15Pixel_noRangeCheck(int idx) {
return pixels[idx];
}
static public int perChannelBitCountMask(int bitCount) {
int mask = ((~0x1F) >> bitCount) & 0x1F;
int mask2 = (mask << 10) | (mask << 5) | mask;
return mask2;
}
public void reducePerChannelBitCount(int bitCount) {
if (bitCount >= 5)
return;
int mask = perChannelBitCountMask(bitCount);
short[] pixels = this.pixels;
for (int i = 0; i < pixels.length; i++) pixels[i] = (short) (pixels[i] & mask);
}
public void reduceColorCount(int numColors) {
assertPowerOfTwo(numColors);
int bits = dualLog(numColors);
assertDivisibleBy(3, bits);
int bitsPerChannel = bits / 3;
reducePerChannelBitCount(bitsPerChannel);
}
}
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 CutListToBudget {
final public CutListToBudget setMaxPrice(double maxPrice) {
return maxPrice(maxPrice);
}
public CutListToBudget maxPrice(double maxPrice) {
this.maxPrice = maxPrice;
return this;
}
final public double getMaxPrice() {
return maxPrice();
}
public double maxPrice() {
return maxPrice;
}
public double maxPrice;
final public CutListToBudget setInputList(Iterable inputList) {
return inputList(inputList);
}
public CutListToBudget inputList(Iterable inputList) {
this.inputList = inputList;
return this;
}
final public Iterable getInputList() {
return inputList();
}
public Iterable inputList() {
return inputList;
}
public Iterable inputList;
final public List getOutputList() {
return outputList();
}
public List outputList() {
return outputList;
}
public List outputList;
final public double getFinalPrice() {
return finalPrice();
}
public double finalPrice() {
return finalPrice;
}
public double finalPrice;
final public CutListToBudget setAllowPartial(boolean allowPartial) {
return allowPartial(allowPartial);
}
public CutListToBudget allowPartial(boolean allowPartial) {
this.allowPartial = allowPartial;
return this;
}
final public boolean getAllowPartial() {
return allowPartial();
}
public boolean allowPartial() {
return allowPartial;
}
public boolean allowPartial = false;
final public A getFullLastElement() {
return fullLastElement();
}
public A fullLastElement() {
return fullLastElement;
}
public A fullLastElement;
transient public IF1 getPrice;
public double getPrice(A element) {
return getPrice != null ? getPrice.get(element) : getPrice_base(element);
}
final public double getPrice_fallback(IF1 _f, A element) {
return _f != null ? _f.get(element) : getPrice_base(element);
}
public double getPrice_base(A element) {
throw unimplemented();
}
transient public IF2 reduceElement;
public A reduceElement(A element, double budget) {
return reduceElement != null ? reduceElement.get(element, budget) : reduceElement_base(element, budget);
}
final public A reduceElement_fallback(IF2 _f, A element, double budget) {
return _f != null ? _f.get(element, budget) : reduceElement_base(element, budget);
}
public A reduceElement_base(A element, double budget) {
return null;
}
public CutListToBudget(IF1 getPrice) {
this.getPrice = getPrice;
}
public CutListToBudget(IF1 getPrice, double maxPrice, Iterable inputList) {
this.inputList = inputList;
this.maxPrice = maxPrice;
this.getPrice = getPrice;
}
public void run() {
try {
outputList = new ArrayList();
finalPrice = 0;
for (var element : unnullForIteration(inputList)) {
double price = getPrice(element);
if (finalPrice + price > maxPrice) {
if (allowPartial) {
A partial = reduceElement(element, maxPrice - finalPrice);
if (partial != null) {
fullLastElement = element;
finalPrice += getPrice(partial);
outputList.add(partial);
if (finalPrice > maxPrice)
throw fail("reduceElement failure (over budget)");
}
}
break;
}
finalPrice += price;
outputList.add(element);
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
public List get() {
if (outputList == null)
run();
return outputList;
}
public CutListToBudget allowPartial(IF2 reduceElement) {
this.reduceElement = reduceElement;
return allowPartial(true);
}
public A lastElement() {
return last(get());
}
public Percent lastElementKeptPercentage() {
return fullLastElement == null ? null : new Percent(getPrice(lastElement()) / getPrice(fullLastElement) * 100);
}
}
static public class GeneralSSIList extends AbstractSSIList {
public GeneralSSIList() {
init();
}
public GeneralSSIList(Collection extends AbstractSSI> l) {
super(l);
}
@Override
public AbstractSSI importSSI(AbstractSSI ssi) {
return ssi;
}
}
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 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 CombinedStringifier implements IStringifier {
public CopyOnWriteArrayList> stringifiers = new CopyOnWriteArrayList();
public IStringifier defaultStringifier = new Stringifier_ToString();
public CombinedStringifier(IPartialStringifier... stringifiers) {
addAll(this.stringifiers, stringifiers);
}
public String toString(A o) {
for (var stringifier : stringifiers) {
String s = stringifier.toStringOpt(o);
if (s != null)
return s;
}
return defaultStringifier.toString(o);
}
public String toString() {
return formatFunctionCall("CombinedStringifier", listPlus((List) stringifiers, defaultStringifier));
}
}
static public class SinglePixelPosterizer implements IPosterizer {
public int brightnessLevels;
public double factor1, factor2;
public SinglePixelPosterizer(int brightnessLevels) {
this.brightnessLevels = brightnessLevels;
factor1 = doubleRatio(brightnessLevels, 256);
factor2 = doubleRatio(255, brightnessLevels - 1);
}
public int get(int brightness) {
return iround(ifloor(brightness * factor1) * factor2);
}
}
static public class FastRegions_Hi15Image extends AbstractFastRegions {
public int getColor(int pos) {
return image.getHi15Pixel_noRangeCheck(pos);
}
public RGB rgbForRegion(ImageRegion r) {
return hi15ToRGB((short) r.firstPixelLogicalColor());
}
public FastRegions_Hi15Image(Hi15Image img) {
super(img);
}
public FastRegions_Hi15Image(BufferedImage img) {
this(new Hi15Image(img));
}
}
static public class G22_RegionToSSIs_v2 extends Meta implements IFieldsToList {
public IImageRegion region;
public G22_RegionToSSIs_v2() {
}
public G22_RegionToSSIs_v2(IImageRegion region) {
this.region = region;
}
public String toString() {
return shortClassName_dropNumberPrefix(this) + "(" + region + ")";
}
public Object[] _fieldsToList() {
return new Object[] { region };
}
public Color color;
public List ssis;
public List growingSSIs = new ArrayList();
final public G22_RegionToSSIs_v2 setWithDiagonals(boolean withDiagonals) {
return withDiagonals(withDiagonals);
}
public G22_RegionToSSIs_v2 withDiagonals(boolean withDiagonals) {
this.withDiagonals = withDiagonals;
return this;
}
final public boolean getWithDiagonals() {
return withDiagonals();
}
public boolean withDiagonals() {
return withDiagonals;
}
public boolean withDiagonals = false;
final public G22_RegionToSSIs_v2 setCheckCoherence(boolean checkCoherence) {
return checkCoherence(checkCoherence);
}
public G22_RegionToSSIs_v2 checkCoherence(boolean checkCoherence) {
this.checkCoherence = checkCoherence;
return this;
}
final public boolean getCheckCoherence() {
return checkCoherence();
}
public boolean checkCoherence() {
return checkCoherence;
}
public boolean checkCoherence = true;
final public G22_RegionToSSIs_v2 setCheckStreaks(boolean checkStreaks) {
return checkStreaks(checkStreaks);
}
public G22_RegionToSSIs_v2 checkStreaks(boolean checkStreaks) {
this.checkStreaks = checkStreaks;
return this;
}
final public boolean getCheckStreaks() {
return checkStreaks();
}
public boolean checkStreaks() {
return checkStreaks;
}
public boolean checkStreaks = true;
public int x1, y;
public class GrowingSSI {
final public GrowingSSI setY1(int y1) {
return y1(y1);
}
public GrowingSSI y1(int y1) {
this.y1 = y1;
return this;
}
final public int getY1() {
return y1();
}
public int y1() {
return y1;
}
public int y1;
public ShortBuffer data = new ShortBuffer();
public int y2() {
return y1 + l(data) / 2;
}
public SSI finish() {
return addAndReturn(ssis, new SSI(y1, y2()).data(data.toArray()).color(color));
}
public boolean isEmpty() {
return data.isEmpty();
}
public int lastx1() {
return data.get(l(data) - 2);
}
public int lastx2() {
return data.get(l(data) - 1);
}
public IntRange lastRange() {
return isEmpty() ? null : intRange(lastx1(), lastx2());
}
public boolean canAdd(IntRange r) {
return isEmpty() || intRangesOverlapNempty(r.start, r.end, lastx1() - diag(), lastx2() + diag());
}
public void add(IntRange r) {
if (checkCoherence() && !canAdd(r))
throw fail("Coherence fail", "lastx1", lastx1(), "lastx2", lastx2(), "r", r);
data.add(toShort_enforce(r.start));
data.add(toShort_enforce(r.end));
}
}
public void finishSSI(int iSSI) {
growingSSIs.remove(iSSI).finish();
}
private GrowingSSI startSSI(IntRange range) {
return startSSI(l(growingSSIs), range);
}
private GrowingSSI startSSI(int iSSI, IntRange range) {
if (scaffoldingEnabled())
printVars("startSSI", "iSSI", iSSI, "range", range);
var ssi = new GrowingSSI().y1(y);
ssi.add(range);
return addAndReturn(growingSSIs, iSSI, ssi);
}
public List lastStreaks() {
return reallyLazyMap(growingSSIs, __1 -> __1.lastRange());
}
public int diag() {
return withDiagonals ? 1 : 0;
}
public List get() {
if (region == null)
return null;
color = region.color();
ssis = new ArrayList();
Rect r = region.bounds();
int x1 = this.x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2 - y1, w = r.w;
boolean scaff = scaffoldingEnabled();
for (y = y1; y < y2; y++) {
var _y_2 = y;
List streaks = shiftIntRanges(x1, genericStreaks(w, x -> region.contains(x1 + x, _y_2)));
var lastStreaks = lastStreaks();
if (checkStreaks())
assertProperStreaks(lastStreaks);
int iStreak = 0, iSSI = 0;
int nStreaks = l(streaks);
if (scaff)
printVars("y", _y_2, "lastStreaks", lastStreaks, "streaks", streaks);
while (iStreak < nStreaks) {
ping();
var range = streaks.get(iStreak);
var ssi = _get(growingSSIs, iSSI);
if (scaff)
printVars("y", _y_2, "iStreak", iStreak, "iSSI", iSSI, "range", range, "ssi", ssi == null ? null : ssi.lastRange());
if (ssi == null || range.end <= ssi.lastx1() - diag()) {
startSSI(iSSI++, range);
++iStreak;
continue;
}
if (range.start >= ssi.lastx2() + diag()) {
finishSSI(iSSI);
continue;
}
int jStreak = iStreak + 1;
while (jStreak < nStreaks && ssi.canAdd(streaks.get(jStreak))) ++jStreak;
int jSSI = iSSI + 1;
while (jSSI < l(growingSSIs) && growingSSIs.get(jSSI).canAdd(range)) ++jSSI;
int nSSI = jSSI - iSSI, nStreak = jStreak - iStreak;
if (scaff)
printVars("nSSI", nSSI, "nStreak", nStreak);
Best best = new Best();
if (nSSI > 1) {
if (nStreak > 1)
throw fail("ANOMALY", "nSSI", nSSI, "nStreak", nStreak, "ssis", subList(lastStreaks(), iSSI, jSSI), "streaks", subList(streaks, iStreak, jStreak));
for (int idx = iSSI; idx < jSSI; idx++) best.put(idx, l(growingSSIs.get(idx).lastRange()));
jSSI = best.get();
while (jSSI-- > iSSI) finishSSI(iSSI);
} else if (nStreak > 1) {
for (int idx = iStreak; idx < jStreak; idx++) best.put(idx, l(streaks.get(idx)));
jStreak = best.get();
while (iStreak < jStreak) startSSI(iSSI++, streaks.get(iStreak++));
}
growingSSIs.get(iSSI++).add(streaks.get(iStreak++));
}
while (iSSI < l(growingSSIs)) finishSSI(iSSI);
}
for (var ssi : cloneAndClear(growingSSIs)) ssi.finish();
return ssis;
}
}
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);
}
}
static public class TargetAndActual extends MetaWithChangeListeners {
public TargetAndActual() {
}
public transient FieldVar varTarget_cache;
public FieldVar varTarget() {
if (varTarget_cache == null)
varTarget_cache = varTarget_load();
return varTarget_cache;
}
public FieldVar varTarget_load() {
return new FieldVar(this, "target", () -> target(), target -> target(target));
}
final public TargetAndActual setTarget(A target) {
return target(target);
}
public TargetAndActual target(A target) {
if (!eq(this.target, target)) {
this.target = target;
change();
}
return this;
}
final public A getTarget() {
return target();
}
public A target() {
return target;
}
public A target;
public transient FieldVar varActual_cache;
public FieldVar varActual() {
if (varActual_cache == null)
varActual_cache = varActual_load();
return varActual_cache;
}
public FieldVar varActual_load() {
return new FieldVar(this, "actual", () -> actual(), actual -> actual(actual));
}
final public TargetAndActual setActual(A actual) {
return actual(actual);
}
public TargetAndActual actual(A actual) {
if (!eq(this.actual, actual)) {
this.actual = actual;
change();
}
return this;
}
final public A getActual() {
return actual();
}
public A actual() {
return actual;
}
public A actual;
public TargetAndActual(A target, A actual) {
this.actual = actual;
this.target = target;
}
public TargetAndActual(A target) {
this.target = target;
}
public String toString() {
return commaCombine(target == null ? null : "Target: " + target, actual == null ? null : "Actual: " + actual);
}
final public A get() {
return value();
}
public A value() {
return actual;
}
public boolean hasTarget() {
return target != null;
}
final public void value(A actual) {
set(actual);
}
public void set(A actual) {
actual(actual);
}
}
static public class FieldVar extends VarWithNotify {
public IHasChangeListeners containingObject;
public String fieldName;
public IF0 getter;
public IVF1 setter;
public FieldVar(IHasChangeListeners containingObject, String fieldName, IF0 getter, IVF1 setter) {
this.setter = setter;
this.getter = getter;
this.fieldName = fieldName;
this.containingObject = containingObject;
containingObject.onChangeAndNow(() -> _updateFromObject());
}
public void _updateFromObject() {
set(getter.get());
}
public void fireChange() {
setter.get(get());
super.fireChange();
}
public FieldVar onChange(IVF1 r) {
if (r != null)
onChange(() -> r.get(get()));
return this;
}
}
static public class Stage implements Runnable {
public String name;
public boolean done = false;
public Object result;
public PersistableThrowable error;
public IF0 code;
static public String _fieldOrder = "name done result";
public Stage() {
}
public Stage(String name) {
this.name = name;
}
public Stage(String name, IF0 code) {
this.code = code;
this.name = name;
}
transient public Set onComputed;
public Stage onComputed(Runnable r) {
onComputed = createOrAddToSyncLinkedHashSet(onComputed, r);
return this;
}
public Stage removeComputedListener(Runnable r) {
main.remove(onComputed, r);
return this;
}
public void computed() {
if (onComputed != null)
for (var listener : onComputed) pcallF_typed(listener);
}
public void run() {
try {
if (done || code == null)
return;
try {
result = code.get();
computed();
} catch (Throwable e) {
printStackTrace(e);
error = persistableThrowable(e);
} finally {
done = true;
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
}
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 interface IRef extends IF0 {
public default void replaceValue(A oldValue, A newValue) {
}
}
static public class VectorOptimizedSSIList extends AbstractSSIList {
public VectorOptimizedSSIList() {
init();
}
public VectorOptimizedSSIList(Collection extends AbstractSSI> l) {
super(l);
}
static public VectorOptimizedSSIList alreadyOptimized(List l) {
VectorOptimizedSSIList list = new VectorOptimizedSSIList();
list.addAll(l);
return list;
}
@Override
public AbstractSSI importSSI(AbstractSSI ssi) {
return vectorizeSSIIfBeneficial(ssi.toSSI());
}
}
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 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]