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 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 javax.imageio.*; import java.math.*; import javax.swing.border.TitledBorder; import javax.swing.border.*; import java.awt.datatransfer.StringSelection; import java.text.NumberFormat; import javax.swing.undo.UndoManager; import javax.net.ssl.*; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import javax.imageio.metadata.*; import javax.imageio.stream.*; import java.awt.geom.*; import net.coobird.thumbnailator.Thumbnailator; import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.DataFlavor; import javax.swing.event.AncestorListener; import javax.swing.event.AncestorEvent; import javax.swing.Timer; import java.awt.datatransfer.UnsupportedFlavorException; class main { abstract static class ChessOCR_DynChessBoardRecognizer extends DynModule { String segmenterPreset; transient Iterator>> segmenters; List segments; Rect boardLocation; double recognitionScore; String status; String selectedSquare; String piece; List> recognized; String fen; static boolean _switchableField_showSelectedSquare = true; boolean showSelectedSquare = true; static boolean _switchableField_showSegmenterSection = true; boolean showSegmenterSection = true; static boolean _switchableField_squareHeightAtBottom = true; boolean squareHeightAtBottom = true; // for YouTube videos transient int recreatedSquareSize = 32; transient ReliableSingleThread rst = dm_rst(module(), new Runnable() { public void run() { try { recognize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "recognize();"; }}); transient BufferedImage img, board, square, recreated; transient List> squareImages; transient ImageSurface isInput, isBoard, isSquare, isRecreated; transient List pieces = ai_chessPieces(); transient Map> recreateStock; // false = dark, true = light public JComponent visualize() { isBoard = jImageSurface(); imageSurfaceOnHover(isBoard, new VF1() { public void get(Pt p) { try { if (board == null || p == null) { noToolTip(isBoard); return; } setToolTip(isBoard, toolTipForSquare(boardPointToSquare(p))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (board == null || p == null) ret with noToolTip(isBoard);\r\n setToolTi..."; }}); imageSurfaceOnLeftClick(isBoard, new VF1() { public void get(Pt p) { try { selectSquare(boardPointToSquare(p)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectSquare(boardPointToSquare(p))"; }}); isRecreated = jImageSurface(recreated); imageSurfaceOnHover(isRecreated, new VF1() { public void get(Pt p) { try { if (recreated == null || p == null) { noToolTip(isRecreated); return; } setToolTip(isRecreated, toolTipForSquare(recreatedPointToSquare(p))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (recreated == null || p == null) ret with noToolTip(isRecreated);\r\n s..."; }}); imageSurfaceOnLeftClick(isRecreated, new VF1() { public void get(Pt p) { try { selectSquare(recreatedPointToSquare(p)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectSquare(recreatedPointToSquare(p))"; }}); isInput = jImageSurface(or_func(img, () -> whiteImage(100))); isInput.onNewImage = rst; isInput.zoomToWindow(); JComponent recreatedSection = jCenteredSection("Recreated", jscroll_center(isRecreated)), boardSection = jCenteredSection("Chess board in image", centerAndSouthWithMargin(jscroll_center(isBoard), dm_centeredCalculatedLabel(() -> "Recognition score: " + formatDouble(recognitionScore, 2)) )); JButton btnScreenshot = jbutton("Grab screenshot & recognize", runnableThread(new Runnable() { public void run() { try { grabScreenshot(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "grabScreenshot();"; }})); JButton popDownButton = jPopDownButton_noText( "Show possible chess boards found", runnableThread(new Runnable() { public void run() { try { showSegments(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showSegments();"; }}), "Publish training image...", runnableThread(new Runnable() { public void run() { try { publishImage(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "publishImage();"; }})); return withCalc(rst, jvsplit( jCenteredSection("Input image", jscroll_center(isInput)), northCenterAndSouthWithMargins( !showSegmenterSection ? centeredLine(btnScreenshot, popDownButton) : westCenterAndEastWithMargin( btnScreenshot, segmenterSection(), hstackWithSpacing( jbutton("Recognize", rst), popDownButton )), (!showSelectedSquare ? hgridWithSpacing(boardSection, recreatedSection) : hgridWithSpacing( recreatedSection, boardSection, jCenteredLiveValueSection(dm_calculatedLiveValue(String.class, () -> "Selected square" + (empty(selectedSquare) ? "" : " (" + selectedSquare + ")")), centerAndSouthWithMargin( jscroll_center(isSquare = jImageSurface(square)), rightAlignedLine( withLabel("Piece: ", dm_comboBox("piece", pieces)), jbutton("Save & upload", runnableThread(new Runnable() { public void run() { try { saveAndUploadPiece(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveAndUploadPiece();"; }}))) )))), vstackWithSpacing( dm_label("status"), rightAlignedLine(withLabel("FEN (chess position):", dm_calculatedBoldLabel(() -> or2(fen, "[Calculating...]"))), jbutton("Copy", runnableThread(new Runnable() { public void run() { try { copyFEN(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyFEN();"; }}))) ) ))); } void recognize() { status("Recognizing..."); segmenters = makeSegmenters(); if (empty(segmenters)) { infoBox(status("No segmenter")); return; } //img = dm_shootScreenHidingOS(); if (isInput != null) img = isInput.getImage(); ChessPieceRecognizer pieceRecognizer = chessOCR_pieceRecognizer(); ChessOCR_TwoStageRecognizer rec = new ChessOCR_TwoStageRecognizer(pieceRecognizer, img, segmenters); rec.verbose(true); clearImageSurfaces(isBoard, isRecreated); setField("fen" , ""); boolean done = false; Var lastLocation = new Var(); while (!done && !rst.triggered()) { done = !rec.step(); Rect r = rec.bestBoardLocation(); if (r != null) rec.tryRect(print("wiggling", wiggleRect(r))); r = rec.bestBoardLocation(); if (r != null && setVar_trueIfChanged(lastLocation, r)) newBestLocation(r, pieceRecognizer); } if (done && !lastLocation.has()) status("No chess board found"); } String status(String status) { setField("status", status); return status; } Object _getReloadData() { return img; } void _setReloadData(BufferedImage img) { this.img = img; } void setImage(BufferedImage img) { this.img = img; if (isInput != null) isInput.setImageAndZoomToDisplay(img); rst.trigger(); } String boardPointToSquare(Pt p) { double space = imageMergeSpacing(); double squareW = board.getWidth()/8.0+space; double squareH = board.getHeight()/8.0+space; int x = clamp(iratio_floor(p.x+space/2, squareW), 0, 7); int y = clamp(iratio_floor(p.y+space/2, squareH), 0, 7); return strCharPlus('A', x) + (8-y); } String recreatedPointToSquare(Pt p) { int x = clamp(iratio_floor(p.x, recreatedSquareSize), 0, 7); int y = clamp(iratio_floor(p.y, recreatedSquareSize), 0, 7); return strCharPlus('A', x) + (8-y); } void saveAndUploadPiece() { AutoCloseable __0 = enter(); try { if (square == null || empty(piece)) return; chessOCR_uploadPieceImage(selectedSquare, piece, square); if (mapGet(mapGet(recreateStock, chess_isLightSquare(selectedSquare)), piece) == null) recreateStock = null; rst.trigger(); } finally { _close(__0); }} void recreate() { if (recognized == null) return; if (recreateStock == null) recreateStock = mapToValues(ll(false, true), light -> mapValues(pairsToMap(reversePairs(chessPieceImagesFromAGIBlue(light))), imageID -> resizeImage(loadImage2(imageID), recreatedSquareSize, recreatedSquareSize))); List out = new ArrayList(); int i = 0; for (String piece : pairsA(recognized)) { boolean light = even(i/8+i%8); out.add(or_func(mapGet(mapGet(recreateStock, light), piece), () -> whiteImage(recreatedSquareSize, recreatedSquareSize))); ++i; } List rows = new ArrayList(); for (List row : listToChunks(out, 8)) rows.add(mergeBufferedImagesHorizontally(row, "spacing" , 0)); recreated = mergeBufferedImagesVertically(rows, "spacing" , 0); if (isRecreated != null) isRecreated.setImageAndZoomToDisplay(recreated); } Pair recognitionForSquare(String square) { int x; int y ; Pair __4= chess_squareToPos(square); x = __4.a; y = __4.b; return _get(recognized, y*8+x); } String toolTipForSquare(String square) { Pair rec = recognitionForSquare(square); return square + " - " + (rec == null ? "?" : rec.a + " [" + iround(clamp(rec.b, 0, 100)) + "%]"); } void selectSquare(String _square) { setField("selectedSquare" , _square); String rec = pairA(recognitionForSquare(selectedSquare)); if (rec != null) setField("piece" , rec); int x; int y ; Pair __5= chess_squareToPos(selectedSquare); x = __5.a; y = __5.b; square = _get(_get(squareImages, y), x); ChessPieceProfile1 profile = chessOCR_pieceProfileFromRawImage_1(square, "withPreprocessedImages" , true); isSquare.setImage(mergeBufferedImagesHorizontally( itemPlusList(square, map("toBufferedImage",profile.preprocessedImages)))); //printVars_str("leftClick", +p, +selectedSquare, +x, +y, +square); } void showSegments() { List segments = this.segments; showImage_centered(n2(segments, "segment") + " found", mergeBufferedImagesVertically(map(segments, r -> clipBufferedImage(img, r)))); } void publishImage() { AutoCloseable __1 = enter(); try { BufferedImage img = this.img; String segmenterPreset = this.segmenterPreset; JCheckBox cbFound = jcheckbox(true), cbHasBoard = jcheckbox(true); JTextField tfFEN = jtextfield(fen), tfComments = jtextfield(), tfImageCredits = jtextfield(); showFormTitled("Publish training image", "Image", jImageSurface(scaleImageToWidth(img, 500)), "Segmenter used", jlabel(segmenterPreset), "Is there a chess board in the image?", cbHasBoard, "FEN (empty if no board in image)", tfFEN, "Was the chess board found?", cbFound, // TODO: make clearer what this means if there is no board in image "Image credits (optional)", tfImageCredits, "Random comments", tfComments, "NOTE:", jMultiLineLabel("By clicking 'publish', you PUBLISH this image (fair use/public domain)."), "", jThreadedButton("Publish", new Runnable() { public void run() { try { AutoCloseable __2 = tempInfoBox_noHide("Uploading training image..."); try { String imageURL = uploadToImageServer("Chess board recognition training image", img); String desc = "Chess board recognition training image " + assertNempty("Parseable image URL", parseSnippetImageURL(imageURL)); LinkedHashMap map = new LinkedHashMap(); map.put("Input image", imageURL); mapPutIfNemptyValue(map, "Image credits", gtt(tfImageCredits)); String fen = gtt(tfFEN); map.put("Image has chess board", yesNo_short_firstUpper(isChecked(cbHasBoard) || nempty(fen))); mapPutIfNemptyValue(map, "FEN", fen); map.put("Segmenter used", segmenterPreset); map.put("Chess board found", yesNo_short_firstUpper(isChecked(cbFound))); if (isChecked(cbFound)) map.put("Board location", struct(boardLocation)); String sliceID = agiBlue_chessBoardRecognitionTrainingImagesSliceID(); List toPost = new ArrayList(); String name = agiBlue_createUnusedNumberedPage(sliceID, desc + " #"); for (String key : keys( map)) { String value = map.get(key); toPost.add(litmap("q" , name, "key", key, "value", value)); } agiBot_postMulti(keyPairForProgram(), toPost, "slice" , sliceID); infoBox("Training image uploaded!"); openURLInBrowser(agiBlue_linkForPhrase(name, "slice" , sliceID)); disposeWindow(heldButton()); } finally { _close(__2); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __2 = tempInfoBox_noHide(\"Uploading training image...\"); try {\r..."; }}) ); } finally { _close(__1); }} String makeFEN() { return chess_makeFEN(listToChunks(pairsA(recognized), 8)); } void newBestLocation(Rect r, ChessPieceRecognizer pieceRecognizer) { setField("segments" , singletonUnlessNull(r)); boolean corrected = squareHeightAtBottom && abs(r.w-r.h) > 3; if (corrected) r.h = r.w; List comments = new ArrayList(); if (corrected) comments.add("height-corrected"); status("Chess board found at: " + r + appendRoundBracketed(joinWithComma(comments))); setField("boardLocation" , r); board = clipBufferedImage(img, r); squareImages = bufferedImageMNGrid(board, 8, 8); if (isBoard != null) isBoard.setImageAndZoomToDisplay( mergeBufferedImagesVertically( map(bufferedImageNVerticalSlices(8, board), i -> mergeBufferedImagesHorizontally(bufferedImageNHorizontalSlices(8, i))))); recognized = new ArrayList(); for (BufferedImage img : concatLists(squareImages)) recognized.add(pieceRecognizer.recognize(img)); setField("recognitionScore" , doubleAvg(pairsB(recognized))); setField("fen" , makeFEN()); print(recognized); recreate(); } Rect wiggleRect(Rect r) { if (r == null) return null; int range = 1; return intersectRects(imageRect(img), rectFromPoints(varyInt(range, r.x), varyInt(range, r.y), varyInt(range, r.x2()), varyInt(range, r.y2()))); } void copyFEN() { if (empty(fen)) return; copyToClipboard(fen); infoBox("FEN copied to clipboard"); } void grabScreenshot() { isInput.setImageAndZoomToDisplay(dm_shootScreenHidingOS()); rst.trigger(); } abstract JComponent segmenterSection(); abstract Iterator>> makeSegmenters(); } static BufferedImage toBufferedImage(Object o) { return toBufferedImageOpt(o); } static ReliableSingleThread dm_rst(Runnable r) { return dm_rst(dm_current_mandatory(), r); } static ReliableSingleThread dm_rst(DynModule mod, Runnable r) { return dm_rst(mod, new ReliableSingleThread(r)); } static ReliableSingleThread dm_rst(DynModule mod, ReliableSingleThread rst) { rst.enter = dm_rEnter(mod); return rst; } static RuntimeException rethrow(Throwable t) { if (t instanceof Error) _handleError((Error) t); throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static RuntimeException rethrow(String msg, Throwable t) { throw new RuntimeException(msg, t); } static List ai_chessPieces_cache; static List ai_chessPieces() { if (ai_chessPieces_cache == null) ai_chessPieces_cache = ai_chessPieces_load(); return ai_chessPieces_cache; } static List ai_chessPieces_load() { return tlft("\r\n empty\r\n white king\r\n black king\r\n white queen\r\n black queen\r\n white rook\r\n black rook\r\n white bishop\r\n black bishop\r\n white knight\r\n black knight\r\n white pawn\r\n black pawn\r\n "); } static ImageSurface jImageSurface() { return swingNu(ImageSurface.class); } // for BWImage static ImageSurface jImageSurface(MakesBufferedImage img) { return swingNu(ImageSurface.class, img.getBufferedImage()); } static ImageSurface jImageSurface(BufferedImage img) { return swingNu(ImageSurface.class, img); } // onHover is called with null value when mouse moves outside of image surface // onHover receives image coordinates static void imageSurfaceOnHover(ImageSurface is, VF1 onHover) { if (is == null || onHover == null) return; { swing(new Runnable() { public void run() { try { MouseAdapter ma = new MouseAdapter() { public void mouseMoved(MouseEvent e) { pick(e); } public void mouseEntered(MouseEvent e) { pick(e); } public void mouseExited(MouseEvent e) { pick(null); } void pick(MouseEvent e) { callF(onHover, e == null ? (Pt) null : is.pointFromEvent(e)); } }; is.addMouseMotionListener(ma); is.addMouseListener(ma); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "MouseAdapter ma = new MouseAdapter {\r\n public void mouseMoved(MouseEvent..."; }}); } } static A noToolTip(A c) { return setToolTip(c, (String) null); } static A setToolTip(A c, Object toolTip) { return setToolTipText(c, toolTip); } static A setToolTip(Object toolTip, A c) { return setToolTipText(c, toolTip); } static void imageSurfaceOnLeftClick(ImageSurface is, VF1 onClick) { if (is == null || onClick == null) return; { swing(new Runnable() { public void run() { try { MouseAdapter ma = new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() == 1) callF(onClick, is.pointFromEvent(e)); } }; is.addMouseListener(ma); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "MouseAdapter ma = new MouseAdapter {\r\n public void mouseClicked(MouseEve..."; }}); } } static A or_func(A a, IF0 b) { return a != null ? a : callF(b); } static BufferedImage whiteImage(int w, int h) { return newBufferedImage(w, h, Color.white); } static BufferedImage whiteImage(int size) { return whiteImage(size, size); } static JPanel jCenteredSection(Component c) { return jCenteredSection("", c); } static JPanel jCenteredSection(final String title, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = jSection(title, c); ((TitledBorder) p.getBorder()).setTitleJustification(TitledBorder.CENTER); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = jSection(title, c);\r\n ((TitledBorder) p.getBorder()).setTitleJu..."; }}); } static JPanel jCenteredSection(String title) { return jCenteredSection(title, jpanel()); } static JScrollPane jscroll_center(Component c) { return jscroll_centered(c); } static JPanel centerAndSouthWithMargin(Component c, Component s) { return centerAndSouth(c, withTopMargin(s)); } static JLabel dm_centeredCalculatedLabel(IF0 calc) { return centerLabel(dm_calculatedLabel(calc)); } static String formatDouble(double d, int digits) { String format = digits <= 0 ? "0" : "0." + rep(digits, '#'); return new java.text.DecimalFormat(format, new java.text.DecimalFormatSymbols(Locale.ENGLISH)).format(d); } static JButton jbutton(String text, Object action) { return newButton(text, action); } // button without action static JButton jbutton(String text) { return newButton(text, null); } /*static JButton jbutton(BufferedImage img, O action) { ret setButtonImage(img, jbutton("", action)); }*/ static JButton jbutton(Action action) { return swingNu(JButton.class, action); } static Runnable runnableThread(final Runnable r) { return new Runnable() { public void run() { try { startThread(r) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "startThread(r)"; }}; } // menuParams: text, Runnable, ... // also: position := 'left/'center/'right static JButton jPopDownButton_noText(final Object... menuParams) { return toolTip("Additional commands", jPopDownButton("", menuParams)); } static A withCalc(Runnable r, A a) { return withComputing(r, a); } static JSplitPane jvsplit(Component n, Component s) { return jvsplit(n, s, 0.5); } static JSplitPane jvsplit(Component n, Component s, double splitPoint, int delay) { // delay now ignored return jvsplit(n, s, splitPoint); } static JSplitPane jvsplit(Component n, Component s, double splitPoint) { return setSplitPaneOnFirstShowing( swingNu(JSplitPane.class, JSplitPane.VERTICAL_SPLIT, wrap(n), wrap(s)), splitPoint); } static JSplitPane jvsplit(double splitPoint, Component n, Component s) { return jvsplit(n, s, splitPoint); } static JPanel northCenterAndSouthWithMargins(Component n, Component c, Component s) { return applyDefaultMargin(northCenterAndSouth(withBottomMargin(n), c, withTopMargin(s))); } static JPanel centeredLine(Component... components) { return jcenteredline(components); } static JPanel westCenterAndEastWithMargin(Component w, Component c, Component e) { return westCenterAndEast(w, withLeftAndRightMargin(c), e); } static int hstackWithSpacing_spacing = 10; // first part can be spacing value static JPanel hstackWithSpacing(Object... parts) { parts = flattenArray2(parts); // allow collections in parameters int spacing = hstackWithSpacing_spacing; int i = 0; if (first(parts) instanceof Integer) { spacing = toInt(first(parts)); ++i; } JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.weighty = 1; gbc.fill = GridBagConstraints.VERTICAL; gbc.gridheight = GridBagConstraints.REMAINDER; for (; i < l(parts); i++) { if (i != 0) panel.add(javax.swing.Box.createRigidArea(new Dimension(spacing, 0)), gbc); panel.add(wrapForSmartAdd(parts[i]), gbc); } gbc.weightx = 1; panel.add(jrigid(), gbc); return panel; } static JPanel hgridWithSpacing(final Object... parts) { final JPanel panel = hgrid(parts); { swing(new Runnable() { public void run() { try { GridLayout gl = (GridLayout) (panel.getLayout()); gl.setHgap(6); gl.setVgap(6); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "GridLayout gl = (GridLayout) (panel.getLayout());\r\n gl.setHgap(6);\r\n g..."; }}); } return panel; } static class jCenteredLiveValueSection_class extends SingleComponentPanel { LiveValue liveValue; String getTitle() { return liveValue.get(); } jCenteredLiveValueSection_class(LiveValue lv, Component c) { super(c); bindLiveValueListenerToComponent(this, liveValue = lv, new Runnable() { public void run() { try { swingLater(new Runnable() { public void run() { try { setBorder(BorderFactory.createTitledBorder( BorderFactory.createBevelBorder(BevelBorder.LOWERED), liveValue.get())); centerSection(jCenteredLiveValueSection_class.this); revalidate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setBorder(BorderFactory.createTitledBorder(\r\n BorderFactory.createBeve..."; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "swingLater(r {\r\n setBorder(BorderFactory.createTitledBorder(\r\n Bo..."; }}); } } static JPanel jCenteredLiveValueSection(final LiveValue lv, final Component c) { return swingNu(jCenteredLiveValueSection_class.class, lv, c); } static LiveValue dm_calculatedLiveValue(final DynModule module, final Class type, final F0 calc) { Lock __124 = module.lock; lock(__124); try { final SimpleLiveValue value = new SimpleLiveValue(type, callF(calc)); module.onChange(new Runnable() { public void run() { try { value.set(callF(calc)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "value.set(callF(calc))"; }}); return value; } finally { unlock(__124); } } static LiveValue dm_calculatedLiveValue(Class type, F0 calc) { return dm_calculatedLiveValue(dm_current_mandatory(), type, calc); } static LiveValue dm_calculatedLiveValue(Class type, IF0 calc) { return dm_calculatedLiveValue(type, if0ToF0(calc)); } static boolean empty(Collection c) { return c == null || c.isEmpty(); } static boolean empty(CharSequence s) { return s == null || s.length() == 0; } static boolean empty(Map map) { return map == null || map.isEmpty(); } static boolean empty(Object[] o) { return o == null || o.length == 0; } static 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 boolean empty(Iterator i) { return i == null || !i.hasNext(); } static boolean empty(float[] a) { return a == null || a.length == 0; } static boolean empty(int[] a) { return a == null || a.length == 0; } static boolean empty(long[] a) { return a == null || a.length == 0; } static boolean empty(byte[] a) { return a == null || a.length == 0; } static boolean empty(short[] a) { return a == null || a.length == 0; } static boolean empty(File f) { return getFileSize(f) == 0; } static JPanel rightAlignedLine(Component... components) { return jrightAlignedLine(components); } static JPanel rightAlignedLine(List components) { return jrightAlignedLine(components); } public static JComponent withLabel(String label, JComponent component) { return westAndCenter(jlabel(label + " "), component); } static JComboBox dm_comboBox(String field, Collection values) { return jLiveValueComboBox(values, dm_fieldLiveValue(field)); } static int vstackWithSpacing_default = 10; static JPanel vstackWithSpacing(final List parts) { return vstackWithSpacing(parts, vstackWithSpacing_default); } static JPanel vstackWithSpacing(final List parts, final int spacing) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = new Insets(spacing/2, 0, spacing/2, 0); // well... smartAddWithLayout(panel, gbc, toObjectArray(nonNulls(parts))); //gbc = (GridBagConstraints) gbc.clone(); //gbc.fill = GridBagConstraints.BOTH; gbc.weighty = 1; gbc.insets = new Insets(0, 0, 0, 0); panel.add(jrigid(), gbc); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new GridBagLayout);\r\n new GridBagConstraints gbc..."; }}); } static JPanel vstackWithSpacing(Component... parts) { return vstackWithSpacing(asList(parts), vstackWithSpacing_default); } static JLabel dm_label(String fieldName) { return dm_fieldLabel(fieldName); } static JLabel dm_calculatedBoldLabel(IF0 calc) { return makeBold(dm_calculatedLabel(calc)); } static String or2(String a, String b) { return nempty(a) ? a : b; } static String or2(String a, String b, String c) { return or2(or2(a, b), c); } static Map status_map; // key = dialog id static abstract class Status { abstract String answer(String s); } // get status static synchronized Status status() { status_load(); return status_map.get(getDialogID()); } static void status_load() { if (status_map == null) { status_map = new TreeMap(); load("status_map"); } } // set status static synchronized void status(Status s) { status_load(); if (s == null) status_map.remove(getDialogID()); else status_map.put(getDialogID(), s); save("status_map"); } static String status_answer(String s) { Status status = status(); if (status != null) return status.answer(s); return null; } static JWindow infoBox(String text) { return infoMessage(text); } static JWindow infoBox(String text, double seconds) { return infoMessage(text, seconds); } static JWindow infoBox(Throwable e) { return infoMessage(e); } static ChessPieceRecognizer chessOCR_pieceRecognizer() { ChessPieceRecognizer r = new ChessPieceRecognizer(); r.load(); return r; } static void clearImageSurfaces(ImageSurface... l) { for (ImageSurface is : unnull(l)) if (is != null) is.noImage(); } static volatile StringBuffer local_log = new StringBuffer(); // not redirected static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot // in bytes - will cut to half that static volatile int print_log_max = 1024*1024; static volatile int local_log_max = 100*1024; static boolean print_silent = false; // total mute if set static Object print_byThread_lock = new Object(); static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1 static volatile Object print_allThreads; static volatile Object print_preprocess; static void print() { print(""); } static A print(String s, A o) { print((endsWithLetterOrDigit(s) ? s + ": " : s) + o); return o; } // slightly overblown signature to return original object... static A print(A o) { ping_okInCleanUp(); if (print_silent) return o; String s = String.valueOf(o) + "\n"; print_noNewLine(s); return o; } static void print_noNewLine(String s) { Object f = getThreadLocal(print_byThread_dontCreate()); if (f == null) f = print_allThreads; if (f != null) // We do need the general callF machinery here as print_byThread is sometimes shared between modules if (isFalse( f instanceof F1 ? ((F1) f).get(s) : callF(f, s))) return; print_raw(s); } static void print_raw(String s) { if (print_preprocess != null) s = (String) callF(print_preprocess, s); s = fixNewLines(s); Appendable loc = local_log; Appendable buf = print_log; int loc_max = print_log_max; if (buf != loc && buf != null) { print_append(buf, s, print_log_max); loc_max = local_log_max; } if (loc != null) print_append(loc, s, loc_max); System.out.print(s); } static void print_autoRotate() { } static boolean setVar_trueIfChanged(IVar v, A value) { if (v == null) return false; synchronized(v) { if (eq(v.get(), value)) return false; v.set(value); return true; } } static int imageMergeSpacing = 5; static int imageMergeSpacing() { return imageMergeSpacing; } static void imageMergeSpacing(int pixels) { imageMergeSpacing = pixels; } static float clamp(float x, float a, float b) { return x < a ? a : x > b ? b : x; } static double clamp(double x, double a, double b) { return x < a ? a : x > b ? b : x; } static int clamp(int x, int a, int b) { return x < a ? a : x > b ? b : x; } static int iratio_floor(double a, double b) { return ifloor(ratio(a, b)); } static String strCharPlus(char a, int b) { return str(charPlus(a, b)); } static void chessOCR_uploadPieceImage(String square, String piece, BufferedImage img) { AutoCloseable __150 = tempInfoBox_noHide("Uploading..."); try { String imageURL = uploadToImageServer("Chess square: " + piece, img); agiBlue_postInSlice(agiBlue_chessPieceImagesSlice(), imageURL, "is", piece); agiBlue_postInSlice(agiBlue_chessPieceImagesSlice(), imageURL, "was on square", square); infoBox("Uploaded!"); } finally { _close(__150); }} static B mapGet(Map map, A a) { return map == null || a == null ? null : map.get(a); } static B mapGet(A a, Map map) { return map == null || a == null ? null : map.get(a); } static boolean chess_isLightSquare(String square) { int x; int y ; Pair __147= chess_squareToPos(square); x = __147.a; y = __147.b; return even(x+y); } static void _close(AutoCloseable c) { if (c != null) try { c.close(); } catch (Throwable e) { // Some classes stupidly throw an exception on double-closing if (c instanceof javax.imageio.stream.ImageOutputStream) return; else throw rethrow(e); } } static Map mapToValues(Iterable l, Object f) { return mapKeyAndFunction(l, f); } static Map mapToValues(Object f, Iterable l) { return mapKeyAndFunction(f, l); } static Map mapToValues(Iterable l, IF1 f) { return mapKeyAndFunction(f, l); } static List ll(A... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (A x : a) l.add(x); return l; } static Map mapValues(Object func, Map map) { Map m = similarEmptyMap(map); for (Object key : keys(map)) m.put(key, callF(func, map.get(key))); return m; } static Map mapValues(Map map, IF1 f) { return mapValues(f, map); } static Map mapValues(Map map, Object func) { return mapValues(func, map); } static HashMap pairsToMap(Collection> l) { HashMap map = new HashMap(); if (l != null) for (Pair p : l) map.put(p.a, p.b); return map; } static List> reversePairs(Iterable> l) { return map("reversedPair",l); } // returns [] // returns light & dark squares static List> chessPieceImagesFromAGIBlue() { return mapPairsA("parseImageSnippetURL",filter(p -> isURL(p.a) && ai_chessPiecesSet().contains(p.b), agiBlue_pagesAndValuesForKey(agiBlue_chessPieceImagesSlice(), "is"))); } // returns only light or dark squares static List> chessPieceImagesFromAGIBlue(boolean lightSquares) { List> raw = agiBlue_pagesAndValuesForKey(agiBlue_chessPieceImagesSlice(), "is"); List> squares = agiBlue_pagesAndValuesForKey(agiBlue_chessPieceImagesSlice(), "was on square"); Set set = asSet(pairsA(filter(squares, p -> lightSquares == chess_isLightSquare(p.b)))); List> filtered = filter(raw, p -> set.contains(p.a)); return mapPairsA("parseImageSnippetURL",filtered); } static BufferedImage resizeImage(BufferedImage img, int newW, int newH) { return resizeImage(img, newW, newH, Image.SCALE_SMOOTH); } static BufferedImage resizeImage(BufferedImage img, int newW, int newH, int scaleType) { if (newW == img.getWidth() && newH == img.getHeight()) return img; Image tmp = img.getScaledInstance(newW, newH, scaleType); BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = dimg.createGraphics(); g2d.drawImage(tmp, 0, 0, null); g2d.dispose(); return dimg; } static BufferedImage resizeImage(BufferedImage img, int newW) { int newH = iround(img.getHeight()*(double) newW/img.getWidth()); return resizeImage(img, newW, newH); } static BufferedImage resizeImage(int newW, BufferedImage img) { return resizeImage(img, newW); } static BufferedImage loadImage2(String snippetIDOrURL) { return loadBufferedImage(snippetIDOrURL); } static BufferedImage loadImage2(File file) { return loadBufferedImage(file); } static List pairsA(Collection> l) { return firstOfPairs(l); } static boolean even(int i) { return (i & 1) == 0; } static boolean even(long i) { return (i & 1) == 0; } static List> listToChunks(List l, int chunkSize) { int rows = intRatio_ceil(l(l), chunkSize); List> out = emptyList(rows); for (int y = 0; y < rows; y++) out.add(subList(l, y*chunkSize, (y+1)*chunkSize)); return out; } static List> listToChunks(int chunkSize, List l) { return listToChunks(l, chunkSize); } static BufferedImage mergeBufferedImagesHorizontally(BufferedImage... images) { return mergeBufferedImagesHorizontally(toList(images)); } static BufferedImage mergeBufferedImagesHorizontally(List images, Object... __) { if (empty(images)) return null; int spacing = optPar("spacing",__, imageMergeSpacing()); RGB spaceColor = new RGB(0.9f); int w = intSum(mapMethod("getWidth",images))+(l(images)-1)*spacing, h = intMax(mapMethod("getHeight",images)); BufferedImage out = newBufferedImage(w, h, spaceColor); int x = 0; for (int i = 0; i < l(images); i++) { BufferedImage img = images.get(i); int y = (h-img.getHeight())/2; copyBufferedImage(img, out, x, y); x += img.getWidth() + spacing; } return out; } static BufferedImage mergeBufferedImagesVertically(BufferedImage... images) { return mergeBufferedImagesVertically(asList(images)); } static BufferedImage mergeBufferedImagesVertically(List images, Object... __) { return mergeImagesVertically(map("toRGBImage",images), __).getBufferedImage(); } static Pair chess_squareToPos(String square) { if (square == null) return null; assertLength(2, square); return pair(charDiff(upper(first(square)), 'A'), 8-charDiff(second(square), '0')); } static A _get(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } static Object _get(Object o, String field) { return get(o, field); } static Object _get(String field, Object o) { return get(o, field); } static A _get(A[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : null; } static int iround(double d) { return (int) Math.round(d); } static int iround(Number n) { return iround(toDouble(n)); } static A pairA(Pair p) { return p == null ? null : p.a; } static ChessPieceProfile1 chessOCR_pieceProfileFromRawImage_1(BufferedImage img, Object... __) { boolean withPreprocessedImages = boolPar("withPreprocessedImages",__); BWImage bw = chessOCR_piecePreprocessing_1(img); BWImage bw2 = chessOCR_piecePreprocessingForFillGrade_1(img); ChessPieceProfile1 profile = new ChessPieceProfile1( ocr_sideProfile_scaledTo127(20, 0.5, bw), 1f-bwAverageBrightness(bw2)); if (withPreprocessedImages) profile.preprocessedImages = ll(bw, bw2); return profile; } static List itemPlusList(A a, Collection l) { return concatLists(ll(a), l); } static List map(Iterable l, Object f) { return map(f, l); } static List map(Object f, Iterable l) { List x = emptyList(l); if (l != null) for (Object o : l) x.add(callF(f, o)); return x; } static List map(Iterable l, F1 f) { return map(f, l); } static List map(F1 f, Iterable l) { List x = emptyList(l); if (l != null) for (A o : l) x.add(callF(f, o)); return x; } static List map(IF1 f, Iterable l) { return map(l, f); } static List map(Iterable l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) x.add(f.get(o)); return x; } static List map(IF1 f, A[] l) { return map(l, f); } static List map(A[] l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) x.add(f.get(o)); return x; } static List map(Object f, Object[] l) { return map(f, asList(l)); } static List map(Object[] l, Object f) { return map(f, l); } static List map(Object f, Map map) { return map(map, f); } // map: func(key, value) -> list element static List map(Map map, Object f) { List x = new ArrayList(); if (map != null) for (Object _e : map.entrySet()) { Map.Entry e = (Map.Entry) _e; x.add(callF(f, e.getKey(), e.getValue())); } return x; } static List map(Map map, IF2 f) { return map(map, (Object) f); } static ImageSurface showImage_centered(final BufferedImage img) { return (ImageSurface) swing(new F0() { Object get() { try { ImageSurface is = new ImageSurface(img); JPanel panel = new JPanel(new GridBagLayout()); panel.add(is); JFrame frame = showPackedFrame(new JScrollPane(panel)); frameIcon(frame, showImage_defaultIcon); return is; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ImageSurface is = new ImageSurface(img);\r\n JPanel panel = new JPanel(new G..."; }}); } static ImageSurface showImage_centered(final BufferedImage img, final String title) { return setFrameTitle(showImage_centered(img), title); } static ImageSurface showImage_centered(String title, BufferedImage img) { return showImage_centered(img, title); } static ImageSurface showImage_centered(String title, RGBImage img) { return showImage_centered(title, img.getBufferedImage()); } static ImageSurface showImage_centered(ImageSurface is, BufferedImage img) { if (is == null) return showImage_centered(img); is.setImage(img); return is; } // make or update the ImageSurface static ImageSurface showImage_centered(ImageSurface is, String title, BufferedImage img) { if (is == null) return showImage_centered(title, img); is.setImage(img); setFrameTitle(is, title); return is; } static ImageSurface showImage_centered(ImageSurface surface, RGBImage img, String title) { return setFrameTitle(showImage_centered(img, surface), title); } static ImageSurface showImage_centered(RGBImage img, ImageSurface surface) { if (surface == null) return showImage_centered(img); else { surface.setImage(img); return surface; } } static ImageSurface showImage_centered(RGBImage img) { return showImage_centered(img.getBufferedImage()); } static ImageSurface showImage_centered(ImageSurface surface, String title, RGBImage img) { return showImage_centered(surface, img, title); } static String n2(long l) { return formatWithThousands(l); } static String n2(Collection l) { return n2(l(l)); } static String n2(double l, String singular) { return n2(l, singular, singular + "s"); } static String n2(double l, String singular, String plural) { if (fraction(l) == 0) return n2((long) l, singular, plural); else return l + " " + plural; } static String n2(long l, String singular, String plural) { return n_fancy2(l, singular, plural); } static String n2(long l, String singular) { return n_fancy2(l, singular, singular + "s"); } static String n2(Collection l, String singular) { return n2(l(l), singular); } static String n2(Collection l, String singular, String plural) { return n_fancy2(l, singular, plural); } static String n2(Map m, String singular, String plural) { return n_fancy2(m, singular, plural); } static String n2(Map m, String singular) { return n2(l(m), singular); } static String n2(Object[] a, String singular) { return n2(l(a), singular); } static String n2(Object[] a, String singular, String plural) { return n_fancy2(a, singular, plural); } static BufferedImage clipBufferedImage(BufferedImage src, Rectangle clip) { return clipBufferedImage(src, new Rect(clip)); } static BufferedImage clipBufferedImage(BufferedImage src, Rect r) { if (src == null || r == null) return null; // fixClipRect r = intersectRects(r, new Rect(0, 0, src.getWidth(), src.getHeight())); if (rectEmpty(r)) return null; // can't make zero-sized BufferedImage return src.getSubimage(r.x, r.y, r.w, r.h); } static BufferedImage clipBufferedImage(BufferedImage src, int x, int y, int w, int h) { return clipBufferedImage(src, new Rect(x, y, w, h)); } static JCheckBox jcheckbox() { return jCheckBox(); } static JCheckBox jcheckbox(boolean checked) { return jCheckBox(checked); } static JCheckBox jcheckbox(String text, boolean checked) { return jCheckBox(text, checked); } static JCheckBox jcheckbox(String text) { return jCheckBox(text); } // keep old state static JCheckBox jcheckbox(JCheckBox cb, String text) { return jcheckbox(text, isChecked(cb)); } static JTextField jtextfield() { return jTextField(); } static JTextField jtextfield(String text) { return jTextField(text); } static JTextField jtextfield(Object o) { return jTextField(o); } static int showForm_defaultGap = 4; static int showForm_gapBetweenColumns = 10; static JPanel showFormTitled(final String title, final Object... _parts) { JDesktopPane desktop = mainDesktopPane(); if (desktop != null) return showInternalFrameFormTitled(desktop, title, _parts); return swing(new F0() { JPanel get() { try { final Var frame = new Var(); JPanel panel = showForm_makePanel(false, _parts); frame.set(showForm_makeFrame(title, panel)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final new Var frame;\r\n JPanel panel = showForm_makePanel(false, _p..."; }}); } static JPanel showForm_makePanel(Boolean internalFrame, Object... _parts) { List out = showForm_arrange1(showForm_makeComponents(internalFrame, _parts)); return vstackWithSpacing(out, showForm_defaultGap); } static BufferedImage scaleImageToWidth(BufferedImage img, int newW) { return resizeImage(img, newW); } static BufferedImage scaleImageToWidth(int newW, BufferedImage img) { return scaleImageToWidth(img, newW); } static JLabel jlabel(final String text) { return swingConstruct(BetterLabel.class, text); } static JLabel jlabel() { return jlabel(" "); } static JLabel jMultiLineLabel(String text) { return setVerticalAlignment(JLabel.TOP, jlabel(jlabel_textAsHTML(text))); } // action can be Runnable or a function name static JButton jThreadedButton(final String text, final Object action) { return swing(new F0() { JButton get() { try { String text2 = dropPrefix("[disabled] ", text); final JButton btn = new JButton(text2); if (l(text2) < l(text)) btn.setEnabled(false); btn.setToolTipText(btn.getText()); if (action != null) btn.addActionListener(actionListenerInNewThread(action, btn)); return btn; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "S text2 = dropPrefix(\"[disabled] \", text);\r\n final JButton btn = new JButt..."; }}); } static AutoCloseable tempInfoBox_noHide(String msg) { return tempDisposeWindow(infoBox_noHide(msg)); } static String uploadToImageServer(BufferedImage img, String name) { return uploadToImageServerIfNotThere(img, name); } static String uploadToImageServer(String name, BufferedImage img) { return uploadToImageServerIfNotThere(img, name); } static String uploadToImageServer(File f) { return uploadFileToImageServer(f); } static A assertNempty(A a) { return assertNempty("empty", a); } static A assertNempty(String msg, A a) { if (empty(a)) throw fail(msg + ": " + a); return a; } static String parseSnippetImageURL(String url) { return parseImageSnippetURL(url); } static void mapPutIfNemptyValue(Map map, A key, String value) { if (map != null && key != null && nempty(value)) map.put(key, value); } static void mapPutIfNemptyValue(Map map, A key, B value) { if (map != null && key != null && nempty(value)) map.put(key, value); } static String gtt(JTextComponent c) { return getTextTrim(c); } static String gtt(JComboBox cb) { return getTextTrim(cb); } static String yesNo_short_firstUpper(boolean b) { return b ? "Yes" : "No"; } static boolean isChecked(final JCheckBox checkBox) { return checkBox != null && (boolean) swing(new F0() { Boolean get() { try { return checkBox.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret checkBox.isSelected();"; }}); } static boolean isChecked(final JCheckBoxMenuItem mi) { return mi != null && (boolean) swing(new F0() { Boolean get() { try { return mi.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret mi.isSelected();"; }}); } static boolean nempty(Collection c) { return !empty(c); } static boolean nempty(CharSequence s) { return !empty(s); } static boolean nempty(Object[] o) { return !empty(o); } static boolean nempty(byte[] o) { return !empty(o); } static boolean nempty(int[] o) { return !empty(o); } static boolean nempty(Map m) { return !empty(m); } static boolean nempty(Iterator i) { return i != null && i.hasNext(); } static boolean nempty(Object o) { return !empty(o); } static String struct(Object o) { return structure(o); } static String struct(Object o, structure_Data data) { return structure(o, data); } static String agiBlue_chessBoardRecognitionTrainingImagesSliceID() { return "jxoivvjqucrsrque"; } static String agiBlue_createUnusedNumberedPage(String sliceID, String q) { return getString("q",agiBlue_loadBotPage("createUnusedNumberedPage", "q", q, "slice" , sliceID)); } static Set keys(Map map) { return map == null ? new HashSet() : map.keySet(); } static Set keys(Object map) { return keys((Map) map); } static Set keys(MultiMap mm) { return mm.keySet(); } static HashMap litmap(Object... x) { HashMap map = new HashMap(); litmap_impl(map, x); return map; } static void litmap_impl(Map map, Object... x) { if (x != null) for (int i = 0; i < x.length-1; i += 2) if (x[i+1] != null) map.put(x[i], x[i+1]); } static Object agiBot_postMulti(PKIKeyPair keys, List posts, Object... __) { return print(postJSONPage("http://agi.blue/bot/postSigned", paramsPlus(__, "text" , pki_signTextIncludingKey(jsonEncodeLines(posts), keys)))); } static PKIKeyPair keyPairForProgram() { Lock __229 = programLock(); lock(__229); try { File f = secretProgramFile("key-pair.txt"); try { PKIKeyPair pair = pkiKeyPairFromTwoLineFile(f); if (pair != null) return pair; } catch (Throwable __e) { _handleException(__e); } PKIKeyPair pair = pki_newKeyPair(); saveTextFile(f, linesLL(pair.publicKey, pair.privateKey)); return pair; } finally { unlock(__229); } } static void openURLInBrowser(String url) { openPlatformBrowser(url); } static String agiBlue_linkForPhrase(String phrase, Object... additionalParams) { return agiBlueURL() + hquery(arrayPlus /* allow multiple "get" parameters */(additionalParams, "q" , phrase)); } static void disposeWindow(final Window window) { if (window != null) { swing(new Runnable() { public void run() { try { window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); // call listeners myFrames_list.remove(window); window.dispose(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); //..."; }}); } } static void disposeWindow(final Component c) { disposeWindow(getWindow(c)); } static void disposeWindow(Object o) { if (o != null) disposeWindow(((Component) o)); } static void disposeWindow() { disposeWindow(heldInstance(Component.class)); } static JButton heldButton() { return heldInstance(JButton.class); } static String chess_makeFEN(List> recognized) { if (empty(recognized)) return null; List out = new ArrayList(); for (List row : recognized) { int i = 0; StringBuilder buf = new StringBuilder(); while (i < 8) { int j = smartIndexOfNot(row, "empty", i); if (j > i) { buf.append(j-i); i = j; } else { String p = row.get(i++); String piece = secondWord(p); char c = eq(piece, "knight") ? 'n' : first(piece); if (startsWith(p, "white")) c = upper(c); buf.append(c); } } out.add(str(buf)); } return join("/", out); } static List singletonUnlessNull(A a) { return a == null ? emptyList() : ll(a); } static float abs(float f) { return Math.abs(f); } static int abs(int i) { return Math.abs(i); } static double abs(double d) { return Math.abs(d); } static String appendRoundBracketed(String b) { return empty(b) ? "" : "" + " (" + b + ")"; } static String appendRoundBracketed(String a, String b) { return empty(b) ? a : a + appendRoundBracketed(b); } static String joinWithComma(Collection c) { return join(", ", c); } static String joinWithComma(String... c) { return join(", ", c); } static String joinWithComma(Pair p) { return p == null ? "" : joinWithComma(str(p.a), str(p.b)); } static List> bufferedImageMNGrid(int cols, int rows, BufferedImage img) { List> out = new ArrayList(); for (List l : gridOfRects3(img.getWidth(), img.getHeight(), cols, rows)) out.add(map(r -> clipBufferedImage(img, r), l)); return out; } static List> bufferedImageMNGrid(BufferedImage img, int cols, int rows) { return bufferedImageMNGrid(cols, rows, img); } static List bufferedImageNVerticalSlices(int n, BufferedImage img) { return bufferedImageVerticalSlices(doubleRatio(img.getHeight(), n), img); } static List bufferedImageNHorizontalSlices(int n, BufferedImage img) { return bufferedImageHorizontalSlices(doubleRatio(img.getWidth(), n), img); } static List concatLists(Collection... lists) { List l = new ArrayList(); if (lists != null) for (Collection list : lists) if (list != null) l.addAll(list); return l; } static List concatLists(Collection> lists) { List l = new ArrayList(); if (lists != null) for (Collection list : lists) if (list != null) l.addAll(list); return l; } static double doubleAvg(int... a) { return doubleAverage(a); } static double doubleAvg(double... l) { return doubleAverage(l); } static double doubleAvg(Collection l) { return doubleAverage(l); } static List pairsB(Collection> l) { return secondOfPairs(l); } static Rect intersectRects(Rect a, Rect b) { int x = max(a.x, b.x), y = max(a.y, b.y); int x2 = min(a.x+a.w, b.x+b.w), y2 = min(a.y+a.h, b.y+b.h); return new Rect(x, y, x2-x, y2-y); } static Rect imageRect() { return imageRect(currentImage()); } static Rect imageRect(BufferedImage img) { return img == null ? null : new Rect(0, 0, img.getWidth(), img.getHeight()); } static Rect rectFromPoints(int x1, int y1, int x2, int y2) { return pointsRect(x1, y1, x2, y2); } static Rect rectFromPoints(Pt a, Pt b) { return pointsRect(a.x, a.y, b.x, b.y); } static int varyInt(int i) { return varyInt(10, i); } static int varyInt(int range, int i) { return random(i-range, i+range+1); } static String copyToClipboard(Object _text) { return copyTextToClipboard(_text); } static BufferedImage dm_shootScreenHidingOS() { AutoCloseable __113 = dm_tempMinimizeOS(); try { sleepSeconds(3); return shootScreen2(); } finally { _close(__113); }} static String showImage_defaultIcon = "#1004230"; // "#1004227"; static ImageSurface showImage(String snippetIDOrURL, String title) { return showImage(loadImage(snippetIDOrURL), title); } static ImageSurface showImage(String title, BufferedImage img) { return showImage(img, title); } static ImageSurface showImage(final BufferedImage img, final String title) { return (ImageSurface) swing(new F0() { Object get() { try { ImageSurface is = showImage(img); getFrame(is).setTitle(title); return is; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ImageSurface is = showImage(img);\r\n getFrame(is).setTitle(title);\r\n ret..."; }}); } static ImageSurface showImage(final BufferedImage img) { return (ImageSurface) swing(new F0() { Object get() { try { ImageSurface is = new ImageSurface(img); JFrame frame = showPackedFrame(new JScrollPane(is)); moveToTopRightCorner(frame); frameIcon(frame, showImage_defaultIcon); return is; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ImageSurface is = new ImageSurface(img);\r\n JFrame frame = showPackedFrame(..."; }}); } static ImageSurface showImage(String imageID) { return showImage(loadImage2(imageID)); } static ImageSurface showImage(ImageSurface surface, BufferedImage img) { return showImage(img, surface); } static ImageSurface showImage(ImageSurface surface, String title, BufferedImage img) { return showImage(surface, img, title); } static ImageSurface showImage(ImageSurface surface, BufferedImage img, String title) { return setFrameTitle(showImage(img, surface), title); } static ImageSurface showImage(BufferedImage img, ImageSurface surface) { if (surface == null) return showImage(img); else { surface.setImage(img); return surface; } } static ImageSurface showImage(String title, MakesBufferedImage img) { return showImage(title, img.getBufferedImage()); } static ImageSurface showImage(ImageSurface is, MakesBufferedImage img) { return showImage(is, img.getBufferedImage()); } static ImageSurface showImage(RGBImage img) { return showImage(img.getBufferedImage()); } static ImageSurface showImage(RGBImage img, String title) { ImageSurface is = showImage(img.getBufferedImage()); getFrame(is).setTitle(title); return is; } static ImageSurface showImage(ImageSurface surface, RGBImage img) { return showImage(img, surface); } static ImageSurface showImage(RGBImage img, ImageSurface surface) { if (surface == null) return showImage(img); else { surface.setImage(img); return surface; } } static ImageSurface showImage(ImageSurface surface, String title, RGBImage img) { return showImage(surface, img, title); } static ImageSurface showImage(ImageSurface surface, RGBImage img, String title) { return setFrameTitle(showImage(img, surface), title); } static ImageSurface showImage(BWImage img) { return showImage(img.getBufferedImage()); } static ImageSurface showImage() { return showImage(currentImage()); } static ImageSurface showImage(File f) { return showImage(f2s(f), loadImage2(f)); } static Map myFrames_list = weakHashMap(); static List myFrames() { return swing(new F0>() { List get() { try { return keysList(myFrames_list); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret keysList(myFrames_list);"; }}); } static BufferedImage toBufferedImageOpt(Object o) { if (o instanceof BufferedImage) return (BufferedImage) o; if (o instanceof MakesBufferedImage) return ((MakesBufferedImage) o).getBufferedImage(); if (o instanceof File) if (isImageFile(((File) o))) return loadImage2(((File) o)); String c = getClassName(o); // Keep this because it also works on imported objects if (eqOneOf(c, "main$BWImage", "main$RGBImage")) return (BufferedImage) call(o, "getBufferedImage"); if (eq(c, "main$PNGFile")) return (BufferedImage) call(o, "getImage"); return null; } static DynModule dm_current_mandatory() { return assertNotNull("No module set!", dm_currentModule()); } static F0 dm_rEnter(final DynModule mod) { return mod == null ? null : new F0() { AutoCloseable get() { try { return mod.enter(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret mod.enter();"; }}; } static void _handleError(Error e) { call(javax(), "_handleError", e); } static List tlft(String s) { return toLinesFullTrim(s); } static List tlft(File f) { return toLinesFullTrim(f); } static A swingNu(final Class c, final Object... args) { return swingConstruct(c, args); } static Object swing(Object f) { return swingAndWait(f); } static A swing(F0 f) { return (A) swingAndWait(f); } static A swing(IF0 f) { return (A) swingAndWait(f); } static Map> callF_cache = newDangerousWeakHashMap(); static A callF(F0 f) { return f == null ? null : f.get(); } static B callF(F1 f, A a) { return f == null ? null : f.get(a); } static A callF(IF0 f) { return f == null ? null : f.get(); } static B callF(IF1 f, A a) { return f == null ? null : f.get(a); } static C callF(F2 f, A a, B b) { return f == null ? null : f.get(a, b); } static C callF(IF2 f, A a, B b) { return f == null ? null : f.get(a, b); } static void callF(VF1 f, A a) { if (f != null) f.get(a); } static Object callF(Object f, Object... args) { try { if (f instanceof String) return callMC((String) f, args); if (f instanceof Runnable) { ((Runnable) f).run(); return null; } if (f == null) return null; Class c = f.getClass(); ArrayList methods; synchronized(callF_cache) { methods = callF_cache.get(c); if (methods == null) methods = callF_makeCache(c); } int n = l(methods); if (n == 0) { throw fail("No get method in " + getClassName(c)); } if (n == 1) return invokeMethod(methods.get(0), f, args); for (int i = 0; i < n; i++) { Method m = methods.get(i); if (call_checkArgs(m, args, false)) return invokeMethod(m, f, args); } throw fail("No matching get method in " + getClassName(c)); } catch (Exception __e) { throw rethrow(__e); } } // used internally static ArrayList callF_makeCache(Class c) { ArrayList l = new ArrayList(); Class _c = c; do { for (Method m : _c.getDeclaredMethods()) if (m.getName().equals("get")) { m.setAccessible(true); l.add(m); } if (!l.isEmpty()) break; _c = _c.getSuperclass(); } while (_c != null); callF_cache.put(c, l); return l; } static A setToolTipText(final A c, final Object toolTip) { if (c == null) return null; { swing(new Runnable() { public void run() { try { String s = nullIfEmpty(str(toolTip)); if (neq(s, c.getToolTipText())) c.setToolTipText(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = nullIfEmpty(str(toolTip));\r\n if (neq(s, c.getToolTipText()))\r\n ..."; }}); } return c; } static A setToolTipText(Object toolTip, A c) { return setToolTipText(c, toolTip); } // undefined color, seems to be all black in practice static BufferedImage newBufferedImage(int w, int h) { return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); } static BufferedImage newBufferedImage(int w, int h, RGB rgb) { return newBufferedImage(w, h, toColor(rgb)); } static BufferedImage newBufferedImage(int w, int h, Color color) { BufferedImage img = newBufferedImage(w, h); Graphics2D g = img.createGraphics(); g.setColor(color); g.fillRect(0, 0, w, h); return img; } static BufferedImage newBufferedImage(Pt p, Color color) { return newBufferedImage(p.x, p.y, color); } // get purpose 1: access a list/array/map (safer version of x.get(y)) static A get(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } // seems to conflict with other signatures /*static B get(Map map, A key) { ret map != null ? map.get(key) : null; }*/ static A get(A[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : null; } // default to false static boolean get(boolean[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : false; } // get purpose 2: access a field by reflection or a map static Object get(Object o, String field) { try { if (o == null) return null; if (o instanceof Class) return get((Class) o, field); if (o instanceof Map) return ((Map) o).get(field); Field f = getOpt_findField(o.getClass(), field); if (f != null) { f.setAccessible(true); return f.get(o); } if (o instanceof DynamicObject) return ((DynamicObject) o).fieldValues.get(field); } catch (Exception e) { throw asRuntimeException(e); } throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName()); } static Object get_raw(String field, Object o) { return get_raw(o, field); } static Object get_raw(Object o, String field) { try { if (o == null) return null; Field f = get_findField(o.getClass(), field); f.setAccessible(true); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } static Object get(Class c, String field) { try { Field f = get_findStaticField(c, field); f.setAccessible(true); return f.get(null); } catch (Exception e) { throw new RuntimeException(e); } } static Field get_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static Field get_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static Object get(String field, Object o) { return get(o, field); } static JPanel jSection(Component c) { return jSection("", c); } static JPanel jSection(final String title, final Component c) { return swing(new F0() { JPanel get() { try { Border border = BorderFactory.createBevelBorder(BevelBorder.LOWERED); border = BorderFactory.createTitledBorder(border, title); JSection panel = new JSection(c); panel.setBorder(border); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Border border = BorderFactory.createBevelBorder(BevelBorder.LOWERED);\r\n bo..."; }}); } static JPanel jSection(String title) { return jSection(title, jpanel()); } static JPanel jpanel(LayoutManager layout) { return swingNu(JPanel.class, layout); } static JPanel jpanel() { return swingNu(JPanel.class); } static JScrollPane jscroll_centered(Component c) { return jscroll(jFullCenter(c)); } static JPanel centerAndSouth(final Component c, final Component s) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.CENTER, wrap(c)); if (s != null) panel.add(BorderLayout.SOUTH, wrap(s)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.CENT..."; }}); } static int withTopMargin_defaultWidth = 6; static JPanel withTopMargin(Component c) { return withTopMargin(withTopMargin_defaultWidth, c); } static JPanel withTopMargin(final int w, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(w, 0, 0, 0)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }}); } static A centerLabel(A l) { if (l != null) l.setHorizontalAlignment(SwingConstants.CENTER); return l; } static JLabel dm_calculatedLabel(IF0 calc) { return jLiveValueLabel(dm_calculatedLiveValue(Object.class, calc)); } static String rep(int n, char c) { return repeat(c, n); } static String rep(char c, int n) { return repeat(c, n); } static List rep(A a, int n) { return repeat(a, n); } static List rep(int n, A a) { return repeat(n, a); } static boolean newButton_autoToolTip = true; // action can be Runnable or a function name static JButton newButton(final String text, final Object action) { return swing(new F0() { JButton get() { try { String text2 = dropPrefix("[disabled] ", text); final JButton btn = new JButton(text2); if (l(text2) < l(text)) btn.setEnabled(false); if (newButton_autoToolTip) { btn.setToolTipText(btn.getText()); //onChangeAndNow(btn, r { btn.setToolTipText(btn.getText()) }); } // submitButtonOnEnter(btn); // test this first if (action != null) btn.addActionListener(actionListener(action, btn)); return btn; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "S text2 = dropPrefix(\"[disabled] \", text);\r\n final JButton btn = new JButt..."; }}); } static Thread startThread(Object runnable) { return startThread(defaultThreadName(), runnable); } static Thread startThread(String name, Object runnable) { runnable = wrapAsActivity(runnable); return startThread(newThread(toRunnable(runnable), name)); } static Thread startThread(Thread t) { _registerThread(t); t.start(); return t; } static A toolTip(A c, final Object toolTip) { return setToolTipText(c, toolTip); } static A toolTip(Object toolTip, A c) { return setToolTipText(toolTip, c); } // menuParams: text, Runnable, ... // also: position := 'left/'center/'right static JButton jPopDownButton(String text, final Object... menuParams) { return jbutton((empty(text) ? "" : text + " ") + unicode_downPointingTriangle(), new Runnable() { public void run() { try { JPopupMenu menu = new JPopupMenu(); int emptyCount = menu.getComponentCount(); String position = (String) (optPar(menuParams, "position")); // TODO: this fails when you include a separator without a following null fillJPopupMenu(menu, paramsWithout(menuParams, "position")); if (menu.getComponentCount() != emptyCount) { JButton btn = heldInstance(JButton.class); int x = 0; if (eq(position, "center")) x = (btn.getWidth()-getPreferredWidth(menu))/2; else if (eq(position, "right")) x = btn.getWidth()-getPreferredWidth(menu); menu.show(btn, x, btn.getHeight()); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "new JPopupMenu menu;\r\n int emptyCount = menu.getComponentCount();\r\n Str..."; }}); } static A withComputing(Runnable r, A a) { callF(r); return a; } static JSplitPane setSplitPaneOnFirstShowing(final Component c, final double value) { final JSplitPane sp = first(childrenOfType(c, JSplitPane.class)); if (sp != null) onFirstResize(sp, new Runnable() { public void run() { try { sp.setDividerLocation(value); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "sp.setDividerLocation(value);"; }}); return sp; } // c = Component or something implementing swing() static JComponent wrap(Object swingable) { return _recordNewSwingComponent(wrap_2(swingable)); } static JComponent wrap_2(Object swingable) { if (swingable == null) return null; JComponent c; if (swingable instanceof Component) c = componentToJComponent(((Component) swingable)); else c = componentToJComponent((Component) callOpt(swingable, "swing")); if (c instanceof JTable || c instanceof JList || c instanceof JTextArea || c instanceof JEditorPane || c instanceof JTextPane || c instanceof JTree) return jscroll(c); return c == null ? jlabel(str(swingable)) : c; } static A applyDefaultMargin(final A c) { if (c != null) { swing(new Runnable() { public void run() { try { c.setBorder(BorderFactory.createEmptyBorder(withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth, withMargin_defaultWidth)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.setBorder(BorderFactory.createEmptyBorder(withMargin_defaultWidth, withMarg..."; }}); } return c; } static JPanel northCenterAndSouth(Component n, Component c, Component s) { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.NORTH, wrap(n)); panel.add(BorderLayout.CENTER, wrap(c)); panel.add(BorderLayout.SOUTH, wrap(s)); return panel; } static int withBottomMargin_defaultWidth = 6; static JPanel withBottomMargin(Component c) { return withBottomMargin(withBottomMargin_defaultWidth, c); } static JPanel withBottomMargin(final int w, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(0, 0, w, 0)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }}); } static JPanel jcenteredline(final Component... components) { //ret new CenteredLine(components); return swing(new F0() { JPanel get() { try { return jFullCenter(hstackWithSpacing(components)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret jFullCenter(hstackWithSpacing(components));"; }}); } static JPanel jcenteredline(List components) { return jcenteredline(asArray(Component.class, components)); } static JPanel westCenterAndEast(Component w, Component c, Component e) { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.WEST, wrap(w)); panel.add(BorderLayout.CENTER, wrap(c)); panel.add(BorderLayout.EAST, wrap(e)); return panel; } static int withLeftAndRightMargin_defaultWidth = 6; static JPanel withLeftAndRightMargin(Component c) { return withLeftAndRightMargin(withLeftAndRightMargin_defaultWidth, c); } static JPanel withLeftAndRightMargin(int w, Component c) { return withLeftAndRightMargin(w, w, c); } static JPanel withLeftAndRightMargin(final int w1, final int w2, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(0, w1, 0, w2)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }}); } static Object[] flattenArray2(Object... a) { List l = new ArrayList(); if (a != null) for (Object x : a) if (x instanceof Object[]) l.addAll(asList((Object[]) x)); else if (x instanceof Collection) l.addAll((Collection) x); else l.add(x); return asObjectArray(l); } static Object first(Object list) { return first((Iterable) list); } static A first(List list) { return empty(list) ? null : list.get(0); } static A first(A[] bla) { return bla == null || bla.length == 0 ? null : bla[0]; } static A first(IterableIterator i) { return first((Iterator) i); } static A first(Iterator i) { return i == null || !i.hasNext() ? null : i.next(); } static A first(Iterable i) { if (i == null) return null; Iterator it = i.iterator(); return it.hasNext() ? it.next() : null; } static Character first(String s) { return empty(s) ? null : s.charAt(0); } static A first(Pair p) { return p == null ? null : p.a; } static int toInt(Object o) { if (o == null) return 0; if (o instanceof Number) return ((Number) o).intValue(); if (o instanceof String) return parseInt((String) o); throw fail("woot not int: " + getClassName(o)); } static int toInt(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static int l(Object[] a) { return a == null ? 0 : a.length; } static int l(boolean[] a) { return a == null ? 0 : a.length; } static int l(byte[] a) { return a == null ? 0 : a.length; } static int l(short[] a) { return a == null ? 0 : a.length; } static int l(long[] a) { return a == null ? 0 : a.length; } static int l(int[] a) { return a == null ? 0 : a.length; } static int l(float[] a) { return a == null ? 0 : a.length; } static int l(double[] a) { return a == null ? 0 : a.length; } static int l(char[] a) { return a == null ? 0 : a.length; } static int l(Collection c) { return c == null ? 0 : c.size(); } static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible static int l(Map m) { return m == null ? 0 : m.size(); } static int l(CharSequence s) { return s == null ? 0 : s.length(); } static long l(File f) { return f == null ? 0 : f.length(); } static int l(Object o) { return o == null ? 0 : o instanceof String ? l((String) o) : o instanceof Map ? l((Map) o) : o instanceof Collection ? l((Collection) o) : o instanceof Object[] ? l((Object[]) o) : o instanceof boolean[] ? l((boolean[]) o) : o instanceof byte[] ? l((byte[]) o) : o instanceof char[] ? l((char[]) o) : o instanceof short[] ? l((short[]) o) : o instanceof int[] ? l((int[]) o) : o instanceof float[] ? l((float[]) o) : o instanceof double[] ? l((double[]) o) : o instanceof long[] ? l((long[]) o) : (Integer) call(o, "size"); } static Component wrapForSmartAdd(Object o) { if (o == null) return jpanel(); if (o instanceof String) return jlabel((String) o); return wrap(o); } static Component jrigid() { return javax.swing.Box.createRigidArea(new Dimension(0, 0)); } static JPanel hgrid(final Object... parts) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(); Object[] _parts = flattenArray2(parts); panel.setLayout(new GridLayout(1, _parts.length)); smartAdd(panel, _parts); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "new JPanel panel;\r\n O[] _parts = flattenArray2(parts);\r\n panel.setLayou..."; }}); } static A bindLiveValueListenerToComponent(A component, final LiveValue lv, final Runnable listener) { if (lv != null) bindToComponent(component, new Runnable() { public void run() { try { lv.onChangeAndNow(listener); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef bindLiveValueListenerToComponent_debug\r\n print(\"bindLiveValueL..."; }}, new Runnable() { public void run() { try { lv.removeOnChangeListener(listener) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lv.removeOnChangeListener(listener)"; }}); return component; } static void swingLater(long delay, final Object r) { javax.swing.Timer timer = new javax.swing.Timer(toInt(delay), actionListener(wrapAsActivity(r))); timer.setRepeats(false); timer.start(); } static void swingLater(Object r) { SwingUtilities.invokeLater(toRunnable(r)); } static JPanel centerSection(JPanel section) { if (section != null) { swing(new Runnable() { public void run() { try { Border border = section.getBorder(); if (border instanceof TitledBorder) ((TitledBorder) border).setTitleJustification(TitledBorder.CENTER); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Border border = section.getBorder();\r\n if (border instanceof TitledBorder)..."; }}); } return section; } static A revalidate(final A c) { if (c == null || !c.isShowing()) return c; { swing(new Runnable() { public void run() { try { // magic combo to actually relayout and repaint c.revalidate(); c.repaint(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "// magic combo to actually relayout and repaint\r\n c.revalidate();\r\n c.r..."; }}); } return c; } static void revalidate(JFrame f) { revalidate((Component) f); } static void revalidate(JInternalFrame f) { revalidate((Component) f); } static void lock(Lock lock) { try { ping(); if (lock == null) return; try { lock.lockInterruptibly(); } catch (InterruptedException e) { print("Locking interrupted! I probably deadlocked, oops."); printStackTrace(e); rethrow(e); } ping(); } catch (Exception __e) { throw rethrow(__e); } } static void lock(Lock lock, String msg) { print("Locking: " + msg); lock(lock); } static void lock(Lock lock, String msg, long timeout) { print("Locking: " + msg); lockOrFail(lock, timeout); } static ReentrantLock lock() { return fairLock(); } static void unlock(Lock lock, String msg) { if (lock == null) return; print("Unlocking: " + msg); lock.unlock(); } static void unlock(Lock lock) { if (lock == null) return; lock.unlock(); } static F0 if0ToF0(IF0 f) { return f == null ? null : new F0() { A get() { try { return f.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret f.get();"; }}; } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(Throwable e) { throw asRuntimeException(e); } static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); } static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); } static String getType(Object o) { return getClassName(o); } static long getFileSize(String path) { return path == null ? 0 : new File(path).length(); } static long getFileSize(File f) { return f == null ? 0 : f.length(); } static JPanel jrightAlignedLine(final Component... components) { return swing(new F0() { RightAlignedLine get() { try { return new RightAlignedLine(components); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret RightAlignedLine(components);"; }}); } static JPanel jrightAlignedLine(List components) { return jrightAlignedLine(asArray(Component.class, components)); } static JPanel westAndCenter(final Component w, final Component c) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.WEST, wrap(w)); panel.add(BorderLayout.CENTER, wrap(c)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.WEST..."; }}); } static JComboBox jLiveValueComboBox(Collection values, final SimpleLiveValue lv) { final JComboBox cb = jComboBox(values); bindComboBoxToLiveValue(cb, lv); return cb; } static SimpleLiveValue dm_fieldLiveValue(String fieldName) { return dm_fieldLiveValue(dm_current_mandatory(), fieldName); } static SimpleLiveValue dm_fieldLiveValue(final DynModule module, final String fieldName) { Lock __23 = module.lock; lock(__23); try { Class type = getFieldType(module, fieldName); final SimpleLiveValue value = new SimpleLiveValue(type, get(module, fieldName)); module.onChange(new Runnable() { public void run() { try { Object o = get(module, fieldName); value.set(o); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef dm_fieldLiveValue_debug\r\n print(\"dm_fieldLiveValue: setting \" + fi..."; }}); value.onChange(new Runnable() { public void run() { try { module.setField(fieldName, value.get()); ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef dm_fieldLiveValue_debug\r\n print(\"dm_fieldLiveValue: setting 2 \" + ..."; }}); return value; } finally { unlock(__23); } } static JPanel smartAddWithLayout(JPanel panel, Object layout, List parts) { for (Object o : parts) panel.add(wrapForSmartAdd(o), layout); return panel; } static JPanel smartAddWithLayout(JPanel panel, Object layout, Object... parts) { return smartAddWithLayout(panel, layout, asList(flattenArray2(parts))); } static Object[] toObjectArray(Collection c) { List l = asList(c); return l.toArray(new Object[l.size()]); } static List nonNulls(List l) { return withoutNulls(l); } static List nonNulls(A[] l) { return withoutNulls(l); } static Map nonNulls(Map map) { return withoutNulls(map); } static ArrayList asList(A[] a) { return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a)); } static ArrayList asList(int[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (int i : a) l.add(i); return l; } static ArrayList asList(float[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (float i : a) l.add(i); return l; } static 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 ArrayList asList(Producer p) { ArrayList l = new ArrayList(); A a; if (p != null) while ((a = p.next()) != null) l.add(a); return l; } static ArrayList asList(Enumeration e) { ArrayList l = new ArrayList(); if (e != null) while (e.hasMoreElements()) l.add(e.nextElement()); return l; } static JLabel dm_fieldLabel(String fieldName) { return jLiveValueLabel(dm_fieldLiveValue(fieldName)); } static A makeBold(final A c) { if (c != null) { swing(new Runnable() { public void run() { try { c.setFont(c.getFont().deriveFont(Font.BOLD)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.setFont(c.getFont().deriveFont(Font.BOLD));"; }}); } return c; } static String getDialogID() { return (String) callOpt(getMainBot(), "getDialogID"); } static Object load(String varName) { readLocally(varName); return get(mc(), varName); } static Object load(String progID, String varName) { readLocally(progID, varName); return get(mc(), varName); } static void save(String varName) { saveLocally(varName); } static void save(String progID, String varName) { saveLocally(progID, varName); } static boolean infoMessage_alwaysOnTop = true; static double infoMessage_defaultTime = 5.0; // automatically switches to AWT thread for you static JWindow infoMessage(String text) { return infoMessage(text, infoMessage_defaultTime); } static JWindow infoMessage(final String text, final double seconds) { printHidingCredentials(text); return infoMessage_noprint(text, seconds); } static JWindow infoMessage_noprint(String text) { return infoMessage_noprint(text, infoMessage_defaultTime); } static JWindow infoMessage_noprint(final String _text, final double seconds) { final String text = hideCredentials(_text); if (empty(text)) return null; logQuotedWithDate(infoBoxesLogFile(), text); if (isHeadless()) return null; return (JWindow) swingAndWait(new F0() { Object get() { try { final JWindow window = showWindow(infoMessage_makePanel(text)); window.setSize(300, 150); moveToTopRightCorner(window); if (infoMessage_alwaysOnTop) window.setAlwaysOnTop(true); window.setVisible(true); if (seconds != 0) disposeWindowAfter(iround(seconds*1000), window); return window; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JWindow window = showWindow(infoMessage_makePanel(text));\r\n window.s..."; }}); } static JWindow infoMessage(Throwable e) { //showConsole(); printStackTrace(e); return infoMessage(exceptionToStringShort(e)); } static String unnull(String s) { return s == null ? "" : s; } static Collection unnull(Collection l) { return l == null ? emptyList() : l; } static List unnull(List l) { return l == null ? emptyList() : l; } static Map unnull(Map l) { return l == null ? emptyMap() : l; } static Iterable unnull(Iterable i) { return i == null ? emptyList() : i; } static A[] unnull(A[] a) { return a == null ? (A[]) new Object[0] : a; } static BitSet unnull(BitSet b) { return b == null ? new BitSet() : b; } static Pt unnull(Pt p) { return p == null ? new Pt() : p; } //ifclass Symbol static Pair unnull(Pair p) { return p != null ? p : new Pair(null, null); } static boolean endsWithLetterOrDigit(String s) { return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1)); } static void ping_okInCleanUp() { if (ping_pauseAll || ping_anyActions ) ping_impl(true); } // this syntax should be removed... static Object getThreadLocal(Object o, String name) { ThreadLocal t = (ThreadLocal) (getOpt(o, name)); return t != null ? t.get() : null; } static A getThreadLocal(ThreadLocal tl) { return tl == null ? null : tl.get(); } static A getThreadLocal(ThreadLocal tl, A defaultValue) { return or(getThreadLocal(tl), defaultValue); } static ThreadLocal print_byThread_dontCreate() { return print_byThread; } static boolean isFalse(Object o) { return eq(false, o); } static String fixNewLines(String s) { int i = indexOf(s, '\r'); if (i < 0) return s; int l = s.length(); StringBuilder out = new StringBuilder(l); out.append(s, 0, i); for (; i < l; i++) { char c = s.charAt(i); if (c != '\r') out.append(c); else { out.append('\n'); if (i+1 < l && s.charAt(i+1) == '\n') ++i; } } return out.toString(); } static void print_append(Appendable buf, String s, int max) { try { synchronized(buf) { buf.append(s); if (buf instanceof StringBuffer) rotateStringBuffer(((StringBuffer) buf), max); else if (buf instanceof StringBuilder) rotateStringBuilder(((StringBuilder) buf), max); } } catch (Exception __e) { throw rethrow(__e); } } static boolean eq(Object a, Object b) { return a == b || (a == null ? b == null : b != null && a.equals(b)); } static int ifloor(double d) { return (int) Math.floor(d); } static long ratio(long x, long y) { return y == 0 ? 0 : x/y; } static double ratio(double x, double y) { return y == 0 ? 0 : x/y; } static String str(Object o) { return o == null ? "null" : o.toString(); } static String str(char[] c) { return new String(c); } static char charPlus(char a, int b) { return (char) (((int) a) + b); } static ThreadLocal>> agiBlue_postInSlice_queue = new ThreadLocal(); static String agiBlue_postInSlice(String slice, String a, String b, String c) { List> queue = agiBlue_postInSlice_queue.get(); if (queue != null) { queue.add(ll(slice, a, b, c)); return "Queued"; } else return loadPage(agiBlueURL() + "/bot/post" + hquery("slice", slice, "q" , a, "key" , b, "value" , c)); } static String agiBlue_chessPieceImagesSlice() { return "rowmdrceiqdnlfso"; } static Map mapKeyAndFunction(Iterable l, Object f) { return mapKeyAndFunction(f, l); } static Map mapKeyAndFunction(Object f, Iterable l) { HashMap map = new HashMap(); if (l != null) for (Object o : l) map.put(o, callF(f, o)); return map; } static Map similarEmptyMap(Map m) { if (m instanceof TreeMap) return new TreeMap(((TreeMap) m).comparator()); if (m instanceof LinkedHashMap) return new LinkedHashMap(); // default to a hash map return new HashMap(); } static Pair reversedPair(Pair p) { return p == null ? null : pair(p.b, p.a); } static List> mapPairsA(final Object f, Iterable> l) { return mapPairA(f, l); } static List> mapPairsA(F1 f, Iterable> l) { return mapPairA(f, l); } static List> mapPairsA(IF1 f, Iterable> l) { return mapPairA(f, l); } static String parseImageSnippetURL(String url) { String id = regexpExtract("\\d+$", url); return id == null ? null : "#" + id; } static List filter(Iterable c, Object pred) { if (pred instanceof F1) return filter(c, (F1) pred); List x = new ArrayList(); if (c != null) for (Object o : c) if (isTrue(callF(pred, o))) x.add(o); return x; } static List filter(Object pred, Iterable c) { return filter(c, pred); } static List filter(Iterable c, F1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (pred.get(o)) x.add(o); return x; } static List filter(F1 pred, Iterable c) { return filter(c, pred); } //ifclass IF1 static List filter(Iterable c, IF1 pred) { List x = new ArrayList(); if (c != null) for (B o : c) if (pred.get(o)) x.add(o); return x; } static List filter(IF1 pred, Iterable c) { return filter(c, pred); } //endif static boolean isURL(String s) { return startsWithOneOf(s, "http://", "https://", "file:"); } static Set ai_chessPiecesSet_cache; static Set ai_chessPiecesSet() { if (ai_chessPiecesSet_cache == null) ai_chessPiecesSet_cache = ai_chessPiecesSet_load(); return ai_chessPiecesSet_cache; } static Set ai_chessPiecesSet_load() { return asCISet(ai_chessPieces()); } static List> agiBlue_pagesAndValuesForKey(String slice, String key) { List> l = new ArrayList(); for (Map map : (List) loadJSONPage(agiBlueURL() + "/bot/entriesForKey" + hquery("slice", slice, "key", key))) l.add(pair((String) map.get("q"), (String) map.get("value"))); return l; } static Set asSet(Object[] array) { HashSet set = new HashSet(); for (Object o : array) if (o != null) set.add(o); return set; } static Set asSet(String[] array) { TreeSet set = new TreeSet(); for (String o : array) if (o != null) set.add(o); return set; } static Set asSet(Iterable l) { if (l instanceof Set) return (Set) l; HashSet set = new HashSet(); for (A o : unnull(l)) if (o != null) set.add(o); return set; } static boolean loadBufferedImage_useImageCache = true; static BufferedImage loadBufferedImage(String snippetIDOrURLOrFile) { try { ping(); if (snippetIDOrURLOrFile == null) return null; if (isURL(snippetIDOrURLOrFile)) return imageIO_readURL(snippetIDOrURLOrFile); if (isAbsolutePath(snippetIDOrURLOrFile)) return loadBufferedImage(new File(snippetIDOrURLOrFile)); if (!isSnippetID(snippetIDOrURLOrFile)) throw fail("Not a URL or snippet ID or file: " + snippetIDOrURLOrFile); String snippetID = "" + parseSnippetID(snippetIDOrURLOrFile); IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return loadBufferedImage(rl.loadLibrary(snippetID)); File dir = imageSnippetsCacheDir(); if (loadBufferedImage_useImageCache) { dir.mkdirs(); File file = new File(dir, snippetID + ".png"); if (file.exists() && file.length() != 0) try { return ImageIO.read(file); } catch (Throwable e) { e.printStackTrace(); // fall back to loading from sourceforge } } String imageURL = snippetImageURL_http(snippetID); print("Loading image: " + imageURL); BufferedImage image = imageIO_readURL(imageURL); if (loadBufferedImage_useImageCache) { File tempFile = new File(dir, snippetID + ".tmp." + System.currentTimeMillis()); ImageIO.write(image, "png", tempFile); tempFile.renameTo(new File(dir, snippetID + ".png")); //Log.info("Cached image."); } //Log.info("Loaded image."); return image; } catch (Exception __e) { throw rethrow(__e); } } static BufferedImage loadBufferedImage(File file) { try { return file.isFile() ? ImageIO.read(file) : null; } catch (Exception __e) { throw rethrow(__e); } } static List firstOfPairs(Collection> l) { List out = new ArrayList(); for (Pair p : unnull(l)) out.add(firstOfPair(p)); return out; } static int intRatio_ceil(int a, int b) { return idiv_ceil(a, b); } static ArrayList emptyList() { return new ArrayList(); //ret Collections.emptyList(); } static ArrayList emptyList(int capacity) { return new ArrayList(max(0, capacity)); } // Try to match capacity static ArrayList emptyList(Iterable l) { return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList(); } static ArrayList emptyList(Object[] l) { return emptyList(l(l)); } // get correct type at once static ArrayList emptyList(Class c) { return new ArrayList(); } static List subList(List l, int startIndex) { return subList(l, startIndex, l(l)); } static List subList(int startIndex, int endIndex, List l) { return subList(l, startIndex, endIndex); } static List subList(List l, int startIndex, int endIndex) { if (l == null) return null; int n = l(l); startIndex = Math.max(0, startIndex); endIndex = Math.min(n, endIndex); if (startIndex >= endIndex) return ll(); if (startIndex == 0 && endIndex == n) return l; return l.subList(startIndex, endIndex); } static ArrayList toList(A[] a) { return asList(a); } static ArrayList toList(int[] a) { return asList(a); } static ArrayList toList(Set s) { return asList(s); } static ArrayList toList(Iterable s) { return asList(s); } static A optPar(ThreadLocal tl, A defaultValue) { A a = tl.get(); if (a != null) { tl.set(null); return a; } return defaultValue; } static A optPar(ThreadLocal tl) { return optPar(tl, null); } static Object optPar(Object[] params, String name) { return optParam(params, name); } static Object optPar(String name, Object[] params) { return optParam(params, name); } static Object optPar(String name, Map params) { return optParam(name, params); } static A optPar(Object[] params, String name, A defaultValue) { return optParam(params, name, defaultValue); } static A optPar(String name, Object[] params, A defaultValue) { return optParam(params, name, defaultValue); } static int intSum(Collection c, String field) { int sum = 0; for (Object o : unnull(c)) sum += toInt(getOpt(o, field)); return sum; } static int intSum(Iterable l) { int sum = 0; for (Integer i : unnull(l)) if (i != null) sum += i; return sum; } static List mapMethod(Object[] l, final String methodName) { return map(l, new F1() { Object get(Object o) { try { return callOpt(o, methodName); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callOpt(o, methodName)"; }}); } static List mapMethod(Iterable c, final String methodName) { return map(c, new F1() { Object get(Object o) { try { return callOpt(o, methodName); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callOpt(o, methodName)"; }}); } static List mapMethod(String methodName, Iterable c) { return mapMethod(c, methodName); } static List mapMethod(String methodName, Enumeration c) { return mapMethod(methodName, enumerationToIterator(c)); } static int getWidth(Component c) { return c == null ? 0 : (int) swingCall(c, "getWidth"); } static int intMax(Collection c, String field) { int max = Integer.MIN_VALUE; for (Object o : c) max = Math.max(max, toInt(getOpt(o, field))); return max; } static int intMax(Iterable l) { int max = Integer.MIN_VALUE; for (int i : unnull(l)) max = Math.max(max, i); return max; } static int getHeight(Component c) { return c == null ? 0 : (int) swingCall(c, "getHeight"); } static void copyBufferedImage(BufferedImage src, int srcx, int srcy, BufferedImage dest, int destx, int desty, int w, int h) { copyImagePart(src, srcx, srcy, dest, destx, desty, w, h); } static void copyBufferedImage(BufferedImage src, BufferedImage dest, int destx, int desty) { if (src != null) copyBufferedImage(src, 0, 0, dest, destx, desty, src.getWidth(), src.getHeight()); } static RGBImage mergeImagesVertically(RGBImage... images) { return mergeImagesVertically(toList(images)); } static RGBImage mergeImagesVertically(List images, Object... __) { int spacing = optPar("spacing",__, imageMergeSpacing()); RGB spaceColor = optPar("spaceColor",__, new RGB(0.9f)); int h = intSum(images, "height")+(l(images)-1)*spacing, w = intMax(images, "width"); RGBImage out = new RGBImage(w, h, spaceColor); int y = 0; for (int i = 0; i < l(images); i++) { RGBImage img = images.get(i); int x = (w-img.w())/2; copyRGBImage(img, 0, 0, out, x, y); y += img.h() + spacing; } return out; } static RGBImage toRGBImage(BWImage img) { return img == null ? null : img.toRGB(); } static RGBImage toRGBImage(BufferedImage img) { return img == null ? null : new RGBImage(img); } static List assertLength(int length, List l) { assertEquals(length, l(l)); return l; } static String assertLength(int length, String s) { assertEquals(s, length, l(s)); return s; } static String assertLength(String s, int length) { return assertLength(length, s); } static Pair pair(A a, B b) { return new Pair(a, b); } static Pair pair(A a) { return new Pair(a, a); } static int charDiff(char a, char b) { return (int) a-(int) b; } static int charDiff(String a, char b) { return charDiff(stringToChar(a), b); } static String upper(String s) { return s == null ? null : s.toUpperCase(); } static char upper(char c) { return Character.toUpperCase(c); } static A second(List l) { return get(l, 1); } static A second(Iterable l) { if (l == null) return null; Iterator it = iterator(l); if (!it.hasNext()) return null; it.next(); return it.hasNext() ? it.next() : null; } static A second(A[] bla) { return bla == null || bla.length <= 1 ? null : bla[1]; } static B second(Pair p) { return p == null ? null : p.b; } static A second(Producer p) { if (p == null) return null; if (p.next() == null) return null; return p.next(); } static char second(String s) { return charAt(s, 1); } static double toDouble(Object o) { if (o instanceof Number) return ((Number) o).doubleValue(); if (o instanceof BigInteger) return ((BigInteger) o).doubleValue(); if (o == null) return 0.0; throw fail(o); } static boolean boolPar(ThreadLocal tl) { return boolOptParam(tl); } // defaults to false static boolean boolPar(Object[] __, String name) { return boolOptParam(__, name); } static boolean boolPar(String name, Object[] __) { return boolOptParam(__, name); } static boolean boolPar(String name, Map __) { return boolOptParam(name, __); } static boolean boolPar(String name, Object[] params, boolean defaultValue) { return optParam(params, name, defaultValue); } // threshold 0.75 + Cubed distance from black 3.0 + blur + min 3", static BWImage chessOCR_piecePreprocessing_1(BufferedImage img, Object... __) { int version = optPar("version",__, 1); BWImage bw = bwImageTo2Bit(0.75f, img_cubedDistanceFromColor_withGain(rgbBlack(), 3.0, blurFilterBufferedImage( minFilterBufferedImage(3, img)))); if (version == 1) bw = bwAutoCrop(bw); return bw; } // Cubed distance from black 2.5 + min", static BWImage chessOCR_piecePreprocessingForFillGrade_1(BufferedImage img) { return img_cubedDistanceFromColor_withGain(rgbBlack(), 2.5, img); } static byte[] ocr_sideProfile_scaledTo127(int n, double stopAtRatio, BWImage img) { return concatByteArrays_reverseSecond( ocr_leftProfile_scaledTo127(n, stopAtRatio, img), ocr_rightProfile_scaledTo127(n, stopAtRatio, img)); } static float bwAverageBrightness(BWImage img) { return img == null ? 0 : (float) img.averageBrightness(); } static JFrame showPackedFrame(String title, Component contents) { return packFrame(showFrame(title, contents)); } static JFrame showPackedFrame(Component contents) { return packFrame(showFrame(contents)); } static Component frameIcon(Component c, String imageID) { setFrameIconLater(c, imageID); return c; } static Component frameIcon(String imageID, Component c) { setFrameIconLater(c, imageID); return c; } static A setFrameTitle(A c, final String title) { final Frame f = getAWTFrame(c); if (f != null) { swing(new Runnable() { public void run() { try { f.setTitle(title); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.setTitle(title);"; }}); } return c; } static A setFrameTitle(String title, A c) { return setFrameTitle(c, title); } // magically find a field called "frame" in main class :-) static JFrame setFrameTitle(String title) { Object f = getOpt(mc(), "frame"); if (f instanceof JFrame) return setFrameTitle((JFrame) f, title); return null; } static String formatWithThousands(long l) { return formatWithThousandsSeparator(l); } static double fraction(double d) { return d % 1; } static String n_fancy2(long l, String singular, String plural) { return formatWithThousandsSeparator(l) + " " + trim(l == 1 ? singular : plural); } static String n_fancy2(Collection l, String singular, String plural) { return n_fancy2(l(l), singular, plural); } static String n_fancy2(Map m, String singular, String plural) { return n_fancy2(l(m), singular, plural); } static String n_fancy2(Object[] a, String singular, String plural) { return n_fancy2(l(a), singular, plural); } static boolean rectEmpty(Rect r) { return r == null || r.w <= 0 || r.h <= 0; } static JCheckBox jCheckBox() { return swingNu(JCheckBox.class); } static JCheckBox jCheckBox(boolean checked) { return swingNu(JCheckBox.class, "", checked); } static JCheckBox jCheckBox(String text, boolean checked) { return swingNu(JCheckBox.class, text, checked); } static JCheckBox jCheckBox(String text) { return swingNu(JCheckBox.class, text); } static JCheckBox jCheckBox(String text, boolean checked, final Object onChange) { JCheckBox cb = jCheckBox(checked, onChange); cb.setText(text); return cb; } // onChange can be a Runnable or a voidfunc(bool) static JCheckBox jCheckBox(boolean checked, final Object onChange) { final JCheckBox cb = jCheckBox(checked); cb.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { pcallF(onChange, cb.isSelected()); } }); return cb; } static JTextField jTextField() { return jTextField(""); } static JTextField jTextField(final String text) { return swing(new F0() { JTextField get() { try { JTextField tf = new JTextField(unnull(text)); standardTextFieldPopupMenu(tf); jenableUndoRedo(tf); tf.selectAll(); return tf; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JTextField tf = new JTextField(unnull(text));\r\n standardTextFieldPopupMenu..."; }}); } static JTextField jTextField(Object o) { return jTextField(strOrEmpty(o)); } static JDesktopPane mainDesktopPane_value; static JDesktopPane mainDesktopPane() { return mainDesktopPane_value; } static JPanel showInternalFrameFormTitled(final JDesktopPane desktop, final String title, final Object... _parts) { JPanel panel = showForm_makePanel(true, _parts); showForm_makeInternalFrame(desktop, title, panel); return panel; } static JFrame showForm_makeFrame(String title, JPanel panel) { return handleEscapeKey(minFrameWidth(showPackedFrame(title, withMargin(panel)), 400)); } static List showForm_arrange1(List> l) { int minW = showForm_leftWidth(l); List out = new ArrayList(); for (List row : l) out.add(westAndCenter(withRightMargin(showForm_gapBetweenColumns, jMinWidth(minW, first(row))), second(row))); return out; } static List> showForm_makeComponents(final Boolean internalFrame, Object... _parts) { List> l = new ArrayList(); List parts = asList(_parts); JButton submitButton = null; for (int i = 0; i < l(parts); i++) { final Object o = parts.get(i), next = get(parts, i+1); if (o instanceof String && next instanceof Component) setComponentID((Component) next, (String) o); if (o instanceof Component || o instanceof String || next instanceof Component) { // smartAdd accepts strings l.add(mapLL("wrapForSmartAdd", o == null ? new JPanel() : o instanceof String ? humanizeFormLabel((String) o) : o, next)); if (next instanceof JButton && submitButton == null) submitButton = (JButton) next; i++; } else if (isRunnable(o)) l.add(mapLL("wrapForSmartAdd",null, submitButton = jbutton(showFormSubmitButtonName(), new Runnable() { public void run() { try { Object result = call(o); if (neq(Boolean.FALSE, result)) { if (isTrue(internalFrame)) disposeInternalFrame(heldInstance(JButton.class)); else if (isFalse(internalFrame)) disposeFrame(heldInstance(JButton.class)); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Object result = call(o);\r\n if (neq(Boolean.FALSE, result)) {\r\n ..."; }}))); else print("showForm: Unknown element type: " + getClassName(o)); } if (submitButton != null) { final JButton _submitButton = submitButton; onEnterInAllTextFields(concatLists(l), new Runnable() { public void run() { try { clickButton(_submitButton) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "clickButton(_submitButton)"; }}); } // massage labels for (List row : l) { JComponent left = first(row); if (left instanceof JLabel) makeBold((JLabel) left).setVerticalAlignment(JLabel.TOP); } return l; } static A swingConstruct(final Class c, final Object... args) { return swing(new F0() { A get() { try { return nuObject(c, args); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret nuObject(c, args);"; }}); } static A setVerticalAlignment(final int pos, final A a) { if (a != null) { swing(new Runnable() { public void run() { try { a.setVerticalAlignment(pos); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.setVerticalAlignment(pos);"; }}); } return a; } static A setVerticalAlignment(final int pos, final A a) { if (a != null) { swing(new Runnable() { public void run() { try { a.setVerticalAlignment(pos); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.setVerticalAlignment(pos);"; }}); } return a; } static String jlabel_textAsHTML(String text) { return hhtml(replace(htmlencode(text), "\n", "
")); } static String dropPrefix(String prefix, String s) { return s == null ? null : s.startsWith(prefix) ? s.substring(l(prefix)) : s; } static ActionListener actionListenerInNewThread(final Object runnable) { return actionListenerInNewThread(runnable, null); } static ActionListener actionListenerInNewThread(final Object runnable, final Object instanceToHold) { if (runnable instanceof ActionListener) return (ActionListener) runnable; return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { startThread("Action Listener", new Runnable() { public void run() { try { AutoCloseable __1651 = holdInstance(instanceToHold); try { callF(runnable); } finally { _close(__1651); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __1651 = holdInstance(instanceToHold); try {\r\n callF(runna..."; }}); } catch (Throwable __e) { messageBox(__e); }}}; } static
AutoCloseable tempDisposeWindow(final Window w) { return new AutoCloseable() { public void close() { disposeWindow(w); } }; } static JWindow infoBox_noHide(String message) { return infoBoxForever(message); } // there are random upload errors... static int uploadToImageServerIfNotThere_tries = 3; static String uploadToImageServerIfNotThere(BufferedImage img, String name) { return uploadToImageServerIfNotThere(null, img, name); } static String uploadToImageServerIfNotThere(File f, BufferedImage img, String name) { String md5 = md5OfRGBImage(new RGBImage(img)); Throwable lastException = null; for (int tries = 0; tries < uploadToImageServerIfNotThere_tries; tries++) try { long id = imageServerCheckMD5(md5); if (id == 0) return uploadToImageServer_new(f, img, name); else return snippetImgLink(fsI(id)); } catch (Throwable e) { lastException = printException(e); } throw fail(lastException); } static String uploadFileToImageServer(File f) { return uploadToImageServerIfNotThere(f, loadImage2(f), f.getName()); } static String getTextTrim(JTextComponent c) { return trim(getText(c)); } // tested for editable combo box - returns the contents of text field static String getTextTrim(JComboBox cb) { return trim(getText(cb)); } static String getTextTrim(JComponent c) { if (c instanceof JLabel) return trim(((JLabel) c).getText()); if (c instanceof JComboBox) return getTextTrim((JComboBox) c); return getTextTrim((JTextComponent) c); } static boolean structure_showTiming, structure_checkTokenCount; static String structure(Object o) { return structure(o, new structure_Data()); } static String structure(Object o, structure_Data d) { StringWriter sw = new StringWriter(); d.out = new PrintWriter(sw); structure_go(o, d); String s = str(sw); if (structure_checkTokenCount) { print("token count=" + d.n); assertEquals("token count", l(javaTokC(s)), d.n); } return s; } static void structure_go(Object o, structure_Data d) { structure_1(o, d); while (nempty(d.stack)) popLast(d.stack).run(); } static void structureToPrintWriter(Object o, PrintWriter out) { structure_Data d = new structure_Data(); d.out = out; structure_go(o, d); } // leave to false, unless unstructure() breaks static boolean structure_allowShortening = false; // info on how to serialize objects of a certain class static class structure_ClassInfo { List fields; Method customSerializer; } static class structure_Data { PrintWriter out; int stringSizeLimit; int shareStringsLongerThan = 20; boolean noStringSharing = false; IdentityHashMap seen = new IdentityHashMap(); //new BitSet refd; HashMap strings = new HashMap(); HashSet concepts = new HashSet(); HashMap infoByClass = new HashMap(); HashMap persistenceInfo = new HashMap(); int n; // token count List stack = new ArrayList(); // append single token structure_Data append(String token) { out.print(token); ++n; return this; } structure_Data append(int i) { out.print(i); ++n; return this; } // append multiple tokens structure_Data append(String token, int tokCount) { out.print(token); n += tokCount; return this; } // extend last token structure_Data app(String token) { out.print(token); return this; } structure_Data app(int i) { out.print(i); return this; } } static void structure_1(final Object o, final structure_Data d) { try { if (o == null) { d.append("null"); return; } Class c = o.getClass(); boolean concept = false; structure_ClassInfo info = d.infoByClass.get(c); if (info == null) { d.infoByClass.put(c, info = new structure_ClassInfo()); info.customSerializer = findMethodNamed(c, "_serialize"); } List lFields = info.fields; if (lFields == null) { // these are never back-referenced (for readability) if (o instanceof Number) { PrintWriter out = d.out; if (o instanceof Integer) { int i = ((Integer) o).intValue(); out.print(i); d.n += i < 0 ? 2 : 1; return; } if (o instanceof Long) { long l = ((Long) o).longValue(); out.print(l); out.print("L"); d.n += l < 0 ? 2 : 1; return; } if (o instanceof Short) { short s = ((Short) o).shortValue(); d.append("sh "); out.print(s); d.n += s < 0 ? 2 : 1; return; } if (o instanceof Float) { d.append("fl ", 2); quoteToPrintWriter(str(o), out); return; } if (o instanceof Double) { d.append("d(", 3); quoteToPrintWriter(str(o), out); d.append(")"); return; } if (o instanceof BigInteger) { out.print("bigint("); out.print(o); out.print(")"); d.n += ((BigInteger) o).signum() < 0 ? 5 : 4; return; } } if (o instanceof Boolean) { d.append(((Boolean) o).booleanValue() ? "t" : "f"); return; } if (o instanceof Character) { d.append(quoteCharacter((Character) o)); return; } if (o instanceof File) { d.append("File ").append(quote(((File) o).getPath())); return; } // referencable objects follow Integer ref = d.seen.get(o); if (o instanceof String && ref == null) ref = d.strings.get((String) o); if (ref != null) { /*d.refd.set(ref);*/ d.append("t").app(ref); return; } if (!(o instanceof String)) d.seen.put(o, d.n); // record token number else { String s = d.stringSizeLimit != 0 ? shorten((String) o, d.stringSizeLimit) : (String) o; if (!d.noStringSharing) { if (d.shareStringsLongerThan == Integer.MAX_VALUE) d.seen.put(o, d.n); if (l(s) >= d.shareStringsLongerThan) d.strings.put(s, d.n); } quoteToPrintWriter(s, d.out); d.n++; return; } if (o instanceof Set) { /*O set2 = unwrapSynchronizedSet(o); if (set2 != o) { d.append("sync"); o = set2; } TODO */ if (((Set) o) instanceof TreeSet) { d.append(isCISet_gen(((Set) o)) ? "ciset" : "treeset"); structure_1(new ArrayList(((Set) o)), d); return; } // assume it's a HashSet or LinkedHashSet d.append(((Set) o) instanceof LinkedHashSet ? "lhs" : "hashset"); structure_1(new ArrayList(((Set) o)), d); return; } String name = c.getName(); if (o instanceof Collection && !startsWith(name, "main$") /* && neq(name, "main$Concept$RefL") */) { // it's a list if (name.equals("java.util.Collections$SynchronizedList") || name.equals("java.util.Collections$SynchronizedRandomAccessList")) { d.append("sync "); { structure_1(unwrapSynchronizedList(((List) o)), d); return; } } else if (name.equals("java.util.LinkedList")) d.append("ll"); d.append("["); final int l = d.n; final Iterator it = ((Collection) o).iterator(); d.stack.add(new Runnable() { public void run() { try { if (!it.hasNext()) d.append("]"); else { d.stack.add(this); if (d.n != l) d.append(", "); structure_1(it.next(), d); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!it.hasNext())\r\n d.append(\"]\");\r\n else {\r\n d.sta..."; }}); return; } if (o instanceof Map && !startsWith(name, "main$")) { if (o instanceof LinkedHashMap) d.append("lhm"); else if (o instanceof HashMap) d.append("hm"); else if (o instanceof TreeMap) d.append(isCIMap_gen(((TreeMap) o)) ? "cimap" : "tm"); else if (name.equals("java.util.Collections$SynchronizedMap") || name.equals("java.util.Collections$SynchronizedSortedMap") || name.equals("java.util.Collections$SynchronizedNavigableMap")) { d.append("sync "); { structure_1(unwrapSynchronizedMap(((Map) o)), d); return; } } d.append("{"); final int l = d.n; final Iterator it = ((Map) o).entrySet().iterator(); d.stack.add(new Runnable() { boolean v = false; Map.Entry e; public void run() { if (v) { d.append("="); v = false; d.stack.add(this); structure_1(e.getValue(), d); } else { if (!it.hasNext()) d.append("}"); else { e = (Map.Entry) it.next(); v = true; d.stack.add(this); if (d.n != l) d.append(", "); structure_1(e.getKey(), d); } } } }); return; } if (c.isArray()) { if (o instanceof byte[]) { d.append("ba ").append(quote(bytesToHex((byte[]) o))); return; } final int n = Array.getLength(o); if (o instanceof boolean[]) { String hex = boolArrayToHex((boolean[]) o); int i = l(hex); while (i > 0 && hex.charAt(i-1) == '0' && hex.charAt(i-2) == '0') i -= 2; d.append("boolarray ").append(n).app(" ").append(quote(substring(hex, 0, i))); return; } String atype = "array", sep = ", "; if (o instanceof int[]) { //ret "intarray " + quote(intArrayToHex((int[]) o)); atype = "intarray"; sep = " "; } d.append(atype).append("{"); d.stack.add(new Runnable() { int i; public void run() { if (i >= n) d.append("}"); else { d.stack.add(this); if (i > 0) d.append(", "); structure_1(Array.get(o, i++), d); } } }); return; } if (o instanceof Class) { d.append("class(", 2).append(quote(((Class) o).getName())).append(")"); return; } if (o instanceof Throwable) { d.append("exception(", 2).append(quote(((Throwable) o).getMessage())).append(")"); return; } if (o instanceof BitSet) { BitSet bs = (BitSet) o; d.append("bitset{", 2); int l = d.n; for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) { if (d.n != l) d.append(", "); d.append(i); } d.append("}"); return; } // Need more cases? This should cover all library classes... if (name.startsWith("java.") || name.startsWith("javax.")) { d.append("j ").append(quote(str(o))); return; // Hm. this is not unstructure-able } /*if (name.equals("main$Lisp")) { fail("lisp not supported right now"); }*/ if (info.customSerializer != null) { // custom serialization (_serialize method) Object o2 = invokeMethod(info.customSerializer, o); d.append("cu "); String shortName = dropPrefix("main$", name); d.append(shortName); d.out.append(' '); structure_1(o2, d); return; } String dynName = shortDynamicClassName(o); if (concept && !d.concepts.contains(dynName)) { d.concepts.add(dynName); d.append("c "); } // serialize an object with fields. // first, collect all fields and values in fv. TreeSet fields = new TreeSet(new Comparator() { public int compare(Field a, Field b) { return stdcompare(a.getName(), b.getName()); } }); Class cc = c; while (cc != Object.class) { for (Field field : getDeclaredFields_cached(cc)) { String fieldName = field.getName(); if (fieldName.equals("_persistenceInfo")) d.persistenceInfo.put(c, field); if ((field.getModifiers() & (java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.TRANSIENT)) != 0) continue; fields.add(field); // put special cases here...? } cc = cc.getSuperclass(); } // TODO: S fieldOrder = getOpt(c, "_fieldOrder"); lFields = asList(fields); // Render this$1 first because unstructure needs it for constructor call. int n = l(lFields); for (int i = 0; i < n; i++) { Field f = lFields.get(i); if (f.getName().equals("this$1")) { lFields.remove(i); lFields.add(0, f); break; } } info.fields = lFields; } // << if (lFields == null) else { // ref handling for lFields != null Integer ref = d.seen.get(o); if (ref != null) { /*d.refd.set(ref);*/ d.append("t").app(ref); return; } d.seen.put(o, d.n); // record token number } Field persistenceInfoField = (Field) (d.persistenceInfo.get(c)); Map persistenceInfo = persistenceInfoField == null ? null : (Map) persistenceInfoField.get(o); LinkedHashMap fv = new LinkedHashMap(); for (Field f : lFields) { Object value; try { value = f.get(o); } catch (Exception e) { value = "?"; } if (value != null && (persistenceInfo == null || !Boolean.FALSE.equals(persistenceInfo.get(f.getName())))) fv.put(f.getName(), value); } String name = c.getName(); String shortName = dropPrefix("main$", name); if (startsWithDigit(shortName)) shortName = name; // for anonymous classes // Now we have fields & values. Process fieldValues if it's a DynamicObject. // omit field "className" if equal to class's name if (concept && eq(fv.get("className"), shortName)) fv.remove("className"); if (o instanceof DynamicObject) { putAll(fv, (Map) fv.get("fieldValues")); fv.remove("fieldValues"); shortName = shortDynamicClassName(o); fv.remove("className"); } String singleField = fv.size() == 1 ? first(fv.keySet()) : null; d.append(shortName); d.n += countDots(shortName)*2; // correct token count final int l = d.n; final Iterator it = fv.entrySet().iterator(); d.stack.add(new Runnable() { public void run() { try { if (!it.hasNext()) { if (d.n != l) d.append(")"); } else { Map.Entry e = (Map.Entry) it.next(); d.append(d.n == l ? "(" : ", "); d.append((String) e.getKey()).append("="); d.stack.add(this); structure_1(e.getValue(), d); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!it.hasNext()) {\r\n if (d.n != l)\r\n d.append(\")\");\r\n } else..."; }}); } catch (Exception __e) { throw rethrow(__e); } } static String getString(Map map, Object key) { return map == null ? null : (String) map.get(key); } static String getString(List l, int idx) { return (String) get(l, idx); } static String getString(Object o, Object key) { if (o instanceof Map) return getString((Map) o, key); if (key instanceof String) return (String) getOpt(o, (String) key); throw fail("Not a string key: " + getClassName(key)); } static String getString(String key, Object o) { return getString(o, (Object) key); } static Object agiBlue_loadBotPage(String cmd, Object... params) { return loadJSONPage(agiBlueURL() + "/bot" + addSlashPrefix(cmd) + hquery(params)); } static Object postJSONPage(String url, Object... params) { return jsonDecode(postPage(url, params)); } static Object[] paramsPlus(Object[] a1, Object... a2) { if (a2 == null) return a1; if (a1 == null) return a2; if (l(a1) == 1 && a1[0] instanceof Map) return new Object[] { mapPlus((Map) a1[0], a2) }; assertEvenLength(a1); assertEvenLength(a2); Map map = paramsToOrderedMap(a1); int n = l(a2); for (int i = 0; i < n; i += 2) { Object key = a2[i]; if (key != null) map.put(key, a2[i+1]); } return mapToParams(map); } static String pki_signTextIncludingKey(String s, PKIKeyPair keyPair) { s = fromLines(toLines(s)); return s + "sig: " + pki_signatureForText(s, keyPair) + "\n" + "signer: " + keyPair.publicKey + "\n"; } static String jsonEncodeLines(List l) { return mapToLines("jsonEncode",l); } static Lock programLock() { return mainLock(); } static File secretProgramFile(String progID, String fileName) { return new File(getSecretProgramDir(progID), fileName); } static File secretProgramFile(String fileName) { return secretProgramFile(getProgramID(), fileName); } static PKIKeyPair pkiKeyPairFromTwoLineFile(File f) { List l = tlft(loadTextFile(f)); if (l(l) == 2) return new PKIKeyPair(second(l), first(l)); return null; } static volatile PersistableThrowable _handleException_lastException; static List _handleException_onException = synchroList(ll("printStackTrace2")); static void _handleException(Throwable e) { _handleException_lastException = persistableThrowable(e); Throwable e2 = innerException(e); if (e2.getClass() == RuntimeException.class && eq(e2.getMessage(), "Thread cancelled.") || e2 instanceof InterruptedException) return; for (Object f : cloneList(_handleException_onException)) try { callF(f, e); } catch (Throwable e3) { printStackTrace2(e3); // not using pcall here - it could lead to endless loops } } static PKIKeyPair pki_newKeyPair() { try { KeyPair keyPair = PKI.makeKeyPair(); return new PKIKeyPair( PKI.privateKeyToString(keyPair.getPrivate().getEncoded()), PKI.publicKeyToString(keyPair.getPublic())); } catch (Exception __e) { throw rethrow(__e); } } /** writes safely (to temp file, then rename) */ static File saveTextFile(String fileName, String contents) throws IOException { CriticalAction action = beginCriticalAction("Saving file " + fileName + " (" + l(contents) + " chars)"); try { File file = new File(fileName); mkdirsForFile(file); String tempFileName = fileName + "_temp"; File tempFile = new File(tempFileName); if (contents != null) { if (tempFile.exists()) try { String saveName = tempFileName + ".saved." + now(); copyFile(tempFile, new File(saveName)); } catch (Throwable e) { printStackTrace(e); } FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath()); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); PrintWriter printWriter = new PrintWriter(outputStreamWriter); printWriter.print(contents); printWriter.close(); } if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (contents != null) if (!tempFile.renameTo(file)) throw new IOException("Can't rename " + tempFile + " to " + file); vmBus_send("wroteFile", file); return file; } finally { action.done(); } } static File saveTextFile(File fileName, String contents) { try { saveTextFile(fileName.getPath(), contents); return fileName; } catch (Exception __e) { throw rethrow(__e); } } static String linesLL(String... x) { return lines(ll(x)); } static void openPlatformBrowser(String url) { try { if (isHeadless()) return; Desktop.getDesktop().browse(uri(url)); print("Opening platform-specific browser on: " + url); } catch (Exception __e) { throw rethrow(__e); } } static boolean agiBlueURL_noHTTPS = false; static String agiBlueURL_url = "https://agi.blue"; static String agiBlueURL() { return agiBlueURL_noHTTPS ? replacePrefix("https://", "http://", agiBlueURL_url) : agiBlueURL_url; } static String hquery(Map params) { return htmlQuery(params); } static String hquery(Object... data) { return htmlQuery(data); } // one array plus more elements static Object[] arrayPlus(Object[] a1, Object... a2) { return concatArrays(a1, a2); } static Window getWindow(Object o) { if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof Window) return (Window) c; c = c.getParent(); } return null; } static A heldInstance(Class c) { List l = holdInstance_l.get(); for (int i = l(l)-1; i >= 0; i--) { Object o = l.get(i); if (isInstanceOf(o, c)) return (A) o; } throw fail("No instance of " + className(c) + " held"); } static int smartIndexOfNot(List l, A sub) { return smartIndexOfNot(l, sub, 0); } static int smartIndexOfNot(List l, A sub, int start) { int i = start, n = l(l); while (i < n && eq(l.get(i), sub)) ++i; return i; } static String secondWord(String s) { return secondJavaToken(s); } static boolean startsWith(String a, String b) { return a != null && a.startsWith(b); } static boolean startsWith(String a, char c) { return nemptyString(a) && a.charAt(0) == c; } static boolean startsWith(String a, String b, Matches m) { if (!startsWith(a, b)) return false; m.m = new String[] {substring(a, strL(b))}; return true; } static boolean startsWith(List a, List b) { if (a == null || listL(b) > listL(a)) return false; for (int i = 0; i < listL(b); i++) if (neq(a.get(i), b.get(i))) return false; return true; } public static String join(String glue, Iterable strings) { if (strings == null) return ""; if (strings instanceof Collection) { if (((Collection) strings).size() == 1) return str(first(((Collection) strings))); } StringBuilder buf = new StringBuilder(); Iterator i = strings.iterator(); if (i.hasNext()) { buf.append(i.next()); while (i.hasNext()) buf.append(glue).append(i.next()); } return buf.toString(); } public static String join(String glue, String... strings) { return join(glue, Arrays.asList(strings)); } static String join(Iterable strings) { return join("", strings); } static String join(Iterable strings, String glue) { return join(glue, strings); } public static String join(String[] strings) { return join("", strings); } static String join(String glue, Pair p) { return p == null ? "" : str(p.a) + glue + str(p.b); } static List> gridOfRects3(int w, int h, int cols, int rows) { return gridOfRects3(new Rect(0, 0, w, h), cols, rows); } static List> gridOfRects3(Rect r, int cols, int rows) { List> l = new ArrayList(); for (int row = 0; row < rows; row++) { List line = new ArrayList(); int y1 = r.y+iround(r.h*(double) row/rows); int y2 = r.y+iround(r.h*(double) (row+1)/rows); for (int col = 0; col < cols; col++) { int x1 = r.x+iround(r.w*(double) col/cols); int x2 = r.x+iround(r.w*(double) (col+1)/cols); line.add(new Rect(x1, y1, x2-x1, y2-y1)); } l.add(line); } return l; } static List bufferedImageVerticalSlices(double sliceHeight, BufferedImage img) { List out = new ArrayList(); int w = img.getWidth(), h = img.getHeight(); for (double y = 0; iround(y) < h; y += sliceHeight) { int actualY = iround(y), nextY = min(h, iround(y+sliceHeight)); if (nextY > actualY) out.add(clipBufferedImage(img, rectFromPoints(0, actualY, w, nextY))); } return out; } static double doubleRatio(double x, double y) { return y == 0 ? 0 : x/y; } static List bufferedImageHorizontalSlices(double sliceWidth, BufferedImage img) { List out = new ArrayList(); int w = img.getWidth(), h = img.getHeight(); for (double x = 0; iround(x) < w; x += sliceWidth) { int actualX = iround(x), nextX = min(w, iround(x+sliceWidth)); if (nextX > actualX) out.add(clipBufferedImage(img, rectFromPoints(actualX, 0, nextX, h))); } return out; } static double doubleAverage(int... a) { double sum = 0; for (int i = 0; i < l(a); i++) sum += a[i]; return doubleRatio(sum, l(a)); } static double doubleAverage(double... l) { return doubleRatio(doubleSum(l), l(l)); } static double doubleAverage(Collection l) { return doubleRatio(doubleSum(l), l(l)); } static List secondOfPairs(Collection> l) { return map("secondOfPair", l); } static int max(int a, int b) { return Math.max(a, b); } static int max(int a, int b, int c) { return max(max(a, b), c); } static long max(int a, long b) { return Math.max((long) a, b); } static long max(long a, long b) { return Math.max(a, b); } static double max(int a, double b) { return Math.max((double) a, b); } static float max(float a, float b) { return Math.max(a, b); } static double max(double a, double b) { return Math.max(a, b); } static int max(Collection c) { int x = Integer.MIN_VALUE; for (int i : c) x = max(x, i); return x; } static 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 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 byte max(byte[] c) { byte x = -128; for (byte d : c) if (d > x) x = d; return x; } static short max(short[] c) { short x = -0x8000; for (short d : c) if (d > x) x = d; return x; } static int max(int[] c) { int x = Integer.MIN_VALUE; for (int d : c) if (d > x) x = d; return x; } static int min(int a, int b) { return Math.min(a, b); } static long min(long a, long b) { return Math.min(a, b); } static float min(float a, float b) { return Math.min(a, b); } static float min(float a, float b, float c) { return min(min(a, b), c); } static double min(double a, double b) { return Math.min(a, b); } static double min(double[] c) { double x = Double.MAX_VALUE; for (double d : c) x = Math.min(x, d); return x; } static float min(float[] c) { float x = Float.MAX_VALUE; for (float d : c) x = Math.min(x, d); return x; } static byte min(byte[] c) { byte x = 127; for (byte d : c) if (d < x) x = d; return x; } static short min(short[] c) { short x = 0x7FFF; for (short d : c) if (d < x) x = d; return x; } static int min(int[] c) { int x = Integer.MAX_VALUE; for (int d : c) if (d < x) x = d; return x; } static ThreadLocal currentImage_var = new ThreadLocal(); static BufferedImage currentImage() { return currentImage_var.get(); } static void currentImage(BufferedImage img) { currentImage_var.set(img); } static Rect pointsRect(int x1, int y1, int x2, int y2) { return new Rect(x1, y1, x2-x1, y2-y1); } static Random random_random = new Random(); static int random(int n) { return random(random_random, n); } static int random(Random r, int n) { return n <= 0 ? 0 : r.nextInt(n); } static double random(double max) { return random()*max; } static double random() { return random_random.nextInt(100001)/100000.0; } static double random(double min, double max) { return min+random()*(max-min); } // min <= value < max static int random(int min, int max) { return min+random(max-min); } static int random(Random r, int min, int max) { return min+random(r, max-min); } static A random(List l) { return oneOf(l); } static A random(Collection c) { if (c instanceof List) return random((List) c); int i = random(l(c)); return collectionGet(c, i); } static String copyTextToClipboard(Object _text) { String text = str(_text); StringSelection selection = new StringSelection(text); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); vmBus_send("newClipboardContents", text); return text; } static AutoCloseable dm_tempMinimizeOS() { dm_minimizeOS(); return new AutoCloseable() { public String toString() { return "dm_activateOS();"; } public void close() throws Exception { dm_activateOS(); }}; } static void sleepSeconds(double s) { if (s > 0) sleep(round(s*1000)); } // Use program "scrot" to make full-screen screenshots (on Linux); prevents the bug https://bugs.openjdk.java.net/browse/JDK-7168628 // (Bug might be fixed now, so disabling.) static boolean shootScreen_useScrot = false; static BufferedImage shootScreen2() { return shootScreen2(screenRectangle()); } static BufferedImage shootScreen2(Rectangle area) { try { ping(); if (shootScreen_useScrot && eq(area, screenRectangle())) { if (!isOnPATH("scrot")) shootScreen2_fallback(); if (shootScreen_useScrot) { String filename = "screenshot-" + randomID(12) + ".png"; File f = linux_fileInRamDisk(filename); if (f == null) f = prepareProgramFile(filename); try { String cmd = "scrot " + bashQuote(f); String out = backtick(cmd); if (f.exists()) return loadPNG(f); shootScreen2_fallback(); } catch (Throwable e) { print(e); shootScreen2_fallback(); } finally { f.delete(); } } } return new Robot().createScreenCapture(area); } catch (Exception __e) { throw rethrow(__e); } } static BufferedImage shootScreen2(Rect area) { return shootScreen2(area.getRectangle()); } static BufferedImage shootScreen2(int x, int y, int w, int h) { return shootScreen2(new Rectangle(x, y, w, h)); } // internal static void shootScreen2_fallback() { if (shootScreen_useScrot) { if (isLinux()) print("Scrot failed. Reverting to internal screenshots."); shootScreen_useScrot = false; } } static int withMargin_defaultWidth = 6; static JPanel withMargin(Component c) { return withMargin(withMargin_defaultWidth, c); } static JPanel withMargin(int w, Component c) { return withMargin(w, w, c); } static JPanel withMargin(int w, int h, Component c) { return withMargin(w, h, w, h, c); } static JPanel withMargin(final int top, final int left, final int bottom, final int right, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }}); } static Throwable printStackTrace2(Throwable e) { // we go to system.out now - system.err is nonsense print(getStackTrace2(e)); return e; } static void printStackTrace2() { printStackTrace2(new Throwable()); } static void printStackTrace2(String msg) { printStackTrace2(new Throwable(msg)); } static ThreadLocal> holdInstance_l = new ThreadLocal(); static AutoCloseable holdInstance(Object o) { if (o == null) return null; listThreadLocalAdd(holdInstance_l, o); return new AutoCloseable() { public void close() { listThreadLocalPopLast(holdInstance_l); } }; } static B secondOfPair(Pair p) { return p == null ? null : p.b; } static RGBImage loadImage(String snippetIDOrURL) { return new RGBImage(loadBufferedImage(snippetIDOrURL)); } static RGBImage loadImage(File f) { return new RGBImage(loadBufferedImage(f)); } static JFrame getFrame(final Object _o) { return swing(new F0() { JFrame get() { try { Object o = _o; if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof JFrame) return (JFrame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n if (o instanceof ButtonGroup) o = first(buttonsInGroup((Button..."; }}); } static int moveToTopRightCorner_inset = 20; static A moveToTopRightCorner(A a) { return moveToTopRightCorner(moveToTopRightCorner_inset, moveToTopRightCorner_inset, a); } static A moveToTopRightCorner(int insetX, int insetY, A a) { Window w = getWindow(a); if (w != null) w.setLocation(getScreenSize().width-w.getWidth()-insetX, insetY); return a; } static String f2s(File f) { return f == null ? null : f.getAbsolutePath(); } static String f2s(java.nio.file.Path p) { return p == null ? null : f2s(p.toFile()); } static Map weakHashMap() { return newWeakHashMap(); } static List keysList(Map map) { return cloneListSynchronizingOn(keys(map), map); } static boolean isImageFile(File f) { return isImageFileName(fileName(f)); } static String getClassName(Object o) { return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName(); } static boolean eqOneOf(Object o, Object... l) { for (Object x : l) if (eq(o, x)) return true; return false; } static Object call(Object o) { return callF(o); } // varargs assignment fixer for a single string array argument static Object call(Object o, String method, String[] arg) { return call(o, method, new Object[] {arg}); } static Object call(Object o, String method, Object... args) { //ret call_cached(o, method, args); return call_withVarargs(o, method, args); } static A assertNotNull(A a) { assertTrue(a != null); return a; } static A assertNotNull(String msg, A a) { assertTrue(msg, a != null); return a; } static DynModule dm_currentModule() { return (DynModule) dm_current_generic(); } static Class javax() { return getJavaX(); } static List toLinesFullTrim(String s) { List l = new ArrayList(); for (String line : toLines(s)) if (nempty(line = trim(line))) l.add(line); return l; } static List toLinesFullTrim(File f) { List l = new ArrayList(); for (String line : linesFromFile(f)) if (nempty(line = trim(line))) l.add(line); return l; } static void swingAndWait(Runnable r) { try { if (isAWTThread()) r.run(); else EventQueue.invokeAndWait(addThreadInfoToRunnable(r)); } catch (Exception __e) { throw rethrow(__e); } } static Object swingAndWait(final Object f) { if (isAWTThread()) return callF(f); else { final Var result = new Var(); swingAndWait(new Runnable() { public void run() { try { result.set(callF(f)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "result.set(callF(f));"; }}); return result.get(); } } static Map newDangerousWeakHashMap() { return _registerDangerousWeakMap(synchroMap(new WeakHashMap())); } // initFunction: voidfunc(Map) - is called initially, and after clearing the map static Map newDangerousWeakHashMap(Object initFunction) { return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction); } static HashMap> callMC_cache = new HashMap(); static String callMC_key; static Method callMC_value; // varargs assignment fixer for a single string array argument static Object callMC(String method, String[] arg) { return callMC(method, new Object[] {arg}); } static Object callMC(String method, Object... args) { try { Method me; if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround synchronized(callMC_cache) { me = method == callMC_key ? callMC_value : null; } if (me != null) try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } List m; synchronized(callMC_cache) { m = callMC_cache.get(method); } if (m == null) { if (callMC_cache.isEmpty()) { callMC_makeCache(); m = callMC_cache.get(method); } if (m == null) throw fail("Method named " + method + " not found in main"); } int n = m.size(); if (n == 1) { me = m.get(0); synchronized(callMC_cache) { callMC_key = method; callMC_value = me; } try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } } for (int i = 0; i < n; i++) { me = m.get(i); if (call_checkArgs(me, args, false)) return invokeMethod(me, null, args); } throw fail("No method called " + method + " with matching arguments found in main"); } catch (Exception __e) { throw rethrow(__e); } } static void callMC_makeCache() { synchronized(callMC_cache) { callMC_cache.clear(); Class _c = (Class) mc(), c = _c; while (c != null) { for (Method m : c.getDeclaredMethods()) if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) { m.setAccessible(true); multiMapPut(callMC_cache, m.getName(), m); } c = c.getSuperclass(); } } } static Object invokeMethod(Method m, Object o, Object... args) { try { try { return m.invoke(o, args); } catch (InvocationTargetException e) { throw rethrow(getExceptionCause(e)); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args))); } } catch (Exception __e) { throw rethrow(__e); } } static boolean call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) print("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) { Object arg = args[i]; if (!(arg == null ? !types[i].isPrimitive() : isInstanceX(types[i], arg))) { if (debug) print("Bad parameter " + i + ": " + arg + " vs " + types[i]); return false; } } return true; } static String nullIfEmpty(String s) { return isEmpty(s) ? null : s; } static Map nullIfEmpty(Map map) { return isEmpty(map) ? null : map; } static List nullIfEmpty(List l) { return isEmpty(l) ? null : l; } static boolean neq(Object a, Object b) { return !eq(a, b); } static Color toColor(RGB rgb) { return rgb == null ? null : rgb.getColor(); } static Color toColor(int rgb) { return new Color(rgb); } static Color toColor(String hex) { return awtColor(hex); } static Field getOpt_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static RuntimeException asRuntimeException(Throwable t) { if (t instanceof Error) _handleError((Error) t); return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static JScrollPane jscroll(final Component c) { return swing(new F0() { JScrollPane get() { try { return new JScrollPane(c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret new JScrollPane(c);"; }}); } static JPanel jFullCenter(final Component c) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(new GridBagLayout()); panel.add(c); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new GridBagLayout);\r\n panel.add(c);\r\n ret panel;"; }}); } static JLabel jLiveValueLabel(final LiveValue lv) { return bindJLabelToLiveValue(jlabel(), lv); } static String repeat(char c, int n) { n = Math.max(n, 0); char[] chars = new char[n]; for (int i = 0; i < n; i++) chars[i] = c; return new String(chars); } static List repeat(A a, int n) { n = Math.max(n, 0); List l = new ArrayList(n); for (int i = 0; i < n; i++) l.add(a); return l; } static List repeat(int n, A a) { return repeat(a, n); } static ActionListener actionListener(final Object runnable) { return actionListener(runnable, null); } static ActionListener actionListener(final Object runnable, final Object instanceToHold) { if (runnable instanceof ActionListener) return (ActionListener) runnable; final Object info = _threadInfo(); return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { _threadInheritInfo(info); AutoCloseable __1654 = holdInstance(instanceToHold); try { callF(runnable); } finally { _close(__1654); }} catch (Throwable __e) { messageBox(__e); }}}; } static String defaultThreadName_name; static String defaultThreadName() { if (defaultThreadName_name == null) defaultThreadName_name = "A thread by " + programID(); return defaultThreadName_name; } static Runnable wrapAsActivity(Object r) { return toRunnable(r); } // runnable = Runnable or String (method name) static Thread newThread(Object runnable) { return new Thread(_topLevelErrorHandling(toRunnable(runnable))); } static Thread newThread(Object runnable, String name) { if (name == null) name = defaultThreadName(); return new Thread(_topLevelErrorHandling(toRunnable(runnable)), name); } static Thread newThread(String name, Object runnable) { return newThread(runnable, name); } static Runnable toRunnable(final Object o) { if (o instanceof Runnable) return (Runnable) o; return new Runnable() { public void run() { try { callF(o) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(o)"; }}; } static Map _registerThread_threads; static Object _onRegisterThread; // voidfunc(Thread) static Thread _registerThread(Thread t) { if (_registerThread_threads == null) _registerThread_threads = newWeakHashMap(); _registerThread_threads.put(t, true); vm_generalWeakSubMap("thread2mc").put(t, weakRef(mc())); callF(_onRegisterThread, t); return t; } static void _registerThread() { _registerThread(Thread.currentThread()); } static String unicode_downPointingTriangle() { return charToString(0x25BC); } static void fillJPopupMenu(JPopupMenu m, Object... x) { if (x == null) return; for (int i = 0; i < l(x); i++) { Object o = x[i], y = get(x, i+1); if (o instanceof List) fillJPopupMenu(m, asArray((List) o)); else if (isMenuSeparatorIndicator(o)) m.addSeparator(); else if (o instanceof LiveValue && ((LiveValue) o).getType() == String.class && isRunnableX(y)) { final LiveValue lv = (LiveValue) o; final JMenuItem mi = jmenuItem("", y); bindLiveValueListenerToComponent(mi, lv, new Runnable() { public void run() { try { String s = lv.get(); if (isCurlyBracketed(s)) { setEnabled(mi, false); s = unCurlyBracket(s); } else setEnabled(mi, true); setText(mi, s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = lv.get();\r\n if (isCurlyBracketed(s)) {\r\n setEnable..."; }}); m.add(mi); } else if (o instanceof String && isRunnableX(y)) { m.add(jmenuItem((String) o, y)); ++i; } else if (o instanceof JMenuItem) m.add((JMenuItem) o); // "call" might use wrong method else if (o instanceof String || o instanceof Action || o instanceof Component) call(m, "add", o); else if (o != null) print("Unknown menu item: " + o); } } static Object[] paramsWithout(Object[] a1, Object... keys) { if (l(a1) == 1 && a1[0] instanceof Map) return new Object[] { mapMinus((Map) a1[0], keys) }; Set set = lithashset(keys); List l = new ArrayList(); for (int i = 0; i+1 < l(a1); i += 2) if (!set.contains(a1[i])) { l.add(a1[i]); l.add(a1[i+1]); } return toObjectArray(l); } static int getPreferredWidth(Component c) { return preferredWidth(c); } static List childrenOfType(Component c, Class theClass) { List l = new ArrayList(); scanForComponents(c, theClass, l); return l; } static List childrenOfType(Class theClass, Component c) { return childrenOfType(c, theClass); } static void onFirstResize(final Component c, final Object r) { if (c != null && r != null) { swing(new Runnable() { public void run() { try { c.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { c.removeComponentListener(this); pcallF(r); } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.addComponentListener(new ComponentAdapter {\r\n public void componentRes..."; }}); } } static A _recordNewSwingComponent(A c) { if (c != null) callF((Object) vm_generalMap_get("newSwingComponentRegistry"), (Object) c); return c; } static JComponent componentToJComponent(Component c) { if (c instanceof JComponent) return (JComponent) c; if (c instanceof JFrame) return ((JFrame) c).getRootPane(); if (c == null) return null; throw fail("boohoo " + getClassName(c)); } static Object callOpt(Object o) { return callF(o); } static A callOpt(Object o, String method, Object... args) { return (A) callOpt_withVarargs(o, method, args); } static Object[] asArray(List l) { return toObjectArray(l); } static A[] asArray(Class type, List l) { return (A[]) l.toArray((Object[]) Array.newInstance(type, l.size())); } static Object[] asObjectArray(Collection l) { return toObjectArray(l); } static int parseInt(String s) { return empty(s) ? 0 : Integer.parseInt(s); } static int parseInt(char c) { return Integer.parseInt(str(c)); } static 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 JPanel smartAdd(JPanel panel, List parts) { for (Object o : parts) addToContainer(panel, wrapForSmartAdd(o)); return panel; } static JPanel smartAdd(JPanel panel, Object... parts) { return smartAdd(panel, asList(parts)); } static A bindToComponent(final A component, final Runnable onShow, final Runnable onUnShow) { { swing(new Runnable() { public void run() { try { final Var < Boolean > flag = new Var(false); component.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { if (flag.get()) print("Warning: bindToComponent logic failure"); flag.set(true); pcallF(onShow); } public void ancestorRemoved(AncestorEvent event) { if (!flag.get()) print("Warning: bindToComponent logic failure"); flag.set(false); pcallF(onUnShow); } public void ancestorMoved(AncestorEvent event) { } }); if (component.isShowing()) { // Hopefully this matches the AncestorListener logic flag.set(true); pcallF(onShow); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final Var flag = new(false);\r\n component.addAncestorListener(new ..."; }}); } return component; } static A bindToComponent(A component, Runnable onShow) { return bindToComponent(component, onShow, null); } //sbool ping_actions_shareable = true; static volatile boolean ping_pauseAll = false; static int ping_sleep = 100; // poll pauseAll flag every 100 static volatile boolean ping_anyActions = false; static Map ping_actions = newWeakHashMap(); static ThreadLocal ping_isCleanUpThread = new ThreadLocal(); // always returns true static boolean ping() { if (ping_pauseAll || ping_anyActions ) ping_impl(true /* XXX */); //ifndef LeanMode ping_impl(); endifndef return true; } // returns true when it slept static boolean ping_impl(boolean okInCleanUp) { try { if (ping_pauseAll && !isAWTThread()) { do Thread.sleep(ping_sleep); while (ping_pauseAll); return true; } if (ping_anyActions) { // don't allow sharing ping_actions if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get())) failIfUnlicensed(); Object action = null; synchronized(ping_actions) { if (!ping_actions.isEmpty()) { action = ping_actions.get(currentThread()); if (action instanceof Runnable) ping_actions.remove(currentThread()); if (ping_actions.isEmpty()) ping_anyActions = false; } } if (action instanceof Runnable) ((Runnable) action).run(); else if (eq(action, "cancelled")) throw fail("Thread cancelled."); } return false; } catch (Exception __e) { throw rethrow(__e); } } static A printStackTrace(A e) { // we go to system.out now - system.err is nonsense print(getStackTrace(e)); return e; } static void printStackTrace() { printStackTrace(new Throwable()); } static void printStackTrace(String msg) { printStackTrace(new Throwable(msg)); } static void printStackTrace(String msg, Throwable e) { printStackTrace(new Throwable(msg, e)); } static void lockOrFail(Lock lock, long timeout) { try { ping(); if (!lock.tryLock(timeout, TimeUnit.MILLISECONDS)) { String s = "Couldn't acquire lock after " + timeout + " ms."; if (lock instanceof ReentrantLock) { ReentrantLock l = (ReentrantLock) lock; s += " Hold count: " + l.getHoldCount() + ", owner: " + call(l, "getOwner"); } throw fail(s); } ping(); } catch (Exception __e) { throw rethrow(__e); } } static ReentrantLock fairLock() { return new ReentrantLock(true); } static JComboBox jComboBox(final String... items) { return jcombobox(items); } static JComboBox jComboBox(Collection items) { return jcombobox(items); } static ThreadLocal bindComboBoxToLiveValue_debug = new ThreadLocal(); static A bindComboBoxToLiveValue(final A cb, final SimpleLiveValue lv) { final boolean debug = isTrue(bindComboBoxToLiveValue_debug.get()); bindLiveValueListenerToComponent(cb, lv, new Runnable() { public void run() { try { selectItem(cb, lv.get()) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectItem(cb, lv.get())"; }}); onChange(cb, new Runnable() { public void run() { try { String s = getText(cb); // also works on editable combo boxes if (debug) print("ComboBox: " + s); lv.set(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = getText(cb); // also works on editable combo boxes\r\n if (debug)..."; }}); return cb; } static Class getFieldType(Object o, String field) { return fieldType(o, field); } static List withoutNulls(List l) { if (!containsNulls(l)) return l; List l2 = new ArrayList(); for (A a : l) if (a != null) l2.add(a); return l2; } static Map withoutNulls(Map map) { Map map2 = similarEmptyMap(map); for (A a : keys(map)) if (a != null) { B b = map.get(a); if (b != null) map2.put(a, b); } return map2; } static List withoutNulls(A[] l) { List l2 = new ArrayList(); if (l != null) for (A a : l) if (a != null) l2.add(a); return l2; } static Object mainBot; static Object getMainBot() { return mainBot; } static void readLocally(String progID, String varNames) { readLocally2(mc(), progID, varNames); } static void readLocally(String varNames) { readLocally2(mc(), programID(), varNames); } static void readLocally2(Object obj, String varNames) { readLocally2(obj, programID(), varNames); } static int readLocally_stringLength; static ThreadLocal readLocally2_allDynamic = new ThreadLocal(); static ThreadLocal readLocally2_classFinder = new ThreadLocal(); // read a string variable from standard storage // does not overwrite variable contents if there is no file static void readLocally2(Object obj, String progID, String varNames) { try { boolean allDynamic = isTrue(getAndClearThreadLocal(readLocally2_allDynamic)); for (String variableName : javaTokC(varNames)) { File textFile = new File(programDir(progID), variableName + ".text"); String value = loadTextFile(textFile); if (value != null) set(main.class, variableName, value); else { File structureFile = new File(programDir(progID), variableName + ".structure"); value = loadTextFile(structureFile); if (value == null) { File structureGZFile = new File(programDir(progID), variableName + ".structure.gz"); if (!structureGZFile.isFile()) return; //value = loadGZTextFile(structureGZFile); InputStream fis = new FileInputStream(structureGZFile); try { GZIPInputStream gis = newGZIPInputStream(fis); InputStreamReader reader = new InputStreamReader(gis, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(reader); //O o = unstructure_reader(bufferedReader); Object o = unstructure_tok(javaTokC_noMLS_onReader(bufferedReader), allDynamic, readLocally2_classFinder.get()); readLocally_set(obj, variableName, o); return; } finally { _close(fis); }} readLocally_stringLength = l(value); if (nempty(value)) readLocally_set(obj, variableName, unstructure(value, allDynamic, readLocally2_classFinder.get())); } } } catch (Exception __e) { throw rethrow(__e); } } static void readLocally_set(Object c, String varName, Object value) { Object oldValue = get(c, varName); if (oldValue instanceof List && !(oldValue instanceof ArrayList) && value != null) { // Assume it's a synchroList. value = synchroList((List) value); } set(c, varName, value); } static Class mc() { return main.class; } static void saveLocally(String variableName) { saveLocally(programID(), variableName); } static void saveLocally(String progID, String variableName) { saveLocally2(mc(), progID, variableName); } static void saveLocally2(Object obj, String variableName) { saveLocally2(obj, programID(), variableName); } static void saveLocally2(Object obj, String progID, String variableName) { Lock __503 = saveLock(); lock(__503); try { File textFile = new File(programDir(progID), variableName + ".text"); File structureFile = new File(programDir(progID), variableName + ".structure"); Object x = get(obj, variableName); if (x == null) { textFile.delete(); structureFile.delete(); } else if (x instanceof String) { saveTextFile(textFile, (String) x); structureFile.delete(); } else { saveTextFile(structureFile, javaTokWordWrap(structure(x))); textFile.delete(); } } finally { unlock(__503); } } static A printHidingCredentials(A o) { print(hideCredentials(str(o))); return o; } static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); } static String hideCredentials(String url) { try { if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url; } catch (Throwable e) { print("HideCredentials", e); } return url.replaceAll("([&?])(_pass|key)=[^&\\s\"]*", "$1$2="); } static String hideCredentials(Object o) { return hideCredentials(str(o)); } static void logQuotedWithDate(String s) { logQuotedWithTime(s); } static void logQuotedWithDate(String logFile, String s) { logQuotedWithTime(logFile, s); } static void logQuotedWithDate(File logFile, String s) { logQuotedWithTime(logFile, s); } static File infoBoxesLogFile() { return new File(javaxDataDir(), "Logs/infoBoxes.txt"); } static Boolean isHeadless_cache; static boolean isHeadless() { if (isHeadless_cache != null) return isHeadless_cache; if (isAndroid()) return isHeadless_cache = true; if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; // Also check if AWT actually works. // If DISPLAY variable is set but no X server up, this will notice. try { SwingUtilities.isEventDispatchThread(); return isHeadless_cache = false; } catch (Throwable e) { return isHeadless_cache = true; } } static JWindow showWindow(Component c) { JWindow w = new JWindow(); w.add(wrap(c)); return w; } static JPanel infoMessage_makePanel(String text) { final JTextArea ta = wrappedTextArea(text); onClick(ta, new Runnable() { public void run() { try { disposeWindow(ta) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeWindow(ta)"; }}); int size = 14; if (l(text) <= 50) size *= 2; else if (l(text) < 100) size = iround(size*1.5); ta.setFont(typeWriterFont(size)); JScrollPane sp = jscroll(ta); return withMargin(sp); } static A disposeWindowAfter(int delay, final A w) { if (w != null) swingLater(delay, new Runnable() { public void run() { try { w.dispose(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "w.dispose();"; }}); return w; } static A disposeWindowAfter(A w, double seconds) { return disposeWindowAfter(toMS_int(seconds), w); } static A disposeWindowAfter(double seconds, A w) { return disposeWindowAfter(w, seconds); } static String exceptionToStringShort(Throwable e) { lastException(e); e = getInnerException(e); String msg = hideCredentials(unnull(e.getMessage())); if (msg.indexOf("Error") < 0 && msg.indexOf("Exception") < 0) return baseClassName(e) + prependIfNempty(": ", msg); else return msg; } static Map emptyMap() { return new HashMap(); } static Object getOpt(Object o, String field) { return getOpt_cached(o, field); } static Object getOpt(String field, Object o) { return getOpt_cached(o, field); } static Object getOpt_raw(Object o, String field) { try { Field f = getOpt_findField(o.getClass(), field); if (f == null) return null; f.setAccessible(true); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } // access of static fields is not yet optimized static Object getOpt(Class c, String field) { try { if (c == null) return null; Field f = getOpt_findStaticField(c, field); if (f == null) return null; f.setAccessible(true); return f.get(null); } catch (Exception __e) { throw rethrow(__e); } } static Field getOpt_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static A or(A a, A b) { return a != null ? a : b; } static int indexOf(List l, A a, int startIndex) { if (l == null) return -1; int n = l(l); for (int i = startIndex; i < n; i++) if (eq(l.get(i), a)) return i; return -1; } static int indexOf(List l, int startIndex, A a) { return indexOf(l, a, startIndex); } static int indexOf(List l, A a) { if (l == null) return -1; return l.indexOf(a); } static int indexOf(String a, String b) { return a == null || b == null ? -1 : a.indexOf(b); } static int indexOf(String a, String b, int i) { return a == null || b == null ? -1 : a.indexOf(b, i); } static int indexOf(String a, char b) { return a == null ? -1 : a.indexOf(b); } static int indexOf(String a, int i, char b) { return indexOf(a, b, i); } static int indexOf(String a, char b, int i) { return a == null ? -1 : a.indexOf(b, i); } static int indexOf(String a, int i, String b) { return a == null || b == null ? -1 : a.indexOf(b, i); } static int indexOf(A[] x, A a) { int n = l(x); for (int i = 0; i < n; i++) if (eq(x[i], a)) return i; return -1; } static void rotateStringBuffer(StringBuffer buf, int max) { try { if (buf == null) return; synchronized(buf) { if (buf.length() <= max) return; try { int newLength = max/2; int ofs = buf.length()-newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static void rotateStringBuilder(StringBuilder buf, int max) { try { if (buf == null) return; synchronized(buf) { if (buf.length() <= max) return; try { int newLength = max/2; int ofs = buf.length()-newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static int loadPage_defaultTimeout = 60000; static ThreadLocal loadPage_charset = new ThreadLocal(); static boolean loadPage_allowGzip = true, loadPage_debug; static boolean loadPage_anonymous = false; // don't send computer ID static int loadPage_verboseness = 100000; static int loadPage_retries = 1; //60; // seconds static ThreadLocal loadPage_silent = new ThreadLocal(); static volatile int loadPage_forcedTimeout; // ms static ThreadLocal loadPage_forcedTimeout_byThread = new ThreadLocal(); // ms static ThreadLocal>> loadPage_responseHeaders = new ThreadLocal(); static ThreadLocal> loadPage_extraHeaders = new ThreadLocal(); public static String loadPageSilently(String url) { try { return loadPageSilently(new URL(loadPage_preprocess(url))); } catch (Exception __e) { throw rethrow(__e); } } public static String loadPageSilently(URL url) { try { if (url.getProtocol().equals("https")) disableCertificateValidation(); if (!networkAllowanceTest(str(url))) throw fail("Not allowed: " + url); IOException e = null; for (int tries = 0; tries < loadPage_retries; tries++) try { URLConnection con = loadPage_openConnection(url); return loadPage(con, url); } catch (IOException _e) { e = _e; if (loadPageThroughProxy_enabled) { print("Trying proxy because of: " + e); try { return loadPageThroughProxy(str(url)); } catch (Throwable e2) { print(" " + exceptionToStringShort(e2)); } } else if (loadPage_debug) print(exceptionToStringShort(e)); if (tries < loadPage_retries-1) sleepSeconds(1); } throw e; } catch (Exception __e) { throw rethrow(__e); } } static String loadPage_preprocess(String url) { if (url.startsWith("tb/")) // don't think we use this anymore url = tb_mainServer() + "/" + url; if (url.indexOf("://") < 0) url = "http://" + url; return url; } static String loadPage(String url) { try { url = loadPage_preprocess(url); if (!isTrue(loadPage_silent.get())) printWithTime("Loading: " + hideCredentials(url)); return loadPageSilently(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static String loadPage(URL url) { return loadPage(url.toExternalForm()); } static String loadPage(URLConnection con, URL url) throws IOException { return loadPage(con, url, true); } static String loadPage(URLConnection con, URL url, boolean addHeaders) throws IOException { Map extraHeaders = getAndClearThreadLocal(loadPage_extraHeaders); if (addHeaders) try { if (!loadPage_anonymous) setHeaders(con); if (loadPage_allowGzip) con.setRequestProperty("Accept-Encoding", "gzip"); con.setRequestProperty("X-No-Cookies", "1"); for (String key : keys(extraHeaders)) con.setRequestProperty(key, extraHeaders.get(key)); } catch (Throwable e) {} // fails if within doPost vm_generalSubMap("URLConnection per thread").put(currentThread(), con); loadPage_responseHeaders.set(con.getHeaderFields()); InputStream in = null; try { in = urlConnection_getInputStream(con); //vm_generalSubMap("InputStream per thread").put(currentThread(), in); if (loadPage_debug) print("Put stream in map: " + currentThread()); String contentType = con.getContentType(); if (contentType == null) { //printStruct("Headers: ", con.getHeaderFields()); throw new IOException("Page could not be read: " + hideCredentials(url)); } //print("Content-Type: " + contentType); String charset = loadPage_charset == null ? null : loadPage_charset.get(); if (charset == null) charset = loadPage_guessCharset(contentType); if ("gzip".equals(con.getContentEncoding())) { if (loadPage_debug) print("loadPage: Using gzip."); in = newGZIPInputStream(in); } Reader r; try { r = new InputStreamReader(in, unquote(charset)); } catch (UnsupportedEncodingException e) { print(toHex(utf8(charset))); throw e; } StringBuilder buf = new StringBuilder(); int n = 0; while (true) { int ch = r.read(); if (ch < 0) break; buf.append((char) ch); ++n; if ((n % loadPage_verboseness) == 0) print(" " + n + " chars read"); } return buf.toString(); } finally { if (loadPage_debug) print("loadPage done"); //vm_generalSubMap("InputStream per thread").remove(currentThread()); vm_generalSubMap("URLConnection per thread").remove(currentThread()); if (in != null) in.close(); } } static String loadPage_guessCharset(String contentType) { Matcher m = regexpMatcher("text/[a-z]+;\\s*charset=([^\\s]+)\\s*", contentType); String match = m.matches() ? m.group(1) : null; if (loadPage_debug) print("loadPage: contentType=" + contentType + ", match: " + match); /* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */ //return or(match, "ISO-8859-1"); return or(match, "UTF-8"); } static URLConnection loadPage_openConnection(URL url) { URLConnection con = openConnection(url); int timeout = toInt(loadPage_forcedTimeout_byThread.get()); if (timeout == 0) timeout = loadPage_forcedTimeout; if (timeout != 0) setURLConnectionTimeouts(con, loadPage_forcedTimeout); else setURLConnectionDefaultTimeouts(con, loadPage_defaultTimeout); return con; } static List> mapPairA(final Object f, Iterable> l) { return map(l, new F1, Pair>() { Pair get(Pair p) { try { return p == null ? null : pair((C) callF(f, p.a), p.b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "p == null ? null : pair((C) callF(f, p.a), p.b)"; }}); } static List> mapPairA(final F1 f, Iterable> l) { return mapPairA((Object) f, l); } static List> mapPairA(final IF1 f, Iterable> l) { return mapPairA((Object) f, l); } static String regexpExtract(String pat, String s) { if (s == null) return null; Matcher m = regexpMatcher(pat, s); return m.find() ? m.group() : null; } static boolean isTrue(Object o) { if (o instanceof Boolean) return ((Boolean) o).booleanValue(); if (o == null) return false; if (o instanceof ThreadLocal) return isTrue(((ThreadLocal) o).get()); throw fail(getClassName(o)); } static boolean startsWithOneOf(String s, String... l) { for (String x : l) if (startsWith(s, x)) return true; return false; } static TreeSet asCISet(Iterable c) { return toCaseInsensitiveSet(c); } static TreeSet asCISet(String... x) { return toCaseInsensitiveSet(x); } static Object loadJSONPage(String url) { return jsonDecode(loadPage(url)); } static BufferedImage imageIO_readURL(String url) { try { if (startsWith(url, "https:")) // Java is still buggy there :( disableCertificateValidation(); return ImageIO.read(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static boolean isAbsolutePath(String s) { return s != null && new File(s).isAbsolute(); } static boolean isAbsolutePath(File f) { return f != null && f.isAbsolute(); } public static boolean isSnippetID(String s) { try { parseSnippetID(s); return true; } catch (RuntimeException e) { return false; } } public static long parseSnippetID(String snippetID) { long id = Long.parseLong(shortenSnippetID(snippetID)); if (id == 0) throw fail("0 is not a snippet ID"); return id; } static IResourceLoader vm_getResourceLoader() { return proxy(IResourceLoader.class, vm_generalMap_get("_officialResourceLoader")); } static File imageSnippetsCacheDir() { return javaxCachesDir("Image-Snippets"); } static String snippetImageURL_http(String snippetID) { return snippetImageURL_http(snippetID, "png"); } static String snippetImageURL_http(String snippetID, String contentType) { return replacePrefix("https://", "http://", snippetImageURL(snippetID, contentType)).replace(":8443", ":8080"); } static A firstOfPair(Pair p) { return p == null ? null : p.a; } static int idiv_ceil(int a, int b) { return (a+b-1)/b; } static int idiv_ceil(long a, long b) { return toInt_checked((a+b-1)/b); } static A optParam(ThreadLocal tl, A defaultValue) { return optPar(tl, defaultValue); } static A optParam(ThreadLocal tl) { return optPar(tl); } static Object optParam(String name, Map params) { return mapGet(params, name); } // now also takes a map as single array entry static A optParam(Object[] opt, String name, A defaultValue) { int n = l(opt); if (n == 1 && opt[0] instanceof Map) { Map map = (Map) (opt[0]); return map.containsKey(name) ? (A) map.get(name) : defaultValue; } if (!even(l(opt))) throw fail("Odd parameter length"); for (int i = 0; i < l(opt); i += 2) if (eq(opt[i], name)) return (A) opt[i+1]; return defaultValue; } static Object optParam(Object[] opt, String name) { return optParam(opt, name, null); } static IterableIterator enumerationToIterator(final Enumeration e) { return e == null ? null : new IterableIterator() { public boolean hasNext() { return e.hasMoreElements(); } public A next() { return e.nextElement(); } }; } static Object swingCall(final Object o, final String method, final Object... args) { return swing(new F0() { Object get() { try { return call(o, method, args); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret call(o, method, args);"; }}); } static void copyImagePart(BufferedImage src, int srcx, int srcy, BufferedImage dest, int destx, int desty, int w, int h) { Graphics2D g = dest.createGraphics(); BufferedImage sub = src.getSubimage(srcx, srcy, w, h); g.drawImage(sub, destx, desty, null); g.dispose(); } static void copyRGBImage(RGBImage src, int srcX, int srcY, RGBImage dst, int dstX, int dstY) { copyRGBImage(src, srcX, srcY, dst, dstX, dstY, src.getWidth()-srcX, src.getHeight()-srcY); } static void copyRGBImage(RGBImage src, int srcX, int srcY, RGBImage dst, int dstX, int dstY, int w, int h) { w = min(w, dst.getWidth()-dstX); h = min(h, dst.getHeight()-dstY); w = min(w, src.getWidth()-srcX); h = min(h, src.getHeight()-srcY); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) dst.setPixel(dstX+x, dstY+y, src.getInt(srcX+x, srcY+y)); } static A assertEquals(Object x, A y) { return assertEquals(null, x, y); } static A assertEquals(String msg, Object x, A y) { if (assertVerbose()) return assertEqualsVerbose(msg, x, y); if (!(x == null ? y == null : x.equals(y))) throw fail((msg != null ? msg + ": " : "") + y + " != " + x); return y; } static char stringToChar(String s) { if (l(s) != 1) throw fail("bad stringToChar: " + s); return firstChar(s); } static Iterator iterator(Iterable c) { return c == null ? emptyIterator() : c.iterator(); } static char charAt(String s, int i) { return s != null && i >= 0 && i < s.length() ? s.charAt(i) : '\0'; } static boolean boolOptParam(ThreadLocal tl) { return isTrue(optPar(tl)); } // defaults to false static boolean boolOptParam(Object[] __, String name) { return isTrue(optParam(__, name)); } static boolean boolOptParam(String name, Object[] __) { return boolOptParam(__, name); } static boolean boolOptParam(String name, Map __) { return isTrue(optPar(name, __)); } static BWImage bwImageTo2Bit(BWImage img, float threshold) { int w = img.w(), h = img.h(); BWImage img2 = new BWImage(w, h); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) img2.setPixel(x, y, img.getPixel(x, y) >= threshold ? 1f : 0f); return img2; } static BWImage bwImageTo2Bit(BWImage img) { return bwImageTo2Bit(0.5f, img); } static BWImage bwImageTo2Bit(float threshold, BWImage img) { return bwImageTo2Bit(img, threshold); } static BWImage img_cubedDistanceFromColor_withGain(RGBImage img, RGB color, double gain) { int w = img.getWidth(), h = img.getHeight(); int col = color.getInt(); BWImage bw = new BWImage(w, h); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) bw.setPixel(x, y, pow(rgbDiff(img.getInt(x, y), col)*(float) gain, 3)); return bw; } static BWImage img_cubedDistanceFromColor_withGain(BufferedImage img, RGB color, double gain) { return img_cubedDistanceFromColor_withGain(new RGBImage(img), color, gain); } static BWImage img_cubedDistanceFromColor_withGain(RGB color, double gain, BufferedImage img) { return img_cubedDistanceFromColor_withGain(img, color, gain); } static RGB rgbBlack() { return new RGB(0.0); } static BufferedImage blurFilterBufferedImage(BufferedImage img) { return new BoxBlurFilter(1).get(img); } static BufferedImage minFilterBufferedImage(BufferedImage img) { return new MinimumFilter(1).get(img); } static BufferedImage minFilterBufferedImage(int radius, BufferedImage img) { return new MinimumFilter(radius).get(img); } static BWImage bwAutoCrop(BWImage img) { return img.clip(autoCropOfBWImage(img)); } static byte[] concatByteArrays_reverseSecond(byte[] a, byte[] b) { int la = l(a), lb = l(b), n = la+lb; byte[] out = new byte[n]; arraycopy(a, 0, out, 0, la); for (int i = 0; i < lb; i++) out[n-1-i] = b[i]; return out; } static byte[] ocr_leftProfile_scaledTo127(int n, double stopAtRatio, BWImage img) { int w = img.getWidth(), h = img.getHeight(); int stopAt = min(w, iround(w*stopAtRatio)); byte[] out = new byte[n]; for (int y = 0; y < n; y++) { int realY = ifloor(y*h/n); int x = 0; while (x < stopAt && img.getPixel(x, realY) > 0.5f) ++x; out[y] = (byte) iround(x*127.0/stopAt); } return out; } static byte[] ocr_rightProfile_scaledTo127(int n, double stopAtRatio, BWImage img) { int w = img.getWidth(), h = img.getHeight(); int stopAt = min(w, iround(w*stopAtRatio)); byte[] out = new byte[n]; for (int y = 0; y < n; y++) { int realY = ifloor(y*h/n); int x = 0; while (x < stopAt && img.getPixel(w-1-x, realY) > 0.5f) ++x; out[y] = (byte) iround(x*127.0/stopAt); } return out; } static int packFrame_minw = 150, packFrame_minh = 50; static A packFrame(final A c) { { swing(new Runnable() { public void run() { try { Window w = getWindow(c); if (w != null) { w.pack(); int maxW = getScreenWidth()-50, maxH = getScreenHeight()-50; w.setSize( min(maxW, max(w.getWidth(), packFrame_minw)), min(maxH, max(w.getHeight(), packFrame_minh))); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Window w = getWindow(c);\r\n if (w != null) {\r\n w.pack();\r\n int ma..."; }}); } return c; } static JFrame packFrame(ButtonGroup g) { return packFrame(getFrame(g)); } static JFrame showFrame() { return makeFrame(); } static JFrame showFrame(Object content) { return makeFrame(content); } static JFrame showFrame(String title) { return makeFrame(title); } static JFrame showFrame(String title, Object content) { return makeFrame(title, content); } static JFrame showFrame(final JFrame f) { if (f != null) { swing(new Runnable() { public void run() { try { if (frameTooSmall(f)) frameStandardSize(f); if (!f.isVisible()) f.setVisible(true); // XXX if (f.getState() == Frame.ICONIFIED) f.setState(Frame.NORMAL); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (frameTooSmall(f)) frameStandardSize(f);\r\n if (!f.isVisible()) f.setVis..."; }}); } return f; } // make or update frame static JFrame showFrame(String title, Object content, JFrame frame) { if (frame == null) return showFrame(title, content); else { frame.setTitle(title); setFrameContents(frame, content); return frame; } } static JFrame setFrameIconLater(Component c, final String imageID) { final JFrame frame = getFrame(c); if (frame != null) startThread("Loading Icon", new Runnable() { public void run() { try { final Image i = imageIcon(or2(imageID, "#1005557")).getImage(); swingLater(new Runnable() { public void run() { try { frame.setIconImage(i); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "frame.setIconImage(i);"; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final Image i = imageIcon(or2(imageID, \"#1005557\")).getImage();\r\n swingL..."; }}); return frame; } static Frame getAWTFrame(final Object _o) { return swing(new F0() { Frame get() { try { Object o = _o; /* ifdef HaveProcessing if (o instanceof PApplet) o = ((PApplet) o).getSurface(); endifdef */ if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof Frame) return (Frame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n /*\r\n ifdef HaveProcessing\r\n if (o instanceof PApplet) ..."; }}); } static String formatWithThousandsSeparator(long l) { return NumberFormat.getInstance(new Locale("en_US")).format(l); } static String trim(String s) { return s == null ? null : s.trim(); } static String trim(StringBuilder buf) { return buf.toString().trim(); } static String trim(StringBuffer buf) { return buf.toString().trim(); } static Object pcallF(Object f, Object... args) { return pcallFunction(f, args); } static A pcallF(F0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { return null; } } static B pcallF(F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static void pcallF(VF1 f, A a) { try { if (f != null) f.get(a); } catch (Throwable __e) { _handleException(__e); } } static JTextField standardTextFieldPopupMenu(final JTextField tf) { final WeakReference ref = weakRef(tf); componentPopupMenuItem(tf, "Copy text to clipboard", new Runnable() { public void run() { try { copyTextToClipboard(ref.get().getText()) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyTextToClipboard(ref.get().getText())"; }}); componentPopupMenuItem(tf, "Paste", new Runnable() { public void run() { try { ref.get().paste() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ref.get().paste()"; }}); return tf; } static A jenableUndoRedo(final A textcomp) { { swing(new Runnable() { public void run() { try { final UndoManager undo = new UndoManager(); vm_generalWeakSet("Undo Managers").add(undo); textcomp.getDocument().addUndoableEditListener(new UndoableEditListener() { public void undoableEditHappened(UndoableEditEvent evt) { undo.addEdit(evt.getEdit()); } }); textcomp.getActionMap().put("Undo", abstractAction("Undo", new Runnable() { public void run() { try { if (undo.canUndo()) undo.undo() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (undo.canUndo()) undo.undo()"; }})); textcomp.getActionMap().put("Redo", abstractAction("Redo", new Runnable() { public void run() { try { if (undo.canRedo()) undo.redo() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (undo.canRedo()) undo.redo()"; }})); textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo"); textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final new UndoManager undo;\r\n vm_generalWeakSet(\"Undo Managers\").add(undo)..."; }}); } return textcomp; } static String strOrEmpty(Object o) { return o == null ? "" : str(o); } static JInternalFrame showForm_makeInternalFrame(JDesktopPane desktop, String title, JPanel panel) { JInternalFrame f = addInternalFrame(desktop, title, withMargin(panel)); minInternalFrameWidth(f, 400); packInternalFrameVertically(f); centerInternalFrame(f); // TODO: handleEscapeKey(f); return f; } static JFrame handleEscapeKey(final JFrame frame) { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); frame.getRootPane().registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { frame.dispose(); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return frame; } static JFrame minFrameWidth(JFrame frame, int w) { if (frame != null && frame.getWidth() < w) frame.setSize(w, frame.getHeight()); return frame; } static JFrame minFrameWidth(int w, JFrame frame) { return minFrameWidth(frame, w); } static int showForm_leftWidth(List> l) { int minW = 0; for (List row : l) minW = max(minW, getMinimumSize(first(row)).width); return minW; } static int withRightMargin_defaultWidth = 6; static JPanel withRightMargin(Component c) { return withRightMargin(withRightMargin_defaultWidth, c); } static JPanel withRightMargin(final int w, final Component c) { return swing(new F0() { JPanel get() { try { JPanel p = new JPanel(new BorderLayout()); p.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, w)); p.add(c); return p; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }}); } static A jMinWidth(final int w, final A c) { if (c == null) return null; return swing(new F0() { A get() { try { Dimension size = c.getMinimumSize(); c.setMinimumSize(new Dimension(/*max(w, size.width) ??? */w, size.height)); return jPreferWidth(w, c); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Dimension size = c.getMinimumSize();\r\n c.setMinimumSize(new Dimension(/*ma..."; }}); } static void setComponentID(Component c, String id) { if (c != null) componentID_map.put(c, id); } static List mapLL(Object f, Object... data) { return map(f, ll(data)); } static Map humanizeFormLabel_replacements = litmap("id" , "ID", "md5" , "MD5"); static String humanizeFormLabel(String s) { if (containsSpace(s)) return s; return firstToUpper( joinWithSpace(replaceElementsUsingMap(splitCamelCase(s), humanizeFormLabel_replacements)).replace("I D", "ID") ); } static boolean isRunnable(Object o) { return o instanceof Runnable || hasMethod(o, "get"); } static String showFormSubmitButtonName() { return "Submit"; } static void disposeInternalFrame(Component c) { final JInternalFrame f = getInternalFrame(c); if (f != null) { swing(new Runnable() { public void run() { try { f.dispose(); setOpt(f, "lastFocusOwner" , null); // Help GC } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.dispose();\r\n setOpt(f, lastFocusOwner := null); // Help GC"; }}); } } static void disposeFrame(final Component c) { disposeWindow(c); } static void onEnterInAllTextFields(JComponent c, Object action) { if (action == null) return; for (Component tf : allChildren(c)) onEnterIfTextField(tf, action); } static void onEnterInAllTextFields(List c, Object action) { for (Object o : unnull(c)) if (o instanceof JComponent) onEnterInAllTextFields((JComponent) o, action); } static void clickButton(final JButton b) { if (b != null) { swing(new Runnable() { public void run() { try { if (b.isEnabled()) b.doClick(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (b.isEnabled())\r\n b.doClick();"; }}); } } static Object nuObject(String className, Object... args) { try { return nuObject(classForName(className), args); } catch (Exception __e) { throw rethrow(__e); } } // too ambiguous - maybe need to fix some callers /*static O nuObject(O realm, S className, O... args) { ret nuObject(_getClass(realm, className), args); }*/ static A nuObject(Class c, Object... args) { try { if (args.length == 0) return nuObjectWithoutArguments(c); // cached! Constructor m = nuObject_findConstructor(c, args); m.setAccessible(true); return (A) m.newInstance(args); } catch (Exception __e) { throw rethrow(__e); } } static Constructor nuObject_findConstructor(Class c, Object... args) { for (Constructor m : c.getDeclaredConstructors()) { if (!nuObject_checkArgs(m.getParameterTypes(), args, false)) continue; return m; } throw fail("Constructor " + c.getName() + getClasses(args) + " not found" + (args.length == 0 && (c.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 ? " - hint: it's a non-static class!" : "")); } static boolean nuObject_checkArgs(Class[] types, Object[] args, boolean debug) { if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static String hhtml(Object contents) { return containerTag("html", contents); } static List replace(List l, A a, A b) { for (int i = 0; i < l(l); i++) if (eq(l.get(i), a)) l.set(i, b); return l; } static String replace(String s, String a, String b) { return s == null ? null : a == null || b == null ? s : s.replace(a, b); } static String replace(String s, char a, char b) { return s == null ? null : s.replace(a, b); } static String htmlencode(Object o) { return htmlencode(str(o)); } static String htmlencode(String s) { if (s == null) return ""; StringBuilder out = new StringBuilder(Math.max(16, s.length())); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') { int cp = s.codePointAt(i); out.append("&#x"); out.append(intToHex_flexLength(cp)); out.append(';'); i += Character.charCount(cp)-1; } else out.append(c); } return out.toString(); } static void messageBox(final String msg) { if (headless()) print(msg); else { swing(new Runnable() { public void run() { try { JOptionPane.showMessageDialog(null, msg, "JavaX", JOptionPane.INFORMATION_MESSAGE); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JOptionPane.showMessageDialog(null, msg, \"JavaX\", JOptionPane.INFORMATION_MES..."; }}); } } static void messageBox(Throwable e) { //showConsole(); printStackTrace(e); messageBox(hideCredentials(innerException2(e))); } static JWindow infoBoxForever(String message) { return infoBox(message, 0); } static String md5OfRGBImage(RGBImage img) { try { MessageDigest m = MessageDigest.getInstance("MD5"); m.update(intToBytes(img.getWidth())); int[] pixels = img.getPixels(); for (int i = 0; i < l(pixels); i++) m.update(intToBytes(pixels[i])); return bytesToHex(m.digest()); } catch (Exception __e) { throw rethrow(__e); } } static long imageServerCheckMD5(String md5) { assertTrue(isMD5(md5)); String s = loadPage(imageServerURL() + "checkmd5/" + md5); return parseLongOpt(s); } static String uploadToImageServer_new(BufferedImage img, String name) { return uploadToImageServer_new(null, img, name); } static String uploadToImageServer_new(File f, BufferedImage img, String name) { byte[] imgData = f == null ? toPNG(img) : loadBinaryFile(f); return uploadToImageServer_rawBytes(imgData, name); } static String snippetImgLink(String snippetID) { return snippetImageURL(snippetID); } static String fsI(String id) { return formatSnippetID(id); } static String fsI(long id) { return formatSnippetID(id); } static A printException(A e) { printStackTrace(e); return e; } static String getText(final AbstractButton c) { return c == null ? "" : (String) swingAndWait(new F0() { Object get() { try { return c.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getText();"; }}); } static String getText(final JTextComponent c) { return c == null ? "" : (String) swingAndWait(new F0() { Object get() { try { return c.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getText();"; }}); } static String getText(final JLabel l) { return l == null ? "" : (String) swingAndWait(new F0() { Object get() { try { return l.getText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret l.getText();"; }}); } // returns the contents of text field for editable combo box static String getText(final JComboBox cb) { if (cb == null) return null; if (isEditableComboBox(cb)) return unnull((String) cb.getEditor().getItem()); else return str(cb.getSelectedItem()); } static List javaTokC(String s) { if (s == null) return null; int l = s.length(); ArrayList tok = new ArrayList(); int i = 0; while (i < l) { int j = i; char c, d; // scan for whitespace while (j < l) { c = s.charAt(j); d = j+1 >= l ? '\0' : s.charAt(j+1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } i = j; if (i >= l) break; c = s.charAt(i); d = i+1 >= l ? '\0' : s.charAt(i+1); // scan for non-whitespace if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L } else if (c == '[' && d == '[') { do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); j = Math.min(j+2, l); } else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') { do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); j = Math.min(j+3, l); } else ++j; tok.add(javaTok_substringC(s, i, j)); i = j; } return tok; } static A popLast(List l) { return liftLast(l); } // This is a bit rough... finds static and non-static methods. static Method findMethodNamed(Object obj, String method) { if (obj == null) return null; if (obj instanceof Class) return findMethodNamed((Class) obj, method); return findMethodNamed(obj.getClass(), method); } static Method findMethodNamed(Class c, String method) { while (c != null) { for (Method m : c.getDeclaredMethods()) if (m.getName().equals(method)) { m.setAccessible(true); return m; } c = c.getSuperclass(); } return null; } static void quoteToPrintWriter(String s, PrintWriter out) { if (s == null) { out.print("null"); return; } out.print('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') { out.print('\\'); out.print(c); } else if (c == '\r') out.print("\\r"); else if (c == '\n') out.print("\\n"); else if (c == '\0') out.print("\\0"); else out.print(c); } out.print('"'); } static String quoteCharacter(char c) { if (c == '\'') return "'\\''"; if (c == '\\') return "'\\\\'"; if (c == '\r') return "'\\r'"; if (c == '\n') return "'\\n'"; if (c == '\t') return "'\\t'"; return "'" + c + "'"; } static String quote(Object o) { if (o == null) return "null"; return quote(str(o)); } static String quote(String s) { if (s == null) return "null"; StringBuilder out = new StringBuilder((int) (l(s)*1.5+2)); quote_impl(s, out); return out.toString(); } static void quote_impl(String s, StringBuilder out) { out.append('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') out.append('\\').append(c); else if (c == '\r') out.append("\\r"); else if (c == '\n') out.append("\\n"); else if (c == '\0') out.append("\\0"); else out.append(c); } out.append('"'); } static int shorten_default = 100; static String shorten(String s) { return shorten(s, shorten_default); } static String shorten(String s, int max) { return shorten(s, max, "..."); } static String shorten(String s, int max, String shortener) { if (s == null) return ""; if (max < 0) return s; return s.length() <= max ? s : substring(s, 0, min(s.length(), max-l(shortener))) + shortener; } static String shorten(int max, String s) { return shorten(s, max); } static boolean isCISet_gen(Iterable l) { return l instanceof TreeSet && className(((TreeSet) l).comparator()).contains("CIComp"); } static List unwrapSynchronizedList(List l) { if (eqOneOf(className(l), "java.util.Collections$SynchronizedList", "java.util.Collections$SynchronizedRandomAccessList")) return (List) get_raw(l, "list"); return l; } static boolean isCIMap_gen(Map map) { return map instanceof TreeMap && className(((TreeMap) map).comparator()).contains("CIComp"); } static Map unwrapSynchronizedMap(Map map) { if (eqOneOf(className(map), "java.util.Collections$SynchronizedMap", "java.util.Collections$SynchronizedSortedMap", "java.util.Collections$SynchronizedNavigableMap")) return (Map) get_raw(map, "m"); return map; } public static String bytesToHex(byte[] bytes) { return bytesToHex(bytes, 0, bytes.length); } public static String bytesToHex(byte[] bytes, int ofs, int len) { StringBuilder stringBuilder = new StringBuilder(len*2); for (int i = 0; i < len; i++) { String s = "0" + Integer.toHexString(bytes[ofs+i]); stringBuilder.append(s.substring(s.length()-2, s.length())); } return stringBuilder.toString(); } static String boolArrayToHex(boolean[] a) { return bytesToHex(boolArrayToBytes(a)); } static String substring(String s, int x) { return substring(s, x, strL(s)); } static String substring(String s, int x, int y) { if (s == null) return null; if (x < 0) x = 0; if (x >= s.length()) return ""; if (y < x) y = x; if (y > s.length()) y = s.length(); return s.substring(x, y); } static Iterator emptyIterator() { return Collections.emptyIterator(); } static String shortDynamicClassName(Object o) { if (o instanceof DynamicObject && ((DynamicObject) o).className != null) return ((DynamicObject) o).className; return shortClassName(o); } static int stdcompare(Number a, Number b) { return cmp(a, b); } static int stdcompare(String a, String b) { return cmp(a, b); } static int stdcompare(long a, long b) { return a < b ? -1 : a > b ? 1 : 0; } static int stdcompare(Object a, Object b) { return cmp(a, b); } static Map getDeclaredFields_cache = newDangerousWeakHashMap(); static Field[] getDeclaredFields_cached(Class c) { Field[] fields; synchronized(getDeclaredFields_cache) { fields = getDeclaredFields_cache.get(c); if (fields == null) { getDeclaredFields_cache.put(c, fields = c.getDeclaredFields()); for (Field f : fields) f.setAccessible(true); } } return fields; } static boolean startsWithDigit(String s) { return nempty(s) && isDigit(s.charAt(0)); } static Map putAll(Map a, Map b) { if (a != null && b != null) a.putAll(b); return a; } static int countDots(String s) { int n = l(s), count = 0; for (int i = 0; i < n; i++) if (s.charAt(i) == '.') ++count; return count; } static String addSlashPrefix(String s) { return addPrefix("/", s); } static boolean jsonDecode_useOrderedMaps = true; static Object jsonDecode(final String text) { final List tok = jsonTok(text); if (l(tok) == 1) return null; class Y { int i = 1; Object parse() { String t = tok.get(i); if (t.startsWith("\"")) { String s = unquote(tok.get(i)); i += 2; return s; } if (t.equals("{")) return parseMap(); if (t.equals("[")) return this.parseList(); // avoid loading standard function "parseList" if (t.equals("null")) { i += 2; return null; } if (t.equals("false")) { i += 2; return false; } if (t.equals("true")) { i += 2; return true; } boolean minus = false; if (t.equals("-")) { minus = true; i += 2; t = get(tok, i); } if (isInteger(t)) { i += 2; if (eq(get(tok, i), ".")) { String x = t + "." + get(tok, i+2); i += 4; double d = parseDouble(x); if (minus) d = -d; return d; } else { long l = parseLong(t); if (minus) l = -l; return l != (int) l ? new Long(l) : new Integer((int) l); } } throw new RuntimeException("Unknown token " + (i+1) + ": " + t + ": " + text); } Object parseList() { consume("["); List list = new ArrayList(); while (!tok.get(i).equals("]")) { list.add(parse()); if (tok.get(i).equals(",")) i += 2; } consume("]"); return list; } Object parseMap() { consume("{"); Map map = jsonDecode_useOrderedMaps ? new LinkedHashMap() : new TreeMap(); while (!tok.get(i).equals("}")) { String key = unquote(tok.get(i)); i += 2; consume(":"); Object value = parse(); map.put(key, value); if (tok.get(i).equals(",")) i += 2; } consume("}"); return map; } void consume(String s) { if (!tok.get(i).equals(s)) { String prevToken = i-2 >= 0 ? tok.get(i-2) : ""; String nextTokens = join(tok.subList(i, Math.min(i+4, tok.size()))); throw fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")"); } i += 2; } } return new Y().parse(); } static String postPage(String url, Object... params) { return doPost(litmap(params), url); } static Map mapPlus(Map m, Object... data) { m = cloneMap(m); litmap_impl(m, data); return m; } static Object[] assertEvenLength(Object[] a) { assertTrue(even(l(a))); return a; } static LinkedHashMap paramsToOrderedMap(Object... params) { return asLinkedHashMap(paramsToMap(params)); } static Object[] mapToParams(Map map) { return mapToObjectArray(map); } // usually L static String fromLines(Iterable lines) { StringBuilder buf = new StringBuilder(); if (lines != null) for (Object line : lines) buf.append(str(line)).append('\n'); return buf.toString(); } static String fromLines(String... lines) { return fromLines(asList(lines)); } static IterableIterator toLines(File f) { return linesFromFile(f); } static List toLines(String s) { List lines = new ArrayList(); if (s == null) return lines; int start = 0; while (true) { int i = toLines_nextLineBreak(s, start); if (i < 0) { if (s.length() > start) lines.add(s.substring(start)); break; } lines.add(s.substring(start, i)); if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n') i += 2; else ++i; start = i; } return lines; } static int toLines_nextLineBreak(String s, int start) { for (int i = start; i < s.length(); i++) { char c = s.charAt(i); if (c == '\r' || c == '\n') return i; } return -1; } static String pki_signatureForText(String s, PKIKeyPair keyPair) { return base64encode(PKI.sign(toUtf8(s), PKI.privateKeyFromString(keyPair.privateKey))); } static List mapToLines(Map map) { List l = new ArrayList(); for (Object key : keys(map)) l.add(str(key) + " = " + str(map.get(key))); return l; } static String mapToLines(Map map, Object f) { return lines(map(map, f)); } static String mapToLines(Object f, Map map) { return lines(map(map, f)); } static String mapToLines(Object f, Iterable l) { return lines(map(f, l)); } static String mapToLines(Iterable l, IF1 f) { return mapToLines(f, l); } static String jsonEncode(Object o) { StringBuilder buf = new StringBuilder(); jsonEncode(o, buf); return str(buf); } static void jsonEncode(Object o, StringBuilder buf) { if (o == null) buf.append("null"); else if (o instanceof String) buf.append(quote((String) o)); else if (o instanceof Number || o instanceof Boolean) buf.append(o); else if (o instanceof Map) { Map map = (Map) o; buf.append("{"); boolean first = true; for (Object key : keys(map)) { if (first) first = false; else buf.append(","); buf.append(quote((String) key)); buf.append(":"); jsonEncode(map.get(key), buf); } buf.append("}"); } else if (o instanceof Collection) { Collection l = (Collection) o; buf.append("["); boolean first = true; for (Object element : l) { if (first) first = false; else buf.append(","); jsonEncode(element, buf); } buf.append("]"); } else throw fail("Unknown object for JSON encoding: " + className(o)); } static Lock mainLock_lock = fairLock(); static Lock mainLock() { return mainLock_lock; } static File getSecretProgramDir() { return getSecretProgramDir(getProgramID()); } static File getSecretProgramDir(String snippetID) { if (empty(snippetID)) return javaxSecretDir(); return newFile(javaxSecretDir(), formatSnippetID(snippetID)); } static String programID; static String getProgramID() { return nempty(programID) ? formatSnippetIDOpt(programID) : "?"; } // TODO: ask JavaX instead static String getProgramID(Class c) { String id = (String) getOpt(c, "programID"); if (nempty(id)) return formatSnippetID(id); return "?"; } static String getProgramID(Object o) { return getProgramID(getMainClass(o)); } static String loadTextFile(String fileName) { return loadTextFile(fileName, null); } static String loadTextFile(File f, String defaultContents) { try { checkFileNotTooBigToRead(f); if (f == null || !f.exists()) return defaultContents; FileInputStream fileInputStream = new FileInputStream(f); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8"); return loadTextFile(inputStreamReader); } catch (Exception __e) { throw rethrow(__e); } } public static String loadTextFile(File fileName) { return loadTextFile(fileName, null); } static String loadTextFile(String fileName, String defaultContents) { return fileName == null ? defaultContents : loadTextFile(newFile(fileName), defaultContents); } static String loadTextFile(Reader reader) throws IOException { StringBuilder builder = new StringBuilder(); try { char[] buffer = new char[1024]; int n; while (-1 != (n = reader.read(buffer))) builder.append(buffer, 0, n); } finally { reader.close(); } return str(builder); } static List synchroList() { return Collections.synchronizedList(new ArrayList()); } static List synchroList(List l) { return Collections.synchronizedList(l); } static PersistableThrowable persistableThrowable(Throwable e) { return e == null ? null : new PersistableThrowable(e); } static Throwable innerException(Throwable e) { return getInnerException(e); } static ArrayList cloneList(Iterable l) { return l instanceof Collection ? cloneList((Collection) l) : asList(l); } static ArrayList cloneList(Collection l) { if (l == null) return new ArrayList(); synchronized(collectionMutex(l)) { return new ArrayList(l); } } static List beginCriticalAction_inFlight = synchroList(); static class CriticalAction { String description; CriticalAction() {} CriticalAction(String description) { this.description = description;} void done() { beginCriticalAction_inFlight.remove(this); } } static CriticalAction beginCriticalAction(String description) { ping(); CriticalAction c = new CriticalAction(description); beginCriticalAction_inFlight.add(c); return c; } static void cleanMeUp_beginCriticalAction() { int n = 0; while (nempty(beginCriticalAction_inFlight)) { int m = l(beginCriticalAction_inFlight); if (m != n) { n = m; try { print("Waiting for " + n2(n, "critical actions") + ": " + join(", ", collect(beginCriticalAction_inFlight, "description"))); } catch (Throwable __e) { _handleException(__e); } } sleepInCleanUp(10); } } public static File mkdirsForFile(File file) { File dir = file.getParentFile(); if (dir != null) { // is null if file is in current dir dir.mkdirs(); if (!dir.isDirectory()) if (dir.isFile()) throw fail("Please delete the file " + f2s(dir) + " - it is supposed to be a directory!"); else throw fail("Unknown IO exception during mkdirs of " + f2s(file)); } return file; } public static String mkdirsForFile(String path) { mkdirsForFile(new File(path)); return path; } static long now_virtualTime; static long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } public static void copyFile(File src, File dest) { try { FileInputStream inputStream = new FileInputStream(src.getPath()); FileOutputStream outputStream = newFileOutputStream(dest.getPath()); try { copyStream(inputStream, outputStream); inputStream.close(); } finally { outputStream.close(); } } catch (Exception __e) { throw rethrow(__e); } } static FileOutputStream newFileOutputStream(File path) throws IOException { return newFileOutputStream(path.getPath()); } static FileOutputStream newFileOutputStream(String path) throws IOException { return newFileOutputStream(path, false); } static FileOutputStream newFileOutputStream(File path, boolean append) throws IOException { return newFileOutputStream(path.getPath(), append); } static FileOutputStream newFileOutputStream(String path, boolean append) throws IOException { mkdirsForFile(path); FileOutputStream f = new FileOutputStream(path, append); _registerIO(f, path, true); return f; } static void vmBus_send(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); pcallFAll(vm_busListeners_live(), msg, arg); pcallFAll(vm_busListenersByMessage_live().get(msg), msg, arg); } static void vmBus_send(String msg) { vmBus_send(msg, (Object) null); } static String lines(Iterable lines) { return fromLines(lines); } static String lines(Object[] lines) { return fromLines(asList(lines)); } static List lines(String s) { return toLines(s); } static URI uri(String uri) { try { return new URI(uri); } catch (Exception __e) { throw rethrow(__e); } } static String replacePrefix(String prefix, String replacement, String s) { if (!startsWith(s, prefix)) return s; return replacement + substring(s, l(prefix)); } static String htmlQuery(Map params) { return empty(params) ? "" : "?" + makePostData(params); } static String htmlQuery(Object... data) { return empty(data) ? "" : "?" + makePostData(data); } static Object[] concatArrays(Object[]... arrays) { int l = 0; for (Object[] a : arrays) l += l(a); Object[] x = new Object[l]; int i = 0; for (Object[] a : arrays) if (a != null) { System.arraycopy(a, 0, x, i, l(a)); i += l(a); } return x; } static boolean isInstanceOf(Object o, Class type) { return type.isInstance(o); } static String className(Object o) { return getClassName(o); } static String secondJavaToken(String s) { return second(javaTokC_iterator(s)); } static boolean nemptyString(String s) { return s != null && s.length() > 0; } static int strL(String s) { return s == null ? 0 : s.length(); } static int listL(Collection l) { return l == null ? 0 : l.size(); } static double doubleSum(Iterable l) { double sum = 0; for (Double i : unnull(l)) if (i != null) sum += i; return sum; } static double doubleSum(double... l) { double sum = 0; if (l != null) for (double i : l) sum += i; return sum; } static A oneOf(List l) { return empty(l) ? null : l.get(new Random().nextInt(l.size())); } static char oneOf(String s) { return empty(s) ? '?' : s.charAt(random(l(s))); } static String oneOf(String... l) { return oneOf(asList(l)); } static A collectionGet(Collection c, int idx) { if (c == null || idx < 0 || idx >= l(c)) return null; if (c instanceof List) return listGet((List) c, idx); Iterator it = c.iterator(); for (int i = 0; i < idx; i++) if (it.hasNext()) it.next(); else return null; return it.hasNext() ? it.next() : null; } static void dm_minimizeOS() { minimizeFrame(dm_desktopPane()); } static void dm_activateOS() { activateFrame(dm_desktopPane()); } static volatile boolean sleep_noSleep = false; static void sleep(long ms) { ping(); if (ms < 0) return; // allow spin locks if (isAWTThread() && ms > 100) throw fail("Should not sleep on AWT thread"); try { Thread.sleep(ms); } catch (Exception e) { throw new RuntimeException(e); } } static void sleep() { try { if (sleep_noSleep) throw fail("nosleep"); print("Sleeping."); sleepQuietly(); } catch (Exception __e) { throw rethrow(__e); } } static long round(double d) { return Math.round(d); } static Rectangle screenRectangle() { return new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); } static boolean isOnPATH(String cmd) { return findCmdOnPATH(cmd) != null; } static int randomID_defaultLength = 12; static String randomID(int length) { return makeRandomID(length); } static String randomID(Random r, int length) { return makeRandomID(r, length); } static String randomID() { return randomID(randomID_defaultLength); } static String randomID(Random r) { return randomID(r, randomID_defaultLength); } static File linux_fileInRamDisk(String name) { if (!isLinux()) return null; File dir = newFile("/dev/shm"); if (dir.isDirectory()) return newFile(dir, name); return null; } static File prepareProgramFile(String name) { return mkdirsForFile(getProgramFile(name)); } static File prepareProgramFile(String progID, String name) { return mkdirsForFile(getProgramFile(progID, name)); } /** possibly improvable */ static String bashQuote(String text) { if (text == null) return null; return "\"" + text .replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\n", "\\n") .replace("\r", "\\r") + "\""; } static String bashQuote(File f) { return bashQuote(f.getAbsolutePath()); } static int backtick_exitValue; static boolean backtick_verbose, backtick_keepScript; static ThreadLocal backtick_scriptFile = new ThreadLocal(); static ThreadLocal backtick_uninterruptable = new ThreadLocal(); // Great trick, thanks to Tim Bunce @ http://stackoverflow.com/questions/12856620/how-to-handle-signals-in-bash-during-synchronous-execution static boolean backtick_win_cmd = false; // bugfixing static String backtick(String cmd) { try { File outFile = File.createTempFile("_backtick", ""); backtickToFile(cmd, outFile); String result = loadTextFile(outFile.getPath(), ""); if (backtick_verbose) { //print("backtick: script length after=" + backtick_scriptFile->length()); print("[[\n" + result + "]]"); } outFile.delete(); return result; } catch (Exception __e) { throw rethrow(__e); } } static java.lang.Process backtickToFile(String cmd, File outFile) { try { try { java.lang.Process process = backtickToFile_noWait(cmd, outFile); process.waitFor(); backtick_exitValue = process.exitValue(); if (backtick_verbose) System.out.println("Process return code: " + backtick_exitValue); return process; } finally { if (!backtick_keepScript) deleteFile(backtick_scriptFile.get()); backtick_scriptFile.set(null); } } catch (Exception __e) { throw rethrow(__e); } } static java.lang.Process backtickToFile_noWait(String cmd, File outFile) { try { File scriptFile; String ext = isWindows() ? ".bat" : ""; if (backtick_keepScript) scriptFile = makeFileNameUnique_withExtension(javaxCachesDir("Cmd Scripts/backtick"), ".bat"); else scriptFile = File.createTempFile("_backtick", ext); backtick_scriptFile.set(scriptFile); if (backtick_verbose) print("backtick: scriptFile " + f2s(scriptFile)); cmd = trim(cmd); if (numLines(cmd) > 1) throw fail("No multi-line commands allowed"); String command = cmd + " >" + bashQuote(outFile.getPath()) + " 2>&1"; if (!isTrue(backtick_uninterruptable.get()) && !isWindows()) command = fixNewLines("\r\ninterruptable() {\r\n\r\n # handle options\r\n local setsid=\"\"\r\n local debug=false\r\n while true; do\r\n case \"${1:-}\" in\r\n --killall) setsid=setsid; shift ;;\r\n --debug) debug=true; shift ;;\r\n --*) echo \"Invalid option: $1\" 1>&2; exit 1;;\r\n *) break;; # no more options\r\n esac\r\n done\r\n\r\n # start the specified command\r\n $setsid \"$@\" &\r\n local child_pid=$!\r\n\r\n # arrange to propagate a signal to the child process\r\n trap '\r\n exec 1>&2\r\n set +e\r\n trap \"\" SIGPIPE # ensure a possible sigpipe from the echo does not prevent the kill\r\n echo \"${BASH_SOURCE[0]} caught SIGTERM while executing $* (pid $child_pid), sending SIGTERM to it\"\r\n # (race) child may have exited in which case kill will report an error\r\n # if setsid is used then prefix the pid with a \"-\" to indicate that the signal\r\n # should be sent to the entire process group\r\n kill ${setsid:+-}$child_pid\r\n exit 143\r\n ' SIGTERM\r\n # ensure that the trap doesn't persist after we return\r\n trap 'trap - SIGTERM' RETURN\r\n\r\n $debug && echo \"interruptable wait (child $child_pid, self $$) for: $*\"\r\n\r\n # An error status from the child process will trigger an exception (via set -e)\r\n # here unless the caller is checking the return status\r\n wait $child_pid # last command, so status of waited for command is returned\r\n}\r\n\r\ninterruptable ") + command; //Log.info("[Backtick] " + command); if (backtick_verbose) { print("backtick: command " + command); print("backtick: saving to " + scriptFile.getPath()); } saveTextFile(scriptFile.getPath(), command); if (backtick_verbose) print("backtick: command length=" + l(command) + ", file length=" + scriptFile.length()); String[] command2; if (isWindows()) if (backtick_win_cmd) command2 = new String[] { "cmd", "/c", scriptFile.getPath() }; else command2 = new String[] { scriptFile.getPath() }; else command2 = new String[] { "/bin/bash", scriptFile.getPath() }; if (backtick_verbose) print("backtick: command2 " + structure(command2)); return Runtime.getRuntime().exec(command2); } catch (Exception __e) { throw rethrow(__e); } } static BufferedImage loadPNG(File file) { return loadBufferedImage(file); } static Cache isLinux_cache = new Cache("isLinux_load"); static boolean isLinux() { return isLinux_cache.get(); } static Boolean isLinux_load() { return !isWindows() && !isMac() && !isAndroid(); } static Map componentID_map = weakHashMap(); static String componentID(Component c) { return c == null ? null : componentID_map.get(c); } static String getStackTrace2(Throwable e) { return hideCredentials(getStackTrace(unwrapTrivialExceptionWraps(e)) + replacePrefix("java.lang.RuntimeException: ", "FAIL: ", hideCredentials(str(innerException2(e)))) + "\n"); } static void listThreadLocalAdd(ThreadLocal> tl, A a) { List l = tl.get(); if (l == null) tl.set(l = new ArrayList()); l.add(a); } static A listThreadLocalPopLast(ThreadLocal> tl) { List l = tl.get(); if (l == null) return null; A a = popLast(l); if (empty(l)) tl.set(null); return a; } static List buttonsInGroup(ButtonGroup g) { if (g == null) return ll(); return asList(g.getElements()); } static Dimension getScreenSize() { return Toolkit.getDefaultToolkit().getScreenSize(); } static Map newWeakHashMap() { return _registerWeakMap(synchroMap(new WeakHashMap())); } static ArrayList cloneListSynchronizingOn(Collection l, Object mutex) { if (l == null) return new ArrayList(); synchronized(mutex) { return new ArrayList(l); } } static boolean isImageFileName(String s) { return eqicOneOf(fileExtension(s), ".png", ".jpg", ".jpeg", ".gif"); } static String fileName(File f) { return f == null ? null : f.getName(); } static Object call_withVarargs(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); Method me = cache.findStaticMethod(method, args); if (me != null) return invokeMethod(me, null, args); // try varargs List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } { if (!(isStaticMethod(m))) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, null, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found"); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(method, args); if (me != null) return invokeMethod(me, o, args); // try varargs List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, o, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found in " + c); } } catch (Exception __e) { throw rethrow(__e); } } static void assertTrue(Object o) { if (!(eq(o, true) /*|| isTrue(pcallF(o))*/)) throw fail(str(o)); } static boolean assertTrue(String msg, boolean b) { if (!b) throw fail(msg); return b; } static boolean assertTrue(boolean b) { if (!b) throw fail("oops"); return b; } // named like this for historic reasons static InheritableThreadLocal dm_currentModule_value = new InheritableThreadLocal(); static Object dm_current_generic() { return getWeakRef(dm_currentModule_value.get()); } // prevent memory leak static void cleanMeUp_dm_current_generic() { dm_currentModule_value = new InheritableThreadLocal(); } static Class __javax; static Class getJavaX() { try { return __javax; } catch (Exception __e) { throw rethrow(__e); } } static CloseableIterableIterator linesFromFile(File f) { try { if (!f.exists()) return emptyCloseableIterableIterator(); if (ewic(f.getName(), ".gz")) return linesFromReader(utf8bufferedReader(newGZIPInputStream(f))); return linesFromReader(utf8bufferedReader(f)); } catch (Exception __e) { throw rethrow(__e); } } static CloseableIterableIterator linesFromFile(String path) { return linesFromFile(newFile(path)); } // TODO: test if android complains about this static boolean isAWTThread() { if (isAndroid()) return false; if (isHeadless()) return false; return isAWTThread_awt(); } static boolean isAWTThread_awt() { return SwingUtilities.isEventDispatchThread(); } static Runnable addThreadInfoToRunnable(final Object r) { final Object info = _threadInfo(); return info == null ? asRunnable(r) : new Runnable() { public void run() { try { _inheritThreadInfo(info); callF(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_inheritThreadInfo(info); callF(r);"; }}; } static List _registerDangerousWeakMap_preList; static A _registerDangerousWeakMap(A map) { return _registerDangerousWeakMap(map, null); } static A _registerDangerousWeakMap(A map, Object init) { callF(init, map); if (init instanceof String) { final String f = (String) init; init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callMC(f, map)"; }}; } if (javax() == null) { // We're in class init if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList(); _registerDangerousWeakMap_preList.add(pair(map, init)); return map; } call(javax(), "_registerDangerousWeakMap", map, init); return map; } static void _onLoad_registerDangerousWeakMap() { assertNotNull(javax()); if (_registerDangerousWeakMap_preList == null) return; for (Pair p : _registerDangerousWeakMap_preList) _registerDangerousWeakMap(p.a, p.b); _registerDangerousWeakMap_preList = null; } static Map synchroMap() { return synchroHashMap(); } static Map synchroMap(Map map) { return Collections.synchronizedMap(map); } static List classNames(Collection l) { return getClassNames(l); } static List classNames(Object[] l) { return getClassNames(Arrays.asList(l)); } static void multiMapPut(Map> map, A a, B b) { List l = map.get(a); if (l == null) map.put(a, l = new ArrayList()); l.add(b); } static void multiMapPut(MultiMap mm, A key, B value) { if (mm != null && key != null && value != null) mm.put(key, value); } static Throwable getExceptionCause(Throwable e) { Throwable c = e.getCause(); return c != null ? c : e; } static String joinWithSpace(Collection c) { return join(" ", c); } static String joinWithSpace(String... c) { return join(" ", c); } static boolean isInstanceX(Class type, Object arg) { if (type == boolean.class) return arg instanceof Boolean; if (type == int.class) return arg instanceof Integer; if (type == long.class) return arg instanceof Long; if (type == float.class) return arg instanceof Float; if (type == short.class) return arg instanceof Short; if (type == char.class) return arg instanceof Character; if (type == byte.class) return arg instanceof Byte; if (type == double.class) return arg instanceof Double; return type.isInstance(arg); } static boolean isEmpty(Collection c) { return c == null || c.isEmpty(); } static boolean isEmpty(CharSequence s) { return s == null || s.length() == 0; } static boolean isEmpty(Object[] a) { return a == null || a.length == 0; } static boolean isEmpty(byte[] a) { return a == null || a.length == 0; } static boolean isEmpty(Map map) { return map == null || map.isEmpty(); } static java.awt.Color awtColor(String hex) { byte[] b = bytesFromHex(dropPrefix("#", hex)); return new Color(ubyteToInt(b[0]), ubyteToInt(b[1]), ubyteToInt(b[2])); } static A bindJLabelToLiveValue(final A label, final LiveValue lv) { bindLiveValueListenerToComponent(label, lv, new Runnable() { public void run() { try { setText(label, strOrNull(lv.get())) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setText(label, strOrNull(lv.get()))"; }}); return label; } static List> _threadInfo_makers = synchroList(); static Object _threadInfo() { if (empty(_threadInfo_makers)) return null; HashMap map = new HashMap(); pcallFAll(_threadInfo_makers, map); return map; } static List> _threadInheritInfo_retrievers = synchroList(); static void _threadInheritInfo(Object info) { if (info == null) return; pcallFAll(_threadInheritInfo_retrievers, (Map) info); } static String programID() { return getProgramID(); } static String programID(Object o) { return getProgramID(o); } static Runnable _topLevelErrorHandling(final Runnable runnable) { final Object info = _threadInfo(); return new Runnable() { public void run() { try { try { _threadInheritInfo(info); runnable.run(); } catch (Throwable __e) { _handleException(__e); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcall {\r\n _threadInheritInfo(info);\r\n runnable.run();\r\n }"; }}; } static Map vm_generalWeakSubMap(Object name) { synchronized(get(javax(), "generalMap")) { Map map = (Map) (vm_generalMap_get(name)); if (map == null) vm_generalMap_put(name, map = newWeakMap()); return map; } } static WeakReference weakRef(A a) { return newWeakReference(a); } static String charToString(char c) { return String.valueOf(c); } static String charToString(int c) { return String.valueOf((char) c); } static boolean isMenuSeparatorIndicator(Object o) { return eqOneOf(o, "***", "---", "===", ""); } static boolean isRunnableX(Object o) { if (o == null) return false; if (o instanceof String) return hasMethod(mc(), (String) o); return o instanceof Runnable || hasMethod(o, "get"); } static boolean jmenuItem_newThreads = false; static JMenuItem jmenuItem(final String text) { return jMenuItem(text, null); } static JMenuItem jmenuItem(final String text, final Object r) { return swing(new F0() { JMenuItem get() { try { Pair p = jmenu_autoMnemonic(dropPrefix("[disabled] ", text)); JMenuItem mi = new JMenuItem(p.a); if (startsWith(text, "[disabled] ")) disableMenuItem(mi); if (p.b != 0) mi.setMnemonic(p.b); mi.addActionListener(jmenuItem_newThreads ? actionListenerInNewThread(r) : actionListener(r)); return mi; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Pair p = jmenu_autoMnemonic(dropPrefix(\"[disabled] \", text));\r\n JM..."; }}); } static boolean isCurlyBracketed(String s) { return isCurlyBraced(s); } static A setEnabled(A c, boolean enable) { if (c != null) { swing(new Runnable() { public void run() { try { c.setEnabled(enable); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.setEnabled(enable);"; }}); } return c; } static A setEnabled(boolean enable, A c) { return setEnabled(c, enable); } static String unCurlyBracket(String s) { return tok_unCurlyBracket(s); } static boolean setText_opt = true; // optimize by calling getText first static A setText(A c, Object text) { setText((JComponent) c, text); return c; } static A setText(final A c, Object text) { // only for editable combo boxes at this point final String s = strUnnull(text); { swing(new Runnable() { public void run() { try { c.getEditor().setItem(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.getEditor().setItem(s);"; }}); } return c; } static void setText(JLabel c, Object text) { setText((JComponent) c, text); } static JButton setText(JButton c, Object text) { setText((JComponent) c, jlabel_textAsHTML_center_ifNeeded(strUnnull(text))); return c; } static A setText(final A c, Object text) { if (c == null) return null; final String s = strUnnull(text); { swing(new Runnable() { public void run() { try { if (!setText_opt || neq(callOpt(c, "getText"), s)) call(c, "setText", s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (!setText_opt || neq(callOpt(c, \"getText\"), s))\r\n call(c, \"setText\", s);"; }}); } return c; } static Map mapMinus(Map map, Object... keys) { if (empty(keys)) return map; Map m2 = cloneMap(map); for (Object key : keys) m2.remove(key); return m2; } static HashSet lithashset(A... items) { HashSet set = new HashSet(); for (A a : items) set.add(a); return set; } static int preferredWidth(Component c) { return c == null ? 0 : getPreferredSize(c).width; } static void scanForComponents(final Component c, final Class theClass, final List l) { if (theClass.isInstance(c)) l.add((A) c); if (c instanceof Container) { swing(new Runnable() { public void run() { try { for (Component comp : ((Container) c).getComponents()) scanForComponents(comp, theClass, l); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "for (Component comp : ((Container) c).getComponents())\r\n scanForComponen..."; }}); } } static Object vm_generalMap_get(Object key) { return vm_generalMap().get(key); } static Object callOpt_withVarargs(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(method, args); if (me == null) { // TODO: varargs return null; } if ((me.getModifiers() & Modifier.STATIC) == 0) return null; return invokeMethod(me, null, args); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(method, args); if (me != null) return invokeMethod(me, o, args); // try varargs List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, o, newArgs); } return null; } } catch (Exception __e) { throw rethrow(__e); } } static void addToContainer(final Container a, final Component b) { if (a != null && b != null) { swing(new Runnable() { public void run() { try { a.add(b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.add(b);"; }}); } } static void failIfUnlicensed() { assertTrue("license off", licensed()); } static Thread currentThread() { return Thread.currentThread(); } static String getStackTrace(Throwable throwable) { lastException(throwable); return getStackTrace_noRecord(throwable); } static String getStackTrace_noRecord(Throwable throwable) { StringWriter writer = new StringWriter(); throwable.printStackTrace(new PrintWriter(writer)); return hideCredentials(writer.toString()); } static String getStackTrace() { return getStackTrace_noRecord(new Throwable()); } static JComboBox jcombobox(final String... items) { return swing(new F0() { JComboBox get() { try { return new JComboBox(items); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret new JComboBox(items);"; }}); } static JComboBox jcombobox(Collection items) { return jcombobox(toStringArray(items)); } static JComboBox jcombobox(Collection items, String selectedItem) { return selectItem(selectedItem, jcombobox(items)); } static JComboBox selectItem(final String item, final JComboBox cb) { if (cb != null) { swing(new Runnable() { public void run() { try { cb.setSelectedItem(item); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cb.setSelectedItem(item);"; }}); } return cb; } static JComboBox selectItem(final JComboBox cb, final String item) { return selectItem(item, cb); } static JList selectItem(JList list, A item) { { swing(new Runnable() { public void run() { try { selectRow(list, jlist_indexOf(list, item)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selectRow(list, jlist_indexOf(list, item));"; }}); } return list; } static A onChange(A spinner, Object r) { { swing(new Runnable() { public void run() { try { spinner.addChangeListener(changeListener(r)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "spinner.addChangeListener(changeListener(r));"; }}); } return spinner; } static A onChange(A b, Object r) { { swing(new Runnable() { public void run() { try { b.addItemListener(itemListener(r)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "b.addItemListener(itemListener(r));"; }}); } return b; } static void onChange(JTextComponent tc, Object r) { onUpdate(tc, r); } static A onChange(A slider, final Object r) { { swing(new Runnable() { public void run() { try { slider.addChangeListener(changeListener(r)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "slider.addChangeListener(changeListener(r));"; }}); } return slider; } static JComboBox onChange(Object r, JComboBox cb) { return onChange(cb, r); } static JComboBox onChange(JComboBox cb, final Object r) { if (isEditableComboBox(cb)) onChange(textFieldFromComboBox(cb), r); else onSelectedItem(cb, new VF1() { public void get(String s) { try { callF(r) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(r)"; }}); return cb; } static Class fieldType(Object o, String field) { Field f = getField(o, field); return f == null ? null : f.getType(); } static boolean containsNulls(Collection c) { return contains(c, null); } static A getAndClearThreadLocal(ThreadLocal tl) { A a = tl.get(); tl.set(null); return a; } static File programDir_mine; // set this to relocate program's data static File programDir() { return programDir(getProgramID()); } static File programDir(String snippetID) { boolean me = sameSnippetID(snippetID, programID()); if (programDir_mine != null && me) return programDir_mine; File dir = new File(javaxDataDir(), formatSnippetIDOpt(snippetID)); if (me) { String c = caseID(); if (nempty(c)) dir = newFile(dir, c); } return dir; } static File programDir(String snippetID, String subPath) { return new File(programDir(snippetID), subPath); } static A set(A o, String field, Object value) { if (o == null) return null; if (o instanceof Class) set((Class) o, field, value); else try { Field f = set_findField(o.getClass(), field); f.setAccessible(true); smartSet(f, o, value); } catch (Exception e) { throw new RuntimeException(e); } return o; } static void set(Class c, String field, Object value) { if (c == null) return; try { Field f = set_findStaticField(c, field); f.setAccessible(true); smartSet(f, null, value); } catch (Exception e) { throw new RuntimeException(e); } } static Field set_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static Field set_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static GZIPInputStream newGZIPInputStream(File f) { return gzInputStream(f); } static GZIPInputStream newGZIPInputStream(InputStream in) { return gzInputStream(in); } static Object unstructure(String text) { return unstructure(text, false); } static Object unstructure(String text, final boolean allDynamic) { return unstructure(text, allDynamic, null); } static int structure_internStringsLongerThan = 50; static int unstructure_unquoteBufSize = 100; static int unstructure_tokrefs; // stats abstract static class unstructure_Receiver { abstract void set(Object o); } // classFinder: func(name) -> class (optional) static Object unstructure(String text, boolean allDynamic, Object classFinder) { if (text == null) return null; return unstructure_tok(javaTokC_noMLS_iterator(text), allDynamic, classFinder); } static Object unstructure_reader(BufferedReader reader) { return unstructure_tok(javaTokC_noMLS_onReader(reader), false, null); } static Object unstructure_tok(final Producer tok, final boolean allDynamic, final Object _classFinder) { final boolean debug = unstructure_debug; final class X { int i = -1; final Object classFinder = _classFinder != null ? _classFinder : _defaultClassFinder(); HashMap refs = new HashMap(); HashMap tokrefs = new HashMap(); HashSet concepts = new HashSet(); HashMap classesMap = new HashMap(); List stack = new ArrayList(); String curT; char[] unquoteBuf = new char[unstructure_unquoteBufSize]; String unquote(String s) { return unquoteUsingCharArray(s, unquoteBuf); } // look at current token String t() { return curT; } // get current token, move to next String tpp() { String t = curT; consume(); return t; } void parse(final unstructure_Receiver out) { String t = t(); int refID = 0; if (structure_isMarker(t, 0, l(t))) { refID = parseInt(t.substring(1)); consume(); } final int _refID = refID; // if (debug) print("parse: " + quote(t)); final int tokIndex = i; parse_inner(refID, tokIndex, new unstructure_Receiver() { void set(Object o) { if (_refID != 0) refs.put(_refID, o); if (o != null) tokrefs.put(tokIndex, o); out.set(o); } }); } void parse_inner(int refID, int tokIndex, final unstructure_Receiver out) { String t = t(); // if (debug) print("parse_inner: " + quote(t)); Class c = classesMap.get(t); if (c == null) { if (t.startsWith("\"")) { String s = internIfLongerThan(unquote(tpp()), structure_internStringsLongerThan); out.set(s); return; } if (t.startsWith("'")) { out.set(unquoteCharacter(tpp())); return; } if (t.equals("bigint")) { out.set(parseBigInt()); return; } if (t.equals("d")) { out.set(parseDouble()); return; } if (t.equals("fl")) { out.set(parseFloat()); return; } if (t.equals("sh")) { consume(); t = tpp(); if (t.equals("-")) { t = tpp(); out.set((short) (-parseInt(t))); return; } out.set((short) parseInt(t)); return; } if (t.equals("-")) { consume(); t = tpp(); out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return; } if (isInteger(t) || isLongConstant(t)) { consume(); //if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t)); if (isLongConstant(t)) { out.set(parseLong(t)); return; } long l = parseLong(t); boolean isInt = l == (int) l; out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return; } if (t.equals("false") || t.equals("f")) { consume(); out.set(false); return; } if (t.equals("true") || t.equals("t")) { consume(); out.set(true); return; } if (t.equals("-")) { consume(); t = tpp(); out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return; } if (isInteger(t) || isLongConstant(t)) { consume(); //if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t)); if (isLongConstant(t)) { out.set(parseLong(t)); return; } long l = parseLong(t); boolean isInt = l == (int) l; out.set(isInt ? (Object) Integer.valueOf((int) l) : (Object) Long.valueOf(l)); return; } if (t.equals("File")) { consume(); File f = new File(unquote(tpp())); out.set(f); return; } if (t.startsWith("r") && isInteger(t.substring(1))) { consume(); int ref = Integer.parseInt(t.substring(1)); Object o = refs.get(ref); if (o == null) throw fail("unsatisfied back reference " + ref); out.set(o); return; } if (t.startsWith("t") && isInteger(t.substring(1))) { consume(); int ref = Integer.parseInt(t.substring(1)); Object o = tokrefs.get(ref); if (o == null) throw fail("unsatisfied token reference " + ref + " at " + tokIndex); out.set(o); return; } if (t.equals("hashset")) { parseHashSet(out); return; } if (t.equals("lhs")) { parseLinkedHashSet(out); return; } if (t.equals("treeset")) { parseTreeSet(out); return; } if (t.equals("ciset")) { parseCISet(out); return; } if (eqOneOf(t, "hashmap", "hm")) { consume(); parseMap(new HashMap(), out); return; } if (t.equals("lhm")) { consume(); parseMap(new LinkedHashMap(), out); return; } if (t.equals("tm")) { consume(); parseMap(new TreeMap(), out); return; } if (t.equals("cimap")) { consume(); parseMap(ciMap(), out); return; } if (t.equals("ll")) { consume(); { parseList(new LinkedList(), out); return; } } if (t.equals("syncLL")) { // legacy consume(); { parseList(synchroLinkedList(), out); return; } } if (t.equals("sync")) { consume(); { parse(new unstructure_Receiver() { void set(Object value) { if (value instanceof Map) { // Java 7 if (value instanceof NavigableMap) { out.set(Collections.synchronizedNavigableMap((NavigableMap) value)); return; } if (value instanceof SortedMap) { out.set(Collections.synchronizedSortedMap((SortedMap) value)); return; } { out.set(Collections.synchronizedMap((Map) value)); return; } } else { out.set(Collections.synchronizedList((List) value)); return; } } }); return; } } if (t.equals("{")) { parseMap(out); return; } if (t.equals("[")) { this.parseList(new ArrayList(), out); return; } if (t.equals("bitset")) { parseBitSet(out); return; } if (t.equals("array") || t.equals("intarray")) { parseArray(out); return; } if (t.equals("ba")) { consume(); String hex = unquote(tpp()); out.set(hexToBytes(hex)); return; } if (t.equals("boolarray")) { consume(); int n = parseInt(tpp()); String hex = unquote(tpp()); out.set(boolArrayFromBytes(hexToBytes(hex), n)); return; } if (t.equals("class")) { out.set(parseClass()); return; } if (t.equals("l")) { parseLisp(out); return; } if (t.equals("null")) { consume(); out.set(null); return; } if (eq(t, "c")) { consume(); t = t(); assertTrue(isJavaIdentifier(t)); concepts.add(t); } // custom deserialization if (eq(t, "cu")) { consume(); t = tpp(); assertTrue(isJavaIdentifier(t)); String fullClassName = "main$" + t; c = classFinder != null ? (Class) callF(classFinder, fullClassName) : findClass_fullName(fullClassName); if (c == null) throw fail("Class not found: " + fullClassName); final Object o = nuEmptyObject(c); out.set(o); parse(new unstructure_Receiver() { void set(Object value) { call(o, "_deserialize", value); } }); return; } } if (eq(t, "j")) { consume("j"); out.set(parseJava()); return; } if (c == null && !isJavaIdentifier(t)) throw new RuntimeException("Unknown token " + (i+1) + ": " + t); // any other class name (or package name) consume(); String className, fullClassName; // Is it a package name? if (eq(t(), ".")) { consume(); className = fullClassName = t + "." + assertIdentifier(tpp()); } else { className = t; fullClassName = "main$" + t; } if (c == null) { // First, find class if (allDynamic) c = null; else c = classFinder != null ? (Class) callF(classFinder, fullClassName) : findClass_fullName(fullClassName); if (c != null) classesMap.put(className, c); } // Check if it has an outer reference boolean hasBracket = eq(t(), "("); if (hasBracket) consume(); boolean hasOuter = hasBracket && eq(t(), "this$1"); DynamicObject dO = null; Object o = null; final String thingName = t; if (c != null) { o = hasOuter ? nuStubInnerObject(c, classFinder) : nuEmptyObject(c); if (o instanceof DynamicObject) dO = (DynamicObject) o; } else { if (concepts.contains(t) && (c = findClass("Concept")) != null) o = dO = (DynamicObject) nuEmptyObject(c); else dO = new DynamicObject(); dO.className = className; } // Save in references list early because contents of object // might link back to main object if (refID != 0) refs.put(refID, o != null ? o : dO); tokrefs.put(tokIndex, o != null ? o : dO); // NOW parse the fields! final LinkedHashMap fields = new LinkedHashMap(); // preserve order final Object _o = o; final DynamicObject _dO = dO; if (hasBracket) { stack.add(new Runnable() { public void run() { try { if (eq(t(), ",")) consume(); if (eq(t(), ")")) { consume(")"); objRead(_o, _dO, fields); out.set(_o != null ? _o : _dO); } else { final String key = unquote(tpp()); String t = tpp(); if (!eq(t, "=")) throw fail("= expected, got " + t + " after " + quote(key) + " in object " + thingName /*+ " " + sfu(fields)*/); stack.add(this); parse(new unstructure_Receiver() { void set(Object value) { fields.put(key, value); /*ifdef unstructure_debug print("Got field value " + value + ", next token: " + t()); endifdef*/ //if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ifdef unstructure_debug\r\n print(\"in object values, token: \" + t())..."; }}); } else { objRead(o, dO, fields); out.set(o != null ? o : dO); } } void objRead(Object o, DynamicObject dO, Map fields) { if (o != null) if (dO != null) { setOptAllDyn(dO, fields); } else { setOptAll_pcall(o, fields); } else for (Map.Entry e : fields.entrySet()) setDynObjectValue(dO, intern(e.getKey()), e.getValue()); if (o != null) pcallOpt_noArgs(o, "_doneLoading"); } void parseSet(final Set set, final unstructure_Receiver out) { this.parseList(new ArrayList(), new unstructure_Receiver() { void set(Object o) { set.addAll((List) o); out.set(set); } }); } void parseLisp(final unstructure_Receiver out) { throw fail("class Lisp not included"); } void parseBitSet(final unstructure_Receiver out) { consume("bitset"); consume("{"); final BitSet bs = new BitSet(); stack.add(new Runnable() { public void run() { try { if (eq(t(), "}")) { consume("}"); out.set(bs); } else { stack.add(this); parse(new unstructure_Receiver() { void set(Object o) { bs.set((Integer) o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(bs);\r\n ..."; }}); } void parseList(final List list, final unstructure_Receiver out) { consume("["); stack.add(new Runnable() { public void run() { try { if (eq(t(), "]")) { consume(); out.set(list); } else { stack.add(this); parse(new unstructure_Receiver() { void set(Object o) { //if (debug) print("List element type: " + getClassName(o)); list.add(o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"]\")) {\r\n consume();\r\n ifdef unstructure_debug\r..."; }}); } void parseArray(final unstructure_Receiver out) { final String type = tpp(); consume("{"); final List list = new ArrayList(); stack.add(new Runnable() { public void run() { try { if (eq(t(), "}")) { consume("}"); out.set(type.equals("intarray") ? toIntArray(list) : list.toArray()); } else { stack.add(this); parse(new unstructure_Receiver() { void set(Object o) { list.add(o); if (eq(t(), ",")) consume(); } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(type.equals(\"..."; }}); } Object parseClass() { consume("class"); consume("("); String name = unquote(tpp()); consume(")"); Class c = allDynamic ? null : classFinder != null ? (Class) callF(classFinder, name) : findClass_fullName(name); if (c != null) return c; DynamicObject dO = new DynamicObject(); dO.className = "java.lang.Class"; name = dropPrefix("main$", name); dO.fieldValues.put("name", name); return dO; } Object parseBigInt() { consume("bigint"); consume("("); String val = tpp(); if (eq(val, "-")) val = "-" + tpp(); consume(")"); return new BigInteger(val); } Object parseDouble() { consume("d"); consume("("); String val = unquote(tpp()); consume(")"); return Double.parseDouble(val); } Object parseFloat() { consume("fl"); String val; if (eq(t(), "(")) { consume("("); val = unquote(tpp()); consume(")"); } else { val = unquote(tpp()); } return Float.parseFloat(val); } void parseHashSet(unstructure_Receiver out) { consume("hashset"); parseSet(new HashSet(), out); } void parseLinkedHashSet(unstructure_Receiver out) { consume("lhs"); parseSet(new LinkedHashSet(), out); } void parseTreeSet(unstructure_Receiver out) { consume("treeset"); parseSet(new TreeSet(), out); } void parseCISet(unstructure_Receiver out) { consume("ciset"); parseSet(ciSet(), out); } void parseMap(unstructure_Receiver out) { parseMap(new TreeMap(), out); } Object parseJava() { String j = unquote(tpp()); Matches m = new Matches(); if (jmatch("java.awt.Color[r=*,g=*,b=*]", j, m)) return nuObject("java.awt.Color", parseInt(m.unq(0)), parseInt(m.unq(1)), parseInt(m.unq(2))); else { warn("Unknown Java object: " + j); return null; } } void parseMap(final Map map, final unstructure_Receiver out) { consume("{"); stack.add(new Runnable() { boolean v = false; Object key; public void run() { if (v) { v = false; stack.add(this); if (!eq(tpp(), "=")) throw fail("= expected, got " + t() + " in map of size " + l(map)); parse(new unstructure_Receiver() { void set(Object value) { map.put(key, value); if (eq(t(), ",")) consume(); } }); } else { if (eq(t(), "}")) { consume("}"); out.set(map); } else { v = true; stack.add(this); parse(new unstructure_Receiver() { void set(Object o) { key = o; } }); } } // if v else } // run() }); } /*void parseSub(unstructure_Receiver out) { int n = l(stack); parse(out); while (l(stack) > n) stack }*/ void consume() { curT = tok.next(); ++i; } void consume(String s) { if (!eq(t(), s)) { /*S prevToken = i-1 >= 0 ? tok.get(i-1) : ""; S nextTokens = join(tok.subList(i, Math.min(i+2, tok.size()))); fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");*/ throw fail(quote(s) + " expected, got " + quote(t())); } consume(); } // outer wrapper function getting first token and unwinding the stack void parse_initial(unstructure_Receiver out) { consume(); // get first token parse(out); while (nempty(stack)) popLast(stack).run(); } } Boolean b = DynamicObject_loading.get(); DynamicObject_loading.set(true); try { final Var v = new Var(); X x = new X(); x.parse_initial(new unstructure_Receiver() { void set(Object o) { v.set(o); } }); unstructure_tokrefs = x.tokrefs.size(); return v.get(); } finally { DynamicObject_loading.set(b); } } static boolean unstructure_debug = false; static Producer javaTokC_noMLS_onReader(final BufferedReader r) { final class X implements Producer { StringBuilder buf = new StringBuilder(); // stores from "i" char c, d, e = 'x'; // just not '\0' X() { // fill c, d and e nc(); nc(); nc(); } // get next character(s) into c, d and e void nc() { try { c = d; d = e; if (e == '\0') return; int i = r.read(); e = i < 0 ? '\0' : i == '\0' ? '_' // shouldn't happen anymore : (char) i; } catch (Exception __e) { throw rethrow(__e); } } void ncSave() { if (c != '\0') { buf.append(c); nc(); } } public String next() { // scan for whitespace while (c != '\0') { if (c == ' ' || c == '\t' || c == '\r' || c == '\n') nc(); else if (c == '/' && d == '*') { do nc(); while (c != '\0' && !(c == '*' && d == '/')); nc(); nc(); } else if (c == '/' && d == '/') { do nc(); while (c != '\0' && "\r\n".indexOf(c) < 0); } else break; } if (c == '\0') return null; // scan for non-whitespace if (c == '\'' || c == '"') { char opener = c; ncSave(); while (c != '\0') { if (c == opener || c == '\n') { // end at \n to not propagate unclosed string literal errors ncSave(); break; } else if (c == '\\') { ncSave(); ncSave(); } else ncSave(); } } else if (Character.isJavaIdentifierStart(c)) do ncSave(); while (Character.isJavaIdentifierPart(c) || c == '\''); // for stuff like "don't" else if (Character.isDigit(c)) { do ncSave(); while (Character.isDigit(c)); if (c == 'L') ncSave(); // Long constants like 1L } else ncSave(); String t = buf.toString(); buf.setLength(0); return t; } } return new X(); } static Lock saveLock_lock = fairLock(); static Lock saveLock() { return saveLock_lock; } static String javaTokWordWrap(String s) { return javaTokWordWrap(120, s); } // TODO: complete trimming static String javaTokWordWrap(int cols, String s) { int col = 0; List tok = javaTok(s); for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i) && col >= cols && !containsNewLine(t)) tok.set(i, t = rtrimSpaces(t) + "\n"); int idx = t.lastIndexOf('\n'); if (idx >= 0) col = l(t)-(idx+1); else col += l(t); } return join(tok); } static boolean isAGIBlueDomain(String domain) { return domainIsUnder(domain, theAGIBlueDomain()); } static String hostNameFromURL(String url) { try { return new URL(url).getHost(); } catch (Exception __e) { throw rethrow(__e); } } static void logQuotedWithTime(String s) { logQuotedWithTime(standardLogFile(), s); } static void logQuotedWithTime(File logFile, String s) { logQuoted(logFile, logQuotedWithTime_format(s)); } static void logQuotedWithTime(String logFile, String s) { logQuoted(logFile, logQuotedWithTime_format(s)); } static String logQuotedWithTime_format(String s) { return /*formatGMTWithDate_24*/(now()) + " " + s; } static File javaxDataDir_dir; // can be set to work on different base dir static File javaxDataDir() { return javaxDataDir_dir != null ? javaxDataDir_dir : new File(userHome(), "JavaX-Data"); } static File javaxDataDir(String... subs) { return newFile(javaxDataDir(), subs); } static int isAndroid_flag; static boolean isAndroid() { if (isAndroid_flag == 0) isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; return isAndroid_flag > 0; } static JTextArea wrappedTextArea(final JTextArea ta) { enableWordWrapForTextArea(ta); return ta; } static JTextArea wrappedTextArea() { return wrappedTextArea(jtextarea()); } static JTextArea wrappedTextArea(String text) { JTextArea ta = wrappedTextArea(); setText(ta, text); return ta; } static A onClick(final A c, final Object runnable) { if (c != null) { swing(new Runnable() { public void run() { try { c.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { callF(runnable, e); } }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.addMouseListener(new MouseAdapter {\r\n public void mouseClicked(MouseEv..."; }}); } return c; } // re-interpreted for buttons static void onClick(JButton btn, final Object runnable) { onEnter(btn, runnable); } static Font typeWriterFont() { return typeWriterFont(iround(14*getSwingFontScale())); } static Font typeWriterFont(int size) { return new Font("Courier", Font.PLAIN, size); } static int toMS_int(double seconds) { return toInt_checked((long) (seconds*1000)); } // PersistableThrowable doesn't hold GC-disturbing class references in backtrace static volatile PersistableThrowable lastException_lastException; static PersistableThrowable lastException() { return lastException_lastException; } static void lastException(Throwable e) { lastException_lastException = persistableThrowable(e); } static Throwable getInnerException(Throwable e) { if (e == null) return null; while (e.getCause() != null) e = e.getCause(); return e; } static Throwable getInnerException(Runnable r) { return getInnerException(getException(r)); } static String baseClassName(String className) { return substring(className, className.lastIndexOf('.')+1); } static String baseClassName(Object o) { return baseClassName(getClassName(o)); } static String prependIfNempty(String prefix, String s) { return empty(s) ? s : prefix + s; } //static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init); static class getOpt_Map extends WeakHashMap { getOpt_Map() { if (getOpt_special == null) getOpt_special = new HashMap(); clear(); } public void clear() { super.clear(); //print("getOpt clear"); put(Class.class, getOpt_special); put(String.class, getOpt_special); } } static final Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map())); //static final Map> getOpt_cache = _registerWeakMap(synchroMap(new getOpt_Map)); static HashMap getOpt_special; // just a marker /*static void getOpt_special_init(Map map) { map.put(Class.class, getOpt_special); map.put(S.class, getOpt_special); }*/ static Object getOpt_cached(Object o, String field) { try { if (o == null) return null; Class c = o.getClass(); HashMap map; synchronized(getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } if (map == getOpt_special) { if (o instanceof Class) return getOpt((Class) o, field); /*if (o instanceof S) ret getOpt(getBot((S) o), field);*/ if (o instanceof Map) return ((Map) o).get(field); } Field f = map.get(field); if (f != null) return f.get(o); if (o instanceof DynamicObject) return mapGet2(((DynamicObject) o).fieldValues, field); return null; } catch (Exception __e) { throw rethrow(__e); } } // used internally - we are in synchronized block static HashMap getOpt_makeCache(Class c) { HashMap map; if (isSubtypeOf(c, Map.class)) map = getOpt_special; else { map = new HashMap(); if (!reflection_classesNotToScan().contains(c.getName())) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) { f.setAccessible(true); String name = f.getName(); if (!map.containsKey(name)) map.put(name, f); } _c = _c.getSuperclass(); } while (_c != null); } } if (getOpt_cache != null) getOpt_cache.put(c, map); return map; } static volatile boolean disableCertificateValidation_attempted = false; static void disableCertificateValidation() { try { if (disableCertificateValidation_attempted) return; disableCertificateValidation_attempted = true; try { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} }}; // Ignore differences between given hostname and certificate hostname HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; // Install the all-trusting trust manager SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(hv); } catch (Throwable __e) { _handleException(__e); } } catch (Exception __e) { throw rethrow(__e); } } static boolean networkAllowanceTest(String url) { return isAllowed("networkAllowanceTest", url); } static final boolean loadPageThroughProxy_enabled = false; static String loadPageThroughProxy(String url) { return null; } static String tb_mainServer_default = "http://code.botcompany.de:8081"; static Object tb_mainServer_override; // func -> S static String tb_mainServer() { if (tb_mainServer_override != null) return (String) callF(tb_mainServer_override); return trim(loadTextFile(tb_mainServer_file(), tb_mainServer_default)); } static File tb_mainServer_file() { return getProgramFile("#1001638", "mainserver.txt"); } static boolean tb_mainServer_isDefault() { return eq(tb_mainServer(), tb_mainServer_default); } static A printWithTime(A a) { print(hmsWithColons() + ": " + a); return a; } static void setHeaders(URLConnection con) throws IOException { String computerID = getComputerID_quick(); if (computerID != null) try { con.setRequestProperty("X-ComputerID", computerID); con.setRequestProperty("X-OS", System.getProperty("os.name") + " " + System.getProperty("os.version")); } catch (Throwable e) { //printShortException(e); } } static Map vm_generalSubMap(Object name) { synchronized(get(javax(), "generalMap")) { Map map = (Map) (vm_generalMap_get(name)); if (map == null) vm_generalMap_put(name, map = synchroMap()); return map; } } static InputStream urlConnection_getInputStream(URLConnection con) throws IOException { UnknownHostException lastException = null; for (int _repeat_638 = 0; _repeat_638 < 2; _repeat_638++) { try { if (con instanceof HttpURLConnection) if (((HttpURLConnection) con).getResponseCode() == 500) throw new IOException(joinNemptiesWithColonSpace("Server code 500", tryToReadErrorStreamFromURLConnection(((HttpURLConnection) con)))); return con.getInputStream(); } catch (UnknownHostException e) { lastException = e; print("Retrying because of: " + e); continue; } } throw lastException; } static String unquote(String s) { if (s == null) return null; if (startsWith(s, '[')) { int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; if (i < s.length() && s.charAt(i) == '[') { String m = s.substring(1, i); if (s.endsWith("]" + m + "]")) return s.substring(i+1, s.length()-i-1); } } if (s.length() > 1) { char c = s.charAt(0); if (c == '\"' || c == '\'') { int l = endsWith(s, c) ? s.length()-1 : s.length(); StringBuilder sb = new StringBuilder(l-1); for (int i = 1; i < l; i++) { char ch = s.charAt(i); if (ch == '\\') { char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1); // Octal escape? if (nextChar >= '0' && nextChar <= '7') { String code = "" + nextChar; i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; } } sb.append((char) Integer.parseInt(code, 8)); continue; } switch (nextChar) { case '\"': ch = '\"'; break; case '\\': ch = '\\'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case '\'': ch = '\''; break; // Hex Unicode: u???? case 'u': if (i >= l - 5) { ch = 'u'; break; } int code = Integer.parseInt( "" + s.charAt(i + 2) + s.charAt(i + 3) + s.charAt(i + 4) + s.charAt(i + 5), 16); sb.append(Character.toChars(code)); i += 5; continue; default: ch = nextChar; // added by Stefan } i++; } sb.append(ch); } return sb.toString(); } } return s; // not quoted - return original } static String toHex(byte[] bytes) { return bytesToHex(bytes); } static String toHex(byte[] bytes, int ofs, int len) { return bytesToHex(bytes, ofs, len); } static byte[] utf8(String s) { return toUtf8(s); } static Matcher regexpMatcher(String pat, String s) { return compileRegexp(pat).matcher(unnull(s)); } static URLConnection openConnection(String url) { try { return openConnection(new URL(url)); } catch (Exception __e) { throw rethrow(__e); } } static URLConnection openConnection(URL url) { try { ping(); callOpt(javax(), "recordOpenURLConnection", str(url)); return url.openConnection(); } catch (Exception __e) { throw rethrow(__e); } } static URLConnection setURLConnectionTimeouts(URLConnection con, long timeout) { con.setConnectTimeout(toInt(timeout)); con.setReadTimeout(toInt(timeout)); if (con.getConnectTimeout() != timeout || con.getReadTimeout() != timeout) print("Warning: Timeouts not set by JDK."); return con; } static URLConnection setURLConnectionDefaultTimeouts(URLConnection con, long timeout) { if (con.getConnectTimeout() == 0) { con.setConnectTimeout(toInt(timeout)); if (con.getConnectTimeout() != timeout) print("Warning: URL connect timeout not set by JDK."); } if (con.getReadTimeout() == 0) { con.setReadTimeout(toInt(timeout)); if (con.getReadTimeout() != timeout) print("Warning: URL read timeout not set by JDK."); } return con; } static TreeSet toCaseInsensitiveSet(Iterable c) { if (isCISet(c)) return (TreeSet) c; TreeSet set = caseInsensitiveSet(); addAll(set, c); return set; } static TreeSet toCaseInsensitiveSet(String... x) { TreeSet set = caseInsensitiveSet(); addAll(set, x); return set; } static String shortenSnippetID(String snippetID) { if (snippetID.startsWith("#")) snippetID = snippetID.substring(1); String httpBlaBla = "http://tinybrain.de/"; if (snippetID.startsWith(httpBlaBla)) snippetID = snippetID.substring(httpBlaBla.length()); return "" + parseLong(snippetID); } static A proxy(Class intrface, final Object target) { if (target == null) return null; if (isInstance(intrface, target)) return (A) target; return (A) java.lang.reflect.Proxy.newProxyInstance(intrface.getClassLoader(), new Class[] { intrface }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) { return call(target, method.getName(), unnull(args)); } }); } static A proxy(Object target, Class intrface) { return proxy(intrface, target); } static File javaxCachesDir_dir; // can be set to work on different base dir static File javaxCachesDir() { return javaxCachesDir_dir != null ? javaxCachesDir_dir : new File(userHome(), "JavaX-Caches"); } static File javaxCachesDir(String sub) { return newFile(javaxCachesDir(), sub); } static String snippetImageURL(long snippetID) { return snippetImageURL(fsI(snippetID)); } static String snippetImageURL(String snippetID) { return snippetImageURL(snippetID, "png"); } static String snippetImageURL(String snippetID, String contentType) { if (isURL(snippetID)) return snippetID; long id = parseSnippetID(snippetID); String url; if (id == 1000010 || id == 1000012) url = "http://tinybrain.de:8080/tb/show-blobimage.php?id=" + id; else if (isImageServerSnippet(id)) url = imageServerLink(id); else //url = "http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_" + id + "&contentType=image/" + contentType; url = "https://www.botcompany.de:8443/img/" + id; return url; } static int toInt_checked(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static ThreadLocal assertVerbose_value = new ThreadLocal(); static void assertVerbose(boolean b) { assertVerbose_value.set(b); } static boolean assertVerbose() { return isTrue(assertVerbose_value.get()); } static A assertEqualsVerbose(Object x, A y) { assertEqualsVerbose((String) null, x, y); return y; } static A assertEqualsVerbose(String msg, Object x, A y) { if (!eq(x, y)) { throw fail((msg != null ? msg + ": " : "") + /*sfu*/(y) + " != " + /*sfu*/(x)); } else print("OK: " + /*sfu*/(x)); return y; } static char firstChar(String s) { return s.charAt(0); } static double pow(double a, double b) { return Math.pow(a, b); } static float pow(float a, float b) { return (float) Math.pow(a, b); } static BigInteger pow(BigInteger a, int b) { return a.pow(b); } static float rgbDiff(RGB a, RGB b) { return (float) (Math.abs(a.r-b.r) + Math.abs(a.g-b.g) + Math.abs(a.b-b.b))/3; } // 0xRRGGBB - result is between 0 and 1 static float rgbDiff(int a, int b) { int r1 = (a >> 16) & 0xFF; int g1 = (a >> 8) & 0xFF; int b1 = a & 0xFF; int r2 = (b >> 16) & 0xFF; int g2 = (b >> 8) & 0xFF; int b2 = b & 0xFF; return (Math.abs(r1-r2) + Math.abs(g1-g2) + Math.abs(b1-b2))/(3f*255); } static float autoCropOfBWImage_threshold = 0.9f; static Rect autoCropOfBWImage(BWImage img) { return autoCropOfBWImage(img, new Rect(0, 0, img.getWidth(), img.getHeight())); } static Rect autoCropOfBWImage(BWImage img, Rect r) { return autoCropOfBWImage(img, r, autoCropOfBWImage_threshold); } // r = initial rectangle static Rect autoCropOfBWImage(BWImage img, Rect r, float threshold) { int x1 = r.x, y1 = r.y, x2 = r.x2(), y2 = r.y2(); // left side end1: while (x1 < x2) { for (int y = y1; y < y2; y++) if (img.getPixel(x1, y) <= threshold) break end1; x1++; } // top side end2: while (y1 < y2) { for (int x = x1; x < x2; x++) if (img.getPixel(x, y1) <= threshold) break end2; y1++; } // right side end3: while (x2 > x1) { for (int y = y1; y < y2; y++) if (img.getPixel(x2-1, y) <= threshold) break end3; x2--; } // bottom side end4: while (y2 > y1) { for (int x = x1; x < x2; x++) if (img.getPixel(x, y2-1) <= threshold) break end4; y2--; } if (x2 <= x1 || y2 <= y1) return r; else return new Rect(x1, y1, x2 - x1, y2 - y1); } static void arraycopy(Object[] a, Object[] b) { if (a != null && b != null) arraycopy(a, 0, b, 0, min(a.length, b.length)); } static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) { if (n != 0) System.arraycopy(src, srcPos, dest, destPos, n); } static int getScreenWidth() { return getScreenSize().width; } static int getScreenHeight() { return getScreenSize().height; } static String makeFrame_defaultIcon; static boolean makeFrame_hideConsole = false; static ThreadLocal> makeFrame_post = new ThreadLocal(); static JFrame makeFrame() { return makeFrame((Component) null); } static JFrame makeFrame(Object content) { return makeFrame(programTitle(), content); } static JFrame makeFrame(String title) { return makeFrame(title, null); } static JFrame makeFrame(String title, Object content) { return makeFrame(title, content, true); } static JFrame makeFrame(final String title, final Object content, final boolean showIt) { final VF1 post = optParam(makeFrame_post); return swing(new F0() { JFrame get() { try { if (getFrame(content) != null) return getFrame(setFrameTitle((Component) content, title)); final JFrame frame = new JFrame(title); if (makeFrame_defaultIcon != null) setFrameIconLater(frame, makeFrame_defaultIcon); _initFrame(frame); Component wrapped = wrap(content); if (wrapped != null) frame.getContentPane().add(wrapped); frame.setBounds(defaultNewFrameBounds()); callF(post, frame); if (showIt) frame.setVisible(true); //callOpt(content, "requestFocus"); //exitOnFrameClose(frame); if (showIt && makeFrame_hideConsole) { hideConsole(); makeFrame_hideConsole = false; } return frame; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (getFrame(content) != null)\r\n ret getFrame(setFrameTitle((Component) ..."; }}); } static boolean frameTooSmall(JFrame frame) { return frame.getWidth() < 100 || frame.getHeight() < 50; } static void frameStandardSize(JFrame frame) { frame.setBounds(300, 100, 500, 400); } static void setFrameContents(final Component c, final Object contents) { { swing(new Runnable() { public void run() { try { JFrame frame = getFrame(c); frame.getContentPane().removeAll(); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(wrap(contents)); revalidate(frame); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JFrame frame = getFrame(c);\r\n frame.getContentPane().removeAll();\r\n fra..."; }}); } } static int imageIcon_cacheSize = 10; static boolean imageIcon_verbose = false; static Map imageIcon_cache; static Lock imageIcon_lock = lock(); static ThreadLocal imageIcon_fixGIF = new ThreadLocal(); // not going through BufferedImage preserves animations static ImageIcon imageIcon(String imageID) { try { if (imageID == null) return null; Lock __1810 = imageIcon_lock; lock(__1810); try { if (imageIcon_cache == null) imageIcon_cache = new MRUCache(imageIcon_cacheSize); imageID = fsI(imageID); ImageIcon ii = imageIcon_cache.get(imageID); if (ii == null) { if (imageIcon_verbose) print("Loading image icon: " + imageID); File f = loadBinarySnippet(imageID); Boolean b = imageIcon_fixGIF.get(); if (!isFalse(b)) ii = new ImageIcon(loadBufferedImageFixingGIFs(f)); else ii = new ImageIcon(f.toURI().toURL()); } else imageIcon_cache.remove(imageID); // move to front of cache on access imageIcon_cache.put(imageID, ii); return ii; } finally { unlock(__1810); } } catch (Exception __e) { throw rethrow(__e); } } // doesn't fix GIFs static ImageIcon imageIcon(File f) { try { return new ImageIcon(f.toURI().toURL()); } catch (Exception __e) { throw rethrow(__e); } } static ImageIcon imageIcon(Image img) { return new ImageIcon(img); } static ImageIcon imageIcon(RGBImage img) { return imageIcon(img.getBufferedImage()); } static Object pcallFunction(Object f, Object... args) { try { return callFunction(f, args); } catch (Throwable __e) { _handleException(__e); } return null; } static A componentPopupMenuItem(A c, final String name, final Object action) { componentPopupMenu(c, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, name, action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, name, action);"; }}); return c; } static void componentPopupMenuItem(JComponent c, final JMenuItem menuItem) { componentPopupMenu(c, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, menuItem); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, menuItem);"; }}); } static Set vm_generalWeakSet(Object name) { synchronized(get(javax(), "generalMap")) { Set set = (Set) (vm_generalMap_get(name)); if (set == null) vm_generalMap_put(name, set = newWeakHashSet()); return set; } } static AbstractAction abstractAction(String name, final Object runnable) { return new AbstractAction(name) { public void actionPerformed(ActionEvent evt) { pcallF(runnable); } }; } static ThreadLocal addInternalFrame_dontSelect = new ThreadLocal(); static ThreadLocal addInternalFrame_layer = new ThreadLocal(); static ThreadLocal addInternalFrame_toBack = new ThreadLocal(); static JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final int x, final int y, final int w, final int h) { return addInternalFrame(desktop, title, x, y, w, h, null); } static JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final int x, final int y, final int w, final int h, final Component contents) { return addInternalFrame(desktop, title, rect(x, y, w, h), contents); } static JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final Component contents) { return addInternalFrame(desktop, title, null, contents); } static JInternalFrame addInternalFrame(final JDesktopPane desktop, final String title, final Rect r, final Component contents) { final boolean dontSelect = isTrue(optParam(addInternalFrame_dontSelect)); final boolean toBack = isTrue(optParam(addInternalFrame_toBack)); final Integer layer = optParam(addInternalFrame_layer); return swing(new F0() { JInternalFrame get() { try { JInternalFrame frame; if (contents instanceof JInternalFrame) frame = (JInternalFrame) contents; else { frame = jInternalFrame(title); setInternalFrameContents(frame, contents); } frame.setVisible(true); desktop.add(frame, layer); if (r != null) setBounds(frame, r); else internalFrameDefaultPosition(frame); if (dontSelect) if (toBack) frame.toBack(); else frame.toFront(); else frame.setSelected(true); return fixInternalFrame(frame); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JInternalFrame frame;\r\n if (contents instanceof JInternalFrame)\r\n fra..."; }}); } static JInternalFrame addInternalFrame(JDesktopPane desktop, String title) { return addInternalFrame(desktop, title, jpanel()); } static JInternalFrame minInternalFrameWidth(final JInternalFrame frame, final int w) { { swing(new Runnable() { public void run() { try { if (frame != null && frame.getWidth() < w) frame.setSize(w, frame.getHeight()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (frame != null && frame.getWidth() < w)\r\n frame.setSize(w, frame.getH..."; }}); } return frame; } static JInternalFrame minInternalFrameWidth(int w, JInternalFrame frame) { return minInternalFrameWidth(frame, w); } static A packInternalFrameVertically(A c) { return packInternalFrameVertically(-1, c); } static A packInternalFrameVertically(int width, A c) { final JInternalFrame win = getInternalFrame(c); if (win == null) return c; final int w = width < 0 ? win.getWidth() : width; { swing(new Runnable() { public void run() { try { win.pack(); win.setSize(w, win.getHeight()); fixInternalFrame(win); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "win.pack();\r\n win.setSize(w, win.getHeight());\r\n fixInternalFrame(win);"; }}); } return c; } static JInternalFrame centerInternalFrame(final JInternalFrame f) { { swing(new Runnable() { public void run() { try { Container c = f.getParent(); if (c != null) { //print("Container type: " + className(c) + ", bounds: " + c.getBounds()); f.setLocation((c.getWidth()-f.getWidth())/2, (c.getHeight()-f.getHeight())/2); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Container c = f.getParent();\r\n if (c != null) {\r\n //print(\"Container ..."; }}); } return f; } static JInternalFrame centerInternalFrame(final int w, final int h, final JInternalFrame f) { { swing(new Runnable() { public void run() { try { f.setSize(w, h); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.setSize(w, h);"; }}); } return centerInternalFrame(f); } static Dimension getMinimumSize(final Component c) { return c == null ? null : swing(new F0() { Dimension get() { try { return c.getMinimumSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getMinimumSize();"; }}); } static A jPreferWidth(int w, A c) { Dimension size = c.getPreferredSize(); c.setPreferredSize(new Dimension(/*max(w, size.width) ??? */w, size.height)); return c; } static boolean containsSpace(String s) { return containsSpaces(s); } static String firstToUpper(String s) { if (empty(s)) return s; return Character.toUpperCase(s.charAt(0)) + s.substring(1); } static List replaceElementsUsingMap(Iterable l, final Map map) { return map(l, new F1() { A get(A a) { try { return getOrKeep(map, a); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "getOrKeep(map, a)"; }}); } static List splitCamelCase(String s) { return ai_splitCamelCase(s); } static boolean hasMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args) != null; } static JInternalFrame getInternalFrame(final Object _o) { return _o == null ? null : swing(new F0() { JInternalFrame get() { try { Object o = _o; if (o instanceof ButtonGroup) o = first(buttonsInGroup((ButtonGroup) o)); if (!(o instanceof Component)) return null; Component c = (Component) o; while (c != null) { if (c instanceof JInternalFrame) return (JInternalFrame) c; c = c.getParent(); } return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O o = _o;\r\n if (o instanceof ButtonGroup) o = first(buttonsInGroup((Button..."; }}); } static Field setOpt_findField(Class c, String field) { HashMap map; synchronized(getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } return map.get(field); } static void setOpt(Object o, String field, Object value) { try { if (o == null) return; Class c = o.getClass(); HashMap map; if (getOpt_cache == null) map = getOpt_makeCache(c); // in class init else synchronized(getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } if (map == getOpt_special) { if (o instanceof Class) { setOpt((Class) o, field, value); return; } // It's probably a subclass of Map. Use raw method setOpt_raw(o, field, value); return; } Field f = map.get(field); if (f != null) smartSet(f, o, value); // possible improvement: skip setAccessible } catch (Exception __e) { throw rethrow(__e); } } static void setOpt(Class c, String field, Object value) { if (c == null) return; try { Field f = setOpt_findStaticField(c, field); if (f != null) smartSet(f, null, value); } catch (Exception e) { throw new RuntimeException(e); } } static Field setOpt_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) { f.setAccessible(true); return f; } _c = _c.getSuperclass(); } while (_c != null); return null; } static List allChildren(Component c) { return childrenOfType(c, Component.class); } static void onEnterIfTextField(Component c, Object action) { if (action == null) return; if (c instanceof JTextField) onEnter((JTextField) c, action); else if (c instanceof JComboBox) onEnter((JComboBox) c, action); } static Map classForName_cache = synchroHashMap(); static Class classForName(String name) { try { if (classForName_cache == null) return Class.forName(name); // in class init Class c = classForName_cache.get(name); if (c == null) classForName_cache.put(name, c = Class.forName(name)); return c; } catch (Exception __e) { throw rethrow(__e); } } static Map nuObjectWithoutArguments_cache = newDangerousWeakHashMap(); static Object nuObjectWithoutArguments(String className) { try { return nuObjectWithoutArguments(classForName(className)); } catch (Exception __e) { throw rethrow(__e); } } static A nuObjectWithoutArguments(Class c) { try { if (nuObjectWithoutArguments_cache == null) // in class init return (A) nuObjectWithoutArguments_findConstructor(c).newInstance(); Constructor m = nuObjectWithoutArguments_cache.get(c); if (m == null) nuObjectWithoutArguments_cache.put(c, m = nuObjectWithoutArguments_findConstructor(c)); return (A) m.newInstance(); } catch (Exception __e) { throw rethrow(__e); } } static Constructor nuObjectWithoutArguments_findConstructor(Class c) { for (Constructor m : c.getDeclaredConstructors()) if (empty(m.getParameterTypes())) { m.setAccessible(true); return m; } throw fail("No default constructor found in " + c.getName()); } static List getClasses(Object[] array) { List l = new ArrayList(); for (Object o : array) l.add(_getClass(o)); return l; } static String containerTag(String tag) { return containerTag(tag, ""); } static String containerTag(String tag, Object contents, Object... params) { String openingTag = hopeningTag(tag, params); String s = str(contents); return openingTag + s + ""; } static String intToHex_flexLength(int i) { return Integer.toHexString(i); } static boolean headless() { return isHeadless(); } static Throwable innerException2(Throwable e) { if (e == null) return null; while (empty(e.getMessage()) && e.getCause() != null) e = e.getCause(); return e; } static byte[] intToBytes(int i) { return new byte[] { (byte) (i >>> 24), (byte) (i >>> 16), (byte) (i >>> 8), (byte) i}; } static boolean isMD5(String s) { return l(s) == 32 && isLowerHexString(s); } static String imageServerURL() { return or2(trim(loadTextFile(javaxDataDir("image-server-url.txt"))), "http://botcompany.de/images/raw/"); } static long parseLongOpt(String s) { return isInteger(s) ? parseLong(s) : 0; } static byte[] toPNG(BufferedImage img) { return convertToPNG(img); } public static byte[] loadBinaryFile(String fileName) { try { if (!new File(fileName).exists()) return null; FileInputStream in = new FileInputStream(fileName); byte buf[] = new byte[1024]; ByteArrayOutputStream out = new ByteArrayOutputStream(); int l; while (true) { l = in.read(buf); if (l <= 0) break; out.write(buf, 0, l); } in.close(); return out.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } } public static byte[] loadBinaryFile(File file) { return loadBinaryFile(file.getPath()); } static String uploadToImageServer_rawBytes(byte[] imgData, String name) { String page = postPage(imageServerURL() + "upload/" + randomID() /* anti-anti-spam */, "data", bytesToHex(imgData), "name", name); print(page); Matcher m = Pattern.compile("/raw/([0-9]+)").matcher(page); if (!m.find()) return null; return snippetImgLink(m.group(1)); } static String formatSnippetID(String id) { return "#" + parseSnippetID(id); } static String formatSnippetID(long id) { return "#" + id; } static boolean isEditableComboBox(final JComboBox cb) { return cb != null && swing(new F0() { Boolean get() { try { return cb.isEditable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret cb.isEditable();"; }}); } static String javaTok_substringC(String s, int i, int j) { return s.substring(i, j); } static A liftLast(List l) { if (l.isEmpty()) return null; int i = l(l)-1; A a = l.get(i); l.remove(i); return a; } static byte[] boolArrayToBytes(boolean[] a) { byte[] b = new byte[(l(a)+7)/8]; for (int i = 0; i < l(a); i++) if (a[i]) b[i/8] |= 1 << (i & 7); return b; } static String shortClassName(Object o) { if (o == null) return null; Class c = o instanceof Class ? (Class) o : o.getClass(); String name = c.getName(); return shortenClassName(name); } static int cmp(Number a, Number b) { return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue()); } static int cmp(double a, double b) { return a < b ? -1 : a == b ? 0 : 1; } static 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 boolean isDigit(char c) { return Character.isDigit(c); } static String addPrefix(String prefix, String s) { return s.startsWith(prefix) ? s : prefix + s; } static List jsonTok(String s) { List tok = new ArrayList(); int l = l(s); int i = 0; while (i < l) { int j = i; char c; String cc; // scan for whitespace while (j < l) { c = s.charAt(j); cc = s.substring(j, Math.min(j+2, l)); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (cc.equals("/*")) { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (cc.equals("//")) { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); // cc is not needed in rest of loop body // scan for non-whitespace (json strings, "null" identifier, numbers. everything else automatically becomes a one character token.) if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isLetter(c)) do ++j; while (j < l && Character.isLetter(s.charAt(j))); else if (Character.isDigit(c)) do ++j; while (j < l && Character.isDigit(s.charAt(j))); else ++j; tok.add(s.substring(i, j)); i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static boolean isInteger(String s) { int n = l(s); if (n == 0) return false; int i = 0; if (s.charAt(0) == '-') if (++i >= n) return false; while (i < n) { char c = s.charAt(i); if (c < '0' || c > '9') return false; ++i; } return true; } static double parseDouble(String s) { return Double.parseDouble(s); } static long parseLong(String s) { if (empty(s)) return 0; return Long.parseLong(dropSuffix("L", s)); } static long parseLong(Object s) { return Long.parseLong((String) s); } static ThreadLocal doPost_silently = new ThreadLocal(); static ThreadLocal doPost_timeout = new ThreadLocal(); static ThreadLocal> doPost_extraHeaders = new ThreadLocal(); static String doPost(Map urlParameters, String url) { return doPost(makePostData(urlParameters), url); } static String doPost(String urlParameters, String url) { try { URL _url = new URL(url); ping(); return doPost(urlParameters, _url.openConnection(), _url); } catch (Exception __e) { throw rethrow(__e); } } static String doPost(String urlParameters, URLConnection conn, URL url) { try { boolean silently = isTrue(optParam(doPost_silently)); Long timeout = optParam(doPost_timeout); Map extraHeaders = optPar(doPost_extraHeaders); setHeaders(conn); for (String key : keys(extraHeaders)) conn.setRequestProperty(key, extraHeaders.get(key)); int l = lUtf8(urlParameters); if (!silently) print("Sending POST request: " + hideCredentials(url) + " (" + l + " bytes)"); // connect and do POST if (timeout != null) setURLConnectionTimeouts(conn, timeout); ((HttpURLConnection) conn).setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Length", str(l)); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); writer.write(urlParameters); writer.flush(); String contents = loadPage_utf8(conn, url, false); writer.close(); return contents; } catch (Exception __e) { throw rethrow(__e); } } static Map cloneMap(Map map) { if (map == null) return new HashMap(); // assume mutex is equal to collection synchronized(map) { return map instanceof TreeMap ? new TreeMap((TreeMap) map) // copies comparator : map instanceof LinkedHashMap ? new LinkedHashMap(map) : new HashMap(map); } } static LinkedHashMap asLinkedHashMap(Map map) { if (map instanceof LinkedHashMap) return (LinkedHashMap) map; LinkedHashMap m = new LinkedHashMap(); if (map != null) synchronized(collectionMutex(map)) { m.putAll(map); } return m; } static Map paramsToMap(Object... params) { int n = l(params); if (l(params) == 1 && params[0] instanceof Map) return (Map) params[0]; LinkedHashMap map = new LinkedHashMap(); for (int i = 0; i+1 < n; i += 2) mapPut(map, params[i], params[i+1]); return map; } static Object[] mapToObjectArray(Map map) { List l = new ArrayList(); for (Object o : keys(map)) { l.add(o); l.add(map.get(o)); } return toObjectArray(l); } static String base64encode(byte[] a) { int aLen = a.length; int numFullGroups = aLen/3; int numBytesInPartialGroup = aLen - 3*numFullGroups; int resultLen = 4*((aLen + 2)/3); StringBuffer result = new StringBuffer(resultLen); char[] intToAlpha = intToBase64; // Translate all full groups from byte array elements to Base64 int inCursor = 0; for (int i=0; i> 2]); result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]); result.append(intToAlpha[byte2 & 0x3f]); } // Translate partial group if present if (numBytesInPartialGroup != 0) { int byte0 = a[inCursor++] & 0xff; result.append(intToAlpha[byte0 >> 2]); if (numBytesInPartialGroup == 1) { result.append(intToAlpha[(byte0 << 4) & 0x3f]); result.append("=="); } else { // assert numBytesInPartialGroup == 2; int byte1 = a[inCursor++] & 0xff; result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); result.append(intToAlpha[(byte1 << 2)&0x3f]); result.append('='); } } // assert inCursor == a.length; // assert result.length() == resultLen; return result.toString(); } /** * This array is a lookup table that translates 6-bit positive integer * index values into their "Base64 Alphabet" equivalents as specified * in Table 1 of RFC 2045. */ static final char intToBase64[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; static byte[] toUtf8(String s) { try { return s.getBytes("UTF-8"); } catch (Exception __e) { throw rethrow(__e); } } static File javaxSecretDir_dir; // can be set to work on different base dir static File javaxSecretDir() { return javaxSecretDir_dir != null ? javaxSecretDir_dir : new File(userHome(), "JavaX-Secret"); } static File javaxSecretDir(String sub) { return newFile(javaxSecretDir(), sub); } static File newFile(File base, String... names) { for (String name : names) base = new File(base, name); return base; } static File newFile(String name) { return name == null ? null : new File(name); } static String formatSnippetIDOpt(String s) { return isSnippetID(s) ? formatSnippetID(s) : s; } static Class getMainClass() { return mc(); } static Class getMainClass(Object o) { try { if (o == null) return null; if (o instanceof Class && eq(((Class) o).getName(), "x30")) return (Class) o; return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main"); } catch (Exception __e) { throw rethrow(__e); } } static ThreadLocal> checkFileNotTooBigToRead_tl = new ThreadLocal(); static void checkFileNotTooBigToRead(File f) { callF(checkFileNotTooBigToRead_tl.get(), f); } static Object collectionMutex(List l) { return l; } static Object collectionMutex(Object o) { if (o instanceof List) return o; String c = className(o); if (eq(c, "java.util.TreeMap$KeySet")) c = className(o = getOpt(o, "m")); else if (eq(c, "java.util.HashMap$KeySet")) c = className(o = get_raw(o, "this$0")); if (eqOneOf(c, "java.util.TreeMap$AscendingSubMap", "java.util.TreeMap$DescendingSubMap")) c = className(o = get_raw(o, "m")); return o; } static List collect(Collection c, String field) { return collectField(c, field); } static List collect(String field, Collection c) { return collectField(c, field); } /*ifclass Concept static L collect(Class c, S field) { ret collect(list(c), field); } endif TODO: make translator ignore stuff in ifclass until resolved */ static void sleepInCleanUp(long ms) { try { if (ms < 0) return; Thread.sleep(ms); } catch (Exception __e) { throw rethrow(__e); } } static void copyStream(InputStream in, OutputStream out) { try { byte[] buf = new byte[65536]; while (true) { int n = in.read(buf); if (n <= 0) return; out.write(buf, 0, n); } } catch (Exception __e) { throw rethrow(__e); } } static void _registerIO(Object object, String path, boolean opened) { } static Object vmBus_wrapArgs(Object... args) { return empty(args) ? null : l(args) == 1 ? args[0] : args; } static void pcallFAll(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) pcallF(f, args); } static void pcallFAll(Iterator it, Object... args) { while (it.hasNext()) pcallF(it.next(), args); } static Set vm_busListeners_live_cache; static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache; } static Set vm_busListeners_live_load() { return vm_generalIdentityHashSet("busListeners"); } static Map vm_busListenersByMessage_live_cache; static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache; } static Map vm_busListenersByMessage_live_load() { return vm_generalHashMap("busListenersByMessage"); } static String makePostData(Map map) { StringBuilder buf = new StringBuilder(); for (Map.Entry e : map.entrySet()) { String key = (String) (e.getKey()); Object val = e.getValue(); if (val != null) { String value = str(val); if (nempty(buf)) buf.append("&"); buf.append(urlencode(key)).append("=").append(urlencode(/*escapeMultichars*/(value))); } } return str(buf); } static String makePostData(Object... params) { StringBuilder buf = new StringBuilder(); int n = l(params); for (int i = 0; i+1 < n; i += 2) { String key = (String) (params[i]); Object val = params[i+1]; if (val != null) { String value = str(val); if (nempty(buf)) buf.append("&"); buf.append(urlencode(key)).append("=").append(urlencode(/*escapeMultichars*/(value))); } } return str(buf); } static Producer javaTokC_iterator(final String s) { return new Producer() { final int l = s.length(); int i = 0; public String next() { if (i >= l) return null; int j = i; char c, d; // scan for whitespace while (j < l) { c = s.charAt(j); d = j+1 >= l ? '\0' : s.charAt(j+1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } i = j; if (i >= l) return null; c = s.charAt(i); d = i+1 >= l ? '\0' : s.charAt(i+1); // scan for non-whitespace if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L } else if (c == '[' && d == '[') { do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); j = Math.min(j+2, l); } else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') { do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); j = Math.min(j+3, l); } else ++j; String t = quickSubstring(s, i, j); i = j; return t; } }; } static A listGet(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } static void minimizeFrame(final Component c) { { swing(new Runnable() { public void run() { try { JFrame f = getFrame(c); if (f != null) f.setState(JFrame.ICONIFIED); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JFrame f = getFrame(c);\r\n if (f != null)\r\n f.setState(JFrame.ICONIFIED);"; }}); } } static JDesktopPane dm_desktopPane() { return dm_getOSOpt("desktop"); } static boolean activateFrame(final Component c) { return swing(new F0() { Boolean get() { try { Frame f = getAWTFrame(c); if (f == null) return false; if (!f.isVisible()) f.setVisible(true); if (f.getState() == Frame.ICONIFIED) f.setState(Frame.NORMAL); // My glorious Windows hack // See: https://stackoverflow.com/questions/309023/how-to-bring-a-window-to-the-front if (isWindows()) { boolean fullscreen = f.getExtendedState() == Frame.MAXIMIZED_BOTH; f.setExtendedState(JFrame.ICONIFIED); f.setExtendedState(fullscreen ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL); } f.toFront(); return true; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Frame f = getAWTFrame(c);\r\n if (f == null) false;\r\n if (!f.isVisible())..."; }}); } static Object sleepQuietly_monitor = new Object(); static void sleepQuietly() { try { assertFalse(isAWTThread()); synchronized(sleepQuietly_monitor) { sleepQuietly_monitor.wait(); } } catch (Exception __e) { throw rethrow(__e); } } static File findCmdOnPATH(String cmd) { String path = System.getenv("PATH"); List dirs = splitAt(path, File.pathSeparator); String c = isWindows() ? addSuffix(cmd, ".exe") : cmd; for (String dir : dirs) { File f = new File(dir, c); if (f.isFile()) return f; } return null; } static String makeRandomID(int length) { return makeRandomID(length, defaultRandomGenerator()); } static String makeRandomID(int length, Random random) { char[] id = new char[length]; for (int i = 0; i < id.length; i++) id[i] = (char) ((int) 'a' + random.nextInt(26)); return new String(id); } static String makeRandomID(Random r, int length) { return makeRandomID(length, r); } static File getProgramFile(String progID, String fileName) { if (new File(fileName).isAbsolute()) return new File(fileName); return new File(getProgramDir(progID), fileName); } static File getProgramFile(String fileName) { return getProgramFile(getProgramID(), fileName); } static boolean deleteFile(File file) { return file != null && file.delete(); } public static boolean isWindows() { return System.getProperty("os.name").contains("Windows"); } static File makeFileNameUnique_withExtension(File f, String ext) { File orig = f; int n = 0; ext = addPrefixIfNempty(".", dropPrefix(".", ext)); String name = dropSuffixIC(ext, orig.getName()); f = new File(dirOfFile(orig), name + ext); while (f.exists()) f = new File(dirOfFile(orig), name + "." + (++n) + ext); return f; } static int numLines(String s) { return countLines(s); } static boolean isMac() { return System.getProperty("os.name").toLowerCase().contains("mac"); } static Throwable unwrapTrivialExceptionWraps(Throwable e) { if (e == null) return e; while (e.getClass() == RuntimeException.class && e.getCause() != null && eq(e.getMessage(), str(e.getCause()))) e = e.getCause(); return e; } static List _registerWeakMap_preList; static A _registerWeakMap(A map) { if (javax() == null) { // We're in class init if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList(); _registerWeakMap_preList.add(map); return map; } try { call(javax(), "_registerWeakMap", map); } catch (Throwable e) { printException(e); print("Upgrade JavaX!!"); } return map; } static void _onLoad_registerWeakMap() { assertNotNull(javax()); if (_registerWeakMap_preList == null) return; for (Object o : _registerWeakMap_preList) _registerWeakMap(o); _registerWeakMap_preList = null; } static boolean eqicOneOf(String s, String... l) { for (String x : l) if (eqic(s, x)) return true; return false; } static String fileExtension(File f) { if (f == null) return null; return fileExtension(f.getName()); } static String fileExtension(String s) { return substring(s, smartLastIndexOf(s, '.')); } static final Map callOpt_cache = newDangerousWeakHashMap(); static Object callOpt_cached(Object o, String methodName, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); // TODO: (super-rare) case where method exists static and non-static // with different args Method me = cache.findMethod(methodName, args); if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null; return invokeMethod(me, null, args); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(methodName, args); if (me == null) return null; return invokeMethod(me, o, args); } } catch (Exception __e) { throw rethrow(__e); } } static _MethodCache callOpt_getCache(Class c) { synchronized(callOpt_cache) { _MethodCache cache = callOpt_cache.get(c); if (cache == null) callOpt_cache.put(c, cache = new _MethodCache(c)); return cache; } } static boolean isStaticMethod(Method m) { return methodIsStatic(m); } static Object[] massageArgsForVarArgsCall(Method m, Object[] args) { Class[] types = m.getParameterTypes(); int n = types.length-1, nArgs = args.length; if (nArgs < n) return null; for (int i = 0; i < n; i++) if (!argumentCompatibleWithType(args[i], types[i])) return null; Class varArgType = types[n].getComponentType(); for (int i = n; i < nArgs; i++) if (!argumentCompatibleWithType(args[i], varArgType)) return null; Object[] newArgs = new Object[n+1]; arraycopy(args, 0, newArgs, 0, n); Object[] varArgs = arrayOfType(varArgType, nArgs-n); arraycopy(args, n, varArgs, 0, nArgs-n); newArgs[n] = varArgs; return newArgs; } static A getWeakRef(Reference ref) { return ref == null ? null : ref.get(); } static CloseableIterableIterator emptyCloseableIterableIterator_instance = new CloseableIterableIterator() { public Object next() { throw fail(); } public boolean hasNext() { return false; } }; static CloseableIterableIterator emptyCloseableIterableIterator() { return emptyCloseableIterableIterator_instance; } static boolean ewic(String a, String b) { return endsWithIgnoreCase(a, b); } static boolean ewic(String a, String b, Matches m) { return endsWithIgnoreCase(a, b, m); } static CloseableIterableIterator linesFromReader(Reader r) { final BufferedReader br = bufferedReader(r); return iteratorFromFunction_f0_autoCloseable(new F0() { String get() { try { return readLineFromReaderWithClose(br); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret readLineFromReaderWithClose(br);"; }}, _wrapIOCloseable(r)); } static BufferedReader utf8bufferedReader(InputStream in) { try { return bufferedReader(_registerIOWrap(new InputStreamReader(in, "UTF-8"), in)); } catch (Exception __e) { throw rethrow(__e); } } static BufferedReader utf8bufferedReader(File f) { try { return utf8bufferedReader(newFileInputStream(f)); } catch (Exception __e) { throw rethrow(__e); } } static Runnable asRunnable(Object o) { return toRunnable(o); } static void _inheritThreadInfo(Object info) { _threadInheritInfo(info); } static Map synchroHashMap() { return Collections.synchronizedMap(new HashMap()); } static List getClassNames(Collection l) { List out = new ArrayList(); if (l != null) for (Object o : l) out.add(o == null ? null : getClassName(o)); return out; } static byte[] bytesFromHex(String s) { return hexToBytes(s); } static int ubyteToInt(byte b) { return b & 0x0FF; } static String strOrNull(Object o) { return o == null ? null : str(o); } static Object vm_generalMap_put(Object key, Object value) { return mapPutOrRemove(vm_generalMap(), key, value); } static Map newWeakMap() { return newWeakHashMap(); } static WeakReference newWeakReference(A a) { return a == null ? null : new WeakReference(a); } static JMenuItem jMenuItem(final String text) { return jmenuItem(text); } static JMenuItem jMenuItem(String text, Object r) { return jmenuItem(text, r); } static Pair jmenu_autoMnemonic(String s) { int i = indexOf(s, '&'); if (i >= 0 && i < l(s) && isLetterOrDigit(s.charAt(i+1))) return pair(substring(s, 0, i) + substring(s, i+1), (int) s.charAt(i+1)); return pair(s, 0); } static JMenuItem disableMenuItem(final JMenuItem mi) { if (mi != null) { swing(new Runnable() { public void run() { try { mi.setEnabled(false); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "mi.setEnabled(false);"; }}); } return mi; } static boolean isCurlyBraced(String s) { List tok = tok_combineCurlyBrackets_keep(javaTok(s)); return l(tok) == 3 && startsWithAndEndsWith(tok.get(1), "{", "}"); } static String tok_unCurlyBracket(String s) { return isCurlyBraced(s) ? join(dropFirstThreeAndLastThree(javaTok(s))) : s; } static String strUnnull(Object o) { return o == null ? "" : str(o); } static String jlabel_textAsHTML_center_ifNeeded(String text) { if (swic(text, "") && ewic(text, "")) return text; if (!containsNewLines(text)) return text; return jlabel_textAsHTML_center(text); } static Dimension getPreferredSize(final Component c) { return c == null ? null : swing(new F0() { Dimension get() { try { return c.getPreferredSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getPreferredSize();"; }}); } static Map vm_generalMap_map; static Map vm_generalMap() { if (vm_generalMap_map == null) vm_generalMap_map = (Map) get(javax(), "generalMap"); return vm_generalMap_map; } static volatile boolean licensed_yes = true; static boolean licensed() { if (!licensed_yes) return false; ping_okInCleanUp(); return true; } static void licensed_off() { licensed_yes = false; } static String[] toStringArray(Collection c) { String[] a = new String[l(c)]; Iterator it = c.iterator(); for (int i = 0; i < l(a); i++) a[i] = it.next(); return a; } static String[] toStringArray(Object o) { if (o instanceof String[]) return (String[]) o; else if (o instanceof Collection) return toStringArray((Collection) o); else throw fail("Not a collection or array: " + getClassName(o)); } static void selectRow(final JTable table, final int i) { if (table != null) { swing(new Runnable() { public void run() { try { if (i >= 0 && i < table.getRowCount()) { table.setRowSelectionInterval(i, i); scrollRowToVisible(table, i); } else table.clearSelection(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (i >= 0 && i < table.getRowCount()) {\r\n table.setRowSelectionInterval..."; }}); } } static void selectRow(final JList list, final int i) { if (list != null) { swing(new Runnable() { public void run() { try { if (i >= 0 && i < listRowCount(list)) list.setSelectedIndex(i); else list.clearSelection(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (i >= 0 && i < listRowCount(list))\r\n list.setSelectedIndex(i);\r\n e..."; }}); } } static int jlist_indexOf(JList list, A item) { return swing(new F0() { Integer get() { try { ListModel model = list.getModel(); int n = model.getSize(); for (int i = 0; i < n; i++) if (eq(model.getElementAt(i), item)) return i; return -1; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ListModel model = list.getModel();\r\n int n = model.getSize();\r\n for ..."; }}); } static ChangeListener changeListener(final Object r) { return new ChangeListener() { public void stateChanged(ChangeEvent e) { pcallF(r); } }; } static ItemListener itemListener(final Object r) { return new ItemListener() { public void itemStateChanged(ItemEvent e) { pcallF(r); } }; } // action = runnable or method name static void onUpdate(JComponent c, final Object r) { if (c instanceof JTextComponent) ((JTextComponent) c).getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent e) { call(r); } public void removeUpdate(DocumentEvent e) { call(r); } public void changedUpdate(DocumentEvent e) { call(r); } }); else if (c instanceof ItemSelectable) // JCheckBox and others ((ItemSelectable) c).addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { call(r); } }); else print("Warning: onUpdate doesn't know " + getClassName(c)); } static void onUpdate(List l, Object r) { for (JComponent c : l) onUpdate(c, r); } static JTextField textFieldFromComboBox(JComboBox cb) { return (JTextField) cb.getEditor().getEditorComponent(); } static JComboBox onSelectedItem(final JComboBox cb, final VF1 f) { addActionListener(cb, new Runnable() { public void run() { try { pcallF(f, selectedItem(cb)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(f, selectedItem(cb))"; }}); return cb; } static Field getField(Object o, String field) { if (o == null) return null; return setOpt_findField(_getClass(o), field); } static boolean contains(Collection c, Object o) { return c != null && c.contains(o); } static boolean contains(Object[] x, Object o) { if (x != null) for (Object a : x) if (eq(a, o)) return true; return false; } static boolean contains(String s, char c) { return s != null && s.indexOf(c) >= 0; } static boolean contains(String s, String b) { return s != null && s.indexOf(b) >= 0; } static boolean contains(BitSet bs, int i) { return bs != null && bs.get(i); } static boolean sameSnippetID(String a, String b) { if (!isSnippetID(a) || !isSnippetID(b)) return false; return parseSnippetID(a) == parseSnippetID(b); } static volatile String caseID_caseID; static String caseID() { return caseID_caseID; } static void caseID(String id) { caseID_caseID = id; } static void smartSet(Field f, Object o, Object value) throws Exception { try { f.set(o, value); } catch (Exception e) { Class type = f.getType(); // take care of common case (long to int) if (type == int.class && value instanceof Long) value = ((Long) value).intValue(); if (type == LinkedHashMap.class && value instanceof Map) { f.set(o, asLinkedHashMap((Map) value)); return; } throw e; } } static int gzInputStream_defaultBufferSize = 65536; static GZIPInputStream gzInputStream(File f) { try { return gzInputStream(new FileInputStream(f)); } catch (Exception __e) { throw rethrow(__e); } } static GZIPInputStream gzInputStream(File f, int bufferSize) { try { return gzInputStream(new FileInputStream(f), bufferSize); } catch (Exception __e) { throw rethrow(__e); } } static GZIPInputStream gzInputStream(InputStream in) { return gzInputStream(in, gzInputStream_defaultBufferSize); } static GZIPInputStream gzInputStream(InputStream in, int bufferSize) { try { return _registerIOWrap(new GZIPInputStream(in, gzInputStream_defaultBufferSize), in); } catch (Exception __e) { throw rethrow(__e); } } static Producer javaTokC_noMLS_iterator(final String s) { return javaTokC_noMLS_iterator(s, 0); } static Producer javaTokC_noMLS_iterator(final String s, final int startIndex) { return new Producer() { final int l = s.length(); int i = startIndex; public String next() { if (i >= l) return null; int j = i; char c, d; // scan for whitespace while (j < l) { c = s.charAt(j); d = j+1 >= l ? '\0' : s.charAt(j+1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } i = j; if (i >= l) return null; c = s.charAt(i); d = i+1 >= l ? '\0' : s.charAt(i+1); // scan for non-whitespace if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L } else ++j; String t = quickSubstring(s, i, j); i = j; return t; } }; } static Object _defaultClassFinder_value = defaultDefaultClassFinder(); static Object _defaultClassFinder() { return _defaultClassFinder_value; } static String unquoteUsingCharArray(String s, char[] buf) { if (s == null) return null; if (startsWith(s, '[')) { int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; if (i < s.length() && s.charAt(i) == '[') { String m = s.substring(1, i); if (s.endsWith("]" + m + "]")) return s.substring(i+1, s.length()-i-1); } } if (s.length() > 1) { char c = s.charAt(0); if (c == '\"' || c == '\'') { int l = endsWith(s, c) ? s.length()-1 : s.length(); if (l > buf.length) return unquote(s); // fallback int n = 0; for (int i = 1; i < l; i++) { char ch = s.charAt(i); if (ch == '\\') { char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1); // Octal escape? if (nextChar >= '0' && nextChar <= '7') { String code = "" + nextChar; i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; } } buf[n++] = (char) Integer.parseInt(code, 8); continue; } switch (nextChar) { case '\"': ch = '\"'; break; case '\\': ch = '\\'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case '\'': ch = '\''; break; // Hex Unicode: u???? case 'u': if (i >= l - 5) { ch = 'u'; break; } int code = Integer.parseInt( "" + s.charAt(i + 2) + s.charAt(i + 3) + s.charAt(i + 4) + s.charAt(i + 5), 16); char[] x = Character.toChars(code); int lx = x.length; for (int j = 0; j < lx; j++) buf[n++] = x[j]; i += 5; continue; default: ch = nextChar; // added by Stefan } i++; } buf[n++] = ch; } return new String(buf, 0, n); } } return s; // not quoted - return original } static boolean structure_isMarker(String s, int i, int j) { if (i >= j) return false; if (s.charAt(i) != 'm') return false; ++i; while (i < j) { char c = s.charAt(i); if (c < '0' || c > '9') return false; ++i; } return true; } static String internIfLongerThan(String s, int l) { return s == null ? null : l(s) >= l ? intern(s) : s; } static char unquoteCharacter(String s) { assertTrue(s.startsWith("'") && s.length() > 1); return unquote("\"" + s.substring(1, s.endsWith("'") ? s.length()-1 : s.length()) + "\"").charAt(0); } static float parseFloat(String s) { return Float.parseFloat(s); } static boolean isLongConstant(String s) { if (!s.endsWith("L")) return false; s = s.substring(0, l(s)-1); return isInteger(s); } static TreeMap ciMap() { return caseInsensitiveMap(); } static List parseList(String s) { return (List) safeUnstructure(s); } static List synchroLinkedList() { return Collections.synchronizedList(new LinkedList()); } static byte[] hexToBytes(String s) { if (odd(l(s))) throw fail("Hex string has odd length: " + quote(shorten(10, s))); int n = l(s) / 2; byte[] bytes = new byte[n]; for (int i = 0; i < n; i++) { int a = parseHexChar(s.charAt(i*2)); int b = parseHexChar(s.charAt(i*2+1)); if (a < 0 || b < 0) throw fail("Bad hex byte: " + quote(substring(s, i*2, i*2+2)) + " at " + i*2 + "/" + l(s)); bytes[i] = (byte) ((a << 4) | b); } return bytes; } static boolean[] boolArrayFromBytes(byte[] a, int n) { boolean[] b = new boolean[n]; int m = min(n, l(a)*8); for (int i = 0; i < m; i++) b[i] = (a[i/8] & 1 << (i & 7)) != 0; return b; } static boolean isJavaIdentifier(String s) { if (empty(s) || !Character.isJavaIdentifierStart(s.charAt(0))) return false; for (int i = 1; i < s.length(); i++) if (!Character.isJavaIdentifierPart(s.charAt(i))) return false; return true; } static HashMap findClass_fullName_cache = new HashMap(); // returns null on not found // this is the simple version that is not case-tolerant static Class findClass_fullName(String name) { synchronized(findClass_fullName_cache) { if (findClass_fullName_cache.containsKey(name)) return findClass_fullName_cache.get(name); Class c; try { c = Class.forName(name); } catch (ClassNotFoundException e) { c = null; } findClass_fullName_cache.put(name, c); return c; } } static Map nuEmptyObject_cache = newDangerousWeakHashMap(); static A nuEmptyObject(Class c) { try { Constructor ctr; synchronized(nuEmptyObject_cache) { ctr = nuEmptyObject_cache.get(c); if (ctr == null) { nuEmptyObject_cache.put(c, ctr = nuEmptyObject_findConstructor(c)); ctr.setAccessible(true); } } try { return (A) ctr.newInstance(); } catch (InstantiationException e) { if (empty(e.getMessage())) if ((c.getModifiers() & Modifier.ABSTRACT) != 0) throw fail("Can't instantiate abstract class " + className(c), e); else throw fail("Can't instantiate " + className(c), e); else throw rethrow(e); } } catch (Exception __e) { throw rethrow(__e); } } static Constructor nuEmptyObject_findConstructor(Class c) { for (Constructor m : c.getDeclaredConstructors()) if (m.getParameterTypes().length == 0) return m; throw fail("No default constructor declared in " + c.getName()); } static String assertIdentifier(String s) { return assertIsIdentifier(s); } static String assertIdentifier(String msg, String s) { return assertIsIdentifier(msg, s); } static A nuStubInnerObject(Class c) { return nuStubInnerObject(c, null); } static A nuStubInnerObject(Class c, Object classFinder) { try { Class outerType = getOuterClass(c, classFinder); Constructor m = c.getDeclaredConstructor(outerType); m.setAccessible(true); return (A) m.newInstance(new Object[] {null}); } catch (Exception __e) { throw rethrow(__e); } } static HashMap findClass_cache = new HashMap(); // currently finds only inner classes of class "main" // returns null on not found // this is the simple version that is not case-tolerant static Class findClass(String name) { synchronized(findClass_cache) { if (findClass_cache.containsKey(name)) return findClass_cache.get(name); if (!isJavaIdentifier(name)) return null; Class c; try { c = Class.forName("main$" + name); } catch (ClassNotFoundException e) { c = null; } findClass_cache.put(name, c); return c; } } static void setOptAllDyn(DynamicObject o, Map fields) { if (fields == null) return; HashMap fieldMap = instanceFieldsMap(o); for (Map.Entry e : fields.entrySet()) { String field = e.getKey(); Object val = e.getValue(); boolean has = fieldMap.containsKey(field); if (has) setOpt(o, field, val); else { o.fieldValues = syncMapPut2_createLinkedHashMap(o.fieldValues, intern(field), val); } } } static void setOptAll_pcall(Object o, Map fields) { if (fields == null) return; for (String field : keys(fields)) try { setOpt(o, field, fields.get(field)); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } static void setOptAll_pcall(Object o, Object... values) { //values = expandParams(c.getClass(), values); warnIfOddCount(values); for (int i = 0; i+1 < l(values); i += 2) { String field = (String) values[i]; Object value = values[i+1]; try { setOpt(o, field, value); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } } static void setDynObjectValue(DynamicObject o, String field, Object value) { o.fieldValues = syncMapPut2_createLinkedHashMap(o.fieldValues, field, value); } static String intern(String s) { return fastIntern(s); } static void pcallOpt_noArgs(Object o, String method) { try { callOpt_noArgs(o, method); } catch (Throwable __e) { _handleException(__e); } } static int[] toIntArray(List l) { int[] a = new int[l(l)]; for (int i = 0; i < a.length; i++) a[i] = l.get(i); return a; } static TreeSet ciSet() { return caseInsensitiveSet(); } static boolean jmatch(String pat, String s) { return jmatch(pat, s, null); } static boolean jmatch(String pat, String s, Matches matches) { if (s == null) return false; return jmatch(pat, javaTok(s), matches); } static boolean jmatch(String pat, List toks) { return jmatch(pat, toks, null); } static boolean jmatch(String pat, List toks, Matches matches) { List tokpat = javaTok(pat); String[] m = match2(tokpat, toks); //print(structure(tokpat) + " on " + structure(toks) + " => " + structure(m)); if (m == null) return false; else { if (matches != null) matches.m = m; return true; } } static boolean warn_on = true; static ThreadLocal> warn_warnings = new ThreadLocal(); static void warn(String s) { if (warn_on) print("Warning: " + s); } static void warn(String s, List warnings) { warn(s); if (warnings != null) warnings.add(s); addToCollection(warn_warnings.get(), s); } // TODO: extended multi-line strings static int javaTok_n, javaTok_elements; static boolean javaTok_opt = false; static List javaTok(String s) { ++javaTok_n; ArrayList tok = new ArrayList(); int l = s == null ? 0 : s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; // scan for whitespace while (j < l) { c = s.charAt(j); d = j+1 >= l ? '\0' : s.charAt(j+1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } tok.add(javaTok_substringN(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i+1 >= l ? '\0' : s.charAt(i+1); // scan for non-whitespace // Special JavaX syntax: 'identifier if (c == '\'' && Character.isJavaIdentifierStart(d) && i+2 < l && "'\\".indexOf(s.charAt(i+2)) < 0) { j += 2; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))) ++j; } else if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { int c2 = s.charAt(j); if (c2 == opener || c2 == '\n' && opener == '\'') { // allow multi-line strings, but not for ' ++j; break; } else if (c2 == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for stuff like "don't" else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L } else if (c == '[' && d == '[') { do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); j = Math.min(j+2, l); } else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') { do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); j = Math.min(j+3, l); } else ++j; tok.add(javaTok_substringC(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); javaTok_elements += tok.size(); return tok; } static List javaTok(List tok) { return javaTokWithExisting(join(tok), tok); } static boolean odd(int i) { return (i & 1) != 0; } static boolean odd(long i) { return (i & 1) != 0; } static boolean odd(BigInteger i) { return odd(toInt(i)); } static boolean containsNewLine(String s) { return contains(s, '\n'); // screw \r, nobody needs it } public static String rtrimSpaces(String s) { if (s == null) return null; int i = s.length(); while (i > 0 && " \t".indexOf(s.charAt(i-1)) >= 0) --i; return i < s.length() ? s.substring(0, i) : s; } static boolean domainIsUnder(String domain, String mainDomain) { return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain); } static String theAGIBlueDomain() { return "agi.blue"; } static File standardLogFile() { return getProgramFile("log"); } static void logQuoted(String logFile, String line) { logQuoted(getProgramFile(logFile), line); } static void logQuoted(File logFile, String line) { appendToFile(logFile, quote(line) + "\n"); } static String _userHome; static String userHome() { if (_userHome == null) return actualUserHome(); return _userHome; } static File userHome(String path) { return new File(userDir(), path); } static void enableWordWrapForTextArea(final JTextArea ta) { if (ta != null) { swing(new Runnable() { public void run() { try { ta.setLineWrap(true); ta.setWrapStyleWord(true); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ta.setLineWrap(true);\r\n ta.setWrapStyleWord(true);"; }}); } } static JTextArea jtextarea() { return jTextArea(); } static JTextArea jtextarea(String text) { return jTextArea(text); } static JTextField onEnter(final JTextField tf, final Object action) { if (action == null || tf == null) return tf; tf.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { tf.selectAll(); callF(action); } catch (Throwable __e) { messageBox(__e); }}}); return tf; } static JButton onEnter(JButton btn, final Object action) { if (action == null || btn == null) return btn; btn.addActionListener(actionListener(action)); return btn; } static JList onEnter(JList list, Object action) { list.addKeyListener(enterKeyListener(rCallOnSelectedListItem(list, action))); return list; } static JComboBox onEnter(final JComboBox cb, final Object action) { { swing(new Runnable() { public void run() { try { if (cb.isEditable()) { JTextField text = (JTextField) cb.getEditor().getEditorComponent(); onEnter(text, action); } else { cb.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "enter"); cb.getActionMap().put("enter", abstractAction("", new Runnable() { public void run() { try { cb.hidePopup(); callF(action); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cb.hidePopup(); callF(action);"; }})); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (cb.isEditable()) {\r\n JTextField text = (JTextField) cb.getEditor().g..."; }}); } return cb; } static JTable onEnter(final JTable table, final Object action) { table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter"); table.getActionMap().put("Enter", new AbstractAction() { public void actionPerformed(ActionEvent e) { callF(action, table.getSelectedRow()); } }); return table; } /*static JTextArea onEnter(final JTextArea ta, fO action) { addKeyListener(ta, enterKeyListener(action)); ret ta; }*/ static JTextField onEnter(Object action, JTextField tf) { return onEnter(tf, action); } static float getSwingFontScale() { return or((Float) vm_generalMap_get("swingFontScale_value"), 1f); } static Throwable getException(Runnable r) { try { callF(r); return null; } catch (Throwable e) { return e; } } static void clear(Collection c) { if (c != null) c.clear(); } static void put(Map map, A a, B b) { if (map != null) map.put(a, b); } static void put(List l, int i, A a) { if (l != null && i >= 0 && i < l(l)) l.set(i, a); } static B mapGet2(Map map, A a) { return map == null ? null : map.get(a); } static B mapGet2(A a, Map map) { return map == null ? null : map.get(a); } static boolean isSubtypeOf(Class a, Class b) { return b.isAssignableFrom(a); // << always hated that method, let's replace it! } static Set reflection_classesNotToScan_value = litset( "jdk.internal.loader.URLClassPath" ); static Set reflection_classesNotToScan() { return reflection_classesNotToScan_value; } static volatile Object isAllowed_function; // func(S, O[]) -> bool static volatile boolean isAllowed_all = true; static boolean isAllowed(String askingMethod, Object... args) { // check on VM level Object f = vm_generalMap_get("isAllowed_function"); if (f != null && !isTrue(callF(f, askingMethod, args))) return false; // check locally return isAllowed_all || isTrue(callF(isAllowed_function, askingMethod, args)); } static String hmsWithColons() { return hmsWithColons(now()); } static String hmsWithColons(long time) { return new SimpleDateFormat("HH:mm:ss").format(time); } static String getComputerID_quick() { return computerID(); } static String joinNemptiesWithColonSpace(String... strings) { return joinNempties(": ", strings); } static String joinNemptiesWithColonSpace(Collection strings) { return joinNempties(": ", strings); } static String tryToReadErrorStreamFromURLConnection(URLConnection conn) { try { if (conn instanceof HttpURLConnection) return stream2string(((HttpURLConnection) conn).getErrorStream()); // TODO: ensure some max length return null; } catch (Throwable __e) { return null; } } static boolean endsWith(String a, String b) { return a != null && a.endsWith(b); } static boolean endsWith(String a, char c) { return nempty(a) && lastChar(a) == c; } static boolean endsWith(String a, String b, Matches m) { if (!endsWith(a, b)) return false; m.m = new String[] {dropLast(l(b), a)}; return true; } static Map compileRegexp_cache = syncMRUCache(10); static java.util.regex.Pattern compileRegexp(String pat) { java.util.regex.Pattern p = compileRegexp_cache.get(pat); if (p == null) { compileRegexp_cache.put(pat, p = java.util.regex.Pattern.compile(pat)); } return p; } static boolean isCISet(Iterable l) { return l instanceof TreeSet && ((TreeSet) l).comparator() == caseInsensitiveComparator(); } static TreeSet caseInsensitiveSet() { return caseInsensitiveSet_treeSet(); } static TreeSet caseInsensitiveSet(Collection c) { return caseInsensitiveSet_treeSet(c); } static void addAll(Collection c, Iterable b) { if (c != null && b != null) for (A a : b) c.add(a); } static boolean addAll(Collection c, Collection b) { return c != null && b != null && c.addAll(b); } static boolean addAll(Collection c, B... b) { return c != null && c.addAll(Arrays.asList(b)); } static Map addAll(Map a, Map b) { if (a != null) a.putAll(b); return a; } static boolean isInstance(Class type, Object arg) { return type.isInstance(arg); } static boolean isImageServerSnippet(long id) { return id >= 1100000 && id < 1200000; } static String imageServerLink(String md5OrID) { if (possibleMD5(md5OrID)) return "https://botcompany.de/images/md5/" + md5OrID; return imageServerLink(parseSnippetID(md5OrID)); } static String imageServerLink(long id) { return "https://botcompany.de/images/" + id; } static String programTitle() { return getProgramName(); } static void _initFrame(JFrame f) { myFrames_list.put(f, Boolean.TRUE); standardTitlePopupMenu(f); } static Rectangle defaultNewFrameBounds_r = new Rectangle(300, 100, 500, 400); static Rectangle defaultNewFrameBounds() { return swing(new F0() { Rectangle get() { try { defaultNewFrameBounds_r.translate(60, 20); if (!screenRectangle().contains(defaultNewFrameBounds_r)) defaultNewFrameBounds_r.setLocation(30+random(30), 20+random(20)); return new Rectangle(defaultNewFrameBounds_r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "defaultNewFrameBounds_r.translate(60, 20);\r\n if (!screenRectangle().contai..."; }}); } static void hideConsole() { final JFrame frame = consoleFrame(); if (frame != null) { autoVMExit(); swingLater(new Runnable() { public void run() { try { frame.setVisible(false); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "frame.setVisible(false);"; }}); } } static File loadBinarySnippet(String snippetID) { try { IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.loadLibrary(snippetID); long id = parseSnippetID(snippetID); if (isImageServerSnippet(id)) return loadImageAsFile(snippetID); File f = DiskSnippetCache_getLibrary(id); if (fileSize(f) == 0) f = loadDataSnippetToFile(snippetID); return f; } catch (Exception __e) { throw rethrow(__e); } } static boolean loadBufferedImageFixingGIFs_debug = false; static ThreadLocal> loadBufferedImageFixingGIFs_output = new ThreadLocal(); static Image loadBufferedImageFixingGIFs(File file) { try { if (!file.exists()) return null; // Load anything but GIF the normal way if (!isGIF(file)) return ImageIO.read(file); if (loadBufferedImageFixingGIFs_debug) print("loadBufferedImageFixingGIFs" + ": checking gif"); // Get GIF reader ImageReader reader = ImageIO.getImageReadersByFormatName("gif").next(); // Give it the stream to decode from reader.setInput(ImageIO.createImageInputStream(file)); int numImages = reader.getNumImages(true); // Get 'metaFormatName'. Need first frame for that. IIOMetadata imageMetaData = reader.getImageMetadata(0); String metaFormatName = imageMetaData.getNativeMetadataFormatName(); // Find out if GIF is bugged boolean foundBug = false; for (int i = 0; i < numImages && !foundBug; i++) { // Get metadata IIOMetadataNode root = (IIOMetadataNode)reader.getImageMetadata(i).getAsTree(metaFormatName); // Find GraphicControlExtension node int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { org.w3c.dom.Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { // Get delay value String delay = ((IIOMetadataNode)node).getAttribute("delayTime"); // Check if delay is bugged if (Integer.parseInt(delay) == 0) { foundBug = true; } break; } } } if (loadBufferedImageFixingGIFs_debug) print("loadBufferedImageFixingGIFs" + ": " + f2s(file) + " foundBug=" + foundBug); // Load non-bugged GIF the normal way Image image; if (!foundBug) { image = Toolkit.getDefaultToolkit().createImage(f2s(file)); } else { // Prepare streams for image encoding ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); { ImageOutputStream ios = ImageIO.createImageOutputStream(baoStream); try { // Get GIF writer that's compatible with reader ImageWriter writer = ImageIO.getImageWriter(reader); // Give it the stream to encode to writer.setOutput(ios); writer.prepareWriteSequence(null); for (int i = 0; i < numImages; i++) { // Get input image BufferedImage frameIn = reader.read(i); // Get input metadata IIOMetadataNode root = (IIOMetadataNode)reader.getImageMetadata(i).getAsTree(metaFormatName); // Find GraphicControlExtension node int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { org.w3c.dom.Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { // Get delay value String delay = ((IIOMetadataNode)node).getAttribute("delayTime"); // Check if delay is bugged if (Integer.parseInt(delay) == 0) { // Overwrite with a valid delay value ((IIOMetadataNode)node).setAttribute("delayTime", "10"); } break; } } // Create output metadata IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(frameIn), null); // Copy metadata to output metadata metadata.setFromTree(metadata.getNativeMetadataFormatName(), root); // Create output image IIOImage frameOut = new IIOImage(frameIn, null, metadata); // Encode output image writer.writeToSequence(frameOut, writer.getDefaultWriteParam()); } writer.endWriteSequence(); } finally { _close(ios); }} // Create image using encoded data byte[] data = baoStream.toByteArray(); setVar(loadBufferedImageFixingGIFs_output.get(), data); if (loadBufferedImageFixingGIFs_debug) print("Data size: " + l(data)); image = Toolkit.getDefaultToolkit().createImage(data); } return image; } catch (Exception __e) { throw rethrow(__e); } } static Object callFunction(Object f, Object... args) { return callF(f, args); } static ThreadLocal componentPopupMenu_mouseEvent; static void componentPopupMenu_init() { { swing(new Runnable() { public void run() { try { if (componentPopupMenu_mouseEvent == null) componentPopupMenu_mouseEvent = (ThreadLocal) vm_generalMap_get("mouseEvent"); if (componentPopupMenu_mouseEvent == null) vm_generalMap_put("componentPopupMenu_mouseEvent" , componentPopupMenu_mouseEvent = new ThreadLocal()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (componentPopupMenu_mouseEvent == null)\r\n componentPopupMenu_mouseEve..."; }}); } } // menuMaker = voidfunc(JPopupMenu) static void componentPopupMenu(final JComponent component, final Object menuMaker) { if (component == null || menuMaker == null) return; { swing(new Runnable() { public void run() { try { Object adapter = componentPopupMenu_initForComponent(component); ((List) _get(adapter, "maker")).add(menuMaker); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Object adapter = componentPopupMenu_initForComponent(component);\r\n ((List)..."; }}); } } static Object componentPopupMenu_initForComponent(final JComponent component) { return component == null ? null : swing(new F0() { Object get() { try { componentPopupMenu_init(); Object adapter = findComponentPopupMenuListener_gen(component); if (adapter == null) { componentPopupMenu_Adapter a = new componentPopupMenu_Adapter(); component.addMouseListener(a); adapter = a; } return adapter; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "componentPopupMenu_init();\r\n O adapter = findComponentPopupMenuListener_ge..."; }}); } static class componentPopupMenu_Adapter extends MouseAdapter { List maker = new ArrayList(); boolean internalFrameLeftButtonMagic = false; Point pressedAt; public void mousePressed(MouseEvent e) { displayMenu(e); pressedAt = internalFrameLeftButtonMagic && e.getClickCount() == 1 && internalFrameActive(e.getComponent()) ? e.getLocationOnScreen() : null; } public void mouseReleased(MouseEvent e) { // TODO: show a little less often on left mouse click if (internalFrameLeftButtonMagic && eq(pressedAt, e.getLocationOnScreen())) displayMenu2(e); else displayMenu(e); } void displayMenu(MouseEvent e) { if (e.getSource() instanceof JInternalFrame) return; if (e.isPopupTrigger()) displayMenu2(e); } void displayMenu2(MouseEvent e) { JPopupMenu menu = new JPopupMenu(); int emptyCount = menu.getComponentCount(); AutoCloseable __1298 = tempSetTL(componentPopupMenu_mouseEvent, e); try { for (Object menuMaker : maker) pcallF(menuMaker, menu); vmBus_send("showingPopupMenu", e.getComponent(), menu); // show menu if any items in it if (menu.getComponentCount() != emptyCount) menu.show(e.getComponent(), e.getX(), e.getY()); } finally { _close(__1298); }} } static void addMenuItem(JPopupMenu menu, String text, Object action) { menu.add(jmenuItem(text, action)); } static void addMenuItem(JPopupMenu menu, JMenuItem menuItem) { menu.add(menuItem); } static void addMenuItem(JMenu menu, String text, Object action) { menu.add(jmenuItem(text, action)); } static void addMenuItem(Menu menu, String text, Object action) { menu.add(menuItem(text, action)); } static void addMenuItem(JMenu menu, JMenuItem menuItem) { menu.add(menuItem); } static Set newWeakHashSet() { return synchroWeakHashSet(); } static Rect rect(int x, int y, int w, int h) { return new Rect(x, y, w, h); } static boolean jInternalFrame_iconifiable = true; static JInternalFrame jInternalFrame() { return jInternalFrame(""); } static JInternalFrame jInternalFrame(final String title) { return swing(new F0() { JInternalFrame get() { try { JInternalFrame f = new JInternalFrame(title, true, true, true, jInternalFrame_iconifiable); f.setVisible(true); return f; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JInternalFrame f = new JInternalFrame(title, true, true, true, jInternalFrame..."; }}); } static void setInternalFrameContents(final Component c, final Object contents) { { swing(new Runnable() { public void run() { try { JInternalFrame frame = getInternalFrame(c); if (frame == null) return; frame.getContentPane().removeAll(); frame.getContentPane().setLayout(new BorderLayout()); if (contents != null) frame.getContentPane().add(wrap(contents)); revalidate(frame); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JInternalFrame frame = getInternalFrame(c);\r\n if (frame == null) return;\r\n..."; }}); } } static A setBounds(final int x, final int y, final int w, final int h, final A a) { if (a != null) { swing(new Runnable() { public void run() { try { a.setBounds(x, y, w, h); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.setBounds(x, y, w, h);"; }}); } return a; } static A setBounds(final A a, final Rect r) { if (a != null) { swing(new Runnable() { public void run() { try { a.setBounds(toRectangle(r)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "a.setBounds(toRectangle(r));"; }}); } return a; } static A setBounds(A a, int x, int y, int w, int h) { return setBounds(x, y, w, h, a); } static void internalFrameDefaultPosition(JInternalFrame f) { f.setSize(500, 300); centerInternalFrame(f); } static int fixInternalFrame_borderTopLeft = 0; static int fixInternalFrame_borderBottomRight = 40; // for title bar static JInternalFrame fixInternalFrame(final JInternalFrame f) { return swing(new F0() { JInternalFrame get() { try { Container c = f.getParent(); if (c == null) return f; Rect r = toRect(f.getBounds()); int a = fixInternalFrame_borderTopLeft, b = fixInternalFrame_borderBottomRight; Rect outer = new Rect(a, a, c.getWidth()-b, c.getHeight()-b); if (!rectContains(outer, r)) f.setLocation( max(a, min(r.x, outer.x2())), max(a, min(r.y, outer.y2()))); if (r.w > c.getWidth() || r.h > c.getHeight()) f.setSize(c.getWidth()-a, c.getHeight()-a); return f; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Container c = f.getParent();\r\n if (c == null) ret f;\r\n Rect r = toRect(..."; }}); } static boolean containsSpaces(String s) { return indexOf(s, ' ') >= 0; } static A getOrKeep(Map map, A a) { if (map == null) return a; A v = map.get(a); return v != null ? v : a; } static List ai_splitCamelCase(String s) { int j = 0; List l = new ArrayList(); // new addition if (isAllUpperCase(s)) { l.add(s); return l; } for (int i = 0; i < l(s); i++) if (isUpperCaseLetter(s.charAt(i)) && i > j) { l.add(substring(s, j, i)); j = i; } if (j < l(s)) l.add(substring(s, j)); return l; } static Method findMethod_cached(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { _MethodCache cache = callOpt_getCache(((Class) o)); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (isStaticMethod(m) && findMethod_checkArgs(m, args, false)) return m; return null; } else { _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (findMethod_checkArgs(m, args, false)) return m; return null; } } catch (Exception __e) { throw rethrow(__e); } } static void setOpt_raw(Object o, String field, Object value) { try { if (o == null) return; if (o instanceof Class) setOpt_raw((Class) o, field, value); else { Field f = setOpt_raw_findField(o.getClass(), field); if (f != null) { f.setAccessible(true); smartSet(f, o, value); } } } catch (Exception __e) { throw rethrow(__e); } } static void setOpt_raw(Class c, String field, Object value) { try { if (c == null) return; Field f = setOpt_raw_findStaticField(c, field); if (f != null) { f.setAccessible(true); smartSet(f, null, value); } } catch (Exception __e) { throw rethrow(__e); } } static Field setOpt_raw_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static Field setOpt_raw_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static Class _getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; // could optimize this } } static Class _getClass(Object o) { return o == null ? null : o instanceof Class ? (Class) o : o.getClass(); } static Class _getClass(Object realm, String name) { try { return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); } catch (ClassNotFoundException e) { return null; // could optimize this } } static String hopeningTag(String tag, Map params) { return hopeningTag(tag, mapToParams(params)); } static String hopeningTag(String tag, Object... params) { StringBuilder buf = new StringBuilder(); buf.append("<" + tag); for (int i = 0; i < l(params); i += 2) { String name = (String) get(params, i); Object val = get(params, i+1); if (nempty(name) && val != null) { if (val == html_valueLessParam()) buf.append(" " + name); else { String s = str(val); if (!empty(s)) buf.append(" " + name + "=" + htmlQuote(s)); } } } buf.append(">"); return str(buf); } static boolean isLowerHexString(String s) { for (int i = 0; i < l(s); i++) { char c = s.charAt(i); if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f') { // ok } else return false; } return true; } static byte[] convertToPNG(BufferedImage img) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ImageIO.write(img, "png", stream); return stream.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } static String shortenClassName(String name) { if (name == null) return null; int i = lastIndexOf(name, "$"); if (i < 0) i = lastIndexOf(name, "."); return i < 0 ? name : substring(name, i+1); } static String dropSuffix(String suffix, String s) { return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s; } static int lUtf8(String s) { return l(utf8(s)); } static String loadPage_utf8(URL url) { return loadPage_utf8(url.toString()); } static String loadPage_utf8(String url) { AutoCloseable __11 = tempSetTL(loadPage_charset, "UTF-8"); try { return loadPage(url); } finally { _close(__11); }} static String loadPage_utf8(URLConnection con, URL url, boolean addHeaders) throws IOException { AutoCloseable __12 = tempSetTL(loadPage_charset, "UTF-8"); try { return loadPage(con, url, addHeaders); } finally { _close(__12); }} static void mapPut(Map map, A key, B value) { if (map != null && key != null && value != null) map.put(key, value); } static List collectField(Collection c, String field) { List l = new ArrayList(); if (c != null) for (Object a : c) l.add(getOpt(a, field)); return l; } static List collectField(String field, Collection c) { return collectField(c, field); } static Set vm_generalIdentityHashSet(Object name) { synchronized(get(javax(), "generalMap")) { Set set = (Set) (vm_generalMap_get(name)); if (set == null) vm_generalMap_put(name, set = syncIdentityHashSet()); return set; } } static Map vm_generalHashMap(Object name) { synchronized(get(javax(), "generalMap")) { Map m = (Map) (vm_generalMap_get(name)); if (m == null) vm_generalMap_put(name, m = syncHashMap()); return m; } } static String urlencode(String x) { try { return URLEncoder.encode(unnull(x), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } static String quickSubstring(String s, int i, int j) { if (i == j) return ""; return s.substring(i, j); } static A dm_getOSOpt(String field) { return (A) getOpt(dm_os(), field); } static void assertFalse(Object o) { if (!(eq(o, false) /*|| isFalse(pcallF(o))*/)) throw fail(str(o)); } static boolean assertFalse(boolean b) { if (b) throw fail("oops"); return b; } static boolean assertFalse(String msg, boolean b) { if (b) throw fail(msg); return b; } // TODO: returns empty first, but not empty last static List splitAt(String s, String splitter) { List parts = new ArrayList(); int i = 0; if (s != null) while (i < l(s)) { int j = indexOf(s, splitter, i); if (j < 0) j = l(s); parts.add(substring(s, i, j)); i = j+l(splitter); } return parts; } static String addSuffix(String s, String suffix) { return s == null || s.endsWith(suffix) ? s : s + suffix; } static Random defaultRandomGenerator() { return ThreadLocalRandom.current(); } static File getProgramDir() { return programDir(); } static File getProgramDir(String snippetID) { return programDir(snippetID); } static String addPrefixIfNempty(String prefix, String s) { return addPrefixIfNotEmpty(prefix, s); } static String dropSuffixIC(String suffix, String s) { return s == null ? null : ewic(s, suffix) ? s.substring(0, l(s)-l(suffix)) : s; } static File dirOfFile(File f) { return f == null ? null : f.getParentFile(); } static int countLines(String s) { return l(toLines(s)); // yeah could be optimized :-) } static boolean eqic(String a, String b) { if ((a == null) != (b == null)) return false; if (a == null) return true; return a.equalsIgnoreCase(b); } static boolean eqic(char a, char b) { if (a == b) return true; char u1 = Character.toUpperCase(a); char u2 = Character.toUpperCase(b); if (u1 == u2) return true; return Character.toLowerCase(u1) == Character.toLowerCase(u2); } static int smartLastIndexOf(String s, char c) { if (s == null) return 0; int i = s.lastIndexOf(c); return i >= 0 ? i : l(s); } static boolean methodIsStatic(Method m) { return (m.getModifiers() & Modifier.STATIC) != 0; } static boolean argumentCompatibleWithType(Object arg, Class type) { return arg == null ? !type.isPrimitive() : isInstanceX(type, arg); } static A[] arrayOfType(Class type, int n) { return makeArray(type, n); } static A[] arrayOfType(int n, Class type) { return arrayOfType(type, n); } static boolean endsWithIgnoreCase(String a, String b) { int la = l(a), lb = l(b); return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb); } static boolean endsWithIgnoreCase(String a, String b, Matches m) { if (!endsWithIgnoreCase(a, b)) return false; m.m = new String[] { substring(a, 0, l(a)-l(b)) }; return true; } static BufferedReader bufferedReader(Reader r) { return r instanceof BufferedReader ? (BufferedReader) r : _registerIOWrap(new BufferedReader(r), r); } static CloseableIterableIterator iteratorFromFunction_f0_autoCloseable(final F0 f, final AutoCloseable closeable) { class IFF2 extends CloseableIterableIterator { A a; boolean done = false; public boolean hasNext() { getNext(); return !done; } public A next() { getNext(); if (done) throw fail(); A _a = a; a = null; return _a; } void getNext() { if (done || a != null) return; a = f.get(); done = a == null; } public void close() throws Exception { if (closeable != null) closeable.close(); } }; return new IFF2(); } static String readLineFromReaderWithClose(BufferedReader r) { try { String s = r.readLine(); if (s == null) r.close(); return s; } catch (Exception __e) { throw rethrow(__e); } } static AutoCloseable _wrapIOCloseable(final AutoCloseable c) { return c == null ? null : new AutoCloseable() { public String toString() { return "c.close();\r\n _registerIO(c, null, false);"; } public void close() throws Exception { c.close(); _registerIO(c, null, false); }}; } static A _registerIOWrap(A wrapper, Object wrapped) { return wrapper; } static FileInputStream newFileInputStream(File path) throws IOException { return newFileInputStream(path.getPath()); } static FileInputStream newFileInputStream(String path) throws IOException { FileInputStream f = new FileInputStream(path); _registerIO(f, path, true); return f; } static B mapPutOrRemove(Map map, A key, B value) { if (map != null && key != null) if (value != null) return map.put(key, value); else return map.remove(key); return null; } static boolean isLetterOrDigit(char c) { return Character.isLetterOrDigit(c); } static List tok_combineCurlyBrackets_keep(List tok) { List l = new ArrayList(); for (int i = 0; i < l(tok); i++) { String t = tok.get(i); if (odd(i) && eq(t, "{")) { int j = findEndOfCurlyBracketPart(tok, i); l.add(joinSubList(tok, i, j)); i = j-1; } else l.add(t); } return l; } static boolean startsWithAndEndsWith(String s, String prefix, String suffix) { return startsWith(s, prefix) && endsWith(s, suffix); } static List dropFirstThreeAndLastThree(List l) { return dropFirstAndLast(3, l); } static boolean swic(String a, String b) { return startsWithIgnoreCase(a, b); } static boolean swic(String a, String b, Matches m) { if (!swic(a, b)) return false; m.m = new String[] {substring(a, l(b))}; return true; } static boolean containsNewLines(String s) { return containsNewLine(s); } static String jlabel_textAsHTML_center(String text) { return "
" + replace(htmlencode(text), "\n", "
") + "
"; } static void scrollRowToVisible(JTable t, int rowIndex) { int colIndex = 0; if (!(t.getParent() instanceof JViewport)) return; JViewport viewport = (JViewport) t.getParent(); Rectangle rect = t.getCellRect(rowIndex, colIndex, true); Rectangle viewRect = viewport.getViewRect(); int x = viewRect.x; int y = viewRect.y; if (rect.x >= viewRect.x && rect.x <= (viewRect.x + viewRect.width - rect.width)){ } else if (rect.x < viewRect.x){ x = rect.x; } else if (rect.x > (viewRect.x + viewRect.width - rect.width)) { x = rect.x - viewRect.width + rect.width; } if (rect.y >= viewRect.y && rect.y <= (viewRect.y + viewRect.height - rect.height)){ } else if (rect.y < viewRect.y){ y = rect.y; } else if (rect.y > (viewRect.y + viewRect.height - rect.height)){ y = rect.y - viewRect.height + rect.height; } viewport.setViewPosition(new Point(x,y)); } static int listRowCount(JList list) { return list == null ? 0 : swing(new F0() { Integer get() { try { return list.getModel().getSize(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret list.getModel().getSize();"; }}); } static void addActionListener(JTextField tf, final Runnable action) { onEnter(tf, action); } static void addActionListener(final JComboBox cb, final Runnable action) { if (cb != null) { swing(new Runnable() { public void run() { try { cb.addActionListener(actionListener(action)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cb.addActionListener(actionListener(action));"; }}); } } static void addActionListener(final AbstractButton b, final Runnable action) { if (b != null) { swing(new Runnable() { public void run() { try { b.addActionListener(actionListener(action)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "b.addActionListener(actionListener(action));"; }}); } } static String selectedItem(JList l) { return getSelectedItem(l); } static String selectedItem(JComboBox cb) { return getSelectedItem(cb); } static Object defaultDefaultClassFinder() { return new F1() { Class get(String name) { try { Class c = findClass_fullName(name); if (c != null) return c; if (startsWith(name, "loadableUtils.utils$")) return findClass_fullName("main" + substring(name, 19)); return null; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Class c = findClass_fullName(name);\r\n if (c != null) ret c;\r\n if (start..."; }}; } static
TreeMap caseInsensitiveMap() { return new TreeMap(caseInsensitiveComparator()); } static Object safeUnstructure(String s) { return unstructure(s, true); } static int parseHexChar(char c) { if (c >= '0' && c <= '9') return charDiff(c, '0'); if (c >= 'a' && c <= 'f') return charDiff(c, 'a')+10; if (c >= 'A' && c <= 'F') return charDiff(c, 'A')+10; return -1; } static String assertIsIdentifier(String s) { if (!isIdentifier(s)) throw fail("Not an identifier: " + quote(s)); return s; } static String assertIsIdentifier(String msg, String s) { if (!isIdentifier(s)) throw fail(msg + " - Not an identifier: " + quote(s)); return s; } static Class getOuterClass(Class c) { return getOuterClass(c, null); } static Class getOuterClass(Class c, Object classFinder) { try { String s = c.getName(); int i = s.lastIndexOf('$'); String name = substring(s, 0, i); if (classFinder != null) return (Class) callF(classFinder, name); return Class.forName(name); } catch (Exception __e) { throw rethrow(__e); } } static HashMap instanceFieldsMap(Object o) { Class c = o.getClass(); HashMap map; synchronized(getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } return map; } static LinkedHashMap syncMapPut2_createLinkedHashMap(LinkedHashMap map, A key, B value) { if (map != null && key != null) if (value != null) { if (map == null) map = new LinkedHashMap(); synchronized(collectionMutex(map)) { map.put(key, value); } } else synchronized(collectionMutex(map)) { map.remove(key); } return map; } static void warnIfOddCount(Object... list) { if (odd(l(list))) printStackTrace("Odd list size: " + list); } static Method fastIntern_method; static String fastIntern(String s) { try { if (s == null) return null; if (fastIntern_method == null) { fastIntern_method = findMethodNamed(javax(), "internPerProgram"); if (fastIntern_method == null) upgradeJavaXAndRestart(); } return (String) fastIntern_method.invoke(null, s); } catch (Exception __e) { throw rethrow(__e); } } static Map> callOpt_noArgs_cache = newDangerousWeakHashMap(); static Object callOpt_noArgs(Object o, String method) { try { if (o == null) return null; if (o instanceof Class) return callOpt(o, method); // not optimized Class c = o.getClass(); HashMap map; synchronized(callOpt_noArgs_cache) { map = callOpt_noArgs_cache.get(c); if (map == null) map = callOpt_noArgs_makeCache(c); } Method m = map.get(method); return m != null ? m.invoke(o) : null; } catch (Exception __e) { throw rethrow(__e); } } // used internally - we are in synchronized block static HashMap callOpt_noArgs_makeCache(Class c) { HashMap map = new HashMap(); Class _c = c; do { for (Method m : c.getDeclaredMethods()) if (m.getParameterTypes().length == 0 && !reflection_isForbiddenMethod(m)) { m.setAccessible(true); String name = m.getName(); if (!map.containsKey(name)) map.put(name, m); } _c = _c.getSuperclass(); } while (_c != null); callOpt_noArgs_cache.put(c, map); return map; } // match2 matches multiple "*" (matches a single token) wildcards and zero or one "..." wildcards (matches multiple tokens) static String[] match2(List pat, List tok) { // standard case (no ...) int i = pat.indexOf("..."); if (i < 0) return match2_match(pat, tok); pat = new ArrayList(pat); // We're modifying it, so copy first pat.set(i, "*"); while (pat.size() < tok.size()) { pat.add(i, "*"); pat.add(i+1, ""); // doesn't matter } return match2_match(pat, tok); } static String[] match2_match(List pat, List tok) { List result = new ArrayList(); if (pat.size() != tok.size()) { return null; } for (int i = 1; i < pat.size(); i += 2) { String p = pat.get(i), t = tok.get(i); if (eq(p, "*")) result.add(t); else if (!equalsIgnoreCase(unquote(p), unquote(t))) // bold change - match quoted and unquoted now return null; } return result.toArray(new String[result.size()]); } static boolean addToCollection(Collection c, A a) { return c != null && c.add(a); } static String javaTok_substringN(String s, int i, int j) { if (i == j) return ""; if (j == i+1 && s.charAt(i) == ' ') return " "; return s.substring(i, j); } static List javaTokWithExisting(String s, List existing) { ++javaTok_n; int nExisting = javaTok_opt && existing != null ? existing.size() : 0; ArrayList tok = existing != null ? new ArrayList(nExisting) : new ArrayList(); int l = s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; // scan for whitespace while (j < l) { c = s.charAt(j); d = j+1 >= l ? '\0' : s.charAt(j+1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else if (c == '/' && d == '*') { do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); j = Math.min(j+2, l); } else if (c == '/' && d == '/') { do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); } else break; } if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j)) tok.add(existing.get(n)); else tok.add(javaTok_substringN(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i+1 >= l ? '\0' : s.charAt(i+1); // scan for non-whitespace // Special JavaX syntax: 'identifier if (c == '\'' && Character.isJavaIdentifierStart(d) && i+2 < l && "'\\".indexOf(s.charAt(i+2)) < 0) { j += 2; while (j < l && Character.isJavaIdentifierPart(s.charAt(j))) ++j; } else if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener /*|| s.charAt(j) == '\n'*/) { // allow multi-line strings ++j; break; } else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L } else if (c == '[' && d == '[') { do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); j = Math.min(j+2, l); } else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') { do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); j = Math.min(j+3, l); } else ++j; if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j)) tok.add(existing.get(n)); else tok.add(javaTok_substringC(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); javaTok_elements += tok.size(); return tok; } static boolean javaTokWithExisting_isCopyable(String t, String s, int i, int j) { return t.length() == j-i && s.regionMatches(i, t, 0, j-i); // << could be left out, but that's brave } static Lock appendToFile_lock = lock(); static boolean appendToFile_keepOpen = false; static HashMap appendToFile_writers = new HashMap(); static void appendToFile(String path, String s) { try { Lock __684 = appendToFile_lock; lock(__684); try { // Let's just generally synchronize this to be safe. mkdirsForFile(new File(path)); path = getCanonicalPath(path); Writer writer = appendToFile_writers.get(path); if (writer == null) { //print("[Logging to " + path + "]"); writer = new BufferedWriter(new OutputStreamWriter( newFileOutputStream(path, true), "UTF-8")); if (appendToFile_keepOpen) appendToFile_writers.put(path, writer); } writer.write(s); if (!appendToFile_keepOpen) writer.close(); } finally { unlock(__684); } } catch (Exception __e) { throw rethrow(__e); } } static void appendToFile(File path, String s) { if (path != null) appendToFile(path.getPath(), s); } static void cleanMeUp_appendToFile() { AutoCloseable __686 = tempCleaningUp(); try { Lock __685 = appendToFile_lock; lock(__685); try { closeAllWriters(values(appendToFile_writers)); appendToFile_writers.clear(); } finally { unlock(__685); } } finally { _close(__686); }} static String actualUserHome_value; static String actualUserHome() { if (actualUserHome_value == null) { if (isAndroid()) actualUserHome_value = "/storage/emulated/0/"; else actualUserHome_value = System.getProperty("user.home"); } return actualUserHome_value; } static File actualUserHome(String sub) { return newFile(new File(actualUserHome()), sub); } static File userDir() { return new File(userHome()); } static File userDir(String path) { return new File(userHome(), path); } static JTextArea jTextArea() { return jTextArea(""); } static JTextArea jTextArea(final String text) { return jTextAreaWithUndo(text); } static KeyListener enterKeyListener(final Object action) { return new KeyAdapter() { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_ENTER) pcallF(action); } }; } static Runnable rCallOnSelectedListItem(final JList list, final Object action) { return new Runnable() { public void run() { try { pcallF(action, getSelectedItem(list)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcallF(action, getSelectedItem(list))"; }}; } static HashSet litset(A... items) { return lithashset(items); } static String _computerID; static Lock computerID_lock = lock(); public static String computerID() { if (_computerID == null) { Lock __896 = computerID_lock; lock(__896); try { if (_computerID != null) return _computerID; File file = computerIDFile(); _computerID = loadTextFile(file.getPath()); if (_computerID == null) { // legacy load _computerID = loadTextFile(userDir(".tinybrain/computer-id")); if (_computerID == null) _computerID = makeRandomID(12, new SecureRandom()); saveTextFile(file, _computerID); } } finally { unlock(__896); } } return _computerID; } static String joinNempties(String sep, String... strings) { return joinStrings(sep, strings); } static String joinNempties(String sep, Collection strings) { return joinStrings(sep, strings); } static String stream2string(InputStream in) { return utf8streamToString(in); } static char lastChar(String s) { return empty(s) ? '\0' : s.charAt(l(s)-1); } static String[] dropLast(String[] a, int n) { n = Math.min(n, a.length); String[] b = new String[a.length-n]; System.arraycopy(a, 0, b, 0, b.length); return b; } static List dropLast(List l) { return subList(l, 0, l(l)-1); } static List dropLast(int n, List l) { return subList(l, 0, l(l)-n); } static List dropLast(Iterable l) { return dropLast(asList(l)); } static String dropLast(String s) { return substring(s, 0, l(s)-1); } static String dropLast(String s, int n) { return substring(s, 0, l(s)-n); } static String dropLast(int n, String s) { return dropLast(s, n); } static Map syncMRUCache(int size) { return synchroMap(new MRUCache(size)); } static Comparator caseInsensitiveComparator() { return betterCIComparator(); } static TreeSet caseInsensitiveSet_treeSet() { return new TreeSet(caseInsensitiveComparator()); } static TreeSet caseInsensitiveSet_treeSet(Collection c) { return toCaseInsensitiveSet_treeSet(c); } static boolean possibleMD5(String s) { return isMD5(s); } static String getProgramName_cache; static String getProgramName() { Lock __2177 = downloadLock(); lock(__2177); try { if (getProgramName_cache == null) getProgramName_cache = getSnippetTitleOpt(programID()); return getProgramName_cache; } finally { unlock(__2177); } } static void _onLoad_getProgramName() { { startThread(new Runnable() { public void run() { try { getProgramName(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "getProgramName();"; }}); } } static void standardTitlePopupMenu(final JFrame frame) { // standard right-click behavior on titles if (isSubstanceLAF()) titlePopupMenu(frame, new VF1() { public void get(JPopupMenu menu) { try { boolean alwaysOnTop = frame.isAlwaysOnTop(); menu.add(jmenuItem("Restart Program", "restart")); menu.add(jmenuItem("Duplicate Program", "duplicateThisProgram")); menu.add(jmenuItem("Show Console", "showConsole")); menu.add(jCheckBoxMenuItem("Always On Top", alwaysOnTop, new Runnable() { public void run() { try { toggleAlwaysOnTop(frame) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "toggleAlwaysOnTop(frame)"; }})); menu.add(jMenuItem("Shoot Window", new Runnable() { public void run() { try { shootWindowGUI_external(frame, 500) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "shootWindowGUI_external(frame, 500)"; }})); //addMenuItem(menu, "Bigger fonts", f swingBiggerFonts); //addMenuItem(menu, "Smaller fonts", f swingSmallerFonts); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "bool alwaysOnTop = frame.isAlwaysOnTop();\r\n menu.add(jmenuItem(\"Restar..."; }}); } static JFrame consoleFrame() { return (JFrame) getOpt(get(getJavaX(), "console"), "frame"); } static void autoVMExit() { call(getJavaX(), "autoVMExit"); } static File loadImageAsFile(String snippetIDOrURL) { try { if (isURL(snippetIDOrURL)) throw fail("not implemented"); if (!isSnippetID(snippetIDOrURL)) throw fail("Not a URL or snippet ID: " + snippetIDOrURL); String snippetID = "" + parseSnippetID(snippetIDOrURL); File file = imageSnippetCacheFile(snippetID); if (fileSize(file) > 0) return file; String imageURL = snippetImageURL_noHttps(snippetID); System.err.println("Loading image: " + imageURL); byte[] data = loadBinaryPage(imageURL); saveBinaryFile(file, data); return file; } catch (Exception __e) { throw rethrow(__e); } } // If you change this, also change DiskSnippetCache_fileToLibID static File DiskSnippetCache_file(long snippetID) { return new File(getGlobalCache(), "data_" + snippetID + ".jar"); } // Data files are immutable, use centralized cache public static File DiskSnippetCache_getLibrary(long snippetID) throws IOException { File file = DiskSnippetCache_file(snippetID); return file.exists() ? file : null; } public static void DiskSnippetCache_putLibrary(long snippetID, byte[] data) throws IOException { saveBinaryFile(DiskSnippetCache_file(snippetID), data); } static byte[] loadDataSnippetImpl(String snippetID) throws IOException { byte[] data; try { URL url = new URL(dataSnippetLink(snippetID)); print("Loading library: " + hideCredentials(url)); try { data = loadBinaryPage(url.openConnection()); } catch (RuntimeException e) { data = null; } if (data == null || data.length == 0) { url = new URL("http://data.tinybrain.de/blobs/" + parseSnippetID(snippetID)); print("Loading library: " + hideCredentials(url)); data = loadBinaryPage(url.openConnection()); } print("Bytes loaded: " + data.length); } catch (FileNotFoundException e) { throw new IOException("Binary snippet #" + snippetID + " not found or not public"); } return data; } static long fileSize(String path) { return getFileSize(path); } static long fileSize(File f) { return getFileSize(f); } static File loadDataSnippetToFile(String snippetID) { try { snippetID = fsI(snippetID); IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.loadLibrary(snippetID); File f = DiskSnippetCache_file(parseSnippetID(snippetID)); List urlsTried = new ArrayList(); List errors = new ArrayList(); try { URL url = addAndReturn(urlsTried, new URL(dataSnippetLink(snippetID))); print("Loading library: " + hideCredentials(url)); try { loadBinaryPageToFile(openConnection(url), f); if (fileSize(f) == 0) throw fail(); } catch (Throwable e) { errors.add(e); url = addAndReturn(urlsTried, new URL("http://data.tinybrain.de/blobs/" + psI(snippetID))); print("Trying other server: " + hideCredentials(url)); loadBinaryPageToFile(openConnection(url), f); print("Got bytes: " + fileSize(f)); } // TODO: check if we hit the "LOADING" message if (fileSize(f) == 0) throw fail(); System.err.println("Bytes loaded: " + fileSize(f)); } catch (Throwable e) { //printStackTrace(e); errors.add(e); throw fail("Binary snippet " + snippetID + " not found or not public. URLs tried: " + allToString(urlsTried) + ", errors: " + allToString(errors)); } return f; } catch (Exception __e) { throw rethrow(__e); } } static byte[] isGIF_magic = bytesFromHex("47494638"); // Actual signature is longer, but we're lazy static boolean isGIF(byte[] data) { return byteArrayStartsWith(data, isGIF_magic); } static boolean isGIF(File f) { return isGIF(loadBeginningOfBinaryFile(f, l(isGIF_magic))); } static void setVar(IVar v, A value) { if (v != null) v.set(value); } static Object findComponentPopupMenuListener_gen(final JComponent c) { return c == null ? null : swing(new F0() { Object get() { try { return firstWithClassShortNamed("componentPopupMenu_Adapter", c.getMouseListeners()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret firstWithClassShortNamed('componentPopupMenu_Adapter, c.getMouseListeners..."; }}); } static boolean internalFrameActive(Component c) { final JInternalFrame f = getInternalFrame(c); return f != null && swing(new F0() { Boolean get() { try { return f.isSelected(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret f.isSelected();"; }}); } static AutoCloseable tempSetTL(ThreadLocal tl, A a) { return tempSetThreadLocal(tl, a); } static MenuItem menuItem(String text, final Object r) { MenuItem mi = new MenuItem(text); mi.addActionListener(actionListener(r)); return mi; } static Set synchroWeakHashSet() { return Collections.newSetFromMap((Map) newWeakHashMap()); } static Rectangle toRectangle(Rect r) { return r == null ? null : r.getRectangle(); } static Rect toRect(Rectangle r) { return r == null ? null : new Rect(r); } static Rect toRect(RectangularShape r) { return r == null ? null : toRect(r.getBounds()); } static boolean rectContains(int x1, int y1, int w, int h, Pt p) { return p.x >= x1 && p.y >= y1 && p.x < x1+w && p.y < y1+h; } static boolean rectContains(Rect a, Rect b) { return b.x >= a.x && b.y >= a.y && b.x2() <= a.x2() && b.y2() <= a.y2(); } static boolean rectContains(Rect a, int x, int y) { return a != null && a.contains(x, y); } static boolean isAllUpperCase(String s) { return hasLettersAllUpperCase(s); } static boolean isUpperCaseLetter(char c) { return Character.isUpperCase(c); } static Method findMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args); } static boolean findMethod_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static Class getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; } } static Class getClass(Object o) { return o instanceof Class ? (Class) o : o.getClass(); } static Class getClass(Object realm, String name) { try { try { return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); } catch (ClassNotFoundException e) { return null; } } catch (Exception __e) { throw rethrow(__e); } } static String classNameToVM(String name) { return name.replace(".", "$"); } static Object html_valueLessParam_cache; static Object html_valueLessParam() { if (html_valueLessParam_cache == null) html_valueLessParam_cache = html_valueLessParam_load(); return html_valueLessParam_cache; } static Object html_valueLessParam_load() { return new Object(); } static String htmlQuote(String s) { return "\"" + htmlencode_forParams(s) + "\""; } static int lastIndexOf(String a, String b) { return a == null || b == null ? -1 : a.lastIndexOf(b); } static int lastIndexOf(String a, char b) { return a == null ? -1 : a.lastIndexOf(b); } static Set syncIdentityHashSet() { return (Set) synchronizedSet(identityHashSet()); } static Map syncHashMap() { return synchroHashMap(); } static Object dm_os() { { Object __328= vm_generalMap_get("stefansOS"); if (__328 != null) return __328; } return creator(); } static String addPrefixIfNotEmpty(String prefix, String s) { return empty(s) ? "" : prefix + s; } static void restart() { Object j = getJavaX(); call(j, "cleanRestart", get(j, "fullArgs")); } static void duplicateThisProgram() { nohupJavax(trim(programID() + " " + smartJoin((String[]) get(getJavaX(), "fullArgs")))); } static void showConsole() { callOpt(get(javax(), "console"), "showConsole"); } static String asString(Object o) { return o == null ? null : o.toString(); } static A[] makeArray(Class type, int n) { return (A[]) Array.newInstance(type, n); } static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) { return a != null && a.regionMatches(true, offsetA, b, offsetB, len); } // i must point at the (possibly imaginary) opening bracket // index returned is index of closing bracket + 1 static int findEndOfCurlyBracketPart(List cnc, int i) { int j = i+2, level = 1; while (j < cnc.size()) { if (eq(cnc.get(j), "{")) ++level; else if (eq(cnc.get(j), "}")) --level; if (level == 0) return j+1; ++j; } return cnc.size(); } static String joinSubList(List l, int i, int j) { return join(subList(l, i, j)); } static String joinSubList(List l, int i) { return join(subList(l, i)); } static List dropFirstAndLast(int n, List l) { return new ArrayList(subList(l, n, l(l)-n)); } static List dropFirstAndLast(List l) { return dropFirstAndLast(1, l); } static String dropFirstAndLast(String s) { return substring(s, 1, l(s)-1); } static boolean startsWithIgnoreCase(String a, String b) { return regionMatchesIC(a, 0, b, 0, b.length()); } static String getSelectedItem(JList l) { return (String) l.getSelectedValue(); } static String getSelectedItem(JComboBox cb) { return strOrNull(cb.getSelectedItem()); } static boolean isIdentifier(String s) { return isJavaIdentifier(s); } static void upgradeJavaXAndRestart() { run("#1001639"); restart(); sleep(); } static boolean reflection_isForbiddenMethod(Method m) { return m.getDeclaringClass() == Object.class && eqOneOf(m.getName(), "finalize", "clone", "registerNatives"); } static boolean equalsIgnoreCase(String a, String b) { return eqic(a, b); } static boolean equalsIgnoreCase(char a, char b) { return eqic(a, b); } static String getCanonicalPath(File f) { try { return f == null ? null : f.getCanonicalPath(); } catch (Exception __e) { throw rethrow(__e); } } static String getCanonicalPath(String path) { return getCanonicalPath(newFile(path)); } static AutoCloseable tempCleaningUp() { return tempSetTL(ping_isCleanUpThread, true); } static void closeAllWriters(Collection l) { for (Writer w : unnull(l)) { try { w.close(); } catch (Throwable __e) { _handleException(__e); }} } static Collection values(Map map) { return map == null ? emptyList() : map.values(); } static Collection values(MultiMap mm) { return mm == null ? emptyList() : concatLists(values(mm.data)); } static JTextArea jTextAreaWithUndo() { return jTextAreaWithUndo(""); } static JTextArea jTextAreaWithUndo(final String text) { return jenableUndoRedo(swingNu(JTextArea.class, text)); } static File computerIDFile() { return javaxDataDir("Basic Info/computer-id.txt"); } static String joinStrings(String sep, String... strings) { return joinStrings(sep, Arrays.asList(strings)); } static String joinStrings(String sep, Collection strings) { StringBuilder buf = new StringBuilder(); for (String s : unnull(strings)) if (nempty(s)) { if (nempty(buf)) buf.append(sep); buf.append(s); } return str(buf); } static String utf8streamToString(InputStream in) { return readerToString(utf8bufferedReader(in)); } static betterCIComparator_C betterCIComparator_instance; static betterCIComparator_C betterCIComparator() { if (betterCIComparator_instance == null) betterCIComparator_instance = new betterCIComparator_C(); return betterCIComparator_instance; } static class betterCIComparator_C implements Comparator { public int compare(String s1, String s2) { if (s1 == null) return s2 == null ? 0 : -1; if (s2 == null) return 1; int n1 = s1.length(); int n2 = s2.length(); int min = Math.min(n1, n2); for (int i = 0; i < min; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 != c2) { c1 = Character.toUpperCase(c1); c2 = Character.toUpperCase(c2); if (c1 != c2) { c1 = Character.toLowerCase(c1); c2 = Character.toLowerCase(c2); if (c1 != c2) { // No overflow because of numeric promotion return c1 - c2; } } } } return n1 - n2; } } static TreeSet toCaseInsensitiveSet_treeSet(Iterable c) { if (isCISet(c)) return (TreeSet) c; TreeSet set = caseInsensitiveSet_treeSet(); addAll(set, c); return set; } static TreeSet toCaseInsensitiveSet_treeSet(String... x) { TreeSet set = caseInsensitiveSet_treeSet(); addAll(set, x); return set; } static Lock downloadLock_lock = fairLock(); static Lock downloadLock() { return downloadLock_lock; } static String getSnippetTitleOpt(String s) { return isSnippetID(s) ? getSnippetTitle(s) : s; } static boolean isSubstanceLAF() { return substanceLookAndFeelEnabled(); } // menuMaker = voidfunc(JPopupMenu) // return true if menu could be added static boolean titlePopupMenu(final Component c, final Object menuMaker) { JComponent titleBar = getTitlePaneComponent(getPossiblyInternalFrame(c)); if (titleBar == null) { print("Can't add title right click!"); return false; } else { componentPopupMenu(titleBar, menuMaker); return true; } } // r : runnable or voidfunc(bool) static JCheckBoxMenuItem jCheckBoxMenuItem(String text, boolean checked, final Object r) { final JCheckBoxMenuItem mi = new JCheckBoxMenuItem(text, checked); addActionListener(mi, new Runnable() { public void run() { try { callF(r, isChecked(mi)) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(r, isChecked(mi))"; }}); return mi; } static void toggleAlwaysOnTop(JFrame frame) { frame.setAlwaysOnTop(!frame.isAlwaysOnTop()); } static void shootWindowGUI_external(JFrame frame) { call(hotwireOnce("#1007178"), "shootWindowGUI", frame); } static void shootWindowGUI_external(final JFrame frame, int delay) { call(hotwireOnce("#1007178"), "shootWindowGUI", frame, delay); } static File imageSnippetCacheFile(String snippetID) { File dir = imageSnippetsCacheDir(); if (!loadBufferedImage_useImageCache) return null; return new File(dir, parseSnippetID(snippetID) + ".png"); } static String snippetImageURL_noHttps(String snippetID) { return snippetImageURL_noHttps(snippetID, "png"); } static String snippetImageURL_noHttps(String snippetID, String contentType) { return snippetImageURL(snippetID, contentType) .replace("https://www.botcompany.de:8443/", "http://www.botcompany.de:8080/") .replace("https://botcompany.de/", "http://botcompany.de/"); } static ThreadLocal>> loadBinaryPage_responseHeaders = new ThreadLocal(); static ThreadLocal> loadBinaryPage_extraHeaders = new ThreadLocal(); static byte[] loadBinaryPage(String url) { try { print("Loading " + url); return loadBinaryPage(loadPage_openConnection(new URL(url))); } catch (Exception __e) { throw rethrow(__e); } } static byte[] loadBinaryPage(URLConnection con) { try { Map extraHeaders = getAndClearThreadLocal(loadBinaryPage_extraHeaders); setHeaders(con); for (String key : keys(extraHeaders)) con.setRequestProperty(key, extraHeaders.get(key)); return loadBinaryPage_noHeaders(con); } catch (Exception __e) { throw rethrow(__e); } } static byte[] loadBinaryPage_noHeaders(URLConnection con) { try { ByteArrayOutputStream buf = new ByteArrayOutputStream(); InputStream inputStream = con.getInputStream(); loadBinaryPage_responseHeaders.set(con.getHeaderFields()); long len = 0; try { len = con.getContentLength/*Long*/(); } catch (Throwable e) { printStackTrace(e); } int n = 0; while (true) { int ch = inputStream.read(); if (ch < 0) break; buf.write(ch); if (++n % 100000 == 0) println(" " + n + (len != 0 ? "/" + len : "") + " bytes loaded."); } inputStream.close(); return buf.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } /** writes safely (to temp file, then rename) */ public static byte[] saveBinaryFile(String fileName, byte[] contents) { try { File file = new File(fileName); File parentFile = file.getParentFile(); if (parentFile != null) parentFile.mkdirs(); String tempFileName = fileName + "_temp"; FileOutputStream fileOutputStream = newFileOutputStream(tempFileName); fileOutputStream.write(contents); fileOutputStream.close(); if (file.exists() && !file.delete()) throw new IOException("Can't delete " + fileName); if (!new File(tempFileName).renameTo(file)) throw new IOException("Can't rename " + tempFileName + " to " + fileName); vmBus_send("wroteFile", file); return contents; } catch (Exception __e) { throw rethrow(__e); } } static byte[] saveBinaryFile(File fileName, byte[] contents) { return saveBinaryFile(fileName.getPath(), contents); } static File getGlobalCache() { File file = new File(javaxCachesDir(), "Binary Snippets"); file.mkdirs(); return file; } static String dataSnippetLink(String snippetID) { long id = parseSnippetID(snippetID); if (id >= 1100000 && id < 1200000) return imageServerURL() + id; if (id >= 1400000 && id < 1500000) return "http://butter.botcompany.de:8080/files/" + id + "?_pass=" + muricaPassword(); if (id >= 1200000 && id < 1300000) { // Woody files, actually String pw = muricaPassword(); if (empty(pw)) throw fail("Please set 'murica password by running #1008829"); return "http://butter.botcompany.de:8080/1008823/raw/" + id + "?_pass=" + pw; // XXX, although it typically gets hidden when printing } else return "http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_" + id + "&contentType=application/binary"; } static A addAndReturn(Collection c, A a) { if (c != null) c.add(a); return a; } static void loadBinaryPageToFile(String url, File file) { try { print("Loading " + url); loadBinaryPageToFile(openConnection(new URL(url)), file); } catch (Exception __e) { throw rethrow(__e); } } static void loadBinaryPageToFile(URLConnection con, File file) { try { setHeaders(con); loadBinaryPageToFile_noHeaders(con, file); } catch (Exception __e) { throw rethrow(__e); } } static void loadBinaryPageToFile_noHeaders(URLConnection con, File file) { try { File ftemp = new File(f2s(file) + "_temp"); FileOutputStream buf = newFileOutputStream(mkdirsFor(ftemp)); try { InputStream inputStream = con.getInputStream(); long len = 0; try { len = con.getContentLength/*Long*/(); } catch (Throwable e) { printStackTrace(e); } String pat = " {*}" + (len != 0 ? "/" + len : "") + " bytes loaded."; copyStreamWithPrints(inputStream, buf, pat); inputStream.close(); buf.close(); file.delete(); renameFile_assertTrue(ftemp, file); } finally { if (buf != null) buf.close(); } } catch (Exception __e) { throw rethrow(__e); } } static long psI(String snippetID) { return parseSnippetID(snippetID); } static List allToString(Iterable c) { List l = new ArrayList(); for (Object o : unnull(c)) l.add(str(o)); return l; } static List allToString(Object[] c) { List l = new ArrayList(); for (Object o : unnull(c)) l.add(str(o)); return l; } static boolean byteArrayStartsWith(byte[] a, byte[] b) { if (a == null || b == null) return false; if (a.length < b.length) return false; for (int i = 0; i < b.length; i++) if (a[i] != b[i]) return false; return true; } static byte[] loadBeginningOfBinaryFile(File file, int maxBytes) { return loadBinaryFilePart(file, 0, maxBytes); } static A firstWithClassShortNamed(String shortName, Iterable l) { if (l != null) for (A o : l) if (eq(shortClassName(o), shortName)) return o; return null; } static A firstWithClassShortNamed(String shortName, A[] l) { if (l != null) for (A o : l) if (eq(shortClassName(o), shortName)) return o; return null; } static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) { if (tl == null) return null; final A prev = setThreadLocal(tl, a); return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }}; } static boolean hasLettersAllUpperCase(String s) { return hasLetters(s) && !containsLowerCase(s); } static String htmlencode_forParams(String s) { if (s == null) return ""; StringBuilder out = new StringBuilder(Math.max(16, s.length())); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); /*if (c >= 0x100) out.append("&#x").append(charToHex(c)).append(';'); else*/ if (c > 127 || c == '"' || c == '<' || c == '>') { out.append("&#"); out.append((int) c); out.append(';'); } else out.append(c); } return out.toString(); } static Set synchronizedSet() { return synchroHashSet(); } static Set synchronizedSet(Set set) { return Collections.synchronizedSet(set); } static Set identityHashSet() { return Collections.newSetFromMap(new IdentityHashMap()); } static WeakReference creator_class; static Object creator() { return creator_class == null ? null : creator_class.get(); } static void nohupJavax(final String javaxargs) { { startThread(new Runnable() { public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "call(hotwireOnce(\"#1008562\"), \"nohupJavax\", javaxargs);"; }}); } } static void nohupJavax(final String javaxargs, final String vmArgs) { { startThread(new Runnable() { public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs, vmArgs); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "call(hotwireOnce(\"#1008562\"), \"nohupJavax\", javaxargs, vmArgs);"; }}); } } // Try to get the quoting right... static String smartJoin(String[] args) { if (empty(args)) return ""; if (args.length == 1) return args[0]; String[] a = new String[args.length]; for (int i = 0; i < a.length; i++) a[i] = !isJavaIdentifier(args[i]) && !isQuoted(args[i]) ? quote(args[i]) : args[i]; return join(" ", a); } static String smartJoin(List args) { return smartJoin(toStringArray(args)); } static Class run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } static String readerToString(Reader r) { try { try { StringBuilder buf = new StringBuilder(); int n = 0; while (true) { int ch = r.read(); if (ch < 0) break; buf.append((char) ch); ++n; //if ((n % loadPage_verboseness) == 0) print(" " + n + " chars read"); } return buf.toString(); } finally { r.close(); } } catch (Exception __e) { throw rethrow(__e); } } static String getSnippetTitle(String id) { try { if (id == null) return null; if (!isSnippetID(id)) return "?"; IResourceLoader rl = vm_getResourceLoader(); if (rl != null) return rl.getSnippetTitle(id); if (isLocalSnippetID(id)) return localSnippetTitle(id); long parsedID = parseSnippetID(id); String url; if (isImageServerSnippet(parsedID)) url = imageServerURL() + "title/" + parsedID + muricaCredentialsQuery(); else if (isGeneralFileServerSnippet(parsedID)) url = "http://butter.botcompany.de:8080/files/name/" + parsedID; else url = tb_mainServer() + "/tb-int/getfield.php?id=" + parsedID + "&field=title" + standardCredentials_noCookies(); String title = trim(loadPageSilently(url)); if (title != null) try { saveTextFileIfChanged(snippetTitle_cacheFile(id), title); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } return or(title, "?"); } catch (Exception __e) { throw rethrow(__e); } } static String getSnippetTitle(long id) { return getSnippetTitle(fsI(id)); } static boolean substanceLookAndFeelEnabled() { return startsWith(getLookAndFeel(), "org.pushingpixels."); } static JComponent getTitlePaneComponent(RootPaneContainer window) { if (window instanceof JInternalFrame) return getInternalFrameTitlePaneComponent((JInternalFrame) window); if (!substanceLookAndFeelEnabled() || window == null) return null; JRootPane rootPane = window.getRootPane(); if (rootPane != null) { Object /*SubstanceRootPaneUI*/ ui = rootPane.getUI(); return (JComponent) call(ui, "getTitlePane"); } return null; } static RootPaneContainer getPossiblyInternalFrame(Component c) { JInternalFrame f = getInternalFrame(c); if (f != null) return f; return optCast(RootPaneContainer.class, getWindow(c)); } static Class hotwireOnce(String programID) { return hotwireCached(programID, false); } static A println(A a) { return print(a); } static volatile boolean muricaPassword_pretendNotAuthed = false; static String muricaPassword() { if (muricaPassword_pretendNotAuthed) return null; return trim(loadTextFile(muricaPasswordFile())); } public static File mkdirsFor(File file) { return mkdirsForFile(file); } static void copyStreamWithPrints(InputStream in, OutputStream out, String pat) { try { byte[] buf = new byte[65536]; int total = 0; while (true) { int n = in.read(buf); if (n <= 0) return; out.write(buf, 0, n); if ((total+n)/100000 > total/100000) print(pat.replace("{*}", str(roundDownTo(total, 100000)))); total += n; } } catch (Exception __e) { throw rethrow(__e); } } static void renameFile_assertTrue(File a, File b) { try { if (!a.exists()) throw fail("Source file not found: " + f2s(a)); if (b.exists()) throw fail("Target file exists: " + f2s(b)); mkdirsForFile(b); if (!a.renameTo(b)) throw fail("Can't rename " + f2s(a) + " to " + f2s(b)); } catch (Exception __e) { throw rethrow(__e); } } static byte[] loadBinaryFilePart(File file, long start, long end) { try { RandomAccessFile raf = new RandomAccessFile(file, "r"); int n = toInt(min(raf.length(), end-start)); byte[] buffer = new byte[n]; try { raf.seek(start); raf.readFully(buffer, 0, n); return buffer; } finally { raf.close(); } } catch (Exception __e) { throw rethrow(__e); } } static A setThreadLocal(ThreadLocal tl, A value) { if (tl == null) return null; A old = tl.get(); tl.set(value); return old; } static boolean hasLetters(String s) { for (int i = 0; i < s.length(); i++) if (Character.isLetter(s.charAt(i))) return true; return false; } static boolean containsLowerCase(String s) { for (int i = 0; i < l(s); i++) if (isLowerCase(s.charAt(i))) return true; return false; } static Set synchroHashSet() { return Collections.synchronizedSet(new HashSet()); } // supports the usual quotings (", variable length double brackets) except ' quoting static boolean isQuoted(String s) { if (isNormalQuoted(s)) return true; // use the exact version return isMultilineQuoted(s); } static Class hotwire(String src) { assertFalse(_inCore()); Class j = getJavaX(); if (isAndroid()) { synchronized(j) { // hopefully this goes well... List libraries = new ArrayList(); File srcDir = (File) call(j, "transpileMain", src, libraries); if (srcDir == null) throw fail("transpileMain returned null (src=" + quote(src) + ")"); Object androidContext = get(j, "androidContext"); return (Class) call(j, "loadx2android", srcDir, src); } } else { Class c = (Class) (call(j, "hotwire", src)); hotwire_copyOver(c); return c; } } static A callMain(A c, String... args) { callOpt(c, "main", new Object[] {args}); return c; } static void callMain() { callMain(mc()); } static boolean isLocalSnippetID(String snippetID) { return isSnippetID(snippetID) && isLocalSnippetID(psI(snippetID)); } static boolean isLocalSnippetID(long snippetID) { return snippetID >= 1000 && snippetID <= 9999; } static String localSnippetTitle(String snippetID) { if (!isLocalSnippetID(snippetID)) return null; File f = localSnippetFile(snippetID); if (!f.exists()) return null; return or2(getFileInfoField(dropExtension(f), "Title"), "Unnamed"); } static String muricaCredentialsQuery() { return htmlQuery(muricaCredentials()); } static boolean isGeneralFileServerSnippet(long id) { return id >= 1400000 && id < 1500000; } static String standardCredentials_noCookies() { return standardCredentials() + "&noCookies=1"; } static boolean saveTextFileIfChanged(File f, String contents) { return saveTextFileIfDifferent(f, contents); } static File snippetTitle_cacheFile(String snippetID) { return javaxCachesDir("Snippet Titles/" + psI(snippetID)); } static String getLookAndFeel() { return getClassName(UIManager.getLookAndFeel()); } static JComponent getInternalFrameTitlePaneComponent(JInternalFrame f) { return (JComponent) childWithClassNameEndingWith(f, "InternalFrameTitlePane"); } static A optCast(Class c, Object o) { return isInstance(c, o) ? (A) o : null; } static TreeMap hotwireCached_cache = new TreeMap(); static Lock hotwireCached_lock = lock(); static Class hotwireCached(String programID) { return hotwireCached(programID, true); } static Class hotwireCached(String programID, boolean runMain) { return hotwireCached(programID, runMain, false); } static Class hotwireCached(String programID, boolean runMain, boolean dependent) { Lock __2261 = hotwireCached_lock; lock(__2261); try { programID = formatSnippetID(programID); Class c = hotwireCached_cache.get(programID); if (c == null) { c = hotwire(programID); if (dependent) makeDependent(c); if (runMain) callMain(c); hotwireCached_cache.put(programID, c); } return c; } finally { unlock(__2261); } } static File muricaPasswordFile() { return new File(javaxSecretDir(), "murica/muricaPasswordFile"); } static int roundDownTo(int x, int n) { return x/n*n; } static long roundDownTo(long x, long n) { return x/n*n; } static boolean isLowerCase(char c) { return Character.isLowerCase(c); } static boolean isNormalQuoted(String s) { int l = l(s); if (!(l >= 2 && s.charAt(0) == '"' && lastChar(s) == '"')) return false; int j = 1; while (j < l) if (s.charAt(j) == '"') return j == l-1; else if (s.charAt(j) == '\\' && j+1 < l) j += 2; else ++j; return false; } static boolean isMultilineQuoted(String s) { if (!startsWith(s, "[")) return false; int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; return i < s.length() && s.charAt(i) == '['; } static boolean _inCore() { return false; } static List hotwire_copyOver_after = synchroList(); static void hotwire_copyOver(Class c) { // TODO: make a mechanism for making such "inheritable" fields for (String field : ll("print_log", "print_silent", "androidContext", "_userHome")) setOptIfNotNull(c, field, getOpt(mc(), field)); setOptIfNotNull(c, "mainBot" , getMainBot()); setOpt(c, "creator_class" , new WeakReference(mc())); pcallFAll(hotwire_copyOver_after, c); } static File localSnippetFile(long snippetID) { return localSnippetsDir(snippetID + ".text"); } static File localSnippetFile(String snippetID) { return localSnippetFile(parseSnippetID(snippetID)); } static String getFileInfoField(File f, String field) { return getOneLineFileInfoField(f, field); } static File dropExtension(File f) { return f == null ? null : fileInSameDir(f, dropExtension(f.getName())); } static String dropExtension(String s) { return takeFirst(s, smartLastIndexOf(s, '.')); } static Object[] muricaCredentials() { String pass = muricaPassword(); return nempty(pass) ? new Object[] {"_pass", pass } : new Object[0]; } static String standardCredentials() { String user = standardCredentialsUser(); String pass = standardCredentialsPass(); if (nempty(user) && nempty(pass)) return "&_user=" + urlencode(user) + "&_pass=" + urlencode(pass); return ""; } static boolean saveTextFileIfDifferent(File f, String contents) { if (eq(loadTextFile(f), contents)) return false; { saveTextFile(f, contents); return true; } } static Component childWithClassNameEndingWith(Component c, String suffix) { if (endsWith(className(c), suffix)) return c; Component x; for (Component comp : getComponents(c)) if ((x = childWithClassNameEndingWith(comp, suffix)) != null) return x; return null; } static Object makeDependent_postProcess; static void makeDependent(Object c) { if (c == null) return; assertTrue("Not a class", c instanceof Class); dependentClasses(); // cleans up the list hotwire_classes.add(new WeakReference(c)); Object local_log = getOpt(mc(), "local_log"); if (local_log != null) setOpt(c, "local_log", local_log); /*if (isTrue(getOpt(c, 'ping_actions_shareable))) setOpt(c, +ping_actions);*/ Object print_byThread = getOpt(mc(), "print_byThread"); if (print_byThread != null) setOpt(c, "print_byThread", print_byThread); callF(makeDependent_postProcess, c); } static void setOptIfNotNull(Object o, String field, Object value) { if (value != null) setOpt(o, field, value); } static File localSnippetsDir() { return javaxDataDir("Personal Programs"); } static File localSnippetsDir(String sub) { return newFile(localSnippetsDir(), sub); } static String getOneLineFileInfoField(File f, String field) { File infoFile = associatedInfosFile(f); List lines = lines(loadTextFile(infoFile)); return firstStartingWithIC_drop(lines, field + ": "); } static File fileInSameDir(File f, String newName) { return newFile(parentFile(f), newName); } static List takeFirst(List l, int n) { return l(l) <= n ? l : newSubListOrSame(l, 0, n); } static List takeFirst(int n, List l) { return takeFirst(l, n); } static String takeFirst(int n, String s) { return substring(s, 0, n); } static String takeFirst(String s, int n) { return substring(s, 0, n); } static List takeFirst(int n, Iterable i) { List l = new ArrayList(); Iterator it = i.iterator(); for (int _repeat_32 = 0; _repeat_32 < n; _repeat_32++) { if (it.hasNext()) l.add(it.next()); else break; } return l; } static String standardCredentialsUser() { return trim(loadTextFile( oneOfTheFiles( javaxSecretDir("tinybrain-username"), userDir(".tinybrain/username")))); } static String standardCredentialsPass() { return trim(loadTextFile( oneOfTheFiles( javaxSecretDir("tinybrain-userpass"), userDir(".tinybrain/userpass")))); } static List getComponents(final Component c) { return !(c instanceof Container) ? emptyList() : asList(swing(new F0() { Component[] get() { try { return ((Container) c).getComponents(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret ((Container) c).getComponents();"; }})); } static List dependentClasses() { return cleanUpAndGetWeakReferencesList(hotwire_classes); } static List> hotwire_classes = synchroList(); static Class hotwireDependent(String src) { Class c = hotwire(src); makeDependent(c); return c; } static File associatedInfosFile(File f) { return replaceExtension(f, ".infos"); } static String firstStartingWithIC_drop(Collection l, final String prefix) { for (String s : unnull(l)) if (swic(s, prefix)) return substring(s, l(prefix)); return null; } static String firstStartingWithIC_drop(String prefix, Collection l) { return firstStartingWithIC_drop(l, prefix); } static File parentFile(File f) { return dirOfFile(f); } static List newSubListOrSame(List l, int startIndex) { return newSubListOrSame(l, startIndex, l(l)); } static List newSubListOrSame(List l, int startIndex, int endIndex) { if (l == null) return null; int n = l(l); startIndex = max(0, startIndex); endIndex = min(n, endIndex); if (startIndex >= endIndex) return ll(); if (startIndex == 0 && endIndex == n) return l; return cloneList(l.subList(startIndex, endIndex)); } static File oneOfTheFiles(String... paths) { if (paths != null) for (String path : paths) if (fileExists(path)) return newFile(path); return null; } static File oneOfTheFiles(File... files) { if (files != null) for (File f : files) if (fileExists(f)) return f; return null; } static List cleanUpAndGetWeakReferencesList(List> l) { if (l == null) return null; synchronized(l) { List out = new ArrayList(); for (int i = 0; i < l(l); i++) { A a = l.get(i).get(); if (a == null) l.remove(i--); else out.add(a); } return out; } } static File replaceExtension(File f, String extOld, String extNew) { return newFile(replaceExtension(f2s(f), extOld, extNew)); } static File replaceExtension(File f, String extNew) { return replaceExtension(f, fileExtension(f), extNew); } static String replaceExtension(String s, String extOld, String extNew) { s = dropSuffixIC(addPrefixOptIfNempty(".", extOld), s); return s + addPrefixOptIfNempty(".", extNew); } static String replaceExtension(String name, String extNew) { return replaceExtension(name, fileExtension(name), extNew); } static boolean fileExists(String path) { return path != null && new File(path).exists(); } static boolean fileExists(File f) { return f != null && f.exists(); } static String addPrefixOptIfNempty(String prefix, String s) { return addPrefixIfNotEmpty2(prefix, s); } static String addPrefixIfNotEmpty2(String prefix, String s) { return empty(s) ? "" : addPrefix(prefix, s); } // immutable, has strong refs final static class _MethodCache { final Class c; final HashMap> cache = new HashMap(); _MethodCache(Class c) { this.c = c; _init(); } void _init() { Class _c = c; while (_c != null) { for (Method m : _c.getDeclaredMethods()) if (!reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); _c = _c.getSuperclass(); } // add default methods - this might lead to a duplication // because the overridden method is also added, but it's not // a problem except for minimal performance loss. for (Class intf : allInterfacesImplementedBy(c)) for (Method m : intf.getDeclaredMethods()) if (m.isDefault() && !reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); } // Returns only matching methods Method findMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } Method findStaticMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (isStaticMethod(me) && call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } }static abstract class VF1 implements IVF1 { public abstract void get(A a); }static class JSection extends SingleComponentPanel { JSection(Component c) { super(c); } String getTitle() { Border border = getBorder(); if (border instanceof TitledBorder) return ((TitledBorder) border).getTitle(); return null; } } static class Matches { String[] m; Matches() {} Matches(String... m) { this.m = m;} String get(int i) { return i < m.length ? m[i] : null; } String unq(int i) { return unquote(get(i)); } String fsi(int i) { return formatSnippetID(unq(i)); } String fsi() { return fsi(0); } String tlc(int i) { return unq(i).toLowerCase(); } boolean bool(int i) { return "true".equals(unq(i)); } String rest() { return m[m.length-1]; } // for matchStart int psi(int i) { return Integer.parseInt(unq(i)); } public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; } public int hashCode() { return _hashCode(toList(m)); } public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); } } static class Var implements IVar { Var() {} Var(A v) { this.v = v;} A v; // you can access this directly if you use one thread public synchronized void set(A a) { if (v != a) { v = a; notifyAll(); } } public synchronized A get() { return v; } public synchronized boolean has() { return v != null; } public synchronized void clear() { v = null; } public String toString() { return str(get()); } }static class ChessPieceProfile1 { byte[] sideProfile; float fillGrade; transient List preprocessedImages; ChessPieceProfile1() {} ChessPieceProfile1(byte[] sideProfile, float fillGrade) { this.fillGrade = fillGrade; this.sideProfile = sideProfile;} public boolean equals(Object o) { if (o instanceof ChessPieceProfile1) return fillGrade == ((ChessPieceProfile1) o).fillGrade && byteArrayEquals(sideProfile, ((ChessPieceProfile1) o).sideProfile); return false; } public int hashCode() { return _hashCode(fillGrade) + arrayHashCode(sideProfile); } }static abstract class LiveValue { abstract Class getType(); abstract A get(); abstract void onChange(Runnable l); abstract void removeOnChangeListener(Runnable l); void onChangeAndNow(Runnable l) { onChange(l); callF(l); } } // thumbnailator static class ImageSurface extends Surface { BufferedImage image; double zoomX = 1, zoomY = 1, zoomFactor = 1.5; private Rectangle selection; List tools = new ArrayList(); Object overlay; // voidfunc(Graphics2D) Runnable onSelectionChange; static boolean verbose = false; boolean noMinimumSize = true; String titleForUpload; Object onZoom; boolean specialPurposed = false; // true = don't show image changing commands in popup menu boolean zoomable = true; boolean noAlpha = false; // set to true to speed up drawing if you don't use alpha Object interpolationMode = RenderingHints.VALUE_INTERPOLATION_BILINEAR; Object onNewImage; BufferedImage imageToDraw; // if you want to draw a different image public ImageSurface() { this(dummyImage()); } static BufferedImage dummyImage() { return new RGBImage(1, 1, new int[] { 0xFFFFFF }).getBufferedImage(); } ImageSurface(MakesBufferedImage image) { this(image != null ? image.getBufferedImage() : dummyImage()); } ImageSurface(BufferedImage image) { setImage(image); clearSurface = false; 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))"; }}); } public ImageSurface(RGBImage image, double zoom) { this(image); setZoom(zoom); } // point is already in image coordinates protected 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); JMenuItem miZoomToWindow = new JMenuItem("Zoom to window"); miZoomToWindow.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { zoomToDisplaySize(); } }); menu.add(miZoomToWindow); 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: " + image.getWidth() + "*" + image.getHeight() + ")", null); menu.addSeparator(); } 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) cte..."; }}); addMenuItem(menu, "Save image...", new Runnable() { public void run() { try { saveImage() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveImage()"; }}); addMenuItem(menu, "Upload image...", new Runnable() { public void run() { try { uploadTheImage() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "uploadTheImage()"; }}); 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) { addMenuItem(menu, "Paste image from clipboard", new Runnable() { public void run() { try { loadFromClipboard() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "loadFromClipboard()"; }}); 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()"; }}); } void noImage() { setImage((BufferedImage) null); } void crop() { if (selection == null) return; BufferedImage img = cloneClipBufferedImage(getImage(), selection); selection = null; setImage(img); } void loadFromClipboard() { BufferedImage img = getImageFromClipboard(); if (img != null) setImage(img); } void saveImage() { RGBImage image = new RGBImage(getImage(), null); JFileChooser fileChooser = new JFileChooser(getProgramDir()); if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { try { image.save(fileChooser.getSelectedFile()); } catch (IOException e) { popup(e); } } } public void render(int w, int h, Graphics2D g) { if (verbose) _print("render"); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationMode); g.setColor(Color.white); BufferedImage image = or(imageToDraw, this.image); if (image == null) g.fillRect(0, 0, w, h); else { int iw = getZoomedWidth(), ih = getZoomedHeight(); boolean alpha = !noAlpha && hasTransparency(image); if (alpha) g.fillRect(0, 0, w, h); if (eq(interpolationMode, "thumbnailator")) g.drawImage(Thumbnailator.createThumbnail(image, iw, ih), 0, 0, null); else 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); // smoother 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); } if (selection != null) { if (verbose) _print("render selection"); // drawRect is inclusive, selection is exclusive, so... whatever, tests show it's cool. 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) { if (this.zoomX == zoomX && this.zoomY == zoomY) return; if (verbose) _print("Setting zoom"); this.zoomX = zoomX; this.zoomY = zoomY; revalidate(); repaint(); centerPoint(new Point(getImage().getWidth()/2, getImage().getHeight()/2)); pcallF(onZoom); } public Dimension getMinimumSize() { if (noMinimumSize) return new Dimension(1, 1); int w = getZoomedWidth(); int h = getZoomedHeight(); Dimension min = super.getMinimumSize(); return new Dimension(Math.max(w, min.width), Math.max(h, min.height)); } private int getZoomedHeight() { return (int) (image.getHeight() * zoomY); } private int getZoomedWidth() { return (int) (image.getWidth() * zoomX); } public void setImage(MakesBufferedImage image) { setImage(image.getBufferedImage()); } public void setImage(final BufferedImage img) { { swing(new Runnable() { public void run() { try { BufferedImage newImage = img != null ? img : dummyImage(); BufferedImage oldImage = image; image = newImage; if (!imagesHaveSameSize(oldImage, newImage)) { if (verbose) _print("New image size"); revalidate(); // do we need this? } repaint(); pcallF(onNewImage); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "BufferedImage newImage = img != null ? img : dummyImage();\r\n BufferedIma..."; }}); } } 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() { return new Dimension(getZoomedWidth(), getZoomedHeight()); } /** returns a scrollpane with the scroll-mode prevent-garbage-drawing fix applied */ 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(new Runnable() { public void run() { try { if (image == null) return; Dimension display = getDisplaySize(); double xRatio = (display.width-5)/(double) image.getWidth(); double yRatio = (display.height-5)/(double) image.getHeight(); setZoom(min(xRatio, yRatio)); revalidate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (image == null) return;\r\n Dimension display = getDisplaySize();\r\n do..."; }}); } /** tricky magic to get parent scroll pane */ private Dimension getDisplaySize() { Container c = getParent(); while (c != null) { if (c instanceof JScrollPane) return c.getSize(); c = c.getParent(); } return getSize(); } public void setSelection(Rectangle r) { if (neq(selection, r)) { selection = r; pcallF(onSelectionChange); repaint(); } } public Rectangle getSelection() { return selection; } public RGBImage getRGBImage() { return new RGBImage(getImage()); } // p is in image coordinates 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(); //_print("centerPoint " + p); int x = max(0, p.x-viewSize.width/2); int y = max(0, p.y-viewSize.height/2); //_print("centerPoint " + p + " => " + x + "/" + y); p = new Point(x,y); //_print("centerPoint " + p); 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);"; }}); } Pt pointFromEvent(MouseEvent e) { return pointFromComponentCoordinates(new Pt(e.getX(), e.getY())); } Pt pointFromComponentCoordinates(Pt p) { return new Pt((int) (p.x/zoomX), (int) (p.y/zoomY)); } Pt pointToComponentCoordinates(double x, double y) { return new Pt((int) (x*zoomX), (int) (y*zoomY)); } void uploadTheImage() { call(hotwire(/*#1007313*/"#1016427"), "go", getImage(), titleForUpload); } void showFullScreen() { showFullScreenImageSurface(getImage()); } void zoomIn(double f) { setZoom(getZoomX()*f, getZoomY()*f); } void zoomOut(double f) { setZoom(getZoomX()/f, getZoomY()/f); } } // static function allows garbage collection static 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 class RightAlignedLine extends JPanel { RightAlignedLine(Component... components) { setLayout(LetterLayout.rightAlignedRow()); for (Component component : components) add(component); } public void add(String text) { add(new JLabel(text)); } }static final class BWImage implements MakesBufferedImage, IBWImage { int width, height; byte[] pixels; // color returned when getPixel is called with a position outside the actual image float borderColor = 0.0f; // for unstructure() BWImage() {} // BLACK! BWImage(int width, int height) { this.height = height; this.width = width; pixels = new byte[width*height]; } BWImage(int width, int height, float brightness) { this.height = height; this.width = width; pixels = new byte[width*height]; fillArrayUnlessZero(pixels, _toByte(brightness)); } BWImage(int width, int height, float[] pixels) { this.pixels = new byte[pixels.length]; this.height = height; this.width = width; for (int i = 0; i < pixels.length; i++) this.pixels[i] = _toByte(pixels[i]); } public BWImage(int width, int height, byte[] pixels) { this.height = height; this.width = width; this.pixels = pixels; } public BWImage(BWImage image) { width = image.getWidth(); height = image.getHeight(); byte[] pixels = this.pixels = new byte[width*height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) pixels[y*width+x] = image.getByte(x, y); } // TODO: optimize! BWImage(RGBImage image) { width = image.getWidth(); height = image.getHeight(); byte[] pixels = this.pixels = new byte[height*width]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { RGB rgb = image.getRGB(x, y); pixels[y*width+x] = BWImage._toByte(rgb.getBrightness()); } } /*public BWImage(BufferedImage image) { this(new RGBImage(image)); }*/ BWImage(BufferedImage image) { try { width = image.getWidth(); height = image.getHeight(); int[] pixels = new int[width*height]; byte[] bytePixels = this.pixels = new byte[width*height]; PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); if (!pixelGrabber.grabPixels()) throw fail("Could not grab pixels"); int n = width*height; for (int i = 0; i < n; i++) { //bytePixels[i] = pixelToByte(pixels[i]); int packed = pixels[i]; /*float r = ((packed >> 16) & 0xFF)/255f; float g = ((packed >> 8) & 0xFF)/255f; float b = (packed & 0xFF)/255f; bytePixels[i] = (byte) iround((r+g+b)/3.0f*255f);*/ int r = ((packed >> 16) & 0xFF); int g = ((packed >> 8) & 0xFF); int b = (packed & 0xFF); bytePixels[i] = (byte) ((r+g+b+1)/3); } } catch (Exception __e) { throw rethrow(__e); } } // TODO: does it exactly match the other method? (asRGB+getBrightness+_toByte) static byte pixelToByte(int packed) { /*int r = (packed >> 16) & 0xFF; int g = (packed >> 8) & 0xFF; int b = packed & 0xFF; ret (byte) ((r+g+b)/3.0f);*/ float r = ((packed >> 16) & 0xFF)/255f; float g = ((packed >> 8) & 0xFF)/255f; float b = (packed & 0xFF)/255f; return (byte) ((r+g+b)/3.0f*255f); } public byte getByte(int x, int y) { return inRange(x, y) ? getByte_noRangeCheck(x, y) : _toByte(borderColor); } public double averageBrightness() { double sum = 0; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) sum += getPixel(x, y); return (sum/(double) (height*width)); } public float minimumBrightness() { float min = 1; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) min = Math.min(min, getPixel(x, y)); return min; } public float maximumBrightness() { float max = 0; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) max = Math.max(max, getPixel(x, y)); return max; } float getPixel(int x, int y) { return inRange(x, y) ? _toFloat(getByte(x,y )) : borderColor; } public float getFloatPixel(int x, int y) { return getPixel(x, y); } float getPixel(Pt p) { return getPixel(p.x, p.y); } static byte _toByte(float pixel) { return (byte) (pixel*255f); } static float _toFloat(byte pixel) { return (((int) pixel) & 255)/255f; } private boolean inRange(int x, int y) { return x >= 0 && x < width && y >= 0 && y < height; } public int getWidth() { return width; } int w() { return width; } public int getHeight() { return height; } int h() { return height; } public RGBImage toRGB() { int[] rgbs = new int[width*height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { int b = getByte(x, y) & 0xFF; rgbs[y*width+x] = 0xFF000000 | b*0x010101; } return new RGBImage(width, height, rgbs); } public RGBImage toRGB_slow() { RGB[] rgbs = new RGB[width*height]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { float p = getPixel(x, y); rgbs[y*width+x] = new RGB(p, p, p); } return new RGBImage(width, height, rgbs); } public BWImage clip(int x, int y, int w, int h) { return clip(new Rectangle(x, y, w, h)); } private Rectangle fixClipRect(Rectangle r) { return r.intersection(new Rectangle(0, 0, width, height)); } BWImage clip(Rect r) { return clip(r.getRectangle()); } /** this should be multithread-safe */ public BWImage clip(Rectangle r) { r = fixClipRect(r); byte[] newPixels = new byte[r.height*r.width]; for (int y = 0; y < r.height; y++) for (int x = 0; x < r.width; x++) newPixels[y*r.width+x] = getByte(r.x+x, r.y+y); return new BWImage(r.width, r.height, newPixels); } public void setPixel(int x, int y, float brightness) { setByte(x, y, _toByte(fixPixel(brightness))); } // i = 0 to 255 public void setInt(int x, int y, int i) { setByte(x, y, (byte) limitToUByte(i)); } public void setByte(int x, int y, byte b) { if (x >= 0 && x < width && y >= 0 && y < height) pixels[y*width+x] = b; } byte getByte_noRangeCheck(int x, int y) { return pixels[y*width+x]; } public void setByte(int x, int y, int brightness) { setByte(x, y, (byte) brightness); } private float fixPixel(float pixel) { return Math.max(0, Math.min(1, pixel)); } public float getBorderColor() { return borderColor; } public void setBorderColor(float borderColor) { this.borderColor = borderColor; } public boolean anyPixelBrighterThan(double threshold) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) if (getPixel(x, y) > threshold) return true; return false; } public BufferedImage getBufferedImage() { //ret toRGB().getBufferedImage(); // TYPE_BYTE_GRAY is buggy - see #1015235 BufferedImage bufferedImage = new BufferedImage(width, height, /*BufferedImage.TYPE_BYTE_GRAY*/BufferedImage.TYPE_INT_RGB); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { int b = ((int) getByte(x, y) & 0xFF); bufferedImage.setRGB(x, y, b*0x010101); } return bufferedImage; } byte[] getBytes() { return pixels; } }static class SimpleLiveValue extends LiveValue { Class type; volatile A value; transient List onChange = synchroList(); SimpleLiveValue(Class type) { this.type = type;} SimpleLiveValue(Class type, A value) { this.value = value; this.type = type;} public Class getType() { return type; } public A get() { return value; } public void onChange(Runnable l) { onChange.add(l); } public void onChangeAndNow(Runnable l) { onChange(l); callF(l); } public void removeOnChangeListener(Runnable l) { onChange.remove(l); } void fireChanged() { pcallFAll(onChange); } void set(A a) { if (neq(value, a)) { value = a; fireChanged(); } } }static interface IResourceLoader { String loadSnippet(String snippetID); String getTranspiled(String snippetID); // with libs int getSnippetType(String snippetID); String getSnippetTitle(String snippetID); File loadLibrary(String snippetID); File pathToJavaXJar(); File getSnippetJar(String snippetID, String transpiledSrc); }static class ReliableSingleThread implements Runnable { Object runnable; boolean trigger = false; Thread thread; String name = "Single Thread"; F0 enter; // optional ownership marker, e.g. for DynModules ReliableSingleThread(Object runnable) { this.runnable = runnable;} void trigger() { go(); } synchronized void go() { trigger = true; if (!running()) { AutoCloseable __1107 = callF(enter); try { thread = startThread(name, new Runnable() { public void run() { try { AutoCloseable __1108 = callF(enter); try { _run(); } finally { _close(__1108); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __1108 = callF(enter); try {\r\n _run();\r\n } finally ..."; }}); } finally { _close(__1107); }} } public void run() { go(); } void get() { go(); } // so you can use the ! syntax synchronized boolean running() { return thread != null; } // use only if this is the last time you trigger this void triggerAndWait() { trigger(); while (running()) sleep(1); } void _run() { while (licensed()) { synchronized(this) { if (!trigger) { thread = null; break; } trigger = false; } pcallF(runnable); } } synchronized void cancel() { cancelAndInterruptThread(thread); thread = null; } synchronized boolean triggered() { return trigger; } void cleanMeUp() { cancel(); } }static class PKIKeyPair { String privateKey; String publicKey; PKIKeyPair() {} PKIKeyPair(String privateKey, String publicKey) { this.publicKey = publicKey; this.privateKey = privateKey;}public boolean equals(Object o) { if (!(o instanceof PKIKeyPair)) return false; PKIKeyPair x = (PKIKeyPair) o; return eq(privateKey, x.privateKey) && eq(publicKey, x.publicKey); } public int hashCode() { int h = -1731104693; h = h*2+_hashCode(privateKey); h = h*2+_hashCode(publicKey); return h; } public String toString() { return "PKIKeyPair([secret], " + quote(publicKey) + ")"; } }static class SingleComponentPanel extends JPanel { SingleComponentPanel() { super(new BorderLayout()); } SingleComponentPanel(Component component) { this(); if (component != null) setComponent(component); } void setComponent(final Component component) { { swing(new Runnable() { public void run() { try { removeAll(); if (component != null) add(BorderLayout.CENTER, wrap(component)); _revalidate(SingleComponentPanel.this); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "removeAll();\r\n if (component != null)\r\n add(BorderLayout.CENTER, ..."; }}); } } // Sometimes we need this? void setComponentAndRevalidateParent(Component component) { setComponent(component); _revalidate(_getParent(this)); } void noComponent() { setComponent(null); } Component getComponent() { return getComponentCount() == 0 ? null : getComponent(0); } }static abstract class DynModule { String name, toolTip; PersistableThrowable _error; Map> mechLists; Map _persistenceInfo; transient Object _host; transient Map timers = newWeakHashMap(); // all kinds of resources actually; value is closer helper transient Set _resources = synchroHashSet(); transient Lock lock; // set by stem transient boolean persistOnChangedField = true; transient int changeCount; transient Object changeCountSync = new Object(); transient List onChange; transient boolean verboseTimers = false; transient ReliableSingleThread rstUpdate; transient Set componentFieldsToKeep; transient Map transientGeneralMap = synchroHashMap(); transient Q q; // module command queue transient List onFieldChange; // also for non-persistent fields. L transient boolean _hasPreviousBounds = false; transient StringBuffer _printLog = new StringBuffer(); DynModule() { dm_initErrorHandling(); setMainDesktopPane((JDesktopPane) getCreatorOpt("desktop")); } boolean isVisible() { return isTrue(getOpt(_host, "visible")); } String moduleName() { return name; } void setModuleName(String name) { String oldName = this.name; if (!eq(name, oldName)) { this.name = name; possiblyInternalFrameTitle(vis(), name); vmBus_send("moduleNameChange", this, oldName, name); } } void setModuleToolTip(String toolTip) { this.toolTip = toolTip; } JComponent vis() { return (JComponent) getOpt(_host, "vis"); } A ownResource(A a) { if (a != null) _resources.add(a); return a; } A ownTimer(A timer) { if (timer instanceof AutoCloseable) ownResource((AutoCloseable) timer); ownTimer(timer, "cancelTimerOrInterruptThread"); return timer; } void ownTimer(Object timer, Object closerHelper) { timers.put(timer, closerHelper); } void singleTimer(java.util.Timer timer) { stopAllTimers(); ownTimer(timer); } void stopAllTimers() { for (AutoCloseable resource : getAndClearList(_resources)) { if (verboseTimers) print("Releasing resource: " + resource); try { resource.close(); } catch (Throwable __e) { _handleException(__e); } } { final Map __1052 = getAndClearMap(timers); for (Object timer : keys( __1052)) { Object closerHelper = __1052.get(timer); if (verboseTimers) print("Stopping timer: " + closerHelper + " / " + timer); pcallFInRealOrMyMC(this, closerHelper, timer); }} } void cleanMeUp_dynModule() { stopAllTimers(); } void persistMe() { synchronized(changeCountSync) { ++changeCount; } pcallFAll(onChange); callOpt(_host, "_change"); updateMe(); } void _change() { persistMe(); } void change() { persistMe(); } void updateMe() { rstUpdate().trigger(); } void changeAndUpdate() { _change(); updateMe(); } boolean setField(String name, Object value) { AutoCloseable __1056 = enter(); try { { // lock lock; // this leads to too many problems try { // some really weird classes fail on equals() (BCEL JavaClass, I'm looking at you) if (eq(get(this, name), value)) return false; } catch (Throwable __e) { _handleException(__e); } set(this, name, value); } // releasing lock before calling _change()! pcallFAll(onFieldChange, name); if (persistOnChangedField && !isFalse(mapGet(_persistenceInfo, name))) _change(); return true; } finally { _close(__1056); }} A setFieldAndReturn(String name, A value) { setField(name, value); return value; } boolean setFields(Object... params) { boolean change = false; for (int i = 0; i < l(params); i += 2) if (setField((String) params[i], params[i+1])) change = true; return change; } void start() { _hasPreviousBounds = dm_getBounds() != null; if (hasMethod_onTypes(this, "onTopInput", String.class)) dm_onTopInput_q(new VF1() { public void get(String s) { try { call(module(), "onTopInput", s) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "call(module(), 'onTopInput, s)"; }}); } void revisualize() { call(creator(), "revisualizeModule", _host); } AutoCloseable enter() { AutoCloseable c = tempSetThreadLocal(dm_currentModule_value, new WeakReference(this)); final Object realMC = getMainClass(this); if (printToModule()) c = combineAutoCloseables(c, tempInterceptPrintIfNotIntercepted(_printToModuleInterceptor())); if (realMC != mc()) { if (printToModule()) c = combineAutoCloseables(c, (AutoCloseable) callOpt(realMC, "tempInterceptPrintIfNotIntercepted", _printToModuleInterceptor())); else c = combineAutoCloseables(c, tempInterceptPrintIfNotIntercepted(new F1() { Boolean get(String s) { try { { call(realMC, "print", s); return false; } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret false with call(realMC, 'print, s);"; }})); c = combineAutoCloseables(c, tempSetTL(realMC_tl(), realMC)); } return c; } F1 _printToModuleInterceptor() { return new F1() { Boolean get(String s) { try { if (print_preprocess != null) s = (String) callF(print_preprocess, s); s = fixNewLines(s); Appendable loc = _printLog; Appendable buf = print_log; int loc_max = print_log_max; if (buf != loc && buf != null) { print_append(buf, s, print_log_max); loc_max = local_log_max; } if (loc != null) print_append(loc, s, loc_max); System.out.print(s); return false; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (print_preprocess != null) s = (S) callF(print_preprocess, s);\r\n s = ..."; }}; } boolean printToModule() { return true; } // on by default now AutoCloseable enterAndLock() { return combineAutoCloseables(enter(), tempLock(lock)); } boolean setError(Throwable e) { setField("_error" , persistableThrowable(e)); return true; } void clearError() { setField("_error" , null); } void onChange(Runnable r) { Lock __1053 = lock; lock(__1053); try { if (onChange == null) onChange = synchroList(); addIfNotThere(onChange, r); } finally { unlock(__1053); } } void onFieldChange(VF1 r) { Lock __1054 = lock; lock(__1054); try { if (onFieldChange == null) onFieldChange = synchroList(); addIfNotThere(onFieldChange, r); } finally { unlock(__1054); } } void onChangeAndNow(Runnable r) { onChange(r); callF(r); } // forward to main class void onChangeAndNow(JComponent c, Object r) { onUpdateAndNow(c, r); } /*static*/ A onChange(A tc, Object r) { onUpdate(tc, r); return tc; } void update() {} void unvisualize() { zeroAllFieldsOfTypeExcept(this, Component.class, componentFieldsToKeep); } List menuItems() { return null; } void enhanceFrame(Container f) { internalFramePopupMenuFromActions_threaded(f, menuItems()); String switchableFields = (String) (callOpt(this, "switchableFields")); Set set = asLinkedHashSet(splitAtSpace(switchableFields)); Matches m = new Matches(); for (String field : allFields(this)) if (startsWith(field, "_switchableField_", m)) set.add(m.rest()); for (String field : set) { Class type = fieldType(this, field); if (eq(boolean.class, type)) dm_boolFieldMenuItem(f, field); else if (eq(int.class, type)) dm_intFieldMenuItem(f, field); else if (eq(double.class, type)) dm_doubleFieldMenuItem(f, field); else if (eq(String.class, type)) dm_stringFieldMenuItem(f, field); } } // assume this is called in start(), so no locking ReliableSingleThread rstUpdate() { if (rstUpdate == null) rstUpdate = dm_rst(this, new Runnable() { public void run() { try { AutoCloseable __1057 = enter(); try { update(); } finally { _close(__1057); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __1057 = enter(); try { update(); } finally { _close(__1057); }"; }}); return rstUpdate; } Q q() { AutoCloseable __1058 = enter(); try { if (q == null) { Lock __1055 = lock; lock(__1055); try { if (q == null) q = dm_startQ(); } finally { unlock(__1055); } } return q; } finally { _close(__1058); }} A withUpdate(A a) { rstUpdate().trigger(); return a; } DynModule module() { return this; } DynModule me() { return this; } JComponent visualize() { return dm_noVisualisation(); } String programTitle_cache; String programTitle() { if (programTitle_cache == null) programTitle_cache = snippetTitle(programID(mainClass(this))); return programTitle_cache; } // field must be non-transient void doPersist(String field) { _persistenceInfo = mapMinus(_persistenceInfo, field); } void dontPersist(String field) { _persistenceInfo = mapPlus(_persistenceInfo, "field" , false); } Appendable _actualPrintLog() { return printToModule() ? _printLog : print_log; } } static void _registerTimer(java.util.Timer timer) { _registerTimer_original(timer); dm_currentModule().ownTimer(timer); } /* TODO: thread {} should enter the module svoid _onLoad_moduleThreadInfo { _threadInfo_addMakerAndRetriever( voidfunc(Map map) { mapPut(map, dm_current := dm_currentModule()) }, voidfunc(Map map) { dm_enter((S) map.get('dm_current)) }); } */ static class ChessOCR_TwoStageRecognizer extends SteppableAndBest> { // input BufferedImage inputImage; Iterator>> segmenterStream; ChessPieceRecognizer pieceRecognizer; boolean verbose = false; // internal List rectQueue = syncLinkedList(); Set rectsTried = new HashSet(); ChessOCR_TwoStageRecognizer() {} ChessOCR_TwoStageRecognizer(ChessPieceRecognizer pieceRecognizer, BufferedImage inputImage, Iterator>> segmenterStream) { this.segmenterStream = segmenterStream; this.inputImage = inputImage; this.pieceRecognizer = pieceRecognizer;} public boolean step() { if (nempty(rectQueue)) { tryRect(popFirst(rectQueue)); return true; } if (segmenterStream.hasNext()) { IF1> seg = segmenterStream.next(); if (seg == null) return true; List rects = seg.get(inputImage); addAll(rectQueue, rects); if (verbose) print("Segmenter " + seg + " returned: " + rects); return true; } return false; } // returns true if rect not seen before boolean tryRect(Rect r) { r = rectSetHeightToWidth(r); // square it if (!rectsTried.add(r)) return false; // seen BufferedImage board = clipBufferedImage(inputImage, r); String fen; double score ; Pair __66= chessOCR_recognizeBoard_FENAndScore(board, pieceRecognizer); fen = __66.a; score = __66.b; if (verbose) print("Score " + score + " for rect: " + r); best.put(pair(r, fen), score); return true; } void verbose(boolean verbose) { best.verboseNewBest = this.verbose = verbose; } Rect bestBoardLocation() { return pairA(best.get()); } Pair boardLocationAndScore() { return pair(pairA(best.get()), score()); } }static class Pair implements Comparable> { A a; B b; Pair() {} Pair(A a, B b) { this.b = b; this.a = a;} public int hashCode() { return hashCodeFor(a) + 2*hashCodeFor(b); } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Pair)) return false; Pair t = (Pair) o; return eq(a, t.a) && eq(b, t.b); } public String toString() { return "<" + a + ", " + b + ">"; } public int compareTo(Pair p) { if (p == null) return 1; int i = ((Comparable) a).compareTo(p.a); if (i != 0) return i; return ((Comparable) b).compareTo(p.b); } }static class Rect { int x, y, w, h; Rect() {} Rect(Rectangle r) { x = r.x; y = r.y; w = r.width; h = r.height; } Rect(int x, int y, int w, int h) { this.h = h; this.w = w; this.y = y; this.x = x;} Rect(Pt p, int w, int h) { this.h = h; this.w = w; x = p.x; y = p.y; } Rect(Rect r) { x = r.x; y = r.y; w = r.w; h = r.h; } Rectangle getRectangle() { return new Rectangle(x, y, w, h); } public boolean equals(Object o) { return stdEq2(this, o); } public int hashCode() { return stdHash2(this); } public String toString() { return x + "," + y + " / " + w + "," + h; } int x2() { return x + w; } int y2() { return y + h; } boolean contains(Pt p) { return contains(p.x, p.y); } boolean contains(int _x, int _y) { return _x >= x && _y >= y && _x < x+w && _y < y+h; } boolean empty() { return w <= 0 || h <= 0; } }static class Pt { int x, y; Pt() {} Pt(Point p) { x = p.x; y = p.y; } Pt(int x, int y) { this.y = y; this.x = x;} Point getPoint() { return new Point(x, y); } public boolean equals(Object o) { return stdEq2(this, o); } public int hashCode() { return stdHash2(this); } public String toString() { return x + ", " + y; } }// from http://www.jhlabs.com/ip/blurring.html /* Copyright 2006 Jerry Huxtable Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ static class BoxBlurFilter extends AbstractBufferedImageOp implements IF1 { int hRadius; int vRadius; int iterations = 1; BoxBlurFilter() {} BoxBlurFilter(int radius) { hRadius = vRadius = radius; } BoxBlurFilter(int hRadius, int vRadius) { this.vRadius = vRadius; this.hRadius = hRadius;} public BufferedImage get(BufferedImage src) { return filter(src, null); } public BufferedImage filter(BufferedImage src, BufferedImage dst) { int width = src.getWidth(); int height = src.getHeight(); if ( dst == null ) dst = createCompatibleDestImage( src, null ); int[] inPixels = new int[width*height]; int[] outPixels = new int[width*height]; getRGB( src, 0, 0, width, height, inPixels ); for (int i = 0; i < iterations; i++ ) { blur( inPixels, outPixels, width, height, hRadius ); blur( outPixels, inPixels, height, width, vRadius ); } setRGB( dst, 0, 0, width, height, inPixels ); return dst; } static void blur( int[] in, int[] out, int width, int height, int radius ) { int widthMinus1 = width-1; int tableSize = 2*radius+1; int divide[] = new int[256*tableSize]; for ( int i = 0; i < 256*tableSize; i++ ) divide[i] = i/tableSize; int inIndex = 0; for ( int y = 0; y < height; y++ ) { int outIndex = y; int ta = 0, tr = 0, tg = 0, tb = 0; for ( int i = -radius; i <= radius; i++ ) { int rgb = in[inIndex + clamp(i, 0, width-1)]; ta += (rgb >> 24) & 0xff; tr += (rgb >> 16) & 0xff; tg += (rgb >> 8) & 0xff; tb += rgb & 0xff; } for ( int x = 0; x < width; x++ ) { out[ outIndex ] = (divide[ta] << 24) | (divide[tr] << 16) | (divide[tg] << 8) | divide[tb]; int i1 = x+radius+1; if ( i1 > widthMinus1 ) i1 = widthMinus1; int i2 = x-radius; if ( i2 < 0 ) i2 = 0; int rgb1 = in[inIndex+i1]; int rgb2 = in[inIndex+i2]; ta += ((rgb1 >> 24) & 0xff)-((rgb2 >> 24) & 0xff); tr += ((rgb1 & 0xff0000)-(rgb2 & 0xff0000)) >> 16; tg += ((rgb1 & 0xff00)-(rgb2 & 0xff00)) >> 8; tb += (rgb1 & 0xff)-(rgb2 & 0xff); outIndex += height; } inIndex += width; } } }static abstract class F0 { abstract A get(); }static abstract class F1 { abstract B get(A a); }// you still need to implement hasNext() and next() static abstract class IterableIterator implements Iterator, Iterable { public Iterator iterator() { return this; } public void remove() { unsupportedOperation(); } }static class RGB { public float r, g, b; // can't be final cause persistence 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(int rgb) { this(new Color(rgb)); } public RGB(double brightness) { this.r = this.g = this.b = max(0f, min(1f, (float) brightness)); } public RGB(Color color) { this.r = color.getRed()/255f; this.g = color.getGreen()/255f; this.b = color.getBlue()/255f; } public RGB(String hex) { int i = l(hex)-6; r = Integer.parseInt(hex.substring(i, i+2), 16)/255f; g = Integer.parseInt(hex.substring(i+2, i+4), 16)/255f; b = Integer.parseInt(hex.substring(i+4, i+6), 16)/255f; } public float getComponent(int i) { return i == 0 ? r : i == 1 ? g : b; } public 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))); } int asInt() { return getColor().getRGB() & 0xFFFFFF; } int getInt() { return getColor().getRGB() & 0xFFFFFF; } 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(); } int redInt() { return iround(r*255); } int greenInt() { return iround(g*255); } int blueInt() { return iround(b*255); } }// from http://www.jhlabs.com/ip/filters/download.html /* Copyright 2006 Jerry Huxtable Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * A filter which replcaes each pixel by the mimimum of itself and its eight neightbours. */ static class MinimumFilter extends WholeImageFilter { int hRadius; int vRadius; MinimumFilter() { this(1); } MinimumFilter(int radius) { hRadius = vRadius = radius; } MinimumFilter(int hRadius, int vRadius) { this.vRadius = vRadius; this.hRadius = hRadius;} protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { int index = 0; int[] outPixels = new int[width * height]; int y1 = -vRadius/2, y2 = y1+vRadius; int x1 = -hRadius/2, x2 = x1+hRadius; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = 0xffffffff; for (int dy = y1; dy <= y2; dy++) { int iy = y+dy; int ioffset; if (0 <= iy && iy < height) { ioffset = iy*width; for (int dx = x1; dx <= x2; dx++) { int ix = x+dx; if (0 <= ix && ix < width) { pixel = PixelUtils.combinePixels(pixel, inPixels[ioffset+ix], PixelUtils.MIN); } } } } outPixels[index++] = pixel; } } return outPixels; } }static interface MakesBufferedImage { BufferedImage getBufferedImage(); int getWidth(); int getHeight(); }// TODO: Android N seems to deprecate SHA1PRNG // https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html static class PKI { static String getProvider() { return isAndroid() ? /*"AndroidOpenSSL"*/ "BC" : "SUN"; } public static boolean verifySignature(byte[] publicKey, byte[] signature, String file) throws InvalidKeyException, NoSuchProviderException, NoSuchAlgorithmException, IOException, SignatureException, InvalidKeySpecException { Signature sig = initPublicSignature(publicKey); FileInputStream datafis = new FileInputStream(file); BufferedInputStream bufin = new BufferedInputStream(datafis); byte[] buffer = new byte[1024]; while (bufin.available() != 0) { int len = bufin.read(buffer); sig.update(buffer, 0, len); } bufin.close(); return sig.verify(signature); } public static boolean verifySignature(byte[] publicKey, byte[] signature, byte[] data) { try { Signature sig = initPublicSignature(publicKey); sig.update(data); return sig.verify(signature); } catch (Exception __e) { throw rethrow(__e); } } private static Signature initPublicSignature(byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException { Signature sig = Signature.getInstance("SHA1withDSA", getProvider()); PublicKey pub = KeyFactory.getInstance("DSA", getProvider()).generatePublic(new X509EncodedKeySpec(publicKey)); sig.initVerify(pub); return sig; } public static byte[] sign(String file, byte[] privateKey) { try { Signature dsa = initSignature(privateKey); FileInputStream fis = new FileInputStream(file); BufferedInputStream bufin = new BufferedInputStream(fis); byte[] buffer = new byte[1024]; int len; while ((len = bufin.read(buffer)) >= 0) dsa.update(buffer, 0, len); bufin.close(); return dsa.sign(); } catch (Exception __e) { throw rethrow(__e); } } public static byte[] sign(byte[] data, byte[] privateKey) { try { Signature dsa = initSignature(privateKey); dsa.update(data); return dsa.sign(); } catch (Exception __e) { throw rethrow(__e); } } private static Signature initSignature(byte[] privateKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException { Signature dsa = Signature.getInstance("SHA1withDSA", getProvider()); //X509EncodedKeySpec keySpec = new X509EncodedKeySpec(privateKey); EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); PrivateKey priv = KeyFactory.getInstance("DSA", getProvider()).generatePrivate(keySpec); dsa.initSign(priv); return dsa; } public static KeyPair makeKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", getProvider()); // OLD SecureRandom random = SecureRandom.getInstance("SHA1PRNG", getProvider()); // should work on Android? SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); keyGen.initialize(1024, random); return keyGen.generateKeyPair(); } // Standard key pair is for the MACHINE (not the user) public static boolean makeStandardKeyPairIfNecessary() { try { File publicKeyPath = getStandardPublicKeyPath(); File privateKeyPath = getStandardPrivateKeyPath(); if (!publicKeyPath.exists()) { print("PKI: Making standard key pair"); KeyPair keyPair = makeKeyPair(); byte[] privateKey = keyPair.getPrivate().getEncoded(); print("PKI: Private key hex (debug) - " + bytesToHex(privateKey)); saveTextFile(privateKeyPath, privateKeyToString(privateKey)); String publicKey = publicKeyToString(keyPair.getPublic()); saveTextFile(publicKeyPath, publicKey); print("PKI: Standard key pair made!"); print(); printInfo(); return true; } return false; } catch (Exception __e) { throw rethrow(__e); } } static void printInfo() { print("PKI: Machine's public key: " + publicKeyToString(getStandardPublicKey())); print("PKI: Machine's private key in: " + getStandardPrivateKeyPath()); print("PKI: Machine's public key also in: " + getStandardPublicKeyPath()); print("PKI: User's public key: " + publicKeyToString(userPublicKey())); print("PKI: User's private key in: " + userPrivateKeyPath()); print("PKI: User's public key also in: " + userPublicKeyPath()); } public static File getStandardPrivateKeyPath() { return new File(getSecretProgramDir("#1001547"), "Computer-Private-Key"); } public static File userPublicKeyPath() { return new File(getProgramDir("#1001547"), "User-Public-Key"); } public static File userPrivateKeyPath() { return new File(getSecretProgramDir("#1001547"), "User-Private-Key"); } public static File getStandardPublicKeyPath() { return new File(getProgramDir("#1001547"), "Computer-Public-Key"); } public static byte[] getStandardPrivateKey() { makeStandardKeyPairIfNecessary(); return privateKeyFromString(loadTextFile(getStandardPrivateKeyPath())); } public static byte[] getStandardPublicKey() { makeStandardKeyPairIfNecessary(); return publicKeyFromString(loadTextFile(getStandardPublicKeyPath())); } public static byte[] userPrivateKey() { makeUserKeyPairIfNecessary(); return privateKeyFromString(loadTextFile(userPrivateKeyPath())); } public static byte[] userPublicKey() { makeUserKeyPairIfNecessary(); return publicKeyFromString(loadTextFile(userPublicKeyPath())); } private static String publicKeyToString(PublicKey publicKey) { return publicKeyToString(publicKey.getEncoded()); } public static String privateKeyToString(PrivateKey privateKey) { return privateKeyToString(privateKey.getEncoded()); } public static byte[] publicKeyFromString(String key) { return base64decode(dropPrefixMandatory("publickey:", trim(key))); } public static byte[] privateKeyFromString(String key) { return base64decode(dropPrefixMandatory("privatekey:", trim(key))); } public static byte[] signatureFromString(String key) { return base64decode(key); } public static byte[] dataFromString(String text) { return toUtf8(text); } public static String signatureToString(byte[] signature) { return base64encode(signature); } public static String publicKeyToString(byte[] key) { return "publickey:" + base64encode(key); } public static String privateKeyToString(byte[] key) { return "privatekey:" + base64encode(key); } static boolean makeUserKeyPairIfNecessary() { try { File publicKeyPath = userPublicKeyPath(); File privateKeyPath = userPrivateKeyPath(); if (!publicKeyPath.exists()) { print("PKI: Making user key pair"); KeyPair keyPair = makeKeyPair(); byte[] privateKey = keyPair.getPrivate().getEncoded(); print("PKI: Private key hex (debug) - " + bytesToHex(privateKey)); saveTextFile(privateKeyPath, privateKeyToString(privateKey)); String publicKey = publicKeyToString(keyPair.getPublic()); saveTextFile(publicKeyPath, publicKey); print("PKI: User key pair made!"); print(); printInfo(); return true; } return false; } catch (Exception __e) { throw rethrow(__e); } } } static class BetterLabel extends JLabel { boolean autoToolTip = true; BetterLabel() { // Listeners given out to componentPopupMenu must not directly // reference the outer object (-> weak map problem). final WeakReference < BetterLabel > me = new WeakReference(this); componentPopupMenu(this, BetterLabel_menuItems(me)); } BetterLabel(String text) { this(); this.setText(text); } public void setText(String text) { super.setText(text); if (autoToolTip) if (!swic(text, "")) // HTML labels make super-huge, confusing tool tips setToolTipText(nullIfEmpty(text)); } } // moved outside of class for GC reasons (see above) static VF1 BetterLabel_menuItems(final WeakReference me) { return new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, "Copy text to clipboard", new Runnable() { public void run() { try { copyTextToClipboard(me.get().getText()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyTextToClipboard(me.get().getText());"; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, \"Copy text to clipboard\", r {\r\n copyTextToClipboard(me..."; }}; }// elements are put to front when added (not when accessed) static class MRUCache extends LinkedHashMap { int maxSize = 10; MRUCache() {} MRUCache(int maxSize) { this.maxSize = maxSize;} protected boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } Object _serialize() { return ll(maxSize, cloneLinkedHashMap(this)); } void _deserialize(List l) { maxSize = (int) first(l); putAll((LinkedHashMap) second(l)); } }static interface IF0 { A get(); }static abstract class CloseableIterableIterator extends IterableIterator implements AutoCloseable { public void close() throws Exception {} }static interface IF2 { C get(A a, B b); }static interface Producer { public A next(); }static ThreadLocal DynamicObject_loading = new ThreadLocal(); static class DynamicObject { String className; // just the name, without the "main$" /*new XXX - not initializing anymore - may cause problems in the odd legacy program */ LinkedHashMap fieldValues; DynamicObject() {} // className = just the name, without the "main$" DynamicObject(String className) { this.className = className;} Map _map() { return fieldValues; } }static interface IF1 { B get(A a); }static class PersistableThrowable { String className; String msg; String stacktrace; PersistableThrowable() {} PersistableThrowable(Throwable e) { if (e == null) className = "Crazy Null Error"; else { className = getClassName(e).replace('/', '.'); msg = e.getMessage(); stacktrace = getStackTrace_noRecord(e); } } public String toString() { return nempty(msg) ? className + ": " + msg : className; } }static interface IVar { void set(A a); A get(); boolean has(); void clear(); }static class RGBImage implements MakesBufferedImage { transient BufferedImage bufferedImage; File file; int width, height; int[] pixels; RGBImage() {} RGBImage(BufferedImage image) { this(image, null); } RGBImage(BufferedImage image, File file) { this.file = file; bufferedImage = image; width = image.getWidth(); height = image.getHeight(); pixels = new int[width*height]; PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); try { if (!pixelGrabber.grabPixels()) throw new RuntimeException("Could not grab pixels"); cleanPixels(); // set upper byte to 0 } catch (InterruptedException e) { throw new RuntimeException(e); } } /** We assume it's a file name to load from */ RGBImage(String file) throws IOException { this(new File(file)); } RGBImage(Dimension size, Color color) { this(size.width, size.height, color); } RGBImage(Dimension size, RGB color) { this(size.width, size.height, color); } private void cleanPixels() { for (int i = 0; i < pixels.length; i++) pixels[i] &= 0xFFFFFF; } RGBImage(int width, int height, int[] pixels) { this.width = width; this.height = height; this.pixels = pixels; } RGBImage(int w, int h, RGB[] pixels) { this.width = w; this.height = h; this.pixels = asInts(pixels); } public static int[] asInts(RGB[] pixels) { int[] ints = new int[pixels.length]; for (int i = 0; i < pixels.length; i++) ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB(); return ints; } public RGBImage(int w, int h) { this(w, h, Color.black); } RGBImage(int w, int h, RGB rgb) { this.width = w; this.height = h; this.pixels = new int[w*h]; int col = rgb.asInt(); if (col != 0) for (int i = 0; i < pixels.length; i++) pixels[i] = col; } RGBImage(RGBImage image) { this(image.width, image.height, copyPixels(image.pixels)); } RGBImage(int width, int height, Color color) { this(width, height, new RGB(color)); } RGBImage(File file) throws IOException { this(javax.imageio.ImageIO.read(file)); } private static int[] copyPixels(int[] pixels) { int[] copy = new int[pixels.length]; System.arraycopy(pixels, 0, copy, 0, pixels.length); return copy; } public int getIntPixel(int x, int y) { if (inRange(x, y)) return pixels[y * width + x]; else return 0xFFFFFF; } public static RGB asRGB(int packed) { int r = (packed >> 16) & 0xFF; int g = (packed >> 8) & 0xFF; int b = packed & 0xFF; return new RGB(r / 255f, g / 255f, b / 255f); } public RGB getRGB(int x, int y) { if (inRange(x, y)) return asRGB(pixels[y * width + x]); else return new RGB(0xFFFFFF); } /** alias of getRGB - I kept typing getPixel instead of getRGB all the time, so I finally created it */ RGB getPixel(int x, int y) { return getRGB(x, y); } RGB getPixel(Pt p) { return getPixel(p.x, p.y); } public int getWidth() { return width; } public int getHeight() { return height; } int w() { return width; } int h() { return height; } /** Attention: cached, i.e. does not change when image itself changes */ /** @NotNull */ public BufferedImage getBufferedImage() { if (bufferedImage == null) { bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //bufferedImage.setData(Raster.createRaster(new SampleModel())); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) bufferedImage.setRGB(x, y, pixels[y*width+x]); } return bufferedImage; } RGBImage clip(Rect r) { return r == null ? null : clip(r.getRectangle()); } RGBImage clip(Rectangle r) { r = fixClipRect(r); if (r.x == 0 && r.y == 0 && r.width == width && r.height == height) return this; int[] newPixels; try { newPixels = new int[r.width*r.height]; } catch (RuntimeException e) { System.out.println(r); throw e; } for (int y = 0; y < r.height; y++) { System.arraycopy(pixels, (y+r.y)*width+r.x, newPixels, y*r.width, r.width); } return new RGBImage(r.width, r.height, newPixels); } private Rectangle fixClipRect(Rectangle r) { r = r.intersection(new Rectangle(0, 0, width, height)); if (r.isEmpty()) r = new Rectangle(r.x, r.y, 0, 0); return r; } public File getFile() { return file; } /** can now also do GIF (not just JPEG) */ public static RGBImage load(String fileName) { return load(new File(fileName)); } /** can now also do GIF (not just JPEG) */ public static RGBImage load(File file) { try { BufferedImage bufferedImage = javax.imageio.ImageIO.read(file); return new RGBImage(bufferedImage); } catch (IOException e) { throw new RuntimeException(e); } } public int getInt(int x, int y) { return pixels[y * width + x]; } public void save(File file) throws IOException { String name = file.getName().toLowerCase(); String type; if (name.endsWith(".png")) type = "png"; else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) type = "jpeg"; else throw new IOException("Unknown image extension: " + name); javax.imageio.ImageIO.write(getBufferedImage(), type, file); } public static RGBImage dummyImage() { return new RGBImage(1, 1, new int[] {0xFFFFFF}); } public int[] getPixels() { return pixels; } void setPixel(int x, int y, int r, int g, int b) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y*width+x] = (limitToUByte(r) << 16) | (limitToUByte(g) << 8) | limitToUByte(b); } public void setPixel(int x, int y, RGB rgb) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y*width+x] = rgb.asInt(); } public void setPixel(int x, int y, Color color) { setPixel(x, y, new RGB(color)); } void setInt(int x, int y, int rgb) { setPixel(x, y, rgb); } public void setPixel(int x, int y, int rgb) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y*width+x] = rgb; } void setPixel(Pt p, RGB rgb) { setPixel(p.x, p.y, rgb); } void setPixel(Pt p, Color color) { setPixel(p.x, p.y, color); } public RGBImage copy() { return new RGBImage(this); } public boolean inRange(int x, int y) { return x >= 0 && y >= 0 && x < width && y < height; } public Dimension getSize() { return new Dimension(width, height); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RGBImage rgbImage = (RGBImage) o; if (height != rgbImage.height) return false; if (width != rgbImage.width) return false; if (!Arrays.equals(pixels, rgbImage.pixels)) return false; return true; } @Override public int hashCode() { int result = width; result = 31 * result + height; result = 31 * result + Arrays.hashCode(pixels); return result; } public String getHex(int x, int y) { return getPixel(x, y).getHexString(); } public RGBImage clip(int x, int y, int width, int height) { return clip(new Rectangle(x, y, width, height)); } public RGBImage clipLine(int y) { return clip(0, y, width, 1); } public int numPixels() { return width*height; } } // thread-safe except for analysis output fields static class ChessPieceRecognizer { MultiMap profiles; double magicCombineFactor = 0.0012589254117941495; int version = 1; // for analysis transient Pair, Double> best, runnerUp; void load() { long time = sysNow(); profiles = agiBlue_chessPieceProfiles(agiBlue_chessPieceImages_loadedMultiMap(), "version", version); compact(); done2("Loading " + n2(l(profiles), "piece profile"), time); } void compact() { int n = l(profiles); profiles = uniquifyMultiMapValues(profiles); int m = l(profiles); if (m < n) print("Compacted ChessPieceRecognizer " + n + " => " + m); internByteArrayField("sideProfile",values(profiles)); } Pair recognize(BufferedImage img) { ChessPieceProfile1 profile = chessOCR_pieceProfileFromRawImage_1(img); Lowest_withRunnerUp < Pair < String , ChessPieceProfile1 > > lowest = new Lowest_withRunnerUp(); for (Pair __61 : multiMapToPairs(profiles)) { String piece = pairA(__61); ChessPieceProfile1 p = pairB(__61); float sideProfileDiff = floatRatio(byteArraysTotalDiff(profile.sideProfile, p.sideProfile), l(p.sideProfile)); float fillGradeDiff = abs(profile.fillGrade-p.fillGrade); double score = magicCombine(sideProfileDiff, fillGradeDiff); lowest.put(pair(piece, p), score); } best = lowest.pair(); runnerUp = lowest.runnerUpPair(); return !lowest.has() ? null : pair(pairA(lowest.get()), errorToPercent(lowest.score())); } // for humans double errorToPercent(double d) { return 100-d; } double magicCombine(double sideProfileScore, double fillGradeScore) { double sum = sideProfileScore+fillGradeScore/magicCombineFactor; //print("magicCombine " + sideProfileScore + "*" + magicCombineFactor + "+" + fillGradeScore + " = " + sum); return sum; } public String toString() { return shortClassName(this) + "(v" + version + ", " + nProfiles(l(profiles)) + ")"; } ChessOCR_RecognizedBoard recognizeBoard(BufferedImage board) { ChessOCR_RecognizedBoard out = new ChessOCR_RecognizedBoard(); List> squareImages = bufferedImageMNGrid(board, 8, 8); out.pieces = new ArrayList(); for (BufferedImage img : concatLists(squareImages)) out.pieces.add(recognize(img)); out.score = doubleAvg(pairsB(out.pieces)); out.fen = chess_makeFEN(listToChunks(8, pairsA(out.pieces))); return out; } }static class Cache { Object maker; // func -> A A value; long loaded; static boolean debug = false; long changeCount; Lock lock = lock(); Cache() {} Cache(Object maker) { this.maker = maker;} A get() { if (hasLock(lock)) return value; // Must be called from within maker Lock __717 = lock; lock(__717); try { if (loaded == 0) { value = make(); changeCount++; loaded = sysNow(); } return value; } finally { unlock(__717); } } void clear() { Lock __718 = lock; lock(__718); try { if (debug && loaded != 0) print("Clearing cache"); value = null; changeCount++; loaded = 0; } finally { unlock(__718); } } // clear if older than x seconds // 0 does not do anything void clear(double seconds) { Lock __719 = lock; lock(__719); try { if (seconds != 0 && loaded != 0 && sysNow() >= loaded+seconds*1000) clear(); } finally { unlock(__719); } } // override void set(A a) { Lock __720 = lock; lock(__720); try { value = a; ++changeCount; loaded = sysNow(); } finally { unlock(__720); } } A make() { return (A) callF(maker); } } static interface IBWImage { int getWidth(); int getHeight(); float getFloatPixel(int x, int y); }static abstract class VF2 { abstract void get(A a, B b); }static class ChessOCR_RecognizedBoard { List> pieces; double score; String fen; Rect rectInOriginalImage; // optional }static class LetterLayout implements LayoutManager { private String[] lines; private Map map = new TreeMap(); private RC[] rows; private RC[] cols; private Cell[][] cells; private int spacingX = 10, spacingY = 10; private int insetTop, insetBottom, insetLeft, insetRight; private int template; private boolean formWideLeftSide, formWideRightSide; private static final int STALACTITE = 1, LEFT_ALIGNED_ROW = 2, CENTERED_ROW = 3, FORM = 4, RIGHT_ALIGNED_ROW = 5; private boolean debug = false; public void setLeftBorder(int border) { insetLeft = border; } public void setRightBorder(int border) { insetRight = border; } public static JComponent withBorder(JComponent component, int border) { JPanel panel = new JPanel(new LetterLayout("C").setBorder(border)); panel.add("C", component); return panel; } public static JPanel panel(String... lines) { return new JPanel(new LetterLayout(lines)); } public static JPanel stalactitePanel() { return new JPanel(stalactite()); } static class DummyComponent extends JComponent { } /** * info about one matrix cell */ static class Cell { boolean aux = false; // part of a larger cell, but not top-left corner int minWidth, minHeight; Component component; int colspan, rowspan; double weightX, weightY; } /** * info about one matrix row / column */ static class RC { int min; double weightSum; int start; int minEnd; } private LetterLayout(int template) { this.template = template; } public LetterLayout(String... lines) { this.lines = lines; } public void removeLayoutComponent(Component component) { map.values().remove(component); } public void layoutContainer(Container container) { prepareLayout(container); // do layout if (debug) System.out.println("Container size: " + container.getSize()); Insets insets = getInsets(container); for (int r = 0; r < rows.length; r++) { for (int i = 0; i < cols.length;) { Cell cell = cells[i][r]; if (cell.aux) ++i; else { if (cell.component != null) { int x1 = cols[i].start; int y1 = rows[r].start; int x2 = i + cell.colspan < cols.length ? cols[i + cell.colspan].start - spacingX : container.getWidth() - insets.right; int y2 = r + cell.rowspan < rows.length ? rows[r + cell.rowspan].start - spacingY : container.getHeight() - insets.bottom; if (debug) System.out.println("Layouting ("+i+", "+r+", " + cell.component.getClass().getName() + "): "+x1+" "+y1+" "+x2+" "+y2); cell.component.setBounds(x1, y1, x2 - x1, y2 - y1); } i += cells[i][r].colspan; } } } } private void prepareLayout(Container container) { applyTemplate(container); int numRows = lines.length, numCols = lines[0].length(); for (int i = 1; i < numRows; i++) if (lines[i].length() != numCols) throw new IllegalArgumentException("Lines have varying length"); cells = new Cell[numCols][numRows]; rows = new RC[numRows]; cols = new RC[numCols]; for (int r = 0; r < numRows; r++) rows[r] = new RC(); for (int i = 0; i < numCols; i++) cols[i] = new RC(); for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r] = new Cell(); // define cells for (int r = 0; r < numRows; r++) { String line = lines[r]; for (int i = 0; i < numCols;) { Cell cell = cells[i][r]; if (cell.aux) { ++i; continue; } char ch = line.charAt(i); int iNext = i; do ++iNext; while (iNext < numCols && ch == line.charAt(iNext)); int rNext = r; do ++rNext; while (rNext < numRows && ch == lines[rNext].charAt(i)); cell.weightX = numCols == 1 || iNext > i + 1 ? 1.0 : 0.0; cell.weightY = numRows == 1 || rNext > r + 1 ? 1.0 : 0.0; Component c = map.get(String.valueOf(ch)); cell.component = c; if (c != null) { cell.minWidth = c.getMinimumSize().width + spacingX; cell.minHeight = getMinimumHeight(c) + spacingY; } cell.colspan = iNext - i; cell.rowspan = rNext - r; if (cell.colspan == 1) cols[i].min = Math.max(cols[i].min, cell.minWidth); if (cell.rowspan == 1) rows[r].min = Math.max(rows[r].min, cell.minHeight); for (int r2 = r; r2 < rNext; r2++) for (int i2 = i; i2 < iNext; i2++) if (r2 != r || i2 != i) cells[i2][r2].aux = true; i = iNext; } } // determine minStarts, weightSums while (true) { for (int i = 0; i < numCols; i++) { int minStart = i == 0 ? 0 : cols[i - 1].minEnd; double weightStart = i == 0 ? 0.0 : cols[i - 1].weightSum; for (int r = 0; r < numRows; r++) { Cell cell = cells[i][r]; if (!cell.aux) { RC rc = cols[i + cell.colspan - 1]; rc.minEnd = Math.max(rc.minEnd, minStart + cell.minWidth); rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightX); } } } for (int r = 0; r < numRows; r++) { int minStart = r == 0 ? 0 : rows[r - 1].minEnd; double weightStart = r == 0 ? 0.0 : rows[r - 1].weightSum; for (int i = 0; i < numCols; i++) { Cell cell = cells[i][r]; if (!cell.aux) { RC rc = rows[r + cell.rowspan - 1]; rc.minEnd = Math.max(rc.minEnd, minStart + cell.minHeight); rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightY); } } } if (allWeightsZero(cols)) { for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r].weightX = 1.0; continue; } if (allWeightsZero(rows)) { for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r].weightY = 1.0; continue; } break; } // determine row, col starts Insets insets = getInsets(container); determineStarts(cols, insets.left, container.getWidth() - insets.left - insets.right + spacingX, spacingX); determineStarts(rows, insets.top, container.getHeight() - insets.top - insets.bottom + spacingY, spacingY); } private boolean allWeightsZero(RC[] rcs) { for (int i = 0; i < rcs.length; i++) if (rcs[i].weightSum != 0.0) return false; return true; } private static int getMinimumHeight(Component c) { /*if (c instanceof JTextArea) { return (int) ((JTextArea) c).getUI().getRootView((JTextArea) c).getPreferredSpan(javax.swing.text.View.Y_AXIS); }*/ return c.getMinimumSize().height; } private void applyTemplate(Container container) { if (template == STALACTITE) { Component[] components = container.getComponents(); lines = new String[components.length + 2]; map.clear(); for (int i = 0; i < components.length; i++) { String s = String.valueOf(makeIndexChar(i)); map.put(s, components[i]); lines[i] = s; } lines[components.length] = lines[components.length + 1] = " "; } else if (template == FORM) { /* old method of calculating numRows: int numRows = 0; for (String key : map.keySet()) { if (key.length() == 1) numRows = Math.max(numRows, Character.toLowerCase(key.charAt(0))-'a'); }*/ Component[] components = container.getComponents(); int numRows = components.length/2; lines = new String[numRows+2]; map.clear(); for (int row = 0; row < numRows; row++) { String lower = String.valueOf(makeIndexChar(row)); String upper = String.valueOf(makeAlternateIndexChar(row)); Component rightComponent = components[row * 2 + 1]; if (rightComponent instanceof DummyComponent) upper = lower; lines[row] = (formWideLeftSide ? lower + lower : lower) + (formWideRightSide ? upper + upper : upper); map.put(lower, components[row*2]); if (!(rightComponent instanceof DummyComponent)) map.put(upper, rightComponent); } lines[numRows] = lines[numRows+1] = (formWideLeftSide ? " " : " ") + (formWideRightSide ? " " : " "); } else if (template == LEFT_ALIGNED_ROW) { lines = new String[] { makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; } else if (template == CENTERED_ROW) { lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; } else if (template == RIGHT_ALIGNED_ROW) { lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) }; } } private String makeSingleRow(Container container) { Component[] components = container.getComponents(); StringBuffer buf = new StringBuffer(); map.clear(); for (int i = 0; i < components.length; i++) { String s = String.valueOf(makeAlternateIndexChar(i)); map.put(s, components[i]); buf.append(s); } return buf.toString(); } private static void determineStarts(RC[] rcs, int start, int totalSize, int spacing) { int minTotal = rcs[rcs.length - 1].minEnd; double weightSum = rcs[rcs.length - 1].weightSum; //System.out.println("totalSize="+totalSize+",minTotal="+minTotal+",weightSum="+weightSum); int spare = (int) ((totalSize - minTotal) / (weightSum == 0.0 ? 1.0 : weightSum)); int x = start, minSum = 0; double prevWeightSum = 0.0; for (int i = 0; i < rcs.length; i++) { int width = rcs[i].minEnd - minSum + (int) ((rcs[i].weightSum - prevWeightSum) * spare) - spacing; //System.out.println("i="+i+",prevws="+prevWeightSum+",ws="+rcs[i].weightSum+",min="+rcs[i].min+",width="+width); rcs[i].start = x; x += width + spacing; prevWeightSum = rcs[i].weightSum; minSum = rcs[i].minEnd; } } public void addLayoutComponent(String s, Component component) { map.put(s, component); } public Dimension minimumLayoutSize(Container container) { prepareLayout(container); Insets insets = getInsets(container); Dimension result = new Dimension( insets.left + cols[cols.length - 1].minEnd + insets.right - spacingX, insets.top + rows[rows.length - 1].minEnd + insets.bottom - spacingY); return result; } private Insets getInsets(Container container) { Insets insets = container.getInsets(); return new Insets(insets.top + insetTop, insets.left + insetLeft, insets.bottom + insetBottom, insets.right + insetRight); } public Dimension preferredLayoutSize(Container container) { return minimumLayoutSize(container); } public LetterLayout setSpacing(int x, int y) { spacingX = x; spacingY = y; return this; } public LetterLayout setSpacing(int spacing) { return setSpacing(spacing, spacing); } public LetterLayout setBorder(int top, int left, int bottom, int right) { insetTop = top; insetLeft = left; insetBottom = bottom; insetRight = right; return this; } public LetterLayout setBorder(int inset) { return setBorder(inset, inset, inset, inset); } public LetterLayout setTopBorder(int inset) { insetTop = inset; return this; } /** * layout components from top to bottom; add components without letters! */ public static LetterLayout stalactite() { return new LetterLayout(STALACTITE); } /** * layout components from left to right; add components without letters! */ public static LetterLayout leftAlignedRow() { return new LetterLayout(LEFT_ALIGNED_ROW); } public static LetterLayout leftAlignedRow(int spacing) { return leftAlignedRow().setSpacing(spacing); } /** * layout components from left to right, center in container; add components without letters! */ public static LetterLayout centeredRow() { return new LetterLayout(CENTERED_ROW); } public static LetterLayout rightAlignedRow() { return new LetterLayout(RIGHT_ALIGNED_ROW); } public static JPanel rightAlignedRowPanel(JComponent... components) { return makePanel(new LetterLayout(RIGHT_ALIGNED_ROW), components); } private static JPanel makePanel(LetterLayout letterLayout, JComponent[] components) { JPanel panel = new JPanel(letterLayout); for (JComponent component : components) { panel.add(component); } return panel; } /** * layout components from top to bottom; two components per row */ public static LetterLayout form() { LetterLayout letterLayout = new LetterLayout(FORM); letterLayout.formWideLeftSide = true; letterLayout.formWideRightSide = true; return letterLayout; } /** * layout components from top to bottom; two components per row * left column is small, right column is wide */ public static LetterLayout formWideRightSide() { LetterLayout letterLayout = new LetterLayout(FORM); letterLayout.formWideRightSide = true; return letterLayout; } public static Component getDummyComponent() { return new DummyComponent(); } public static JPanel newPanel(String... lines) { return new JPanel(new LetterLayout(lines)); } public boolean isDebug() { return debug; } public void setDebug(boolean debug) { this.debug = debug; } public static char makeIndexChar(int idx) { return (char) ('a' + idx*2); } public static char makeAlternateIndexChar(int idx) { return (char) ('b' + idx*2); } public static char LEFT_CHAR = ',', RIGHT_CHAR = '.'; public static void main(String[] args) { System.out.println((int) makeIndexChar(0)); System.out.println((int) makeAlternateIndexChar(0)); System.out.println((int) makeIndexChar(32000)); System.out.println((int) makeAlternateIndexChar(32000)); System.out.println((int) LEFT_CHAR); System.out.println((int) RIGHT_CHAR); } } abstract static class Surface extends JPanel { public boolean clearSurface = true; private boolean clearOnce = false; Surface() { setDoubleBuffered(false); } Graphics2D createGraphics2D(int width, int height, Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setBackground(getBackground()); if (clearSurface || clearOnce) { g2.clearRect(0, 0, width, height); clearOnce = false; } return g2; } public abstract void render(int w, int h, Graphics2D g); public void paintImmediately(int x,int y,int w, int h) { RepaintManager repaintManager = null; boolean save = true; if (!isDoubleBuffered()) { repaintManager = RepaintManager.currentManager(this); save = repaintManager.isDoubleBufferingEnabled(); repaintManager.setDoubleBufferingEnabled(false); } super.paintImmediately(x, y, w, h); if (repaintManager != null) repaintManager.setDoubleBufferingEnabled(save); } public void paint(Graphics g) { Dimension d = getSize(); Graphics2D g2 = createGraphics2D(d.width, d.height, g); render(d.width, d.height, g2); g2.dispose(); } } static class Q implements AutoCloseable { String name = "Unnamed Queue"; List q = synchroLinkedList(); ReliableSingleThread rst = new ReliableSingleThread(new Runnable() { public void run() { try { _run() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_run()"; }}); volatile boolean retired = false; Q() {} Q(String name) { this.name = name;} void add(Runnable r) { q.add(r); _trigger(); } void _trigger() { rst.name = name; rst.go(); } void add(Object r) { add(toRunnable(r)); } void _run() { Runnable r; while (licensed() && !retired && (r = syncPopFirst(q)) != null) { try { r.run(); } catch (Throwable __e) { _handleException(__e); } } } public void close() { retired = true; } // TODO: interrupt thread void done() {} // legacy function boolean isEmpty() { return q.isEmpty(); } int size() { return q.size(); } }static class MultiMap { Map> data = new HashMap>(); MultiMap() {} MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); } MultiMap(MultiMap map) { putAll(map); } MultiMap(Map> data) { this.data = data;} void put(A key, B value) { synchronized(data) { List list = data.get(key); if (list == null) data.put(key, list = _makeEmptyList()); list.add(value); }} void add(A key, B value) { put(key, value); } void addAll(A key, Collection values) { putAll(key, values); } void addAllIfNotThere(A key, Collection values) { synchronized(data) { for (B value : values) setPut(key, value); }} void setPut(A key, B value) { synchronized(data) { if (!containsPair(key, value)) put(key, value); }} boolean containsPair(A key, B value) { synchronized(data) { return get(key).contains(value); }} void putAll(A key, Collection values) { synchronized(data) { if (nempty(values)) getActual(key).addAll(values); }} void removeAll(A key, Collection values) { synchronized(data) { for (B value : values) remove(key, value); }} List get(A key) { synchronized(data) { List list = data.get(key); return list == null ? Collections. emptyList() : list; }} // returns actual mutable live list // creates the list if not there List getActual(A key) { synchronized(data) { List list = data.get(key); if (list == null) data.put(key, list = _makeEmptyList()); return list; }} void clean(A key) { synchronized(data) { List list = data.get(key); if (list != null && list.isEmpty()) data.remove(key); }} Set keySet() { synchronized(data) { return data.keySet(); }} Set keys() { synchronized(data) { return data.keySet(); }} void remove(A key) { synchronized(data) { data.remove(key); }} void remove(A key, B value) { synchronized(data) { List list = data.get(key); if (list != null) { list.remove(value); if (list.isEmpty()) data.remove(key); } }} void clear() { synchronized(data) { data.clear(); }} boolean containsKey(A key) { synchronized(data) { return data.containsKey(key); }} B getFirst(A key) { synchronized(data) { List list = get(key); return list.isEmpty() ? null : list.get(0); }} void addAll(MultiMap map) { putAll(map); } void putAll(MultiMap map) { synchronized(data) { for (A key : map.keySet()) putAll(key, map.get(key)); }} void putAll(Map map) { synchronized(data) { if (map != null) for (Map.Entry e : map.entrySet()) put(e.getKey(), e.getValue()); }} int keysSize() { synchronized(data) { return l(data); }} // full size - note: expensive operation int size() { synchronized(data) { int n = 0; for (List l : data.values()) n += l(l); return n; }} // expensive operation List reverseGet(B b) { synchronized(data) { List l = new ArrayList(); for (A key : data.keySet()) if (data.get(key).contains(b)) l.add(key); return l; }} Map> asMap() { synchronized(data) { return cloneMap(data); }} boolean isEmpty() { synchronized(data) { return data.isEmpty(); }} // override in subclasses List _makeEmptyList() { return new ArrayList(); } // returns live lists Collection> allLists() { synchronized(data) { return new ArrayList(data.values()); } } List allValues() { return concatLists(values(data)); } Object mutex() { return data; } public String toString() { return "mm" + str(data); } }static class Lowest_withRunnerUp extends Lowest { A runnerUp; double runnerUpScore; boolean put(A a, double score) { boolean change = false; synchronized(this) { if (a != null && isNewBest(score)) { runnerUp = best; runnerUpScore = this.score; best = a; this.score = score; change = true; } } if (change) pcallF(onChange); return change; } synchronized Pair runnerUpPair() { return runnerUp == null ? null : main.pair(runnerUp, runnerUpScore); } }abstract static class SteppableAndBest implements Steppable { Best best = new Best(); boolean verbose = false; A get() { return best.get(); } double score() { return best.score(); } }static interface IVF1 { void get(A a); } abstract static class AbstractBufferedImageOp implements BufferedImageOp, Cloneable { public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) { if ( dstCM == null ) dstCM = src.getColorModel(); return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null); } public Rectangle2D getBounds2D( BufferedImage src ) { return new Rectangle(0, 0, src.getWidth(), src.getHeight()); } public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) { if ( dstPt == null ) dstPt = new Point2D.Double(); dstPt.setLocation( srcPt.getX(), srcPt.getY() ); return dstPt; } public RenderingHints getRenderingHints() { return null; } /** * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance * penalty of BufferedImage.getRGB unmanaging the image. * @param image a BufferedImage object * @param x the left edge of the pixel block * @param y the right edge of the pixel block * @param width the width of the pixel arry * @param height the height of the pixel arry * @param pixels the array to hold the returned pixels. May be null. * @return the pixels * @see #setRGB */ public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) { int type = image.getType(); if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB ) return (int [])image.getRaster().getDataElements( x, y, width, height, pixels ); return image.getRGB( x, y, width, height, pixels, 0, width ); } /** * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance * penalty of BufferedImage.setRGB unmanaging the image. * @param image a BufferedImage object * @param x the left edge of the pixel block * @param y the right edge of the pixel block * @param width the width of the pixel arry * @param height the height of the pixel arry * @param pixels the array of pixels to set * @see #getRGB */ public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) { int type = image.getType(); if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB ) image.getRaster().setDataElements( x, y, width, height, pixels ); else image.setRGB( x, y, width, height, pixels, 0, width ); } public Object clone() { try { return super.clone(); } catch ( CloneNotSupportedException e ) { return null; } } }static class ImageSurfaceSelector extends MouseAdapter { ImageSurface is; Point startingPoint; boolean enabled = true; static boolean verbose = false; ImageSurfaceSelector(ImageSurface is) { this.is = is; if (containsInstance(is.tools, ImageSurfaceSelector.class)) return; is.tools.add(this); is.addMouseListener(this); is.addMouseMotionListener(this); } public void mousePressed(MouseEvent evt) { if (verbose) print("mousePressed"); if (evt.getButton() != MouseEvent.BUTTON1) return; if (enabled) startingPoint = getPoint(evt); } public void mouseDragged(MouseEvent e) { if (verbose) print("mouseDragged"); if (startingPoint != null) { Point endPoint = getPoint(e); Rectangle r = new Rectangle(startingPoint, new Dimension(endPoint.x-startingPoint.x+1, endPoint.y-startingPoint.y+1)); normalize(r); r.width = min(r.width, is.getImage().getWidth()-r.x); r.height = min(r.height, is.getImage().getHeight()-r.y); is.setSelection(r); } if (verbose) print("mouseDragged done"); } public static void normalize(Rectangle r) { if (r.width < 0) { r.x += r.width; r.width = -r.width; } if (r.height < 0) { r.y += r.height; r.height = -r.height; } } public void mouseReleased(MouseEvent e) { if (verbose) print("mouseReleased"); mouseDragged(e); if (getPoint(e).equals(startingPoint)) is.setSelection(null); startingPoint = null; } Point getPoint(MouseEvent e) { return new Point((int) (e.getX()/is.getZoomX()), (int) (e.getY()/is.getZoomY())); } }/* Copyright 2006 Jerry Huxtable Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * Some more useful math functions for image processing. * These are becoming obsolete as we move to Java2D. Use MiscComposite instead. */ static class PixelUtils { public final static int REPLACE = 0; public final static int NORMAL = 1; public final static int MIN = 2; public final static int MAX = 3; public final static int ADD = 4; public final static int SUBTRACT = 5; public final static int DIFFERENCE = 6; public final static int MULTIPLY = 7; public final static int HUE = 8; public final static int SATURATION = 9; public final static int VALUE = 10; public final static int COLOR = 11; public final static int SCREEN = 12; public final static int AVERAGE = 13; public final static int OVERLAY = 14; public final static int CLEAR = 15; public final static int EXCHANGE = 16; public final static int DISSOLVE = 17; public final static int DST_IN = 18; public final static int ALPHA = 19; public final static int ALPHA_TO_GRAY = 20; private static Random randomGenerator = new Random(); /** * Clamp a value to the range 0..255 */ static int _clamp(int c) { if (c < 0) return 0; if (c > 255) return 255; return c; } public static int interpolate(int v1, int v2, float f) { return _clamp((int)(v1+f*(v2-v1))); } public static int brightness(int rgb) { int r = (rgb >> 16) & 0xff; int g = (rgb >> 8) & 0xff; int b = rgb & 0xff; return (r+g+b)/3; } public static boolean nearColors(int rgb1, int rgb2, int tolerance) { int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance; } private final static float hsb1[] = new float[3];//FIXME-not thread safe private final static float hsb2[] = new float[3];//FIXME-not thread safe // Return rgb1 painted onto rgb2 public static int combinePixels(int rgb1, int rgb2, int op) { return combinePixels(rgb1, rgb2, op, 0xff); } public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) { return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha); } public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) { if (op == REPLACE) return rgb1; int a1 = (rgb1 >> 24) & 0xff; int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int a2 = (rgb2 >> 24) & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; switch (op) { case NORMAL: break; case MIN: r1 = Math.min(r1, r2); g1 = Math.min(g1, g2); b1 = Math.min(b1, b2); break; case MAX: r1 = Math.max(r1, r2); g1 = Math.max(g1, g2); b1 = Math.max(b1, b2); break; case ADD: r1 = _clamp(r1+r2); g1 = _clamp(g1+g2); b1 = _clamp(b1+b2); break; case SUBTRACT: r1 = _clamp(r2-r1); g1 = _clamp(g2-g1); b1 = _clamp(b2-b1); break; case DIFFERENCE: r1 = _clamp(Math.abs(r1-r2)); g1 = _clamp(Math.abs(g1-g2)); b1 = _clamp(Math.abs(b1-b2)); break; case MULTIPLY: r1 = _clamp(r1*r2/255); g1 = _clamp(g1*g2/255); b1 = _clamp(b1*b2/255); break; case DISSOLVE: if ((randomGenerator.nextInt() & 0xff) <= a1) { r1 = r2; g1 = g2; b1 = b2; } break; case AVERAGE: r1 = (r1+r2)/2; g1 = (g1+g2)/2; b1 = (b1+b2)/2; break; case HUE: case SATURATION: case VALUE: case COLOR: Color.RGBtoHSB(r1, g1, b1, hsb1); Color.RGBtoHSB(r2, g2, b2, hsb2); switch (op) { case HUE: hsb2[0] = hsb1[0]; break; case SATURATION: hsb2[1] = hsb1[1]; break; case VALUE: hsb2[2] = hsb1[2]; break; case COLOR: hsb2[0] = hsb1[0]; hsb2[1] = hsb1[1]; break; } rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]); r1 = (rgb1 >> 16) & 0xff; g1 = (rgb1 >> 8) & 0xff; b1 = rgb1 & 0xff; break; case SCREEN: r1 = 255 - ((255 - r1) * (255 - r2)) / 255; g1 = 255 - ((255 - g1) * (255 - g2)) / 255; b1 = 255 - ((255 - b1) * (255 - b2)) / 255; break; case OVERLAY: int m, s; s = 255 - ((255 - r1) * (255 - r2)) / 255; m = r1 * r2 / 255; r1 = (s * r1 + m * (255 - r1)) / 255; s = 255 - ((255 - g1) * (255 - g2)) / 255; m = g1 * g2 / 255; g1 = (s * g1 + m * (255 - g1)) / 255; s = 255 - ((255 - b1) * (255 - b2)) / 255; m = b1 * b2 / 255; b1 = (s * b1 + m * (255 - b1)) / 255; break; case CLEAR: r1 = g1 = b1 = 0xff; break; case DST_IN: r1 = _clamp((r2*a1)/255); g1 = _clamp((g2*a1)/255); b1 = _clamp((b2*a1)/255); a1 = _clamp((a2*a1)/255); return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; case ALPHA: a1 = a1*a2/255; return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2; case ALPHA_TO_GRAY: int na = 255-a1; return (a1 << 24) | (na << 16) | (na << 8) | na; } if (extraAlpha != 0xff || a1 != 0xff) { a1 = a1*extraAlpha/255; int a3 = (255-a1)*a2/255; r1 = _clamp((r1*a1+r2*a3)/255); g1 = _clamp((g1*a1+g2*a3)/255); b1 = _clamp((b1*a1+b2*a3)/255); a1 = _clamp(a1+a3); } return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; } }/* Copyright 2006 Jerry Huxtable Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * A filter which acts as a superclass for filters which need to have the whole image in memory * to do their stuff. */ static abstract class WholeImageFilter extends AbstractBufferedImageOp implements IF1 { /** * The output image bounds. */ protected Rectangle transformedSpace; /** * The input image bounds. */ protected Rectangle originalSpace; /** * Construct a WholeImageFilter. */ public WholeImageFilter() { } public BufferedImage get(BufferedImage src) { return filter(src, null); } public BufferedImage filter( BufferedImage src, BufferedImage dst ) { int width = src.getWidth(); int height = src.getHeight(); int type = src.getType(); WritableRaster srcRaster = src.getRaster(); originalSpace = new Rectangle(0, 0, width, height); transformedSpace = new Rectangle(0, 0, width, height); transformSpace(transformedSpace); if ( dst == null ) { ColorModel dstCM = src.getColorModel(); dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null); } WritableRaster dstRaster = dst.getRaster(); int[] inPixels = getRGB( src, 0, 0, width, height, null ); inPixels = filterPixels( width, height, inPixels, transformedSpace ); setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels ); return dst; } /** * Calculate output bounds for given input bounds. * @param rect input and output rectangle */ protected void transformSpace(Rectangle rect) { } /** * Actually filter the pixels. * @param width the image width * @param height the image height * @param inPixels the image pixels * @param transformedSpace the output bounds * @return the output pixels */ protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ); } static class Lowest { A best; double score; transient Object onChange; synchronized boolean isNewBest(double score) { return best == null || score < this.score; } synchronized double bestScore() { return best == null ? Double.NaN : score; } double score() { return bestScore(); } synchronized float floatScore() { return best == null ? Float.NaN : (float) score; } synchronized float floatScoreOr(float defaultValue) { return best == null ? defaultValue : (float) score; } boolean put(A a, double score) { boolean change = false; synchronized(this) { if (a != null && isNewBest(score)) { best = a; this.score = score; change = true; } } if (change) pcallF(onChange); return change; } synchronized A get() { return best; } synchronized boolean has() { return best != null; } synchronized Pair pair() { return best == null ? null : main.pair(best, bestScore()); } }static interface Steppable { public boolean step(); // return false if done }static class Best { A best; double score; boolean verboseNewBest, replaceIfSameScore; transient Object onChange; transient Object stringifier; // func(A) -> S synchronized boolean isNewBest(double score) { return best == null || !isNaN(score) && (replaceIfSameScore ? score >= this.score : score > this.score); } synchronized double bestScore() { return best == null ? minusInfinity() : score; } double score() { return bestScore(); } double getScore() { return bestScore(); } synchronized float floatScoreOr(float defaultValue) { return best == null ? defaultValue : (float) score; } boolean put(Pair p) { return p != null && put(p.a, p.b); } boolean put(A a, double score) { ping(); boolean change = false; if (a != null) synchronized(this) { if (isNewBest(score)) { best = a; this.score = score; change = true; } } if (change) { if (verboseNewBest) print("New best! " + this); pcallF(onChange); } return change; } synchronized A get() { return best; } synchronized boolean has() { return best != null; } synchronized Pair pair() { return main.pair(best, bestScore()); } synchronized A getIfScoreAbove(double x) { return score() >= x ? best : null; } public String toString() { return "Score " + formatDouble_significant2(score, 4) + ": " + callStringifier(stringifier, best); } boolean putAndPrintIfNewBest(A a, double score) { if (!put(a, score)) return false; { print(this); return true; } } } static List myInnerClasses_list=litlist( "ChessOCR_DynChessBoardRecognizer", "VF1", "VF2", "JSection", "Var", "ImageSurface", "RightAlignedLine", "BWImage", "SimpleLiveValue", "jCenteredLiveValueSection_class", "SteppableAndBest", "ReliableSingleThread", "PKIKeyPair", "SingleComponentPanel", "Best", "DynModule", "ImageSurfaceSelector", "WholeImageFilter", "Status", "Rect", "IBWImage", "Pt", "F0", "F1", "IterableIterator", "betterCIComparator_C", "RGB", "F2", "MinimumFilter", "MakesBufferedImage", "Flag", "unstructure_Receiver", "PKI", "IF0", "CloseableIterableIterator", "getOpt_Map", "IF2", "Producer", "IF1", "structure_Data", "IVF1", "IVar", "ChessPieceRecognizer", "Cache", "_MethodCache", "Matches", "structure_ClassInfo", "ChessPieceProfile1", "LiveValue", "LetterLayout", "Surface", "Q", "MultiMap", "Lowest_withRunnerUp", "CriticalAction", "Lowest", "IResourceLoader", "AbstractBufferedImageOp", "Steppable", "HashedByteArray", "ChessOCR_TwoStageRecognizer", "Pair", "BoxBlurFilter", "ChessOCR_RecognizedBoard", "BetterLabel", "componentPopupMenu_Adapter", "MRUCache", "TransferableImage", "DynamicObject", "PersistableThrowable", "Scored", "RGBImage", "PixelUtils"); static List myInnerClasses() { return myInnerClasses_list; } static void cancelTimerOrInterruptThread(Object timer) { if (timer instanceof Thread && !(timer instanceof AutoCloseable)) // AutoCloseable takes precedence interruptThread((Thread) timer); else cancelTimer(timer); } static Field makeAccessible(Field f) { f.setAccessible(true); return f; } static Method makeAccessible(Method m) { m.setAccessible(true); return m; } static Set allInterfacesImplementedBy(Class c) { if (c == null) return null; HashSet set = new HashSet(); allInterfacesImplementedBy_find(c, set); return set; } static void allInterfacesImplementedBy_find(Class c, Set set) { if (c.isInterface() && !set.add(c)) return; do { for (Class intf : c.getInterfaces()) allInterfacesImplementedBy_find(intf, set); } while ((c = c.getSuperclass()) != null); } static Method findStaticMethod(Class c, String method, Object... args) { Class _c = c; while (c != null) { for (Method m : c.getDeclaredMethods()) { if (!m.getName().equals(method)) continue; if ((m.getModifiers() & Modifier.STATIC) == 0 || !findStaticMethod_checkArgs(m, args)) continue; return m; } c = c.getSuperclass(); } return null; } static boolean findStaticMethod_checkArgs(Method m, Object[] args) { Class[] types = m.getParameterTypes(); if (types.length != args.length) return false; for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) return false; return true; } static Border getBorder(final JComponent c) { return c == null ? null : swing(new F0() { Border get() { try { return c.getBorder(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getBorder();"; }}); } static String fsi(String id) { return formatSnippetID(id); } static List quoteAll(Collection l) { List x = new ArrayList(); for (String s : l) x.add(quote(s)); return x; } static int _hashCode(Object a) { return a == null ? 0 : a.hashCode(); } static boolean arraysEqual(Object[] a, Object[] b) { if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) if (neq(a[i], b[i])) return false; return true; } static boolean byteArrayEquals(byte[] a, byte[] b) { return Arrays.equals(a, b); } static int arrayHashCode(byte[] a) { return Arrays.hashCode(a); } static JLabel setImage(final BufferedImage img, final JLabel lbl) { if (lbl != null) { swing(new Runnable() { public void run() { try { lbl.setIcon(imageIcon(img)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lbl.setIcon(imageIcon(img));"; }}); } return lbl; } static JLabel setImage(JLabel lbl, BufferedImage img) { return setImage(img, lbl); } static JLabel setImage(final String imageID, final JLabel lbl) { if (lbl != null) { swing(new Runnable() { public void run() { try { lbl.setIcon(imageIcon(imageID)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lbl.setIcon(imageIcon(imageID));"; }}); } return lbl; } static JLabel setImage(JLabel lbl, String imageID) { return setImage(imageID, lbl); } static void componentPopupMenu2(A component, final VF2 menuMaker) { final WeakReference < A > ref = new WeakReference(component); componentPopupMenu(component, new VF1() { public void get(JPopupMenu menu) { try { callF(menuMaker, ref.get(), menu); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(menuMaker, ref!, menu);"; }}); } // onDrop: voidfunc(File), but may also return false static A jHandleFileDrop(A c, final Object onDrop) { new DropTarget(c, new DropTargetAdapter() { public void drop(DropTargetDropEvent e) { try { Transferable tr = e.getTransferable(); DataFlavor[] flavors = tr.getTransferDataFlavors(); for (DataFlavor flavor : flavors) { if (flavor.isFlavorJavaFileListType()) { e.acceptDrop(e.getDropAction()); File file = first((List) tr.getTransferData(flavor)); if (file != null && !isFalse(callF(onDrop, file))) e.dropComplete(true); return; } } } catch (Throwable __e) { _handleException(__e); } e.rejectDrop(); } }); return c; } static A jHandleFileDrop(Object onDrop, A c) { return jHandleFileDrop(c, onDrop); } static JFrame showFullScreen(JComponent c) { return showFullScreen(defaultFrameTitle(), c); } static JFrame showFullScreen(final String title, final JComponent c) { return (JFrame) swingAndWait(new F0() { Object get() { try { GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice(); if (!gd.isFullScreenSupported()) throw fail("No full-screen mode supported!"); boolean dec = JFrame.isDefaultLookAndFeelDecorated(); if (dec) JFrame.setDefaultLookAndFeelDecorated(false); final JFrame window = new JFrame(title); window.setUndecorated(true); if (dec) JFrame.setDefaultLookAndFeelDecorated(true); registerEscape(window, new Runnable() { public void run() { try { disposeWindow(window) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeWindow(window)"; }}); window.add(wrap(c)); gd.setFullScreenWindow(window); // Only this hides the task bar in Peppermint Linux w/Substance for (int i = 100; i <= 1000; i += 100) awtLater(i, new Runnable() { public void run() { try { window.toFront() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "window.toFront()"; }}); return window; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()\r\n ..."; }}); } static void selectFile(final String msg, VF1 action) { selectFile(msg, userDir(), action); } static void selectFile(final String msg, final File defaultFile, VF1 action) { inputFilePath(msg, defaultFile, action); } static void copyImageToClipboard(Image img) { TransferableImage trans = new TransferableImage(img); Toolkit.getDefaultToolkit().getSystemClipboard().setContents( trans, null); vmBus_send("newClipboardContents", img); print("Copied image to clipboard (" + img.getWidth(null) + "*" + img.getHeight(null) + " px)"); } static JComponent selectImageSnippet(VF1 onSelect) { return selectSnippetID_v1(onSelect); } static JComponent selectImageSnippet(String defaultID, VF1 onSelect) { return selectSnippetID_v1(defaultID, onSelect); } static BufferedImage cloneClipBufferedImage(BufferedImage src, Rectangle clip) { return cloneBufferedImage(clipBufferedImage(src, clip)); } static BufferedImage cloneClipBufferedImage(BufferedImage src, Rect r) { return cloneBufferedImage(clipBufferedImage(src, r)); } static BufferedImage cloneClipBufferedImage(BufferedImage src, int x, int y, int w, int h) { return cloneBufferedImage(clipBufferedImage(src, x, y, w, h)); } static BufferedImage getImageFromClipboard() { try { Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (t == null) return null; List l = (List) (getTransferData(t, DataFlavor.javaFileListFlavor)); if (nempty(l)) return loadImage2(first(l)); if (t.isDataFlavorSupported(DataFlavor.imageFlavor)) return (BufferedImage) t.getTransferData(DataFlavor.imageFlavor); return imageFromDataURL(getTextFromClipboard()); } catch (Exception __e) { throw rethrow(__e); } } static void popup(final Throwable throwable) { popupError(throwable); } static void popup(final String msg) { print(msg); SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, msg); } }); } static A _print(String s, A a) { return print(s, a); } static A _print(A a) { return print(a); } static void _print() { print(); } static boolean hasTransparency(BufferedImage img) { return img.getColorModel().hasAlpha(); } static A repaint(A c) { if (c != null) c.repaint(); return c; } static boolean imagesHaveSameSize(BufferedImage a, BufferedImage b) { return a != null && b != null && a.getWidth() == b.getWidth() && a.getHeight() == b.getHeight(); } static Container getParent(final Component c) { return c == null ? null : swing(new F0() { Container get() { try { return c.getParent(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getParent();"; }}); } static JScrollPane enclosingScrollPane(Component c) { while (c.getParent() != null && !(c.getParent() instanceof JViewport) && c.getParent().getComponentCount() == 1) c = c.getParent(); // for jscroll_center if (!(c.getParent() instanceof JViewport)) return null; c = c.getParent().getParent(); return c instanceof JScrollPane ? (JScrollPane) c : null; } // independent timer static void awtLater(int delay, final Object r) { swingLater(delay, r); } static void awtLater(Object r) { swingLater(r); } // dependent timer (runs only when component is visible) static void awtLater(JComponent component, int delay, Object r) { installTimer(component, r, delay, delay, false); } static void awtLater(JFrame frame, int delay, Object r) { awtLater(frame.getRootPane(), delay, r); } static void showFullScreenImageSurface(BufferedImage img) { showFullScreen(jscroll_centered(disposeFrameOnClick(new ImageSurface(img)))); } static void add(BitSet bs, int i) { bs.set(i); } static boolean add(Collection c, A a) { return c != null && c.add(a); } static void add(Container c, Component x) { addToContainer(c, x); } static void fillArrayUnlessZero(byte[] a, byte value) { if (value != 0) Arrays.fill(a, value); } static void fillArrayUnlessZero(int[] a, int value) { if (value != 0) Arrays.fill(a, value); } static void fillArrayUnlessZero(float[] a, float value) { if (value != 0) Arrays.fill(a, value); } static boolean inRange(int x, int n) { return x >= 0 && x < n; } static boolean inRange(int x, int a, int b) { return x >= a && x < b; } static double averageBrightness(BufferedImage img) { return new BWImage(img).averageBrightness(); } static int limitToUByte(int i) { return max(0, min(255, i)); } static File loadLibrary(String snippetID) { return loadBinarySnippet(snippetID); } static Class _run(String progID, String... args) { Class main = hotwire(progID); callMain(main, args); return main; } static void cancelAndInterruptThread(Thread t) { if (t == null) return; cancelThread(t); t.interrupt(); } static void removeAll(Collection a, Collection b) { if (a != null && b != null) a.removeAll(b); } static void removeAll(Map a, Collection b) { if (a != null && b != null) for (A x : b) a.remove(x); } static A _revalidate(A c) { return revalidate(c); } static void _revalidate(JFrame f) { revalidate(f); } static void _revalidate(JInternalFrame f) { revalidate(f); } static Container _getParent(Component c) { return getParent(c); } static Flag dm_initErrorHandling_flag = new Flag(); static void dm_initErrorHandling() { raiseFlagAndDo(dm_initErrorHandling_flag, new Runnable() { public void run() { try { _handleException_addHandler("dm_initErrorHandling_handler"); assertNull(_onRegisterThread); _onRegisterThread = new VF1() { public void get(Thread t) { try { DynModule m = dm_currentModule(); if (m == null) printStackTrace("New thread made outside of a module"); else m.ownTimer(t); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "DynModule m = dm_currentModule();\r\n if (m == null) printStackTrace(\"New ..."; }}; _threadInfo_makers.add(new VF1() { public void get(Map map) { try { mapPut(map, "dm_currentModule_value", dm_currentModule()) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "mapPut(map, 'dm_currentModule_value, dm_currentModule())"; }}); _threadInheritInfo_retrievers.add(new VF1() { public void get(Map map) { try { Object mod = map.get("dm_currentModule_value"); if (mod instanceof DynModule) dm_currentModule_value.set(new WeakReference((DynModule) mod)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "O mod = map.get('dm_currentModule_value);\r\n if (mod instanceof DynModule..."; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_handleException_addHandler(f dm_initErrorHandling_handler);\r\n \r\n asser..."; }}); } static void dm_initErrorHandling_handler(Throwable e) { DynModule m = dm_currentModule(); if (m == null) print("Weird: Error outside of module"); else m.setField("_error" , persistableThrowable(e)); } static void setMainDesktopPane(JDesktopPane desktop) { mainDesktopPane_value = desktop; } static A getCreatorOpt(String field) { return (A) getOpt(creator(), field); } static A possiblyInternalFrameTitle(A c, String title) { JInternalFrame f = getInternalFrame(c); if (f != null) internalFrameTitle(f, title); else frameTitle(getFrame(c), title); return c; } static String possiblyInternalFrameTitle(Component c) { JInternalFrame f = getInternalFrame(c); return f != null ? internalFrameTitle(f) : frameTitle(getFrame(c)); } static void ownResource(AutoCloseable c) { _registerAutoCloseable(c); } static List getAndClearList(Collection l) { if (l == null) return emptyList(); synchronized(collectionMutex(l)) { List out = cloneList(l); l.clear(); return out; } } static Map getAndClearMap(Map map) { if (map == null) return emptyMap(); synchronized(collectionMutex(map)) { Map out = cloneMap(map); map.clear(); return out; } } static Object pcallFInRealOrMyMC(final Object realm, final Object f, final Object... args) { try { return callFInRealOrMyMC(realm, f, args); } catch (Throwable __e) { _handleException(__e); } return null; } static A pcallFInRealOrMyMC(Object realm, F0 f) { try { return f == null ? null : f.get(); } catch (Throwable __e) { return null; } } static B pcallFInRealOrMyMC(Object realm, F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static Rect dm_getBounds(Object module) { return shallowCloneToClass(Rect.class,call(dm_getStem(module), "getFrameRect")); } static Rect dm_getBounds() { return dm_getBounds(dm_current()); } static boolean hasMethod_onTypes(Object o, String method, Class... argTypes) { return findMethod_precise_onTypes(o, method, argTypes) != null; } static void dm_onTopInput_q(final VF1 r) { final DynModule m = dm_current_mandatory(); dm_onTopInput(new VF1() { public void get(final String s) { try { m.q().add(new Runnable() { public void run() { try { callF(r, s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(r, s);"; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switch to m.q();\r\n callF(r, s);"; }}); } static AutoCloseable combineAutoCloseables(final AutoCloseable a, final AutoCloseable b) { return a == null ? b : b == null ? a : new AutoCloseable() { public String toString() { return "a.close(); b.close();"; } public void close() throws Exception { a.close(); b.close(); }}; } static AutoCloseable combineAutoCloseables(AutoCloseable a, AutoCloseable b, AutoCloseable c, AutoCloseable... more) { return combineAutoCloseables(concatLists(ll(a, b, c), asList(more))); } static AutoCloseable combineAutoCloseables(Iterable l) { return foldl(new F2() { AutoCloseable get(AutoCloseable a, AutoCloseable b) { try { return combineAutoCloseables(a,b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "combineAutoCloseables(a,b)"; }}, null, l); } static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) { return print_byThread().get() == null ? tempInterceptPrint(f) : null; } static ThreadLocal realMC_tl_tl = new ThreadLocal(); static ThreadLocal realMC_tl() { return realMC_tl_tl; } static AutoCloseable tempLock(final Lock lock) { if (lock == null) return null; lock(lock); return new AutoCloseable() { public String toString() { return "unlock(lock);"; } public void close() throws Exception { unlock(lock); }}; } static boolean addIfNotThere(Collection c, A a) { return setAdd(c, a); } // action = runnable or method name static void onUpdateAndNow(JComponent c, final Object r) { onUpdate(c, r); callF(r); } static void onUpdateAndNow(List l, Object r) { for (JComponent c : l) onUpdate(c, r); callF(r); } static void zeroAllFieldsOfTypeExcept(Object o, Class type, String... exceptions) { zeroAllFieldsOfTypeExcept(o, type, asSet(exceptions)); } static void zeroAllFieldsOfTypeExcept(Object o, Class type, Collection exceptions) { Set set = asSet(exceptions); for (String field : allFields(o)) if (!set.contains(field) && instanceOf(getOpt(o, field), type)) set(o, field, null); } static void internalFramePopupMenuFromActions_threaded(Container f, List actions) { if (!(f instanceof JInternalFrame)) return; for (final AbstractAction a : unnull(actions)) if (a != null) internalFramePopupMenuItem(((JInternalFrame) f), str(a.getValue(Action.NAME)), runnableThread(new Runnable() { public void run() { try { callAction(a) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callAction(a)"; }})); } static LinkedHashSet asLinkedHashSet(A[] array) { LinkedHashSet set = new LinkedHashSet(); for (A o : array) if (o != null) set.add(o); return set; } static LinkedHashSet asLinkedHashSet(Collection l) { if (l instanceof LinkedHashSet) return (LinkedHashSet) l; LinkedHashSet set = new LinkedHashSet(); for (A o : l) if (o != null) set.add(o); return set; } static List splitAtSpace(String s) { return empty(s) ? emptyList() : asList(s.split("\\s+")); } static Set allFields(Object o) { TreeSet fields = new TreeSet(); Class _c = _getClass(o); do { for (Field f : _c.getDeclaredFields()) fields.add(f.getName()); _c = _c.getSuperclass(); } while (_c != null); return fields; } static void dm_boolFieldMenuItem(Container frame, final String field, final Object... __) { final DynModule m = dm_current_mandatory(); final String humanized = humanizeFormLabel(field); internalFrameTitlePopupMenu(((JInternalFrame) frame), new VF1() { public void get(JPopupMenu menu) { try { menu.add(jCheckBoxMenuItem(humanized, (boolean) _get(m, field), new VF1() { public void get(Boolean b) { try { m.setField(field, b); callF(optPar(__, "onSet")); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.setField(field, b);\r\n callF(optPar(_, 'onSet));"; }})); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "menu.add(jCheckBoxMenuItem(humanized, (bool) _get(m, field), voidfunc(bool b)..."; }}); } static void dm_intFieldMenuItem(Container frame, final String field, final Object... __) { final DynModule m = dm_current_mandatory(); final String humanized = humanizeFormLabel(field); internalFramePopupMenuItem(((JInternalFrame) frame), humanizeFormLabel(field) + "...", new Runnable() { public void run() { try { final JTextField tf = jtextfield(get(m, field)); showFormTitled(or2(stringOptPar(__, "formTitle"), "Set " + humanized), humanized + ":", tf, new Runnable() { public void run() { try { m.setField(field, parseInt(gtt(tf))); callF(optPar(__, "onSet")); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.setField(field, parseInt(gtt(tf)));\r\n callF(optPar(__, \"onSet\"));"; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JTextField tf = jtextfield(get(m, field));\r\n showFormTitled(or2(stri..."; }}); } static void dm_doubleFieldMenuItem(Container frame, final String field, final Object... __) { final DynModule m = dm_current_mandatory(); final String humanized = humanizeFormLabel(field); internalFramePopupMenuItem(((JInternalFrame) frame), humanizeFormLabel(field) + "...", new Runnable() { public void run() { try { final JTextField tf = jtextfield(get(m, field)); showFormTitled(or2(stringOptPar(__, "formTitle"), "Set " + humanized), humanized + ":", tf, new Runnable() { public void run() { try { m.setField(field, parseDouble(gtt(tf))); callF(optPar(__, "onSet")); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.setField(field, parseDouble(gtt(tf)));\r\n callF(optPar(__, \"onSet\"));"; }}); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JTextField tf = jtextfield(get(m, field));\r\n showFormTitled(or2(stri..."; }}); } static void dm_stringFieldMenuItem(Container frame, final String field, final Object... __) { final DynModule m = dm_current_mandatory(); internalFramePopupMenuItem(((JInternalFrame) frame), humanizeFormLabel(field) + "...", new Runnable() { public void run() { try { AutoCloseable __1242 = m.enter(); try { dm_stringFieldDialog(field, __); } finally { _close(__1242); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "AutoCloseable __1242 = m.enter(); try {\r\n dm_stringFieldDialog(field, __);..."; }}); } static Q dm_startQ() { Q q = startQ(); q.rst.enter = dm_rEnter(dm_current_mandatory()); dm_ownResource(q); return q; } static JComponent dm_noVisualisation() { return setToolTip("Module has no visualization", jimage("#1101480")); } static String snippetTitle(String id) { return getSnippetTitle(id); } static String snippetTitle(long id) { return getSnippetTitle(id); } static Class mainClass() { return getMainClass(); } static Class mainClass(Object o) { return getMainClass(o); } static Set _registerTimer_list = newWeakHashSet(); static void _registerTimer_original(java.util.Timer timer) { _registerTimer_list.add(timer); } static void cleanMeUp__registerTimer() { cancelTimers(getAndClearList(_registerTimer_list)); } static List syncLinkedList() { return synchroLinkedList(); } static A popFirst(List l) { if (empty(l)) return null; A a = first(l); l.remove(0); return a; } static A popFirst(Collection l) { if (empty(l)) return null; A a = first(l); l.remove(a); return a; } static Rect rectSetHeightToWidth(Rect r) { return r == null ? null : rect(r.x, r.y, r.w, r.w); } // returns static Pair chessOCR_recognizeBoard_FENAndScore(BufferedImage board, ChessPieceRecognizer pieceRecognizer) { List> recognized = chessOCR_recognizeBoard(board, pieceRecognizer); return pair(chess_makeFEN(listToChunks(pairsA(recognized), 8)), doubleAvg(pairsB(recognized))); } static int hashCodeFor(Object a) { return a == null ? 0 : a.hashCode(); } static boolean stdEq2(Object a, Object b) { if (a == null) return b == null; if (b == null) return false; if (a.getClass() != b.getClass()) return false; for (String field : allFields(a)) if (neq(getOpt(a, field), getOpt(b, field))) return false; return true; } static int stdHash2(Object a) { if (a == null) return 0; return stdHash(a, toStringArray(allFields(a))); } static UnsupportedOperationException unsupportedOperation() { throw new UnsupportedOperationException(); } static int asInt(Object o) { return toInt(o); } static byte[] base64decode(String s) { byte[] alphaToInt = base64decode_base64toint; int sLen = s.length(); int numGroups = sLen/4; if (4*numGroups != sLen) throw new IllegalArgumentException( "String length must be a multiple of four."); int missingBytesInLastGroup = 0; int numFullGroups = numGroups; if (sLen != 0) { if (s.charAt(sLen-1) == '=') { missingBytesInLastGroup++; numFullGroups--; } if (s.charAt(sLen-2) == '=') missingBytesInLastGroup++; } byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; // Translate all full groups from base64 to byte array elements int inCursor = 0, outCursor = 0; for (int i=0; i> 4)); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); result[outCursor++] = (byte) ((ch2 << 6) | ch3); } // Translate partial group, if present if (missingBytesInLastGroup != 0) { int ch0 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); int ch1 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); if (missingBytesInLastGroup == 1) { int ch2 = base64decode_base64toint(s.charAt(inCursor++), alphaToInt); result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); } } // assert inCursor == s.length()-missingBytesInLastGroup; // assert outCursor == result.length; return result; } static int base64decode_base64toint(char c, byte[] alphaToInt) { int result = alphaToInt[c]; if (result < 0) throw new IllegalArgumentException("Illegal character " + c); return result; } static final byte base64decode_base64toint[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; static String dropPrefixMandatory(String prefix, String s) { if (s.startsWith(prefix)) return s.substring(prefix.length()); else throw fail("Prefix " + prefix + " not found in: " + s); } static LinkedHashMap cloneLinkedHashMap(Map map) { return map == null ? new LinkedHashMap() : new LinkedHashMap(map); } static long sysNow() { ping(); return System.nanoTime()/1000000; } // TODO: merge identical profiles static MultiMap agiBlue_chessPieceProfiles(MultiMap images, Object... __) { return mapMultiMapValues(img -> chessOCR_pieceProfileFromRawImage_1(img, __), images); } static MultiMap agiBlue_chessPieceProfiles() { return agiBlue_chessPieceProfiles(agiBlue_chessPieceImages_loadedMultiMap()); } static ThreadLocal> agiBlue_chessPieceImages_loadedMultiMap_cache = new ThreadLocal(); static MultiMap agiBlue_chessPieceImages_loadedMultiMap() { if (agiBlue_chessPieceImages_loadedMultiMap_cache.get() != null) return agiBlue_chessPieceImages_loadedMultiMap_cache.get(); MultiMap mm = ciMultiMap(); for (Pair __251 : chessPieceImagesFromAGIBlue()) { String imageID = pairA(__251); String piece = pairB(__251); mm.put(piece, loadImage2(imageID)); } return mm; } static int done2_minPrint = 10; static long done2(long startTime, String desc) { return done2(startTime, desc, done2_minPrint); } static long done2(long startTime, String desc, int minPrint) { long time = sysNow()-startTime; saveTiming_noPrint(time); if (time >= minPrint) print(desc + " [" + time + " ms]"); return time; } static long done2(String desc, long startTime) { return done2(startTime, desc); } static long done2(long startTime) { return done2(startTime, ""); } static MultiMap uniquifyMultiMapValues(MultiMap mm) { return mm == null ? null : new MultiMap(mapValues("uniquify",mm.data)); } static void internByteArrayField(String field, Collection l) { HashMap map = new HashMap(); for (Object o : unnull(l)) { byte[] value = (byte[]) (getOpt(o, field)); if (value == null) continue; HashedByteArray hashed = new HashedByteArray(value); byte[] existing = map.get(hashed); if (existing != null) setOpt(o, field, existing); else map.put(hashed, value); } } static List> multiMapToPairs(MultiMap mm) { List> out = new ArrayList(); for (A key : keys(mm)) for (B value : mm.get(key)) out.add(pair(key, value)); return out; } static B pairB(Pair p) { return p == null ? null : p.b; } static float floatRatio(float x, float y) { return y == 0 ? 0 : x/y; } static long byteArraysTotalDiff(byte[] a, byte[] b) { long diff = 0; int n = l(a); assertEquals("array length", n, l(b)); for (int i = 0; i < n; i++) diff += abs(((int) a[i])-b[i]); return diff; } static String nProfiles(long n) { return n2(n, "profile"); } static String nProfiles(Collection l) { return nProfiles(l(l)); } static boolean hasLock(Lock lock) { return ((ReentrantLock) lock).isHeldByCurrentThread(); } static Color getBackground(final Component c) { return c == null ? null : swing(new F0() { Color get() { try { return c.getBackground(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret c.getBackground();"; }}); } static A syncPopFirst(List l) { if (empty(l)) return null; synchronized(l) { A a = first(l); l.remove(0); return a; } } static void remove(List l, int i) { if (l != null && i >= 0 && i < l(l)) l.remove(i); } static void remove(Collection l, A a) { if (l != null) l.remove(a); } static Set keySet(Map map) { return map == null ? new HashSet() : map.keySet(); } static Set keySet(Object map) { return keys((Map) map); } static Set keySet(MultiMap mm) { return mm.keySet(); } static A reverseGet(List l, int idx) { if (l == null || idx < 0) return null; int n = l(l); return idx < n ? l.get(n-1-idx) : null; } static boolean containsInstance(Iterable i, Class c) { if (i != null) for (Object o : i) if (isInstanceX(c, o)) return true; return false; } static boolean isNaN(double d) { return Double.isNaN(d); } static double minusInfinity() { return negativeInfinity(); } static float getScore(Scored s) { return s == null ? 0 : s.score; } static String formatDouble_significant2(double d, int digits) { try { digits -= max(0, Math.floor(Math.log10(abs(d))+1)); return formatDouble(d, digits); } catch (Throwable _e) { print("Had number: " + d + ", digits: " + digits); throw rethrow(_e); } } static String callStringifier(Object stringifier, Object o) { return stringifier != null ? str(callF(stringifier, o)) : str(o); } static ArrayList litlist(A... a) { ArrayList l = new ArrayList(a.length); for (A x : a) l.add(x); return l; } static Object _onAWTEnter_f; static AutoCloseable _onAWTEnter() { return (AutoCloseable) callF(_onAWTEnter_f); } static void interruptThread(Thread t) { if (t == null) return; t.interrupt(); URLConnection c = (URLConnection) (vm_generalSubMap("URLConnection per thread").get(t)); if (c != null) { try { print("Closing URLConnection of interrupted thread."); call(c, "disconnect"); } catch (Throwable __e) { _handleException(__e); }} } static void cancelTimer(javax.swing.Timer timer) { if (timer != null) timer.stop(); } static void cancelTimer(java.util.Timer timer) { if (timer != null) timer.cancel(); } static void cancelTimer(Object o) { if (o instanceof java.util.Timer) cancelTimer((java.util.Timer) o); else if (o instanceof javax.swing.Timer) cancelTimer((javax.swing.Timer) o); else if (o instanceof AutoCloseable) { try { ((AutoCloseable) o).close(); } catch (Throwable __e) { _handleException(__e); }} } static String defaultFrameTitle() { return autoFrameTitle(); } static void defaultFrameTitle(String title) { autoFrameTitle_value = title; } static void registerEscape(JFrame frame, final Runnable r) { registerEscape_rootPane(frame.getRootPane(), r); } static void inputFilePath(final String msg, final Object action) { inputFilePath(msg, userDir(), action); } // action: voidfunc(File) static void inputFilePath(final String msg, final File defaultFile, final Object action) { swingLater(new Runnable() { public void run() { try { final JTextField tfPath = jtextfield(f2s(or(defaultFile, userDir()))); String title = joinStrings(" | ", msg, programName()); JComponent form = showFormTitled(title, unnull(msg), centerAndEast(tfPath, jbutton("Browse...", new Runnable() { public void run() { try { JFileChooser fileChooser = new JFileChooser(getTextTrim(tfPath)); if (fileChooser.showOpenDialog(tfPath) == JFileChooser.APPROVE_OPTION) { tfPath.setText(fileChooser.getSelectedFile().getAbsolutePath()); tfPath.requestFocus(); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JFileChooser fileChooser = new JFileChooser(getTextTrim(tfPath));\r\n if..."; }})), new Runnable() { public void run() { try { callF(action, new File(getTextTrim(tfPath))) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(action, new File(getTextTrim(tfPath)))"; }}); renameSubmitButton(form, "OK"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final JTextField tfPath = jtextfield(f2s(or(defaultFile, userDir())));\r\n S..."; }}); } static JComponent selectSnippetID_v1(final VF1 onSelect) { return selectSnippetID_v1("#", onSelect); } static JComponent selectSnippetID_v1(String defaultID, final VF1 onSelect) { final JTextField tfSnippetID = jtextfield(defaultID); if (eq(defaultID, "#")) moveCaretToEnd(tfSnippetID); JComponent panel; renameSubmitButton(panel = showTitledForm("Select Snippet", "Snippet ID:", tfSnippetID, runnableThread(new Runnable() { public void run() { try { callF(onSelect, fsI(getTextTrim(tfSnippetID))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onSelect, fsI(getTextTrim(tfSnippetID)));"; }})), "Select snippet"); return panel; } static BufferedImage cloneBufferedImage(BufferedImage image) { return copyImage(image); } static Object getTransferData(Transferable t, DataFlavor flavor) { try { return t != null && t.isDataFlavorSupported(flavor) ? t.getTransferData(flavor) : null; } catch (Exception __e) { throw rethrow(__e); } } static BufferedImage imageFromDataURL(String url) { String pref = "base64,"; int i = indexOf(url, pref); if (i < 0) return null; return decodeImage(base64decode(substring(url, i+l(pref)))); } static String getTextFromClipboard() { try { Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) return (String) transferable.getTransferData(DataFlavor.stringFlavor); return null; } catch (Exception __e) { throw rethrow(__e); } } static void popupError(final Throwable throwable) { throwable.printStackTrace(); // print stack trace to console for the experts SwingUtilities.invokeLater(new Runnable() { public void run() { String text = throwable.toString(); //text = cutPrefix(text, "java.lang.RuntimeException: "); JOptionPane.showMessageDialog(null, text); } }); } // first delay = delay static Timer installTimer(JComponent component, Object r, long delay) { return installTimer(component, r, delay, delay); } // first delay = delay static Timer installTimer(RootPaneContainer frame, long delay, Object r) { return installTimer(frame.getRootPane(), r, delay, delay); } // first delay = delay static Timer installTimer(JComponent component, long delay, Object r) { return installTimer(component, r, delay, delay); } static Timer installTimer(JComponent component, long delay, long firstDelay, Object r) { return installTimer(component, r, delay, firstDelay); } static Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay) { return installTimer(component, r, delay, firstDelay, true); } static Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay, final boolean repeats) { if (component == null) return null; return (Timer) swingAndWait(new F0() { Object get() { try { final Var timer = new Var(); timer.set(new Timer(toInt(delay), new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { try { AutoCloseable __1849 = tempActivity(r); try { try { if (!allPaused()) if (isFalse(callF(r))) cancelTimer(timer.get()); } catch (Throwable __e) { _handleException(__e); } } finally { _close(__1849); }} catch (Throwable __e) { messageBox(__e); }}})); timer.get().setInitialDelay(toInt(firstDelay)); timer.get().setRepeats(repeats); bindTimerToComponent(timer.get(), component); return timer.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final new Var timer;\r\n timer.set(new Timer(toInt(delay), actionList..."; }}); } static Timer installTimer(RootPaneContainer frame, long delay, long firstDelay, Object r) { return installTimer(frame.getRootPane(), delay, firstDelay, r); } static A disposeFrameOnClick(final A c) { onClick(c, new Runnable() { public void run() { try { disposeFrame(c) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disposeFrame(c)"; }}); return c; } static void cancelThread(Thread t) { if (t == null) return; ping(); /*O mc = getWeakRef((WeakReference) vm_generalWeakSubMap("thread2mc").get(t)); ifdef cancelThread_verbose print("cancelThread: mc=" + mc); endifdef if (mc != null) { Map ping_actions = cast get(mc, 'ping_actions); synchronized(ping_actions) { ping_actions.put(t, "cancelled"); set(mc, ping_anyActions := true); } } else*/ synchronized(ping_actions) { ping_actions.put(t, "cancelled"); ping_anyActions = true; } } static void raiseFlagAndDo(Flag flag, Runnable r) { if (flag.raise()) callF(r); } static void _handleException_addHandler(Object handler) { addIfNotThere(_handleException_onException, handler); } static A assertNull(A a) { assertTrue(a == null); return a; } static A assertNull(String msg, A a) { assertTrue(msg, a == null); return a; } static A internalFrameTitle(A c, final String title) { final JInternalFrame f = getInternalFrame(c); if (f != null) { swing(new Runnable() { public void run() { try { f.setTitle(unnull(title)); toolTip(getInternalFrameTitlePaneComponent(f), title); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.setTitle(unnull(title));\r\n toolTip(getInternalFrameTitlePaneComponent(f)..."; }}); } return c; } static A internalFrameTitle(String title, A c) { return internalFrameTitle(c, title); } static String internalFrameTitle(Component c) { final JInternalFrame f = getInternalFrame(c); return f == null ? null : swing(new F0() { String get() { try { return f.getTitle(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ret f.getTitle();"; }}); } static A frameTitle(A c, String title) { return setFrameTitle(c, title); } static A frameTitle(String title, A c) { return setFrameTitle(c, title); } static String frameTitle(Component c) { return getFrameTitle(c); } static Set _registerAutoCloseable_set = synchroHashSet(); static void _registerAutoCloseable(AutoCloseable c) { addIfNotNull(_registerAutoCloseable_set, c); } static void cleanMeUp__registerAutoCloseable() { closeAutoCloseables(getAndClearList(_registerAutoCloseable_set)); } static A callFInRealOrMyMC(Object realm, F0 f) { return f == null ? null : f.get(); } static B callFInRealOrMyMC(Object realm, F1 f, A a) { return f == null ? null : f.get(a); } static C callFInRealOrMyMC(Object realm, F2 f, A a, B b) { return f == null ? null : f.get(a, b); } static void callFInRealOrMyMC(Object realm, VF1 f, A a) { if (f != null) f.get(a); } static Object callFInRealOrMyMC(Object realm, Object f, Object... args) { if (f instanceof String) { Class mc = getMainClass(realm); if (hasMethod(mc, ((String) f), args)) return call(mc, ((String) f), args); } return callF(f, args); } static A shallowCloneToClass(Class c, Object o) { if (o == null) return null; A a = nuInstance(c); copyFields(o, a); return a; } static Object dm_getStem(Object moduleOrID) { if (isStringOrIntOrLong(moduleOrID)) return dm_getStemByID(moduleOrID); return or(getOpt(dm_getModule(moduleOrID), "_host"), moduleOrID); } static DynModule dm_current() { return dm_currentModule(); } static Method findMethod_precise_onTypes(Object o, String method, Class... argTypes) { try { if (o instanceof Class) { _MethodCache cache = callOpt_getCache(((Class) o)); List methods = cache.cache.get(method); Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { { if (!(isStaticMethod(m))) continue; } int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) { /*if (preciseCall_debug) print("Method score: " + m + " " + score);*/ best.put(m, score); } } return best.get(); } if (o == null) return null; _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); Lowest best = new Lowest(); if (methods != null) for (Method m : methods) { int score = methodApplicabilityScore_onTypes(m, argTypes); if (score < Integer.MAX_VALUE) best.put(m, score); } return best.get(); } catch (Exception __e) { throw rethrow(__e); } } static void dm_onTopInput(final VF1 r) { final DynModule m = dm_current_mandatory(); dm_ownResource(vmBus_onMessage("topInput", new VF1() { public void get(final String s) { try { m.enter(); callF(r, s) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.enter();\r\n callF(r, s)"; }})); } static void dm_onTopInput(final Runnable r) { final DynModule m = dm_current_mandatory(); dm_ownResource(vmBus_onMessage("topInput", new VF1() { public void get(final String s) { try { m.enter(); callF(r) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.enter();\r\n callF(r)"; }})); } static A foldl(F2 f, A seed, Iterable l) { A a = seed; if (l != null) for(B b : l) a = callF(f, a, b); return a; } static A foldl(F2 f, A seed, B[] l) { A a = seed; if (l != null) for(B b : l) a = callF(f, a, b); return a; } static A foldl(Object f, A seed, B[] l) { A a = seed; if (l != null) for(B b : l) a = (A) callF(f, a, b); return a; } static ThreadLocal print_byThread() { synchronized(print_byThread_lock) { if (print_byThread == null) print_byThread = new ThreadLocal(); } return print_byThread; } // f can return false to suppress regular printing // call print_raw within f to actually print something static AutoCloseable tempInterceptPrint(F1 f) { return tempSetThreadLocal(print_byThread(), f); } static boolean setAdd(Collection c, A a) { if (c == null || c.contains(a)) return false; c.add(a); return true; } static boolean instanceOf(Object o, String className) { if (o == null) return false; String c = o.getClass().getName(); return eq(c, className) || eq(c, "main$" + className); } static boolean instanceOf(Object o, Class c) { if (c == null) return false; return c.isInstance(o); } static void internalFramePopupMenuItem(Container f, final String name, final Object action) { internalFrameTitlePopupMenuItem(((JInternalFrame) f), name, action); } static void callAction(Action a) { if (a != null) a.actionPerformed(null); } // menuMaker = voidfunc(JPopupMenu) static void internalFrameTitlePopupMenu(final JInternalFrame f, final Object... params) { { swing(new Runnable() { public void run() { try { Object menuMaker; if (l(params) == 1 && !(params[0] instanceof JMenu)) menuMaker = params[0]; else menuMaker = new VF1() { public void get(JPopupMenu menu) { try { addMenuItems(menu, params) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItems(menu, params)"; }}; Component titleComponent = getInternalFrameTitlePaneComponent(f); if (!(titleComponent instanceof JComponent)) print("Can't add internal frame title popup menu!"); else { componentPopupMenu((JComponent) titleComponent, menuMaker); setOpt(componentPopupMenu_initForComponent((JComponent) titleComponent), "internalFrameLeftButtonMagic" , isTrue(vm_generalMap_get("internalFramePopupOnLeftButton"))); } // Also add to the frame so we can show the items e.g. in a JFrame menu componentPopupMenu(f, menuMaker); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Object menuMaker;\r\n if (l(params) == 1 && !(params[0] instanceof JMenu))\r\n..."; }}); } } static String stringOptPar(Object[] params, String name) { return (String) optPar(params, name); } static void dm_stringFieldDialog(final String field, final Object... __) { final DynModule m = dm_current_mandatory(); final String humanized = humanizeFormLabel(field); final JTextField tf = jtextfield(get(m, field)); showFormTitled(or2(stringOptPar(__, "formTitle"), "Set " + humanized), humanized + ":", tf, new Runnable() { public void run() { try { m.setField(field, gtt(tf)); callF(optPar(__, "onSet")); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "m.setField(field, gtt(tf));\r\n callF(optPar(__, \"onSet\"));"; }}); } static Q startQ() { return new Q(); } static Q startQ(String name) { return new Q(name); } static A dm_ownResource(A resource) { dm_currentModuleMandatory().ownResource(resource); return resource; } static JLabel jimage(Image img) { return jImageLabel(img); } static JLabel jimage(String imageID) { return jImageLabel(imageID); } static void cancelTimers(Collection timers) { for (Object timer : timers) cancelTimer(timer); } static List> chessOCR_recognizeBoard(BufferedImage board, ChessPieceRecognizer pieceRecognizer) { List> squareImages = bufferedImageMNGrid(board, 8, 8); return map(concatLists(squareImages), img -> pieceRecognizer.recognize(img)); } static int stdHash(Object a, String... fields) { if (a == null) return 0; int hash = getClassName(a).hashCode(); for (String field : fields) hash = hash*2+hashCode(getOpt(a, field)); return hash; } static MultiMap mapMultiMapValues(Object func, MultiMap mm) { MultiMap m = similarEmptyMultiMap(mm); for (Object key : keys(mm)) for (Object value : mm.get(key)) m.put(key, callF(func, value)); return m; } static MultiMap mapMultiMapValues(MultiMap mm, Object func) { return mapMultiMapValues(func, mm); } static MultiMap mapMultiMapValues(IF1 func, MultiMap mm) { return mapMultiMapValues((Object) func, mm); } static MultiMap ciMultiMap() { return caseInsensitiveMultiMap(); } static ThreadLocal saveTiming_last = new ThreadLocal(); static void saveTiming(long ms) { print(ms + " ms"); saveTiming_noPrint(ms); } static void saveTiming_noPrint(long ms) { saveTiming_last.set(ms); } static List uniquify(Collection l) { return uniquifyList(l); } static double negativeInfinity() { return Double.NEGATIVE_INFINITY; } static String autoFrameTitle_value; static String autoFrameTitle() { return autoFrameTitle_value != null ? autoFrameTitle_value : getProgramTitle(); } static void autoFrameTitle(Component c) { setFrameTitle(getFrame(c), autoFrameTitle()); } static void registerEscape_rootPane(JComponent rootPane, final Runnable r) { String name = "Escape"; Action action = abstractAction(name, r); KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); rootPane.getActionMap().put(name, action); rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, name); } static String programName() { return getProgramName(); } static JPanel centerAndEast(final Component c, final Component e) { return swing(new F0() { JPanel get() { try { JPanel panel = new JPanel(new BorderLayout()); panel.add(BorderLayout.CENTER, wrap(c)); panel.add(BorderLayout.EAST, wrap(e)); return panel; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JPanel panel = new JPanel(new BorderLayout);\r\n panel.add(BorderLayout.CENT..."; }}); } static A renameSubmitButton(A form, String newName) { renameButton(form, showFormSubmitButtonName(), newName); return form; } static A renameSubmitButton(String newName, A form) { return renameSubmitButton(form, newName); } static A moveCaretToEnd(A ta) { setCaretPosition(ta, textAreaTextLength(ta)); return ta; } static JComponent showTitledForm(String title, Object... _parts) { return showFormTitled(title, _parts); } static BufferedImage copyImage(BufferedImage bi) { if (bi == null) return null; ColorModel cm = bi.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster()); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } static BufferedImage decodeImage(byte[] data) { try { return ImageIO.read(new ByteArrayInputStream(data)); } catch (Exception __e) { throw rethrow(__e); } } static AutoCloseable tempActivity(Object r) { return null; } static boolean allPaused() { return ping_pauseAll; } static void bindTimerToComponent(final Timer timer, JFrame f) { bindTimerToComponent(timer, f.getRootPane()); } static void bindTimerToComponent(final Timer timer, JComponent c) { if (c.isShowing()) timer.start(); c.addAncestorListener(new AncestorListener() { public void ancestorAdded(AncestorEvent event) { timer.start(); } public void ancestorRemoved(AncestorEvent event) { timer.stop(); } public void ancestorMoved(AncestorEvent event) { } }); } static String getFrameTitle(Component c) { JFrame f = getFrame(c); return f == null ? null : f.getTitle(); } static void addIfNotNull(Collection l, A a) { if (a != null && l != null) l.add(a); } static void closeAutoCloseables(Collection l) { if (l != null) for (AutoCloseable c : l) { try { c.close(); } catch (Throwable __e) { _handleException(__e); }} } static A nuInstance(Class c) { return nuEmptyObject(c); } static A copyFields(Object x, A y, String... fields) { if (empty(fields)) { // assume we should copy all fields Map map = objectToMap(x); for (String field : map.keySet()) setOpt(y, field, map.get(field)); } else for (String field : fields) { Object o = getOpt(x, field); if (o != null) setOpt(y, field, o); } return y; } static A copyFields(Object x, A y, Collection fields) { return copyFields(x, y, asStringArray(fields)); } static boolean isStringOrIntOrLong(Object o) { return o instanceof String || o instanceof Integer || o instanceof Long; } static Object dm_getStemByID(Object id) { return dm_callOS("getModuleByID", str(id)); } static Object dm_getModule(Object moduleOrID) { if (moduleOrID == null || eq(moduleOrID, "")) return null; if (isString(moduleOrID) && isIdentifier(((String) moduleOrID))) return dm_getService(((String) moduleOrID)); if (isStringOrIntOrLong(moduleOrID)) return dm_callOS("getDynModuleByID", str(moduleOrID)); return dm_resolveModule(moduleOrID); } // return Int.MAX_VALUE if not applicable // Lower score is better static int methodApplicabilityScore_onTypes(Method m, Class[] argTypes) { Class[] types = m.getParameterTypes(); if (types.length != argTypes.length) return Integer.MAX_VALUE; int score = 0; for (int i = 0; i < types.length; i++) { Class a = argTypes[i]; Class c = types[i]; if (c == a) {} // perfect match else if (isSubclassOf(a, c)) ++score; else return Integer.MAX_VALUE; } return score; } static AutoCloseable vmBus_onMessage(final String msg, final VF1 onMessage) { Map map = vm_busListenersByMessage_live(); synchronized(map) { Set listeners = map.get(msg); if (listeners == null) map.put(msg, listeners = syncIdentityHashSet()); // We're technically violating the one-synchronized-object-per-thread rule, // but it should be OK here. // TODO: remove empty sets from map return tempAdd(listeners, new VF2() { public void get(String _msg, Object arg) { try { callF(onMessage, arg) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, arg)"; }}); } } static AutoCloseable vmBus_onMessage(String msg, final VF2 onMessage) { return vmBus_onMessage(msg, new VF1() { public void get(Object[] o) { try { callF(onMessage, first(o), second(o)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(onMessage, first(o), second(o));"; }}); } static AutoCloseable vmBus_onMessage(String msg, Runnable onMessage) { return vmBus_onMessage(msg, runnableToVF1(onMessage)); } static void internalFrameTitlePopupMenuItem(JInternalFrame f, final String name, final Object action) { internalFrameTitlePopupMenu(f, new VF1() { public void get(JPopupMenu menu) { try { addMenuItem(menu, name, action) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addMenuItem(menu, name, action)"; }}); } static void addMenuItems(JMenu m, Object... x) { fillJMenu(m, x); } static void addMenuItems(JPopupMenu m, Object... x) { fillJPopupMenu(m, x); } static DynModule dm_currentModuleMandatory() { return dm_current_mandatory(); } static JLabel jImageLabel(Image img) { return swingNu(JLabel.class, imageIcon(img)); } static JLabel jImageLabel(javax.swing.Icon icon) { return swingNu(JLabel.class, icon); } static JLabel jImageLabel(String imageID) { return jImageLabel(imageIcon(imageID)); } static JLabel jImageLabel(String text, String imageID) { final JLabel l = swingNu(JLabel.class, text, imageIcon(imageID), JLabel.CENTER); { swing(new Runnable() { public void run() { try { l.setVerticalTextPosition(SwingConstants.BOTTOM); l.setHorizontalTextPosition(SwingConstants.CENTER); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "l.setVerticalTextPosition(SwingConstants.BOTTOM);\r\n l.setHorizontalTextPos..."; }}); } return l; } static int hashCode(Object a) { return a == null ? 0 : a.hashCode(); } static MultiMap similarEmptyMultiMap(MultiMap m) { MultiMap mm = new MultiMap(); if (m != null) mm.data = similarEmptyMap(m.data); return mm; } static MultiMap caseInsensitiveMultiMap() { MultiMap mm = new MultiMap(); mm.data = caseInsensitiveMap(); return mm; } static List uniquifyList(Collection l) { if (l == null) return null; if (l(l) < 2) return asList(l); HashSet set = new HashSet(); List out = new ArrayList(); for (A a : l) if (set.add(a)) out.add(a); return out; } static String getProgramTitle() { return getProgramName(); } static JButton renameButton(JComponent c, String name) { JButton b = first(childrenOfType(c, JButton.class)); if (b != null) b.setText(name); return b; } static JButton renameButton(JComponent c, String oldName, String newName) { JButton b = findButton(c, oldName); if (b != null) b.setText(newName); return b; } static void setCaretPosition(final JTextComponent c, final int pos) { if (c != null) { swing(new Runnable() { public void run() { try { try { int _pos = max(0, min(l(c.getText()), pos)); c.setCaretPosition(_pos); } catch (Throwable __e) { _handleException(__e); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "pcall {\r\n int _pos = max(0, min(l(c.getText()), pos));\r\n c.setCaret..."; }}); } } static int textAreaTextLength(JTextComponent ta) { return l(getText(ta)); } // o is either a map already (string->object) or an arbitrary object, // in which case its fields are converted into a map. static Map objectToMap(Object o) { try { if (o instanceof Map) return (Map) o; TreeMap map = new TreeMap(); Class c = o.getClass(); while (c != Object.class) { Field[] fields = c.getDeclaredFields(); for (final Field field : fields) { if ((field.getModifiers() & Modifier.STATIC) != 0) continue; field.setAccessible(true); final Object value = field.get(o); if (value != null) map.put(field.getName(), value); } c = c.getSuperclass(); } // XXX NEW - hopefully this doesn't break anything if (o instanceof DynamicObject) map.putAll(((DynamicObject) o).fieldValues); return map; } catch (Exception __e) { throw rethrow(__e); } } // same for a collection (convert each element) static List> objectToMap(Iterable l) { if (l == null) return null; List x = new ArrayList(); for (Object o : l) x.add(objectToMap(o)); return x; } static String[] asStringArray(Collection c) { return toStringArray(c); } static String[] asStringArray(Object o) { return toStringArray(o); } static Object dm_callOS(String functionName, Object... args) { return call(dm_os(), functionName, args); } static boolean isString(Object o) { return o instanceof String; } static Object dm_getService(String serviceName) { return empty(serviceName) ? null : dm_getModule(vmBus_query(assertIdentifier(serviceName))); } static Object dm_resolveModule(Object moduleOrStem) { return dm_callOS("resolveModule", moduleOrStem); } static boolean isSubclassOf(Class a, Class b) { return isSubclass(a, b); } static AutoCloseable tempAdd(final Collection l, final A a) { if (l == null || l.contains(a)) return null; l.add(a); return new AutoCloseable() { public String toString() { return "l.remove(a);"; } public void close() throws Exception { l.remove(a); }}; } static A third(List l) { return _get(l, 2); } static A third(Iterable l) { if (l == null) return null; Iterator it = iterator(l); for (int _repeat_1730 = 0; _repeat_1730 < 2; _repeat_1730++) { if (!it.hasNext()) return null; it.next(); } return it.hasNext() ? it.next() : null; } static A third(Producer p) { if (p == null) return null; for (int _repeat_1731 = 0; _repeat_1731 < 2; _repeat_1731++) { if (p.next() == null) return null; } return p.next(); } static A third(A[] bla) { return bla == null || bla.length <= 2 ? null : bla[2]; } static VF1 runnableToVF1(final Runnable r) { return r == null ? null : new VF1() { public void get(A a) { try { r.run() ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "r.run()"; }}; } static void fillJMenu(final JMenu m, Object... x) { //ifdef fillJMenu_debug //print("fillJMenu " + m); //endifdef if (x == null) return; for (int i = 0; i < l(x); i++) { Object o = x[i], y = get(x, i+1); if (o instanceof List) fillJMenu(m, asArray((List) o)); else if (isMenuSeparatorIndicator(o)) m.addSeparator(); else if (o instanceof LiveValue && ((LiveValue) o).getType() == String.class && isRunnableX(y)) { final LiveValue lv = (LiveValue) o; final JMenuItem mi = jmenuItem(or2(unCurlyBracket(lv.get()), "..."), y); bindLiveValueListenerToComponent(mi, lv, new Runnable() { public void run() { try { String s = lv.get(); if (isCurlyBracketed(s)) { setEnabled(mi, false); s = unCurlyBracket(s); } else setEnabled(mi, true); setText(mi, s); revalidate(m); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String s = lv.get();\r\n if (isCurlyBracketed(s)) {\r\n setEnable..."; }}); print("bound live value " + lv + " to menu item " + mi); m.add(mi); ++i; } else if (o instanceof String && isRunnableX(y)) { m.add(jmenuItem((String) o, y)); ++i; } else if (o instanceof JMenuItem) m.add((JMenuItem) o); // "call" might use wrong method else if (o instanceof String || o instanceof Action || o instanceof Component) call(m, "add", o); else if (o == null && y instanceof Runnable) ++i; // text == null => disabled item else print("Unknown menu item: " + o); } } static JButton findButton(Component c, String name) { for (JButton b : childrenOfType(c, JButton.class)) if (eq(b.getText(), name)) return b; for (JButton b : childrenOfType(getFrame(c), JButton.class)) if (eq(b.getText(), name)) return b; return null; } static JButton findButton(Component c) { return childOfType(c, JButton.class); } static Object vmBus_query(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); { Object __466= pcallFAll_returnFirstNotNull(vm_busListeners_live(), msg, arg); if (__466 != null) return __466; } return pcallFAll_returnFirstNotNull(vm_busListenersByMessage_live().get(msg), msg, arg); } static Object vmBus_query(String msg) { return vmBus_query(msg, (Object) null); } static boolean isSubclass(Class a, Class b) { return a != null && b != null && b.isAssignableFrom(a); } static A childOfType(Component c, Class theClass) { return first(childrenOfType(c, theClass)); } static A childOfType(Class theClass, Component c) { return childOfType(c, theClass); } static Object pcallFAll_returnFirstNotNull(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) { Object __707= pcallF(f, args); if (__707 != null) return __707; } return null; } static Object pcallFAll_returnFirstNotNull(Iterator it, Object... args) { while (it.hasNext()) { Object __708= pcallF(it.next(), args); if (__708 != null) return __708; } return null; } static class TransferableImage implements Transferable { Image i; TransferableImage(Image i) { this.i = i;} public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException { if ( flavor.equals( DataFlavor.imageFlavor ) && i != null ) { return i; } else { throw new UnsupportedFlavorException( flavor ); } } public DataFlavor[] getTransferDataFlavors() { DataFlavor[] flavors = new DataFlavor[ 1 ]; flavors[ 0 ] = DataFlavor.imageFlavor; return flavors; } public boolean isDataFlavorSupported( DataFlavor flavor ) { DataFlavor[] flavors = getTransferDataFlavors(); for ( int i = 0; i < flavors.length; i++ ) { if ( flavor.equals( flavors[ i ] ) ) { return true; } } return false; } }static class Scored extends Var { float score; Scored() {} Scored(A a, float score) { super(a); this.score = score; } float score() { return score; } public String toString() { return toIntPercent(score) + "%: " + str(get()); } }static abstract class F2 { abstract C get(A a, B b); }static class HashedByteArray { byte[] data; int hashCode; HashedByteArray() {} HashedByteArray(byte[] data) { this.data = data;} public int hashCode() { if (hashCode == 0) hashCode = oneIfZero(arrayHashCode(data)); return hashCode; } public boolean equals(Object o) { if (o instanceof HashedByteArray) return this == ((HashedByteArray) o) || hashCode() == ((HashedByteArray) o).hashCode() && byteArraysEqual(data, ((HashedByteArray) o).data); return false; } public String toString() { return bytesToHex(data); } }/** this class is fully thread-safe */ static class Flag implements Runnable { private boolean up = false; /** returns true if flag was down before */ public synchronized boolean raise() { if (!up) { up = true; notifyAll(); return true; } else return false; } public synchronized void waitUntilUp() { while (!up) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void waitUntilUp(long timeout) { if (!up) { try { wait(timeout); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized boolean isUp() { return up; } boolean get() { return isUp(); } public String toString() { return isUp() ? "up" : "down"; } // currently does a semi-active wait with latency = 50 ms public void waitForThisOr(Flag otherFlag) { try { while (!isUp() && !otherFlag.isUp()) Thread.sleep(50); } catch (Exception __e) { throw rethrow(__e); } } public void run() { raise(); } } static int toIntPercent(double ratio) { return roundToInt(ratio*100); } static int oneIfZero(int i) { return i == 0 ? 1 : i; } static boolean byteArraysEqual(byte[] a, byte[] b) { return Arrays.equals(a, b); } static int roundToInt(double d) { return (int) Math.round(d); } }