import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import java.util.function.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.awt.geom.*; import javax.imageio.*; import java.math.*; import java.time.Duration; import org.fife.ui.autocomplete.*; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; import com.github.sarxos.webcam.*; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.Const; import org.apache.bcel.generic.*; import java.lang.reflect.Type; import org.ejml.data.*; import org.ejml.dense.row.*; import org.ejml.dense.row.decomposition.eig.*; import me.saharnooby.qoi.plugin.*; import static loadableUtils.utils.VF1; import static loadableUtils.utils.l; import static loadableUtils.utils.getOpt; import static loadableUtils.utils.setOpt; import static loadableUtils.utils.callOpt; import static loadableUtils.utils.newDangerousWeakHashMap; import static loadableUtils.utils.get; import static loadableUtils.utils.assertTrue; import static loadableUtils.utils.isTrue; import loadableUtils.utils; import static loadableUtils.utils.match; import static loadableUtils.utils.getField; import static loadableUtils.utils.bindToComponent; import static loadableUtils.utils.struct; import static loadableUtils.utils.structure; import static loadableUtils.utils.loadPage; import static loadableUtils.utils.cset; import static loadableUtils.utils.DynamicObject_loading; import static loadableUtils.utils.dynamicObjectIsLoading; import static loadableUtils.utils.rethrow; import loadableUtils.utils.F0; import loadableUtils.utils.F1; import loadableUtils.utils.IF0; import loadableUtils.utils.IF1; import loadableUtils.utils.IVF1; import loadableUtils.utils.IVF2; import loadableUtils.utils.SingleComponentPanel; import loadableUtils.utils.Q; import loadableUtils.utils.ImageSurface; import loadableUtils.utils.structure_Data; import loadableUtils.utils.RGBImage; import loadableUtils.utils.RGB; import loadableUtils.utils.BWImage; import loadableUtils.utils.MakesBufferedImage; import loadableUtils.utils.MultiSet; import loadableUtils.utils.Concept; import loadableUtils.utils.Concepts; import loadableUtils.utils.IterableIterator; import loadableUtils.utils.PersistableThrowable; import loadableUtils.utils.DynModule; import loadableUtils.utils.Rect; import loadableUtils.utils.Pt; import loadableUtils.utils.SynchronizedArrayList; import loadableUtils.utils.SecretValue; import static loadableUtils.utils.db_mainConcepts; import static loadableUtils.utils.joinWithSpace; import static loadableUtils.utils.callF; import static loadableUtils.utils.javaTok; import static loadableUtils.utils.jlabel; import static loadableUtils.utils.join; import static loadableUtils.utils.set; import static loadableUtils.utils.call; import static loadableUtils.utils.fail; import static loadableUtils.utils.print; import static loadableUtils.utils.doLater; import static loadableUtils.utils.cget; import static loadableUtils.utils.db; import loadableUtils.utils.IntRange; import loadableUtils.utils.FixedRateTimer; import loadableUtils.utils.MultiMap; import loadableUtils.utils.IMultiMap; import loadableUtils.utils.Meta; import loadableUtils.utils.ITokCondition; import loadableUtils.utils.TokCondition; import loadableUtils.utils.SimpleLiveValue; import loadableUtils.utils.Matrix; import loadableUtils.utils.Best; import loadableUtils.utils.F2; import loadableUtils.utils.RandomAccessAbstractList; import loadableUtils.utils.IProbabilisticScheduler; import loadableUtils.utils.IBWIntegralImage; import loadableUtils.utils.IntBuffer; import loadableUtils.utils.ShortBuffer; import loadableUtils.utils.Cache; import loadableUtils.utils.AbstractMatrix; import loadableUtils.utils.OKOrError; import loadableUtils.utils.WithTimestamp; import loadableUtils.utils.LiveValue; import loadableUtils.utils.Timestamp; import loadableUtils.utils.Complex; import loadableUtils.utils.ProbabilisticScheduler; import loadableUtils.utils.RestartableCountdown; import loadableUtils.utils.Steppable; import loadableUtils.utils.FunctionCall; import loadableUtils.utils.Swingable; import loadableUtils.utils.Average; import loadableUtils.utils.IAutoCloseableF0; import loadableUtils.utils.GrabbableIntPixels; import loadableUtils.utils.BWIntegralImage; import loadableUtils.utils.DoubleRange; import loadableUtils.utils.WithProbability; import static loadableUtils.utils.addPrefixOptIfNempty; import static loadableUtils.utils.lambdaMapMethod; import static loadableUtils.utils.negativeInfinity; import static loadableUtils.utils.score; import static loadableUtils.utils.stepAll; import static loadableUtils.utils.jreplaceExpandRefs; import static loadableUtils.utils.wrappedTextArea; import static loadableUtils.utils.infoMessage; import static loadableUtils.utils.sorted; import static loadableUtils.utils.loadFont_cached; import static loadableUtils.utils.quickSubstring; import static loadableUtils.utils.childrenOfType; import static loadableUtils.utils.nanoTime; import static loadableUtils.utils.addPrefix; import static loadableUtils.utils.b; import static loadableUtils.utils.doEvery_daemon; import static loadableUtils.utils.jCenteredSection; import static loadableUtils.utils.dm_fieldLabel; import static loadableUtils.utils.n; import static loadableUtils.utils.htmlencode_noQuotes; import static loadableUtils.utils.abs; import static loadableUtils.utils.runnableThreadsWithStackTraces; import static loadableUtils.utils.findEndOfBracketPart; import static loadableUtils.utils.lIntArray; import static loadableUtils.utils.getComponents; import static loadableUtils.utils.rep; import static loadableUtils.utils.area; import static loadableUtils.utils.add; import static loadableUtils.utils.singleComponentPanel; import static loadableUtils.utils.simpleDateFormat_local; import static loadableUtils.utils.withMargin; import static loadableUtils.utils.addActionListener; import static loadableUtils.utils.clearTokens; import static loadableUtils.utils.printStruct; import static loadableUtils.utils.intersectRects; import static loadableUtils.utils.deleteFile; import static loadableUtils.utils.stopTimer; import static loadableUtils.utils.dm_os; import static loadableUtils.utils.cyclicGet; import static loadableUtils.utils.ymdMinusHMS; import static loadableUtils.utils.withLeftMargin; import static loadableUtils.utils.jPopDownButton_noText; import static loadableUtils.utils.simpleDateFormat; import static loadableUtils.utils.swingLater; import static loadableUtils.utils.imageMergeSpacing; import static loadableUtils.utils.setImage; import static loadableUtils.utils.regexp; import static loadableUtils.utils.simpleQuote; import static loadableUtils.utils.setFrameTitle; import static loadableUtils.utils.tsNow; import static loadableUtils.utils.jfind_preprocess; import static loadableUtils.utils.formatFunctionCall; import static loadableUtils.utils.copyBufferedImage; import static loadableUtils.utils.localDateWithSeconds; import static loadableUtils.utils.dm_reload; import static loadableUtils.utils.addMargin; import static loadableUtils.utils.subDoubleArray; import static loadableUtils.utils.isIdentifier; import static loadableUtils.utils.jFullCenter; import static loadableUtils.utils.toMinutes; import static loadableUtils.utils.scanForComponents; import static loadableUtils.utils.scaffoldingEnabled; import static loadableUtils.utils.infoBox; import static loadableUtils.utils.toSeconds; import static loadableUtils.utils.rect; import static loadableUtils.utils.cleanUp; import static loadableUtils.utils.dm_stem; import static loadableUtils.utils.forEach; import static loadableUtils.utils.textFieldFromComboBox; import static loadableUtils.utils.stdcompare; import static loadableUtils.utils.centerAndEast; import static loadableUtils.utils.aGlobalID; import static loadableUtils.utils.okOrError; import static loadableUtils.utils.setDoubleBuffered; import static loadableUtils.utils.asVirtualList; import static loadableUtils.utils.bufferedImage; import static loadableUtils.utils.maximumSafeArraySize; import static loadableUtils.utils.dm_q; import static loadableUtils.utils.withLeftAndRightMargin; import static loadableUtils.utils.shortName; import static loadableUtils.utils.hgrid; import static loadableUtils.utils.decimalFormatEnglish; import static loadableUtils.utils.formatDouble; import static loadableUtils.utils.getParent; import static loadableUtils.utils.strOrEmpty; import static loadableUtils.utils.run; import static loadableUtils.utils.replaceExtension; import static loadableUtils.utils.has; import static loadableUtils.utils.last; import static loadableUtils.utils.intSum; import static loadableUtils.utils.warn; import static loadableUtils.utils.distance; import static loadableUtils.utils.toRect; import static loadableUtils.utils.formatDouble_significant2; import static loadableUtils.utils.onLeftClick; import static loadableUtils.utils.addIfNotNull; import static loadableUtils.utils.smartTimerTask; import static loadableUtils.utils.isString; import static loadableUtils.utils.clipBufferedImage; import static loadableUtils.utils.formatDouble1; import static loadableUtils.utils.setText; import static loadableUtils.utils.findButton; import static loadableUtils.utils.splitAtSpace; import static loadableUtils.utils.parseIntOrLong; import static loadableUtils.utils.toJava; import static loadableUtils.utils.getBounds; import static loadableUtils.utils.northAndCenterWithMargin; import static loadableUtils.utils.nBytes; import static loadableUtils.utils.newConceptsWithClassFinder; import static loadableUtils.utils.replaceSublist; import static loadableUtils.utils.codeTokensOnly; import static loadableUtils.utils.standardCredentialsUser; import static loadableUtils.utils.joinSubList; import static loadableUtils.utils.mapToPairs; import static loadableUtils.utils.javaTokC; import static loadableUtils.utils.ratioToIntPercent; import static loadableUtils.utils.jreplace; import static loadableUtils.utils.newButton; import static loadableUtils.utils.newButton_autoToolTip; import static loadableUtils.utils.onUpdate; import static loadableUtils.utils.formatInt; import static loadableUtils.utils.intMax; import static loadableUtils.utils.awtLater; import static loadableUtils.utils.replace; import static loadableUtils.utils.nChars; import static loadableUtils.utils.findCodeTokens; import static loadableUtils.utils.printWithMS; import static loadableUtils.utils.format; import static loadableUtils.utils.onEnter; import static loadableUtils.utils.hsplit; import static loadableUtils.utils.mapWithIndex; import static loadableUtils.utils.containsNewLine; import static loadableUtils.utils.centerAndEastWithMargin; import static loadableUtils.utils.getFrame; import static loadableUtils.utils.centerAndSouth; import static loadableUtils.utils.jscroll_center; import static loadableUtils.utils.jhsplit; import static loadableUtils.utils.dm_fieldLiveValue; import static loadableUtils.utils.isLetter; import static loadableUtils.utils.findAllFiles_noDirs; import static loadableUtils.utils.toObjectArray; import static loadableUtils.utils.getScreenSize; import static loadableUtils.utils.rectFromPoints; import static loadableUtils.utils.runnableThread; import static loadableUtils.utils.toolTip; import static loadableUtils.utils.firstToUpper; import static loadableUtils.utils.allScreenBounds; import static loadableUtils.utils.withBottomMargin; import static loadableUtils.utils.jscroll_centered; import static loadableUtils.utils.hfulltag; import static loadableUtils.utils.endMarker; import static loadableUtils.utils.reTok; import static loadableUtils.utils.fullAlphaMask; import static loadableUtils.utils.toString; import static loadableUtils.utils.div; import static loadableUtils.utils.squareBracket; import static loadableUtils.utils.isQuoted; import static loadableUtils.utils.checkTokCondition; import static loadableUtils.utils.formatLocalDateWithSeconds; import static loadableUtils.utils.applyDefaultMargin; import static loadableUtils.utils.removeFromParent; import static loadableUtils.utils.isDigit; import static loadableUtils.utils.dm_callOS; import static loadableUtils.utils.regionMatches; import static loadableUtils.utils.newRandomAccessFile; import static loadableUtils.utils.grabbableIntPixels; import static loadableUtils.utils.asObjectArray; import static loadableUtils.utils.dm_callOSOpt; import static loadableUtils.utils.metaSet; import static loadableUtils.utils.consoleFrame; import static loadableUtils.utils.centerLabel; import static loadableUtils.utils.jLiveValueLabel; import static loadableUtils.utils.combineAutoCloseables; import static loadableUtils.utils.shortClassName_dropNumberPrefix; import static loadableUtils.utils.identityHashCode; import static loadableUtils.utils.sqrt; import static loadableUtils.utils.listFilesWithSuffix; import static loadableUtils.utils.jbutton; import static loadableUtils.utils.setEnabled; import static loadableUtils.utils.northAndCenter; import static loadableUtils.utils.jline; import static loadableUtils.utils.toMS; import static loadableUtils.utils.intFromBytes_littleEndian_partial; import static loadableUtils.utils.creator; import static loadableUtils.utils.forward; import static loadableUtils.utils.change; import static loadableUtils.utils.assertEquals; import static loadableUtils.utils.joinMap; import static loadableUtils.utils.isJAR; import static loadableUtils.utils.clearAllTokens; import static loadableUtils.utils.withProbability; import static loadableUtils.utils.toPath; import static loadableUtils.utils.getPreferredSize; import static loadableUtils.utils.md5; import static loadableUtils.utils.getBorder; import static loadableUtils.utils.onClick; import static loadableUtils.utils.screenDevices; import static loadableUtils.utils.find; import static loadableUtils.utils.setChecked; import static loadableUtils.utils.setFont; import static loadableUtils.utils.takeFirst; import static loadableUtils.utils.formatColonProperties; import static loadableUtils.utils.plus; import static loadableUtils.utils.ifloor; import static loadableUtils.utils.blend; import static loadableUtils.utils.enableWordWrapForTextArea; import static loadableUtils.utils.isSystemThread; import static loadableUtils.utils.smartIndexOf; import static loadableUtils.utils.indexOf; import static loadableUtils.utils.sqr; import static loadableUtils.utils.repeat; import static loadableUtils.utils.ok; import static loadableUtils.utils.jCheckBox; import static loadableUtils.utils.toMS_int; import static loadableUtils.utils.runnableToIF0; import static loadableUtils.utils.rectTopLeftCorner; import static loadableUtils.utils.scored; import static loadableUtils.utils.htag; import static loadableUtils.utils.asArray; import static loadableUtils.utils.pt; import static loadableUtils.utils.mapMethod; import static loadableUtils.utils.showText; import static loadableUtils.utils.getBytecodePathForClass; import static loadableUtils.utils.smartAdd; import static loadableUtils.utils.transpileRaw_makeTranslator; import static loadableUtils.utils.minus; import static loadableUtils.utils.printWithIndent; import static loadableUtils.utils.keysList; import static loadableUtils.utils.reversedList; import static loadableUtils.utils.intRange; import static loadableUtils.utils.ratio; import static loadableUtils.utils.countIterator; import static loadableUtils.utils.isNaN; import static loadableUtils.utils.fillRect; import static loadableUtils.utils.resizeIntArray; import static loadableUtils.utils.indentx; import static loadableUtils.utils.isChecked; import static loadableUtils.utils.similarEmptyMap; import static loadableUtils.utils.toFile; import static loadableUtils.utils.eqGet; import static loadableUtils.utils.tempAdd; import static loadableUtils.utils.onMouseDown; import static loadableUtils.utils.iff; import static loadableUtils.utils.pixelCount; import static loadableUtils.utils.pairA; import static loadableUtils.utils.dropFirst; import static loadableUtils.utils.mod; import static loadableUtils.utils.squareBracketed; import static loadableUtils.utils.seconds; import static loadableUtils.utils.quickFail; import static loadableUtils.utils.nanosToSeconds; import static loadableUtils.utils.grabbableIntPixels_fastOrSlow; import static loadableUtils.utils.addSuffix; import static loadableUtils.utils.asSet; import static loadableUtils.utils.westCenterAndEast; import static loadableUtils.utils.scaffoldCalled; import static loadableUtils.utils.restart; import static loadableUtils.utils.shootScreen2; import static loadableUtils.utils.toStringWithClass; import static loadableUtils.utils.hopeningTag; import static loadableUtils.utils.filter; import static loadableUtils.utils.assertEqualsVerbose; import static loadableUtils.utils.syncLinkedHashSet; import static loadableUtils.utils.sortFilesByName; import static loadableUtils.utils.mapPut; import static loadableUtils.utils.tag; import static loadableUtils.utils.onChange; import static loadableUtils.utils.pingSource; import static loadableUtils.utils.utf8streamToString; import static loadableUtils.utils.isInQ; import static loadableUtils.utils.withTopMargin; import static loadableUtils.utils.dirOfFile; import static loadableUtils.utils.error; import static loadableUtils.utils.setBackground; import static loadableUtils.utils.renderVars; import static loadableUtils.utils.sysNow; import static loadableUtils.utils.hotwire; import static loadableUtils.utils.metaGet; import static loadableUtils.utils.heldInstance; import static loadableUtils.utils.nestedIterator; import loadableUtils.utils.Pair; import loadableUtils.utils.ISleeper_v2; import loadableUtils.utils.Sleeping; import loadableUtils.utils.IBWImage; import loadableUtils.utils.WidthAndHeight; import loadableUtils.utils.WidthAndHeightImpl; import loadableUtils.utils.Enterable; import loadableUtils.utils.G2Drawable; import loadableUtils.utils.JConceptsTable; import loadableUtils.utils.SimpleCRUD_v2; import static loadableUtils.utils.unstructure; import static loadableUtils.utils._MethodCache; import static loadableUtils.utils.showForm_makeFrame; import loadableUtils.utils.Decolorizer; import static loadableUtils.utils.htmldecode; import loadableUtils.utils.ChangeTriggerable; import loadableUtils.utils.ChangeTrigger; import loadableUtils.utils.IHasChangeListeners; import loadableUtils.utils.MultiSetMap; import loadableUtils.utils.SimpleLeftToRightParser; import loadableUtils.utils.FlexibleRateTimer; import loadableUtils.utils.JFastLogView_noWrap; import loadableUtils.utils.LongBuffer; import loadableUtils.utils.SynchronizedLongBuffer; import loadableUtils.utils.ReliableSingleThread; import loadableUtils.utils.DynamicHStack; import loadableUtils.utils.DynamicStack; import loadableUtils.utils.ListAndIndex; import static loadableUtils.utils.unquote; import loadableUtils.utils.FileWatchService; import static loadableUtils.utils.DiskSnippetCache_file; import static loadableUtils.utils._close; import static loadableUtils.utils._entrySet; import static loadableUtils.utils._get; import static loadableUtils.utils._getClass; import static loadableUtils.utils._hashCode; import static loadableUtils.utils._onJavaXSet; import static loadableUtils.utils._run; import static loadableUtils.utils.a; import static loadableUtils.utils.aOrAn; import static loadableUtils.utils.absDiff; import static loadableUtils.utils.actionListener; import static loadableUtils.utils.addAll; import static loadableUtils.utils.addAndReturn; import static loadableUtils.utils.addAndRevalidate; import static loadableUtils.utils.addBorderToImage; import static loadableUtils.utils.addMenuItem; import static loadableUtils.utils.addMenuItems; import static loadableUtils.utils.addMouseListener; import static loadableUtils.utils.addTab; import static loadableUtils.utils.addWeakChangeListener; import static loadableUtils.utils.all; import static loadableUtils.utils.allImageFiles; import static loadableUtils.utils.allToString; import static loadableUtils.utils.antiAliasGraphics; import static loadableUtils.utils.any; import static loadableUtils.utils.appendBracketed; import static loadableUtils.utils.appendQueryToURL; import static loadableUtils.utils.appendToFileName; import static loadableUtils.utils.appendToTextFile; import static loadableUtils.utils.arrayPlus; import static loadableUtils.utils.arraycopy; import static loadableUtils.utils.asList; import static loadableUtils.utils.asTreeSet; import static loadableUtils.utils.assertIdentifier; import static loadableUtils.utils.assertNempty; import static loadableUtils.utils.assertNotNull; import static loadableUtils.utils.assertSameSize; import static loadableUtils.utils.awtCalcEvery; import static loadableUtils.utils.awtCalcRegularly; import static loadableUtils.utils.awtEvery; import static loadableUtils.utils.awtEveryAndNow; import static loadableUtils.utils.base64encode; import static loadableUtils.utils.bindComboBoxToVar; import static loadableUtils.utils.bindListenerToComponent; import static loadableUtils.utils.blendColors; import static loadableUtils.utils.boostHashCombine; import static loadableUtils.utils.borderless; import static loadableUtils.utils.borderlessScrollPane; import static loadableUtils.utils.bwDistance; import static loadableUtils.utils.bwIntegralImage; import static loadableUtils.utils.bwIntegralImage_withMeta; import static loadableUtils.utils.bytesFromHex; import static loadableUtils.utils.bytesToHex; import static loadableUtils.utils.cDeref; import static loadableUtils.utils.cMigrateField; import static loadableUtils.utils.calcFitScale; import static loadableUtils.utils.callMC; import static loadableUtils.utils.callOpt_getCache; import static loadableUtils.utils.call_withVarargs; import static loadableUtils.utils.cancelThread; import static loadableUtils.utils.center; import static loadableUtils.utils.centerAndSouthOrEast; import static loadableUtils.utils.centerAndSouthWithMargin; import static loadableUtils.utils.centerFrame; import static loadableUtils.utils.centeredLiveValueLabel; import static loadableUtils.utils.charAt; import static loadableUtils.utils.charIndexToCharInToken; import static loadableUtils.utils.characters; import static loadableUtils.utils.checkmarkIconID; import static loadableUtils.utils.ciMap; import static loadableUtils.utils.ciSorted; import static loadableUtils.utils.cic; import static loadableUtils.utils.clamp; import static loadableUtils.utils.clampZeroToOne; import static loadableUtils.utils.classForName; import static loadableUtils.utils.classLoader; import static loadableUtils.utils.className; import static loadableUtils.utils.clear; import static loadableUtils.utils.cloneBufferedImageWithMeta; import static loadableUtils.utils.cloneKeys; import static loadableUtils.utils.cloneList; import static loadableUtils.utils.cloneMap; import static loadableUtils.utils.close; import static loadableUtils.utils.cmp; import static loadableUtils.utils.cmpAlphanumIC; import static loadableUtils.utils.codeTokens; import static loadableUtils.utils.collect; import static loadableUtils.utils.collectionMutex; import static loadableUtils.utils.colorFromHex; import static loadableUtils.utils.colorToIntOpaque; import static loadableUtils.utils.comboBoxContainsItem; import static loadableUtils.utils.commaCombine; import static loadableUtils.utils.compileRegexp; import static loadableUtils.utils.componentPopupMenuItem; import static loadableUtils.utils.componentPopupMenuItems; import static loadableUtils.utils.computerID; import static loadableUtils.utils.concatArrays; import static loadableUtils.utils.concatLists; import static loadableUtils.utils.concatMap; import static loadableUtils.utils.conceptsDir; import static loadableUtils.utils.conceptsWhere; import static loadableUtils.utils.contains; import static loadableUtils.utils.containsIgnoreCase; import static loadableUtils.utils.containsKey; import static loadableUtils.utils.containsPred; import static loadableUtils.utils.containsTabNameWithoutTrailingCount; import static loadableUtils.utils.copyFields; import static loadableUtils.utils.copyStream; import static loadableUtils.utils.countConcepts; import static loadableUtils.utils.countIteratorAsList_incl; import static loadableUtils.utils.countIterator_inclusive_backwards; import static loadableUtils.utils.createEmptyConceptsFileInDir; import static loadableUtils.utils.createGraphics; import static loadableUtils.utils.createOrAddToSyncLinkedHashSet; import static loadableUtils.utils.currentThread; import static loadableUtils.utils.customLayoutPanel; import static loadableUtils.utils.dO; import static loadableUtils.utils.dateWithMSUTC; import static loadableUtils.utils.deleteConcept; import static loadableUtils.utils.deleteConcepts; import static loadableUtils.utils.deriveFont; import static loadableUtils.utils.descTreeMap; import static loadableUtils.utils.desktopOpen; import static loadableUtils.utils.dirExists; import static loadableUtils.utils.dirPath; import static loadableUtils.utils.disableButton; import static loadableUtils.utils.disposeFrame; import static loadableUtils.utils.dm_callStem; import static loadableUtils.utils.dm_checkBox; import static loadableUtils.utils.dm_onFieldChange; import static loadableUtils.utils.dm_rcheckBox; import static loadableUtils.utils.dm_rst; import static loadableUtils.utils.dm_spinner; import static loadableUtils.utils.dm_transientCalculatedLabel; import static loadableUtils.utils.dm_transientCalculatedToolTip; import static loadableUtils.utils.dm_watchFieldAndNow; import static loadableUtils.utils.doPost; import static loadableUtils.utils.domainIsUnder; import static loadableUtils.utils.done; import static loadableUtils.utils.done2_always; import static loadableUtils.utils.doubleRatio; import static loadableUtils.utils.doubleRectFromPoints; import static loadableUtils.utils.drawImage; import static loadableUtils.utils.drawImageOnImage; import static loadableUtils.utils.drawLine; import static loadableUtils.utils.dropPrefix; import static loadableUtils.utils.dropSuffix; import static loadableUtils.utils.dropTrailingBracketedCount; import static loadableUtils.utils.dualLog; import static loadableUtils.utils.dynamicHStack; import static loadableUtils.utils.empty; import static loadableUtils.utils.emptyList; import static loadableUtils.utils.emptyObjectArray; import static loadableUtils.utils.enableScaffolding; import static loadableUtils.utils.enclosingViewPosition; import static loadableUtils.utils.endsWith; import static loadableUtils.utils.entries; import static loadableUtils.utils.entrySet; import static loadableUtils.utils.eq; import static loadableUtils.utils.eqOneOf; import static loadableUtils.utils.eqic; import static loadableUtils.utils.eqicOneOf; import static loadableUtils.utils.evalWithTimeoutOrFail; import static loadableUtils.utils.evalWithTimeoutOrTypedException; import static loadableUtils.utils.even; import static loadableUtils.utils.ewic; import static loadableUtils.utils.exceptionToStringShort; import static loadableUtils.utils.exceptionToStringShorter; import static loadableUtils.utils.exceptionToStringShorter_dontDropOuterExceptions; import static loadableUtils.utils.execFileChooser; import static loadableUtils.utils.f2s; import static loadableUtils.utils.fileExists; import static loadableUtils.utils.fileExtension; import static loadableUtils.utils.fileInfo; import static loadableUtils.utils.fileName; import static loadableUtils.utils.fileSize; import static loadableUtils.utils.findConceptWhereCI; import static loadableUtils.utils.findWebCamByName; import static loadableUtils.utils.first; import static loadableUtils.utils.firstIntFromLong; import static loadableUtils.utils.firstThat; import static loadableUtils.utils.firstToLower; import static loadableUtils.utils.firstValue; import static loadableUtils.utils.flattenCollectionsAndArrays; import static loadableUtils.utils.flattenToList; import static loadableUtils.utils.floatRatio; import static loadableUtils.utils.focus; import static loadableUtils.utils.focusOnFirstShow; import static loadableUtils.utils.focusOnFirstShowVerbose; import static loadableUtils.utils.fontSizePlus; import static loadableUtils.utils.formatDoubleX; import static loadableUtils.utils.formatRecordVars; import static loadableUtils.utils.formatSeconds; import static loadableUtils.utils.formatSnippetID; import static loadableUtils.utils.formatSnippetIDOpt; import static loadableUtils.utils.getCaretPosition; import static loadableUtils.utils.getClass; import static loadableUtils.utils.getClassLoader; import static loadableUtils.utils.getClassName; import static loadableUtils.utils.getContentPane; import static loadableUtils.utils.getFileSize; import static loadableUtils.utils.getHeight; import static loadableUtils.utils.getMainClass; import static loadableUtils.utils.getMetaSrc; import static loadableUtils.utils.getMinimumSize; import static loadableUtils.utils.getOrCreate; import static loadableUtils.utils.getSelectedItem_typed; import static loadableUtils.utils.getString; import static loadableUtils.utils.getText; import static loadableUtils.utils.getTextTrim; import static loadableUtils.utils.getType; import static loadableUtils.utils.getVar; import static loadableUtils.utils.getWidth; import static loadableUtils.utils.getWindow; import static loadableUtils.utils.getterVarOnly; import static loadableUtils.utils.graphics; import static loadableUtils.utils.grayToColor; import static loadableUtils.utils.hasMethodNamed; import static loadableUtils.utils.hashCode; import static loadableUtils.utils.horizontalStrut; import static loadableUtils.utils.hstack; import static loadableUtils.utils.hstackWithSpacing; import static loadableUtils.utils.iBWImageFromFunction; import static loadableUtils.utils.iceil; import static loadableUtils.utils.identifiers; import static loadableUtils.utils.identityHashSet; import static loadableUtils.utils.imageGraphics; import static loadableUtils.utils.imageIcon; import static loadableUtils.utils.imageSurface; import static loadableUtils.utils.imageSurfaceOnLeftMouseDown; import static loadableUtils.utils.imageSurface_pixelated; import static loadableUtils.utils.inc; import static loadableUtils.utils.incAtomicLong; import static loadableUtils.utils.indentStructureString; import static loadableUtils.utils.indentedStructureForUser; import static loadableUtils.utils.indexConceptField; import static loadableUtils.utils.indexConceptFieldCI; import static loadableUtils.utils.indexOfTabName; import static loadableUtils.utils.indexOfTabNameWithoutTrailingCount; import static loadableUtils.utils.inputImage; import static loadableUtils.utils.intArrayToBufferedImage; import static loadableUtils.utils.intFromSpinner; import static loadableUtils.utils.invokeMethod; import static loadableUtils.utils.iround; import static loadableUtils.utils.is; import static loadableUtils.utils.isAnonymousClassName; import static loadableUtils.utils.isDeepContainedInDir_canonical; import static loadableUtils.utils.isEmpty; import static loadableUtils.utils.isFile; import static loadableUtils.utils.isImageFile; import static loadableUtils.utils.isImageFileName; import static loadableUtils.utils.isInstance; import static loadableUtils.utils.isInstanceX; import static loadableUtils.utils.isInteger; import static loadableUtils.utils.isLetterOrDigit; import static loadableUtils.utils.isScreenCoordinateInWindow; import static loadableUtils.utils.isShowing; import static loadableUtils.utils.isSnippetID; import static loadableUtils.utils.isStaticMethod; import static loadableUtils.utils.isSubclassOf; import static loadableUtils.utils.isURL; import static loadableUtils.utils.isValidFileName; import static loadableUtils.utils.itemPlus; import static loadableUtils.utils.iterateWithIndex; import static loadableUtils.utils.iterator; import static loadableUtils.utils.iteratorFromFunction; import static loadableUtils.utils.jBorderlessHigherScrollPane; import static loadableUtils.utils.jCenteredLabel; import static loadableUtils.utils.jCenteredLine; import static loadableUtils.utils.jCenteredRaisedSection; import static loadableUtils.utils.jCheckBoxMenuItem_dyn; import static loadableUtils.utils.jComboBox; import static loadableUtils.utils.jErrorView; import static loadableUtils.utils.jFastLogView_noWrap; import static loadableUtils.utils.jHigherScrollPane; import static loadableUtils.utils.jImage_scaledToHeight; import static loadableUtils.utils.jLabel; import static loadableUtils.utils.jListSpinner; import static loadableUtils.utils.jLiveTextField; import static loadableUtils.utils.jLiveValueComboBox; import static loadableUtils.utils.jMaxWidth; import static loadableUtils.utils.jMenuItem; import static loadableUtils.utils.jMinHeight; import static loadableUtils.utils.jMinSize; import static loadableUtils.utils.jMinWidth; import static loadableUtils.utils.jOnDemand; import static loadableUtils.utils.jPreferHeight; import static loadableUtils.utils.jProgressBarWithText; import static loadableUtils.utils.jRaisedCenteredSection; import static loadableUtils.utils.jRaisedSection; import static loadableUtils.utils.jSimpleLabel; import static loadableUtils.utils.jSmallErrorView; import static loadableUtils.utils.jSpinner; import static loadableUtils.utils.jTextArea_noUndo; import static loadableUtils.utils.jTextField; import static loadableUtils.utils.jTopOrLeftTabs; import static loadableUtils.utils.jTypedComboBox; import static loadableUtils.utils.javaVersion; import static loadableUtils.utils.javaxDataDir; import static loadableUtils.utils.javaxSecretDir; import static loadableUtils.utils.jbuttonWithDisable; import static loadableUtils.utils.jcenteredLabel; import static loadableUtils.utils.jcenteredlabel; import static loadableUtils.utils.jcenteredline; import static loadableUtils.utils.jfind; import static loadableUtils.utils.jfullcenter; import static loadableUtils.utils.jimageButton; import static loadableUtils.utils.jimageButtonScaledToWidth; import static loadableUtils.utils.joinNempties; import static loadableUtils.utils.joinNemptiesWithComma; import static loadableUtils.utils.joinWithComma; import static loadableUtils.utils.jpanel; import static loadableUtils.utils.jscroll; import static loadableUtils.utils.jscrollHorizontal; import static loadableUtils.utils.jscroll_center_borderless; import static loadableUtils.utils.jscroll_centered_borderless; import static loadableUtils.utils.jsonEncode; import static loadableUtils.utils.jtabs; import static loadableUtils.utils.jtextfield; import static loadableUtils.utils.jvsplit; import static loadableUtils.utils.keys; import static loadableUtils.utils.lCommonPrefix; import static loadableUtils.utils.lastIndexOf; import static loadableUtils.utils.length; import static loadableUtils.utils.licensed; import static loadableUtils.utils.lightBlue; import static loadableUtils.utils.lines; import static loadableUtils.utils.linesFromFile; import static loadableUtils.utils.linesFromReader; import static loadableUtils.utils.linesOfCode_javaTok; import static loadableUtils.utils.lines_rtrim; import static loadableUtils.utils.list; import static loadableUtils.utils.listAllFrames; import static loadableUtils.utils.listDirs; import static loadableUtils.utils.listDirsContainingFileNamed; import static loadableUtils.utils.listFields; import static loadableUtils.utils.listFromFunction; import static loadableUtils.utils.listGetOrCreate; import static loadableUtils.utils.listMinusSet; import static loadableUtils.utils.listWebCams; import static loadableUtils.utils.listWithout; import static loadableUtils.utils.litlist; import static loadableUtils.utils.litorderedmap; import static loadableUtils.utils.litset; import static loadableUtils.utils.liveValueCheckBox; import static loadableUtils.utils.liveValue_hasChangeListeners; import static loadableUtils.utils.ll; import static loadableUtils.utils.loadBinaryPage_noHeaders; import static loadableUtils.utils.loadImage2; import static loadableUtils.utils.loadLibrary; import static loadableUtils.utils.loadTextFile; import static loadableUtils.utils.lock; import static loadableUtils.utils.longestPrefixInTreeSet; import static loadableUtils.utils.lowest; import static loadableUtils.utils.makeAccessible; import static loadableUtils.utils.makeBold; import static loadableUtils.utils.makeFileNameUnique_beforeExtension_startWith1_noDot; import static loadableUtils.utils.makeForm3; import static loadableUtils.utils.map; import static loadableUtils.utils.mapEachLine; import static loadableUtils.utils.mapGet; import static loadableUtils.utils.mapI; import static loadableUtils.utils.mapKeys; import static loadableUtils.utils.mapLL; import static loadableUtils.utils.mapNonNulls; import static loadableUtils.utils.mapPlus; import static loadableUtils.utils.mapSortedByValue; import static loadableUtils.utils.mapToArray; import static loadableUtils.utils.mapToTreeSet; import static loadableUtils.utils.mapValues; import static loadableUtils.utils.mapWithSingleValue; import static loadableUtils.utils.max; import static loadableUtils.utils.menuItem; import static loadableUtils.utils.mergeRects; import static loadableUtils.utils.messageBox; import static loadableUtils.utils.methodNames; import static loadableUtils.utils.microSymbol; import static loadableUtils.utils.min; import static loadableUtils.utils.mkdirsForFile; import static loadableUtils.utils.mouseArea; import static loadableUtils.utils.mouseLocationPt; import static loadableUtils.utils.mul; import static loadableUtils.utils.n2; import static loadableUtils.utils.nFrames; import static loadableUtils.utils.nImages; import static loadableUtils.utils.nLabels; import static loadableUtils.utils.nLines; import static loadableUtils.utils.nRegions; import static loadableUtils.utils.nResults; import static loadableUtils.utils.nameRelativeToPhysicalSubdirectory; import static loadableUtils.utils.nempty; import static loadableUtils.utils.neq; import static loadableUtils.utils.newBufferedImage; import static loadableUtils.utils.newFile; import static loadableUtils.utils.newFileInputStream; import static loadableUtils.utils.newFileOutputStream; import static loadableUtils.utils.newGZIPInputStream; import static loadableUtils.utils.newImage; import static loadableUtils.utils.nonNulls; import static loadableUtils.utils.northAndCenterWithMargins; import static loadableUtils.utils.northCenterAndSouthWithMargin; import static loadableUtils.utils.now; import static loadableUtils.utils.nsToMicroseconds; import static loadableUtils.utils.nuInstance; import static loadableUtils.utils.numberOfScreens; import static loadableUtils.utils.odd; import static loadableUtils.utils.onBoundsChange; import static loadableUtils.utils.onChangeAndNow; import static loadableUtils.utils.onFirstShow; import static loadableUtils.utils.onTabSelected; import static loadableUtils.utils.oneOf; import static loadableUtils.utils.openConnection; import static loadableUtils.utils.optCast; import static loadableUtils.utils.optPar; import static loadableUtils.utils.or; import static loadableUtils.utils.or2; import static loadableUtils.utils.or2_rev; import static loadableUtils.utils.origin; import static loadableUtils.utils.outerProduct; import static loadableUtils.utils.ownResource; import static loadableUtils.utils.packFrame; import static loadableUtils.utils.pair; import static loadableUtils.utils.pairB; import static loadableUtils.utils.paramsPlus; import static loadableUtils.utils.paramsToMap; import static loadableUtils.utils.parseDouble; import static loadableUtils.utils.parseInt; import static loadableUtils.utils.parseLong; import static loadableUtils.utils.pcallF; import static loadableUtils.utils.pcallFAll; import static loadableUtils.utils.persistSelectedTabAsLiveValue; import static loadableUtils.utils.persistableThrowable; import static loadableUtils.utils.picturesDir; import static loadableUtils.utils.ping; import static loadableUtils.utils.pixelatedImageSurface; import static loadableUtils.utils.pnl; import static loadableUtils.utils.pnlToLines; import static loadableUtils.utils.pnlToString; import static loadableUtils.utils.popLast; import static loadableUtils.utils.possibleMD5; import static loadableUtils.utils.postPage; import static loadableUtils.utils.posterizeBWImage_withMeta; import static loadableUtils.utils.powersOfTwoUpTo; import static loadableUtils.utils.printStackTrace; import static loadableUtils.utils.printVars; import static loadableUtils.utils.proxy; import static loadableUtils.utils.psI; import static loadableUtils.utils.ptMinus; import static loadableUtils.utils.put; import static loadableUtils.utils.putAll; import static loadableUtils.utils.quote; import static loadableUtils.utils.quoteAll; import static loadableUtils.utils.r_dm_q; import static loadableUtils.utils.random; import static loadableUtils.utils.regexpMatcher; import static loadableUtils.utils.register; import static loadableUtils.utils.registerConcept; import static loadableUtils.utils.remove; import static loadableUtils.utils.removeAll; import static loadableUtils.utils.removeAllComponents; import static loadableUtils.utils.removeSubList; import static loadableUtils.utils.renameFileVerbose; import static loadableUtils.utils.renderRecordVars; import static loadableUtils.utils.renderStackTrace; import static loadableUtils.utils.repaint; import static loadableUtils.utils.replaceAll; import static loadableUtils.utils.replaceLast; import static loadableUtils.utils.replacePrefix; import static loadableUtils.utils.replaceTabTitleComponent; import static loadableUtils.utils.replaceTokens; import static loadableUtils.utils.reproduceRasterBars; import static loadableUtils.utils.rethrowAndAppendToMessage; import static loadableUtils.utils.revalidate; import static loadableUtils.utils.rightAlignLabel; import static loadableUtils.utils.rightAlignedLine; import static loadableUtils.utils.round; import static loadableUtils.utils.roundBracket; import static loadableUtils.utils.roundDownTo; import static loadableUtils.utils.runnableToIVF1; import static loadableUtils.utils.runnableToVF1; import static loadableUtils.utils.sameFile; import static loadableUtils.utils.sameSize; import static loadableUtils.utils.saveBinaryFile; import static loadableUtils.utils.saveGZStructureToFile; import static loadableUtils.utils.saveImage; import static loadableUtils.utils.saveImageWithCounter; import static loadableUtils.utils.saveJPG; import static loadableUtils.utils.saveTextFile; import static loadableUtils.utils.saveTiming_noPrint; import static loadableUtils.utils.scaleAndPosterize; import static loadableUtils.utils.scaleImageWithOp; import static loadableUtils.utils.scalePt; import static loadableUtils.utils.scaleRect; import static loadableUtils.utils.scaledBWImageFromBWIntegralImage_withMeta_height; import static loadableUtils.utils.screenCount; import static loadableUtils.utils.screenNrContaining; import static loadableUtils.utils.screenNrOfWindow; import static loadableUtils.utils.scrollingTabs; import static loadableUtils.utils.second; import static loadableUtils.utils.secondIntFromLong; import static loadableUtils.utils.selectItem; import static loadableUtils.utils.selectTab; import static loadableUtils.utils.selectedTabName; import static loadableUtils.utils.setBorder; import static loadableUtils.utils.setBounds; import static loadableUtils.utils.setButtonImage; import static loadableUtils.utils.setComboBoxItems; import static loadableUtils.utils.setComponent; import static loadableUtils.utils.setEnclosingViewPosition; import static loadableUtils.utils.setHeaders; import static loadableUtils.utils.setHorizontalAlignment; import static loadableUtils.utils.setLocation; import static loadableUtils.utils.setMargin; import static loadableUtils.utils.setMetaSrc; import static loadableUtils.utils.setProgressBarText; import static loadableUtils.utils.setProgressBarValue; import static loadableUtils.utils.setSectionTitle; import static loadableUtils.utils.setSelected; import static loadableUtils.utils.setSelectedItem; import static loadableUtils.utils.setSpinnerValue; import static loadableUtils.utils.setTab; import static loadableUtils.utils.setTabTitle; import static loadableUtils.utils.setTextKeepCaret; import static loadableUtils.utils.setToolTip; import static loadableUtils.utils.setToolTipText; import static loadableUtils.utils.sfuIndent; import static loadableUtils.utils.shallowClone; import static loadableUtils.utils.shortClassName; import static loadableUtils.utils.shortDynName; import static loadableUtils.utils.shorten; import static loadableUtils.utils.shortenClassName; import static loadableUtils.utils.showErrorFrame; import static loadableUtils.utils.showFrame; import static loadableUtils.utils.showImage; import static loadableUtils.utils.showPackedFrame; import static loadableUtils.utils.showTextWordWrapped; import static loadableUtils.utils.sixteenToNine_p; import static loadableUtils.utils.sleep; import static loadableUtils.utils.sleepSeconds; import static loadableUtils.utils.snippetImageURL; import static loadableUtils.utils.sort; import static loadableUtils.utils.sortInPlaceByCalculatedField; import static loadableUtils.utils.sortedByCalculatedField; import static loadableUtils.utils.sortedByComparator; import static loadableUtils.utils.stackTraceToString; import static loadableUtils.utils.standardImports; import static loadableUtils.utils.standardImports_fullyImportedPackages; import static loadableUtils.utils.startQ; import static loadableUtils.utils.startThread; import static loadableUtils.utils.startsWith; import static loadableUtils.utils.startsWithDigit; import static loadableUtils.utils.startsWithIgnoreCase; import static loadableUtils.utils.startsWithOneOf; import static loadableUtils.utils.stdHash; import static loadableUtils.utils.str; import static loadableUtils.utils.strOrClassName; import static loadableUtils.utils.strOrNull; import static loadableUtils.utils.str_shorten; import static loadableUtils.utils.str_toKB; import static loadableUtils.utils.str_toMB_oneDigit; import static loadableUtils.utils.stringLiveValue; import static loadableUtils.utils.stringify; import static loadableUtils.utils.stringsSortedByLength; import static loadableUtils.utils.subList; import static loadableUtils.utils.substring; import static loadableUtils.utils.swic; import static loadableUtils.utils.swing; import static loadableUtils.utils.swingAndWait; import static loadableUtils.utils.swingConfirm; import static loadableUtils.utils.swingNu; import static loadableUtils.utils.syncGetOrCreate; import static loadableUtils.utils.syncL; import static loadableUtils.utils.syncMRUCache; import static loadableUtils.utils.syncMap; import static loadableUtils.utils.syncSet; import static loadableUtils.utils.tabComponentClickFixer; import static loadableUtils.utils.tabNames; import static loadableUtils.utils.tableDependentButton; import static loadableUtils.utils.tablePopupMenuItem_top; import static loadableUtils.utils.tempDisableButton; import static loadableUtils.utils.tempInfoBox; import static loadableUtils.utils.tempInfoBox_noHide; import static loadableUtils.utils.tempMapPut; import static loadableUtils.utils.tempMapPutAll; import static loadableUtils.utils.tempSetRandomSeed; import static loadableUtils.utils.tempSetTL; import static loadableUtils.utils.textOut_or; import static loadableUtils.utils.tlft; import static loadableUtils.utils.toArray; import static loadableUtils.utils.toBW; import static loadableUtils.utils.toBWImage; import static loadableUtils.utils.toBufferedImage; import static loadableUtils.utils.toCIMap; import static loadableUtils.utils.toColor; import static loadableUtils.utils.toDouble; import static loadableUtils.utils.toHex; import static loadableUtils.utils.toInt; import static loadableUtils.utils.toList; import static loadableUtils.utils.toLong; import static loadableUtils.utils.toRect_round; import static loadableUtils.utils.toScanlineBitMatrix; import static loadableUtils.utils.toStringArray; import static loadableUtils.utils.toTypedArray; import static loadableUtils.utils.toUtf8; import static loadableUtils.utils.todo; import static loadableUtils.utils.translatePt; import static loadableUtils.utils.trim; import static loadableUtils.utils.tsNowPlusMS; import static loadableUtils.utils.ubyteToInt; import static loadableUtils.utils.unimplemented; import static loadableUtils.utils.uniq; import static loadableUtils.utils.uniqCI; import static loadableUtils.utils.uniq_returnIfNew; import static loadableUtils.utils.unlisted; import static loadableUtils.utils.unlock; import static loadableUtils.utils.unnull; import static loadableUtils.utils.unnullForIteration; import static loadableUtils.utils.updateEnclosingTabTitleWithCount; import static loadableUtils.utils.userDir; import static loadableUtils.utils.userDir_oneOf_createFirstIfNone; import static loadableUtils.utils.usingStarter; import static loadableUtils.utils.utf8; import static loadableUtils.utils.value; import static loadableUtils.utils.values; import static loadableUtils.utils.valuesList; import static loadableUtils.utils.varWithNotifyToLiveValue; import static loadableUtils.utils.verticalStrut; import static loadableUtils.utils.virtualCountList; import static loadableUtils.utils.vmBus_onMessage; import static loadableUtils.utils.vmBus_send; import static loadableUtils.utils.vstack; import static loadableUtils.utils.vstack2; import static loadableUtils.utils.vstackWithSpacing; import static loadableUtils.utils.vstackWithSpacing_fixed; import static loadableUtils.utils.waitUntil; import static loadableUtils.utils.weakHashMap; import static loadableUtils.utils.westAndCenter; import static loadableUtils.utils.westAndCenterWithMargin; import static loadableUtils.utils.white; import static loadableUtils.utils.whiteImage; import static loadableUtils.utils.withCenteredBoldTitle; import static loadableUtils.utils.withCenteredTitle; import static loadableUtils.utils.withLabel; import static loadableUtils.utils.withLabelToTheRight; import static loadableUtils.utils.withRightAlignedButtons; import static loadableUtils.utils.withRightMargin; import static loadableUtils.utils.withSideAndBottomMargin; import static loadableUtils.utils.withSideAndTopMargin; import static loadableUtils.utils.withSideMargin; import static loadableUtils.utils.withSideMargins; import static loadableUtils.utils.withToolTip; import static loadableUtils.utils.withTopAndBottomMargin; import static loadableUtils.utils.withTopRightAndBottomMargin; import static loadableUtils.utils.wrap; import static loadableUtils.utils.yesNoShort; import static loadableUtils.utils.yesNo_short; import static loadableUtils.utils.zipFile; import loadableUtils.utils.AbstractLayoutManager; import loadableUtils.utils.AnimatedLine; import loadableUtils.utils.Animation; import loadableUtils.utils.BackgroundProcessesUI; import loadableUtils.utils.IBackgroundProcesses; import loadableUtils.utils.IBackgroundProcess; import loadableUtils.utils.CenteredComboBoxRenderer; import loadableUtils.utils.CharInToken; import loadableUtils.utils.ClassNameResolver; import loadableUtils.utils.ClearForAutoRun; import loadableUtils.utils.CloseableIterableIterator; import loadableUtils.utils.CombinedStringifier; import loadableUtils.utils.ConceptWithChangeListeners; import loadableUtils.utils.ConceptWithGlobalID; import loadableUtils.utils.ConceptsComboBox; import loadableUtils.utils.DoubleFPSCounter; import loadableUtils.utils.FastRegions_BWImage; import loadableUtils.utils.FieldVar; import loadableUtils.utils.Flag; import loadableUtils.utils.FunctionTimings; import loadableUtils.utils.HasChangeListeners; import loadableUtils.utils.IF0WithChangeListeners; import loadableUtils.utils.IF2; import loadableUtils.utils.IF2_IntInt_Double; import loadableUtils.utils.IFieldsToList; import loadableUtils.utils.IHasTokenRangeWithSrc; import loadableUtils.utils.IIBWVirtualClip; import loadableUtils.utils.IImageRegion; import loadableUtils.utils.IImageRegions; import loadableUtils.utils.IVar; import loadableUtils.utils.IVarWithNotify; import loadableUtils.utils.IfThen; import loadableUtils.utils.ImageSurface_PositionToolTip; import loadableUtils.utils.IntMinMax; import loadableUtils.utils.JFFMPEGVideoPlayer; import loadableUtils.utils.JFilePathLabel; import loadableUtils.utils.JGallery; import loadableUtils.utils.JMiniJavaIDE; import loadableUtils.utils.JObjectTable; import loadableUtils.utils.JPaintTool; import loadableUtils.utils.JPopDownButton; import loadableUtils.utils.JVideoLibDownloader; import loadableUtils.utils.LineAndColumn; import loadableUtils.utils.Lowest; import loadableUtils.utils.MRUCache; import loadableUtils.utils.MetaWithChangeListeners; import loadableUtils.utils.NotifyingSet; import loadableUtils.utils.PosterizeBWImage; import loadableUtils.utils.PtBuffer; import loadableUtils.utils.RSyntaxTextAreaWithSearch; import loadableUtils.utils.RegionBorder_innerPoints; import loadableUtils.utils.RollingAverage; import loadableUtils.utils.ScanlineBitMatrix; import loadableUtils.utils.ScoredStringSearcher; import loadableUtils.utils.ScreenCamStream; import loadableUtils.utils.ScreenShotMeta; import loadableUtils.utils.SingleThread; import loadableUtils.utils.SnPSettings; import loadableUtils.utils.SourceTriggeredStream; import loadableUtils.utils.TimestampRange; import loadableUtils.utils.TokenRangeWithSrc; import loadableUtils.utils.UIURLSystem; import loadableUtils.utils.Value; import loadableUtils.utils.Var; import loadableUtils.utils.VarContext; import loadableUtils.utils.VarWithNotify; import loadableUtils.utils.VirtualVar; import loadableUtils.utils.WeakVar; import loadableUtils.utils.WithToolTip; import loadableUtils.utils.DoublePt; import loadableUtils.utils.JExtendedTabbedPane; import static loadableUtils.utils.addClassNameToInclude; import static loadableUtils.utils.addComponentAtIndex; import static loadableUtils.utils.addFunctionNameToInclude; import static loadableUtils.utils.addInFront; import static loadableUtils.utils.addKeyListener; import static loadableUtils.utils.addLibrary; import static loadableUtils.utils.addOrRemoveComponent; import static loadableUtils.utils.addPair; import static loadableUtils.utils.allToBufferedImage; import static loadableUtils.utils.appendNewLineIfNempty; import static loadableUtils.utils.appendPrefixIfNempty; import static loadableUtils.utils.asRuntimeException; import static loadableUtils.utils.assertSetEquals; import static loadableUtils.utils.atan2; import static loadableUtils.utils.averageBrightness; import static loadableUtils.utils.awtCalcContinuously; import static loadableUtils.utils.benchForNSeconds; import static loadableUtils.utils.bindChangeListenerToComponent; import static loadableUtils.utils.bindComboBoxToVar_withUserChangeListener; import static loadableUtils.utils.bindHasChangeListenersToComponent; import static loadableUtils.utils.blendColor; import static loadableUtils.utils.boostHashCombine64; import static loadableUtils.utils.bwImage; import static loadableUtils.utils.byteArrayStartsWith; import static loadableUtils.utils.castTo; import static loadableUtils.utils.charToTokenIndex_left; import static loadableUtils.utils.ciSet; import static loadableUtils.utils.classToBCELType; import static loadableUtils.utils.clearMetaSrc; import static loadableUtils.utils.cloneMultiSet; import static loadableUtils.utils.cloneTakeFirst; import static loadableUtils.utils.closeAndClear; import static loadableUtils.utils.cnewUnlisted; import static loadableUtils.utils.colorToInt; import static loadableUtils.utils.combineSteppables_dontDropEnded; import static loadableUtils.utils.compileRegexpIC; import static loadableUtils.utils.concatMapStrings; import static loadableUtils.utils.concatMap_lists; import static loadableUtils.utils.concatMethodArgs; import static loadableUtils.utils.conceptsFile; import static loadableUtils.utils.conceptsFileIn; import static loadableUtils.utils.constructorsWithNumberOfArguments; import static loadableUtils.utils.containsPt; import static loadableUtils.utils.countIteratorToList_incl; import static loadableUtils.utils.createOrRemoveFile; import static loadableUtils.utils.curly; import static loadableUtils.utils.cyclicSubList; import static loadableUtils.utils.cyclicSubList_incl; import static loadableUtils.utils.dbDir; import static loadableUtils.utils.deRoundBracket; import static loadableUtils.utils.dec; import static loadableUtils.utils.deleteDB; import static loadableUtils.utils.doublePt; import static loadableUtils.utils.doubleSum; import static loadableUtils.utils.drawRect; import static loadableUtils.utils.dropPrefixOrNull; import static loadableUtils.utils.editImageID; import static loadableUtils.utils.emptyBitSet; import static loadableUtils.utils.emptyItIt; import static loadableUtils.utils.f2s_opt; import static loadableUtils.utils.fieldNames; import static loadableUtils.utils.fieldObject; import static loadableUtils.utils.fileForLibrary; import static loadableUtils.utils.fillArray; import static loadableUtils.utils.findAllFiles; import static loadableUtils.utils.findFieldOfClass; import static loadableUtils.utils.findSingleInterfaceMethodOrFail; import static loadableUtils.utils.firstKey; import static loadableUtils.utils.fixFieldValues; import static loadableUtils.utils.floor; import static loadableUtils.utils.floorValue; import static loadableUtils.utils.fontMetrics; import static loadableUtils.utils.fontSize; import static loadableUtils.utils.formatElapsedTimeWithAppropriateUnit; import static loadableUtils.utils.frac; import static loadableUtils.utils.getAndClear; import static loadableUtils.utils.getBit; import static loadableUtils.utils.getCenterComponent; import static loadableUtils.utils.getColor; import static loadableUtils.utils.getComponentAtIndex; import static loadableUtils.utils.getConcept; import static loadableUtils.utils.getFont; import static loadableUtils.utils.getList; import static loadableUtils.utils.getPixel; import static loadableUtils.utils.getSliderValue; import static loadableUtils.utils.growRect; import static loadableUtils.utils.handleObjectMethodsInProxyInvocationHandler; import static loadableUtils.utils.hasAlpha; import static loadableUtils.utils.hash; import static loadableUtils.utils.hashRefTok; import static loadableUtils.utils.hostToIP; import static loadableUtils.utils.iceil_div; import static loadableUtils.utils.iff_null; import static loadableUtils.utils.imageRect; import static loadableUtils.utils.imageSize; import static loadableUtils.utils.imageSurfaceOnHover; import static loadableUtils.utils.inRange; import static loadableUtils.utils.indexOfSelectedTab; import static loadableUtils.utils.infinity; import static loadableUtils.utils.innerExceptionOfType; import static loadableUtils.utils.inputText; import static loadableUtils.utils.installCompletionProvider; import static loadableUtils.utils.intArrayToBufferedImageWithoutAlpha; import static loadableUtils.utils.intFromBinary; import static loadableUtils.utils.intRange_incl; import static loadableUtils.utils.integralImage; import static loadableUtils.utils.invokeMethodWithWidening; import static loadableUtils.utils.isAbsoluteURL; import static loadableUtils.utils.isAnonymousClass; import static loadableUtils.utils.isArray; import static loadableUtils.utils.isDeepContainedInDir_absolute; import static loadableUtils.utils.isDirectory; import static loadableUtils.utils.isInterface; import static loadableUtils.utils.isPrimitiveType; import static loadableUtils.utils.isSameFile; import static loadableUtils.utils.isStandardClass; import static loadableUtils.utils.isStandardFunction; import static loadableUtils.utils.isStaticField; import static loadableUtils.utils.iterator_gen; import static loadableUtils.utils.jBoldLabel; import static loadableUtils.utils.jCenteredRaisedBoldLiveValueSection; import static loadableUtils.utils.jExtendedTabs; import static loadableUtils.utils.jFilePathButton; import static loadableUtils.utils.jGazelleLogo; import static loadableUtils.utils.jImageButton; import static loadableUtils.utils.jImageButtonScaledToWidth; import static loadableUtils.utils.jLabelShortCalcedEvery; import static loadableUtils.utils.jLiveValueCheckBoxMenuItem; import static loadableUtils.utils.jMinWidth_pure; import static loadableUtils.utils.jThreadedButton; import static loadableUtils.utils.jVarCheckBox; import static loadableUtils.utils.jVarTextField; import static loadableUtils.utils.jVerticalStrut; import static loadableUtils.utils.javaxClassShortcuts; import static loadableUtils.utils.jcenterNarrowLabel; import static loadableUtils.utils.jcheckbox; import static loadableUtils.utils.jlist; import static loadableUtils.utils.joinMaps; import static loadableUtils.utils.joinNemptiesWithEmptyLines; import static loadableUtils.utils.joinNemptiesWithSpace; import static loadableUtils.utils.joinNemptiesWithSpacedPlus; import static loadableUtils.utils.joinSets; import static loadableUtils.utils.joinWithCommaOr; import static loadableUtils.utils.jscrollVertical; import static loadableUtils.utils.jscroll_borderless; import static loadableUtils.utils.jscroll_vertical; import static loadableUtils.utils.lambdaArgsToString_pureJava; import static loadableUtils.utils.lastEntry; import static loadableUtils.utils.linkVars; import static loadableUtils.utils.listFiles; import static loadableUtils.utils.listMinus; import static loadableUtils.utils.listToSquareishChunks; import static loadableUtils.utils.litmap; import static loadableUtils.utils.liveValueLabel; import static loadableUtils.utils.llNonNulls; import static loadableUtils.utils.load; import static loadableUtils.utils.loadBeginningOfBinaryFile; import static loadableUtils.utils.loadFirstBytes; import static loadableUtils.utils.localFont; import static loadableUtils.utils.localFontFamilies; import static loadableUtils.utils.lookupOrKeep; import static loadableUtils.utils.mapToArrayOrNull; import static loadableUtils.utils.mapToIntArray; import static loadableUtils.utils.map_pcall; import static loadableUtils.utils.markVisualizer; import static loadableUtils.utils.mlsUnindent; import static loadableUtils.utils.moveCaretToLineAndCol; import static loadableUtils.utils.multiMapIndex; import static loadableUtils.utils.multiMapToMapPairs; import static loadableUtils.utils.multiSetMapToMapPairs; import static loadableUtils.utils.n2OrStrOrNull; import static loadableUtils.utils.nCharacters; import static loadableUtils.utils.nPixels; import static loadableUtils.utils.nPoints; import static loadableUtils.utils.nSteps; import static loadableUtils.utils.nanos; import static loadableUtils.utils.neg; import static loadableUtils.utils.nempties; import static loadableUtils.utils.newInstance; import static loadableUtils.utils.newObject; import static loadableUtils.utils.newPreciseCall; import static loadableUtils.utils.not; import static loadableUtils.utils.notNull; import static loadableUtils.utils.numberOfBitsNeededToRepresentNOptions; import static loadableUtils.utils.onSelect; import static loadableUtils.utils.onSelectionChanged; import static loadableUtils.utils.onTabSelectedAndNow; import static loadableUtils.utils.onePathDirection; import static loadableUtils.utils.onePathDirection_long; import static loadableUtils.utils.onePathLookupDirection; import static loadableUtils.utils.optimizedUniq; import static loadableUtils.utils.overlappingPairs; import static loadableUtils.utils.pairsA; import static loadableUtils.utils.paragraphs; import static loadableUtils.utils.parseFloat; import static loadableUtils.utils.parseHexInt; import static loadableUtils.utils.parseHexRange; import static loadableUtils.utils.parseLineAndColumn; import static loadableUtils.utils.parseList; import static loadableUtils.utils.pcallF_typed; import static loadableUtils.utils.pixelsOfBufferedImage; import static loadableUtils.utils.pointDistance; import static loadableUtils.utils.popFirst; import static loadableUtils.utils.pow; import static loadableUtils.utils.preciseGetOrCallMethod; import static loadableUtils.utils.preciseNuObject; import static loadableUtils.utils.primitiveToBoxedType; import static loadableUtils.utils.printVarsInMultipleLines; import static loadableUtils.utils.proxyFromInvocationHandler; import static loadableUtils.utils.ptDiff; import static loadableUtils.utils.ptPlus; import static loadableUtils.utils.regexReplace; import static loadableUtils.utils.regexpFind; import static loadableUtils.utils.regexpIC; import static loadableUtils.utils.regexpReplace; import static loadableUtils.utils.regexpReplace_direct; import static loadableUtils.utils.removeLast; import static loadableUtils.utils.repArray; import static loadableUtils.utils.replaceIfEqual; import static loadableUtils.utils.replaceRegexp; import static loadableUtils.utils.resolve; import static loadableUtils.utils.restructure; import static loadableUtils.utils.reverseInPlace; import static loadableUtils.utils.reversed; import static loadableUtils.utils.rightAlignedLabel; import static loadableUtils.utils.rotatePtLeft; import static loadableUtils.utils.rotatePtRight; import static loadableUtils.utils.roundBracketed; import static loadableUtils.utils.roundRobinCombinedIterator; import static loadableUtils.utils.rst; import static loadableUtils.utils.rstWithPreDelay; import static loadableUtils.utils.rtrim; import static loadableUtils.utils.runResultWithTimestamps; import static loadableUtils.utils.sansSerif; import static loadableUtils.utils.scaleImage; import static loadableUtils.utils.scp; import static loadableUtils.utils.selectTabComponent; import static loadableUtils.utils.setBit; import static loadableUtils.utils.setEditable; import static loadableUtils.utils.setFontSize; import static loadableUtils.utils.setLast; import static loadableUtils.utils.setPixel; import static loadableUtils.utils.shortToString; import static loadableUtils.utils.showFormTitled3; import static loadableUtils.utils.similarEmptySet; import static loadableUtils.utils.sortByCalculatedFieldAlphaNumIC; import static loadableUtils.utils.sortFilesAlphaNumIC; import static loadableUtils.utils.sortIntArrayInPlaceDesc; import static loadableUtils.utils.spinnerSetNumberList; import static loadableUtils.utils.splitAtComma_trim; import static loadableUtils.utils.step; import static loadableUtils.utils.str_pcall; import static loadableUtils.utils.str_px; import static loadableUtils.utils.str_toK; import static loadableUtils.utils.str_toM; import static loadableUtils.utils.str_toMB; import static loadableUtils.utils.stringIf; import static loadableUtils.utils.synchroLinkedList; import static loadableUtils.utils.synchroNavigableMap; import static loadableUtils.utils.tabToSingleSpace; import static loadableUtils.utils.tempAddGlobalCtrlKeyListener; import static loadableUtils.utils.tempRestoreMap; import static loadableUtils.utils.tempSetBoolVar; import static loadableUtils.utils.testBit; import static loadableUtils.utils.toArrayOrNull; import static loadableUtils.utils.toDoubleOrNull; import static loadableUtils.utils.toIVF1; import static loadableUtils.utils.toPoint; import static loadableUtils.utils.toVF1; import static loadableUtils.utils.transformedLiveValueLabel; import static loadableUtils.utils.trimAll; import static loadableUtils.utils.ubyteFromBits; import static loadableUtils.utils.uneditableBlack; import static loadableUtils.utils.uneditableTextArea; import static loadableUtils.utils.uploadImageFileDialog; import static loadableUtils.utils.upper; import static loadableUtils.utils.usedMemory; import static loadableUtils.utils.virtualCountList_incl; import static loadableUtils.utils.waitForVarPredicate; import static loadableUtils.utils.widthAndHeight; import static loadableUtils.utils.withAlpha; import static loadableUtils.utils.withTopAndLeftMargin; import static loadableUtils.utils.wordWrapTypeWriterTextArea; import static loadableUtils.utils.zip; import loadableUtils.utils.AWTOnConceptChangesByClass; import loadableUtils.utils.BoundsFinder; import loadableUtils.utils.ClassMaker; import loadableUtils.utils.CollapsibleLeftPanel; import loadableUtils.utils.CollapsibleNorthPanel; import loadableUtils.utils.DefaultButtonBorder; import loadableUtils.utils.DeleteFilesDialog; import loadableUtils.utils.HasTokenRangeWithSrc; import loadableUtils.utils.HashRefTokenMaker; import loadableUtils.utils.HashedBWImage; import loadableUtils.utils.IBinaryImage; import loadableUtils.utils.IF2_Int; import loadableUtils.utils.IIntIntPred; import loadableUtils.utils.IPersistenceInfo; import loadableUtils.utils.Image2B; import loadableUtils.utils.ImageFileFilter; import loadableUtils.utils.InMemoryClassLoader; import loadableUtils.utils.IndexIterator; import loadableUtils.utils.InstantNeverHideToolTip; import loadableUtils.utils.JSyntaxTextFileEditor; import loadableUtils.utils.JVMStackCellType; import loadableUtils.utils.JavaXPeepholeShortener; import loadableUtils.utils.MethodMaker; import loadableUtils.utils.NamedConcept; import loadableUtils.utils.OnePathWithOrigin; import loadableUtils.utils.PersistableOKOrError; import loadableUtils.utils.PopupMenuMaker; import loadableUtils.utils.PtSet; import loadableUtils.utils.RSTADummyParser; import loadableUtils.utils.RecognizedRegion; import loadableUtils.utils.RectAsRecognizedBox; import loadableUtils.utils.RegionBorder_innerPoints_v2; import loadableUtils.utils.RegionBorder_innerPoints_withDiagonals; import loadableUtils.utils.RenderRecognizedBox; import loadableUtils.utils.RenderText; import loadableUtils.utils.RunResultWithTimestamps; import loadableUtils.utils.UniquifyUsingHasher; import loadableUtils.utils.WeightlessShuffledIterator; import loadableUtils.utils.IntSize; import loadableUtils.utils.TransientObject; import loadableUtils.utils.IMakeEmptyClone; import loadableUtils.utils.ByteIO; import loadableUtils.utils.ByteHead; import loadableUtils.utils.BufferedImageWithMeta; import loadableUtils.utils.RegionToImage2B; import loadableUtils.utils.RunnablesReferenceQueue; import static loadableUtils.utils._print; import static loadableUtils.utils.absdiff; import static loadableUtils.utils.allEq; import static loadableUtils.utils.allToStruct; import static loadableUtils.utils.alphaChannelAverage; import static loadableUtils.utils.alphaChannelFromPixels; import static loadableUtils.utils.antiFilter; import static loadableUtils.utils.appendRoundBracketed; import static loadableUtils.utils.areaRoot; import static loadableUtils.utils.asPercentIncrease; import static loadableUtils.utils.assertNotSame; import static loadableUtils.utils.assertProperStreaks; import static loadableUtils.utils.assertValidFileName; import static loadableUtils.utils.average; import static loadableUtils.utils.avg; import static loadableUtils.utils.baseDirInZip; import static loadableUtils.utils.biggestRegionsFirst; import static loadableUtils.utils.biggestSSIsFirst; import static loadableUtils.utils.bindTextComponentToVarWithNotify_noInitialUndo; import static loadableUtils.utils.bindVarToVar; import static loadableUtils.utils.bitCount; import static loadableUtils.utils.blackImage; import static loadableUtils.utils.blendRGBInts; import static loadableUtils.utils.blurBufferedImage; import static loadableUtils.utils.blurFilterBufferedImage; import static loadableUtils.utils.boxed; import static loadableUtils.utils.boxedIntOrLong; import static loadableUtils.utils.bufferedImageContrastAndBrightness; import static loadableUtils.utils.bwImageFromFunction; import static loadableUtils.utils.cachePosterizer; import static loadableUtils.utils.cbrt; import static loadableUtils.utils.centerTextField; import static loadableUtils.utils.certaintyImage; import static loadableUtils.utils.classIs; import static loadableUtils.utils.classNameWithIdentity; import static loadableUtils.utils.cloneAndClear; import static loadableUtils.utils.colonCombine; import static loadableUtils.utils.color; import static loadableUtils.utils.combinedChildBounds; import static loadableUtils.utils.compilationDateFromClassPath; import static loadableUtils.utils.componentToFront; import static loadableUtils.utils.concat; import static loadableUtils.utils.conceptCount; import static loadableUtils.utils.copyTextToClipboardVerbose; import static loadableUtils.utils.count; import static loadableUtils.utils.createOrAddToSet; import static loadableUtils.utils.cset_trueIfChanged; import static loadableUtils.utils.ctrlLetterKeyListener; import static loadableUtils.utils.cubed; import static loadableUtils.utils.decodeImage; import static loadableUtils.utils.diff; import static loadableUtils.utils.dir2zip; import static loadableUtils.utils.directChildrenOfType; import static loadableUtils.utils.distancePointToLineSegment; import static loadableUtils.utils.doubleAverage; import static loadableUtils.utils.doubleMin; import static loadableUtils.utils.doubleRange; import static loadableUtils.utils.drawPixels; import static loadableUtils.utils.dropStarPrefix; import static loadableUtils.utils.file2stream; import static loadableUtils.utils.fileSavedInfoBox; import static loadableUtils.utils.findMethod_withPrimitiveWidening_onTypes; import static loadableUtils.utils.findMethodsNamed_cached; import static loadableUtils.utils.firstNCubes; import static loadableUtils.utils.flatInfoBox; import static loadableUtils.utils.flipCoin; import static loadableUtils.utils.formatDouble2; import static loadableUtils.utils.formatDouble2X; import static loadableUtils.utils.functionKeyListener; import static loadableUtils.utils.genericStreaks; import static loadableUtils.utils.getMyIP; import static loadableUtils.utils.greaterOrEq; import static loadableUtils.utils.growRectTopAndLeft; import static loadableUtils.utils.hasStaticMethodNamed; import static loadableUtils.utils.haveTranspilationPassword; import static loadableUtils.utils.hi15ToRGBInt_clean; import static loadableUtils.utils.highestBy; import static loadableUtils.utils.highestByField; import static loadableUtils.utils.image2BFromFunction; import static loadableUtils.utils.imageToPixels; import static loadableUtils.utils.indentedStruct; import static loadableUtils.utils.indexOfInSortedArray; import static loadableUtils.utils.insertAt; import static loadableUtils.utils.instancesOf; import static loadableUtils.utils.intRangesOverlapNempty; import static loadableUtils.utils.intToHex_fullLength; import static loadableUtils.utils.itemPlusArray; import static loadableUtils.utils.jLiveValueSlider_int_bothWays; import static loadableUtils.utils.jSlider; import static loadableUtils.utils.javaxBackupDir; import static loadableUtils.utils.jsonDecode; import static loadableUtils.utils.jsonDecodeMap; import static loadableUtils.utils.jsonTok; import static loadableUtils.utils.jvsplit_minZero; import static loadableUtils.utils.lasTok; import static loadableUtils.utils.lastConceptChange; import static loadableUtils.utils.lastIdentifier; import static loadableUtils.utils.lessThanOrEqual; import static loadableUtils.utils.listChildren; import static loadableUtils.utils.listCombine; import static loadableUtils.utils.listZipFile; import static loadableUtils.utils.loadBinaryPageToFile; import static loadableUtils.utils.loadTextFilePart; import static loadableUtils.utils.log; import static loadableUtils.utils.longSum; import static loadableUtils.utils.longerThan; import static loadableUtils.utils.lookupStandardFunctionOrClassNameIC; import static loadableUtils.utils.makeFileNameUnique; import static loadableUtils.utils.mapItemsToListIndex; import static loadableUtils.utils.maxMemory; import static loadableUtils.utils.megapixels; import static loadableUtils.utils.mergeBufferedImagesAsSquare; import static loadableUtils.utils.modificationTime; import static loadableUtils.utils.moveFile; import static loadableUtils.utils.moveFileVerbose; import static loadableUtils.utils.msToNanos; import static loadableUtils.utils.nemptyLines_extractLists; import static loadableUtils.utils.newPreciseCall_sentinel; import static loadableUtils.utils.nextToLast; import static loadableUtils.utils.openInBrowser; import static loadableUtils.utils.openPlatformBrowser; import static loadableUtils.utils.options; import static loadableUtils.utils.parseDoubleOpt; import static loadableUtils.utils.parsePrimitiveType; import static loadableUtils.utils.percentIncrease; import static loadableUtils.utils.pixelsWithInvertedAlpha; import static loadableUtils.utils.preciseGetOrCallMethod_sentinel; import static loadableUtils.utils.printFunctionCall; import static loadableUtils.utils.putOrCreateLinkedHashMap; import static loadableUtils.utils.randomValue; import static loadableUtils.utils.rangeSliderZeroToOne; import static loadableUtils.utils.readLine; import static loadableUtils.utils.reallyLazyMap; import static loadableUtils.utils.rectDistance; import static loadableUtils.utils.regionToIBinaryImage; import static loadableUtils.utils.render; import static loadableUtils.utils.renderImageOnBackground; import static loadableUtils.utils.replaceIfEquals; import static loadableUtils.utils.revalidateIncludingFullCenterContainer; import static loadableUtils.utils.rgbAlphaZeroToOne; import static loadableUtils.utils.rgbDistanceSquaredInt; import static loadableUtils.utils.rgbIntFullAlpha; import static loadableUtils.utils.runResultWithTimestamps_dontPrintStackTrace; import static loadableUtils.utils.sanitizeFileName; import static loadableUtils.utils.scaledBWImageFromBWIntegralImage_withMeta; import static loadableUtils.utils.scaledIBinaryImage; import static loadableUtils.utils.setRGB; import static loadableUtils.utils.setSize; import static loadableUtils.utils.setSliderValue; import static loadableUtils.utils.sfOrSCSnippet; import static loadableUtils.utils.shallowCloneElements; import static loadableUtils.utils.shiftIntRanges; import static loadableUtils.utils.shootLeftScreenHalf; import static loadableUtils.utils.shuffled; import static loadableUtils.utils.shuffledIterator; import static loadableUtils.utils.sign; import static loadableUtils.utils.snippetURL; import static loadableUtils.utils.sortedDesc; import static loadableUtils.utils.sortedKeys; import static loadableUtils.utils.spaceCombine; import static loadableUtils.utils.standardDeviation; import static loadableUtils.utils.stdToString; import static loadableUtils.utils.structTok; import static loadableUtils.utils.structWordWrap; import static loadableUtils.utils.syncSetAdd; import static loadableUtils.utils.sysSeconds; import static loadableUtils.utils.tailFile2; import static loadableUtils.utils.takeFirstNSSILines; import static loadableUtils.utils.takeLast; import static loadableUtils.utils.tempPut; import static loadableUtils.utils.tempShowLoadingAnimation; import static loadableUtils.utils.textAndCaretPosition; import static loadableUtils.utils.threadCount; import static loadableUtils.utils.toByteArray; import static loadableUtils.utils.toImage2B; import static loadableUtils.utils.toMultiSet; import static loadableUtils.utils.toPt_round; import static loadableUtils.utils.toShort_enforce; import static loadableUtils.utils.toTimestamp; import static loadableUtils.utils.toWidthAndHeight; import static loadableUtils.utils.totalSSILines; import static loadableUtils.utils.totalSizeInInts; import static loadableUtils.utils.transparentImage; import static loadableUtils.utils.treeMultiSetMap; import static loadableUtils.utils.trimSubstring; import static loadableUtils.utils.truncateList; import static loadableUtils.utils.typeToBCELType; import static loadableUtils.utils.typeToClass; import static loadableUtils.utils.typeToVMSignature; import static loadableUtils.utils.uniquify; import static loadableUtils.utils.unixTime; import static loadableUtils.utils.unquote_relaxedMLS; import static loadableUtils.utils.unstructureGZFile; import static loadableUtils.utils.urlConnection; import static loadableUtils.utils.utf8BufferedReader; import static loadableUtils.utils.waitForCalculatedValueUsingChangeListener; import static loadableUtils.utils.wrapArrayAsImmutableList; import static loadableUtils.utils.y2; import static loadableUtils.utils.zeroToOneSine; import static loadableUtils.utils.zip2dir; import static loadableUtils.utils.zipTwoLists; import loadableUtils.utils.AbstractSSI; import loadableUtils.utils.AbstractSSIList; import loadableUtils.utils.BStack; import loadableUtils.utils.BijectiveMap; import loadableUtils.utils.BitBuffer; import loadableUtils.utils.BoolVarWithNotify; import loadableUtils.utils.BresenhamLineDrawer; import loadableUtils.utils.CheckerBoard2; import loadableUtils.utils.ComponentDragger; import loadableUtils.utils.ComponentResizeDragger; import loadableUtils.utils.CutListToBudget; import loadableUtils.utils.DoubleBuffer; import loadableUtils.utils.SynchronizedFloatBufferPresentingAsDoubles; import loadableUtils.utils.IDoubleBuffer; import loadableUtils.utils.ILongBuffer; import loadableUtils.utils.DummyPosterizer; import loadableUtils.utils.EphemeralObjectIDs; import loadableUtils.utils.FastRegions_Hi15Image; import loadableUtils.utils.FixedVarContext; import loadableUtils.utils.FlexibleVarContext; import loadableUtils.utils.GeneralSSIList; import loadableUtils.utils.GenericArrayTypeImpl; import loadableUtils.utils.Hi15Image; import loadableUtils.utils.HuffmanByteArray; import loadableUtils.utils.IPosterizer; import loadableUtils.utils.IStackWithOptions; import loadableUtils.utils.IUnstructured; import loadableUtils.utils.JComponentWithChangeListeners; import loadableUtils.utils.JustCountingOutputStream; import loadableUtils.utils.MethodOnObject; import loadableUtils.utils.NotifyingList; import loadableUtils.utils.ParameterizedTypeImpl; import loadableUtils.utils.ProbabilisticList; import loadableUtils.utils.RSTVar; import loadableUtils.utils.SSI; import loadableUtils.utils.SinglePixelPosterizer; import loadableUtils.utils.TailFile; import loadableUtils.utils.TargetAndActual; import loadableUtils.utils.VStack; import loadableUtils.utils.VStackComputableWithStep; import loadableUtils.utils.VectorOptimizedSSIList; import loadableUtils.utils.IPixelSet; import loadableUtils.utils.IF0_Bool; import loadableUtils.utils.IBest; import loadableUtils.utils.IToolTipMaker; import static loadableUtils.utils.doPost_extraHeaders; import loadableUtils.utils.Scorer; import static loadableUtils.utils.pcallFail; import loadableUtils.utils.Updateable; import java.awt.font.GlyphVector; import javax.management.MBeanServer; import java.lang.management.ManagementFactory; import javax.net.*; import javax.net.ssl.*; import java.text.*; import javax.swing.border.TitledBorder; import java.awt.geom.AffineTransform; import org.apache.commons.io.input.ReversedLinesFileReader; import java.awt.geom.*; import oshi.software.os.*; import oshi.SystemInfo; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; public class main { static public List _stickyLibs_1400546 = ll("#1400546", "#1400547", "#1400548"); static public List _stickyLibs_1013490 = ll("#1400553", "#1400552", "#1004016", "#1004015"); static public String programID; static public void _onLoad_initUtils() { utils.__javax = javax(); } static public ThreadLocal dynamicObjectIsLoading_threadLocal() { return DynamicObject_loading; } static { defineRewrite("Challenge", "G22Challenge"); } static { defineRewrite("Label", "G22Label"); } static { defineRewrite("GalleryImage", "G22GalleryImage"); } static public class GazelleScreenCam extends DynModule implements G22ProjectActions { volatile public boolean enabled = true; transient public JPanel buttons; public void setEnabled(boolean b) { setField("enabled", b); } public JComponent visualize_enabled() { return dm_checkBox("enabled"); } { enabled = false; } transient static public boolean autoRunSelfTests = false; public SnPSettings screenCamSnPSettings = new SnPSettings(); public transient FieldVar varScreenCamShowDecolorizerSelection_cache; public FieldVar varScreenCamShowDecolorizerSelection() { if (varScreenCamShowDecolorizerSelection_cache == null) varScreenCamShowDecolorizerSelection_cache = varScreenCamShowDecolorizerSelection_load(); return varScreenCamShowDecolorizerSelection_cache; } public FieldVar varScreenCamShowDecolorizerSelection_load() { return new FieldVar(this, "screenCamShowDecolorizerSelection", () -> screenCamShowDecolorizerSelection(), screenCamShowDecolorizerSelection -> screenCamShowDecolorizerSelection(screenCamShowDecolorizerSelection)); } final public GazelleScreenCam setScreenCamShowDecolorizerSelection(boolean screenCamShowDecolorizerSelection) { return screenCamShowDecolorizerSelection(screenCamShowDecolorizerSelection); } public GazelleScreenCam screenCamShowDecolorizerSelection(boolean screenCamShowDecolorizerSelection) { if (!eq(this.screenCamShowDecolorizerSelection, screenCamShowDecolorizerSelection)) { this.screenCamShowDecolorizerSelection = screenCamShowDecolorizerSelection; change(); } return this; } final public boolean getScreenCamShowDecolorizerSelection() { return screenCamShowDecolorizerSelection(); } public boolean screenCamShowDecolorizerSelection() { return screenCamShowDecolorizerSelection; } public boolean screenCamShowDecolorizerSelection = false; public String script = "64p 8c gradientImage"; public transient FieldVar varNewScript_cache; public FieldVar varNewScript() { if (varNewScript_cache == null) varNewScript_cache = varNewScript_load(); return varNewScript_cache; } public FieldVar varNewScript_load() { return new FieldVar(this, "newScript", () -> newScript(), newScript -> newScript(newScript)); } final public GazelleScreenCam setNewScript(String newScript) { return newScript(newScript); } public GazelleScreenCam newScript(String newScript) { if (!eq(this.newScript, newScript)) { this.newScript = newScript; change(); } return this; } final public String getNewScript() { return newScript(); } public String newScript() { return newScript; } public String newScript; public String screenCamScript; public String selectedTab; public String javaCode; public boolean horizontalLayout = false; public int fpsTarget = 20; public String webCamName; public boolean webCamAccessEnabled = true; final public Set getProjectLibs() { return projectLibs(); } public Set projectLibs() { return projectLibs; } public Set projectLibs = syncSet(); public G22WatchTarget watchTarget; public G22_TestScreenPanel testScreen = new G22_TestScreenPanel(); transient public ImageSurface isPosterized; transient public ScreenCamStream imageStream = new ScreenCamStream(); transient public Gazelle22_ImageToRegions imageToRegions_finished; transient public DoubleFPSCounter fpsCounter = new DoubleFPSCounter(); transient public int fps; transient public WatchTargetSelector watchTargetSelector; transient public RollingAverage remainingMSPerFrame = new RollingAverage(); transient public int remainingMS; transient public FunctionTimings functionTimings = new FunctionTimings(); transient public ReliableSingleThread rstRunScript = dm_rst(me(), new Runnable() { public void run() { try { _runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_runScript();"; } }); transient public JGazelleVScriptRunner scriptRunner; public UIURLSystem uiURLs = new UIURLSystem(); transient public JComboBox cbWebCam; transient public SingleComponentPanel scpWebCamImage; transient public WebcamPanel webCamPanel; transient public JLeftArrowScriptIDE screenCamScriptIDE; transient public GazelleV_LeftArrowScript.Script runningScreenCamScript; final public Concepts getConcepts() { return concepts(); } public Concepts concepts() { return concepts; } transient public Concepts concepts; public String uiURL = "Main Tabs"; transient public SimpleCRUD_v2 labelCRUD; transient public SimpleCRUD_v2 galleryCRUD; transient public JComponent galleryCRUDVis; transient public SimpleCRUD_v2 entityCRUD; transient public JGallery paintToolGallery; transient public FlexibleRateTimer screenCamTimer; transient public SingleComponentPanel scpMain; final public DynamicVStack getTopStack() { return topStack(); } public DynamicVStack topStack() { return topStack; } transient public DynamicVStack topStack; final public JTabbedPane getMainTabs() { return mainTabs(); } public JTabbedPane mainTabs() { return mainTabs; } transient public JTabbedPane mainTabs; transient public boolean showRegionsAsOutline = true; transient public JComponent watchScreenPane; transient public String screenCamRecognitionOutput; final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils = new G22Utils(); transient public BackgroundProcessesUI backgroundProcessesUI = new BackgroundProcessesUI(); transient public BackgroundProcessesUI.Entry bgScreenCam = backgroundProcessesUI.new Entry("Screen Cam").menuItem(jMenuItem("Screen Cam", new Runnable() { public void run() { try { showScreenCam(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showScreenCam();"; } })); transient public BackgroundProcessesUI.Entry bgWebCam = backgroundProcessesUI.new Entry("Web Cam").menuItem(jMenuItem("Web Cam", new Runnable() { public void run() { try { showWebCam(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showWebCam();"; } })); public boolean autoRunChallenge = true; transient public G22ChallengesPanel challengesPanel; transient public JComponent urlBar; transient public JVideoLibDownloader videoLibDownloader; transient public JFFMPEGVideoPlayer videoPlayer; public transient FieldVar varPaintTool_cache; public FieldVar varPaintTool() { if (varPaintTool_cache == null) varPaintTool_cache = varPaintTool_load(); return varPaintTool_cache; } public FieldVar varPaintTool_load() { return new FieldVar(this, "paintTool", () -> paintTool(), paintTool -> paintTool(paintTool)); } final public GazelleScreenCam setPaintTool(JPaintTool paintTool) { return paintTool(paintTool); } public GazelleScreenCam paintTool(JPaintTool paintTool) { if (!eq(this.paintTool, paintTool)) { this.paintTool = paintTool; change(); } return this; } final public JPaintTool getPaintTool() { return paintTool(); } public JPaintTool paintTool() { return paintTool; } public JPaintTool paintTool; public G22AnalysisPanel paintAnalysisPanel; final public G22SelfTests getSelfTests() { return selfTests(); } public G22SelfTests selfTests() { return selfTests; } transient public G22SelfTests selfTests; public transient FieldVar varPaintToolGalleryExpanded_cache; public FieldVar varPaintToolGalleryExpanded() { if (varPaintToolGalleryExpanded_cache == null) varPaintToolGalleryExpanded_cache = varPaintToolGalleryExpanded_load(); return varPaintToolGalleryExpanded_cache; } public FieldVar varPaintToolGalleryExpanded_load() { return new FieldVar(this, "paintToolGalleryExpanded", () -> paintToolGalleryExpanded(), paintToolGalleryExpanded -> paintToolGalleryExpanded(paintToolGalleryExpanded)); } final public GazelleScreenCam setPaintToolGalleryExpanded(boolean paintToolGalleryExpanded) { return paintToolGalleryExpanded(paintToolGalleryExpanded); } public GazelleScreenCam paintToolGalleryExpanded(boolean paintToolGalleryExpanded) { if (!eq(this.paintToolGalleryExpanded, paintToolGalleryExpanded)) { this.paintToolGalleryExpanded = paintToolGalleryExpanded; change(); } return this; } final public boolean getPaintToolGalleryExpanded() { return paintToolGalleryExpanded(); } public boolean paintToolGalleryExpanded() { return paintToolGalleryExpanded; } public boolean paintToolGalleryExpanded = false; transient public JComponent screenCamTab; transient public GazelleV_LeftArrowScriptParser prototypeParser; final public JPanel getGeneralInfoPanel() { return generalInfoPanel(); } public JPanel generalInfoPanel() { return generalInfoPanel; } transient public JPanel generalInfoPanel = jline(); public transient FieldVar varScreenCamAnalyzer_cache; public FieldVar varScreenCamAnalyzer() { if (varScreenCamAnalyzer_cache == null) varScreenCamAnalyzer_cache = varScreenCamAnalyzer_load(); return varScreenCamAnalyzer_cache; } public FieldVar varScreenCamAnalyzer_load() { return new FieldVar(this, "screenCamAnalyzer", () -> screenCamAnalyzer(), screenCamAnalyzer -> screenCamAnalyzer(screenCamAnalyzer)); } final public GazelleScreenCam setScreenCamAnalyzer(G22Analyzer screenCamAnalyzer) { return screenCamAnalyzer(screenCamAnalyzer); } public GazelleScreenCam screenCamAnalyzer(G22Analyzer screenCamAnalyzer) { if (!eq(this.screenCamAnalyzer, screenCamAnalyzer)) { this.screenCamAnalyzer = screenCamAnalyzer; change(); } return this; } final public G22Analyzer getScreenCamAnalyzer() { return screenCamAnalyzer(); } public G22Analyzer screenCamAnalyzer() { return screenCamAnalyzer; } public G22Analyzer screenCamAnalyzer; public transient FieldVar varShowCasedScript_cache; public FieldVar varShowCasedScript() { if (varShowCasedScript_cache == null) varShowCasedScript_cache = varShowCasedScript_load(); return varShowCasedScript_cache; } public FieldVar varShowCasedScript_load() { return new FieldVar(this, "showCasedScript", () -> showCasedScript(), showCasedScript -> showCasedScript(showCasedScript)); } final public GazelleScreenCam setShowCasedScript(G22LeftArrowScript showCasedScript) { return showCasedScript(showCasedScript); } public GazelleScreenCam showCasedScript(G22LeftArrowScript showCasedScript) { if (!eq(this.showCasedScript, showCasedScript)) { this.showCasedScript = showCasedScript; change(); } return this; } final public G22LeftArrowScript getShowCasedScript() { return showCasedScript(); } public G22LeftArrowScript showCasedScript() { return showCasedScript; } public G22LeftArrowScript showCasedScript; transient public G22Analyzer.CompiledAnalyzer runningScreenCamAnalyzer; transient public SourceTriggeredStream imageStreamForAnalyzer; transient public SingleComponentPanel scpScreenCamImage = scp(); public transient FieldVar varImageRecognitionEnabled_cache; public FieldVar varImageRecognitionEnabled() { if (varImageRecognitionEnabled_cache == null) varImageRecognitionEnabled_cache = varImageRecognitionEnabled_load(); return varImageRecognitionEnabled_cache; } public FieldVar varImageRecognitionEnabled_load() { return new FieldVar(this, "imageRecognitionEnabled", () -> imageRecognitionEnabled(), imageRecognitionEnabled -> imageRecognitionEnabled(imageRecognitionEnabled)); } final public GazelleScreenCam setImageRecognitionEnabled(boolean imageRecognitionEnabled) { return imageRecognitionEnabled(imageRecognitionEnabled); } public GazelleScreenCam imageRecognitionEnabled(boolean imageRecognitionEnabled) { if (!eq(this.imageRecognitionEnabled, imageRecognitionEnabled)) { this.imageRecognitionEnabled = imageRecognitionEnabled; change(); } return this; } final public boolean getImageRecognitionEnabled() { return imageRecognitionEnabled(); } public boolean imageRecognitionEnabled() { return imageRecognitionEnabled; } public boolean imageRecognitionEnabled = true; final public List getProjectErrors() { return projectErrors(); } public List projectErrors() { return projectErrors; } public List projectErrors = syncLinkedList(); final public GazelleScreenCam setMaxProjectErrors(int maxProjectErrors) { return maxProjectErrors(maxProjectErrors); } public GazelleScreenCam maxProjectErrors(int maxProjectErrors) { this.maxProjectErrors = maxProjectErrors; return this; } final public int getMaxProjectErrors() { return maxProjectErrors(); } public int maxProjectErrors() { return maxProjectErrors; } transient public int maxProjectErrors = 40; public void start() { try { super.start(); g22utils.module(this); for (String libID : projectLibs) { File f = fileForLibrary(libID); if (fileExists(f)) { print("Loading iibrary " + libID); addLibrary(f); } } testScreen.g22utils(g22utils); testScreen.onChange(() -> change()); dm_onFieldChange("horizontalLayout", new Runnable() { public void run() { try { dm_reload(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "dm_reload();"; } }); concepts.quietSave = true; concepts.modifyOnCreate(true); setModuleName(replaceIfEquals(g22utils.projectName(), g22utils.defaultDBName(), "")); indexConceptField(concepts, G22GalleryImage.class, "path"); indexConceptField(concepts, Example.class, "item"); indexConceptFieldCI(concepts, G22Label.class, "name"); indexConceptField(concepts, G22Variable.class, "name"); indexConceptField(concepts, G22TravelLogEntry.class, "timestamp"); ensureConceptClassesAreIndexed(concepts, G22PointOfInterest.class); g22utils.concepts(concepts); concepts.miscMapPut(G22Utils.class, g22utils); g22utils.backgroundProcessesUI(backgroundProcessesUI); g22utils.functionTimings(functionTimings); G22ProjectInfo projectInfo = g22utils.projectInfo(); File oldProjectDir = projectInfo.projectDir; File projectDir = g22utils.projectDir(); if (cset_trueIfChanged(projectInfo, "projectDir", projectDir) && oldProjectDir != null) { projectInfo.addHistoricalProjectDir(oldProjectDir); } if (G22TravelLogEntry.shouldCreateEntry(g22utils)) startThread("Make Travel Log Entry", new Runnable() { public void run() { try { printWithMS("Creating travel log entry."); registerConcept(concepts, G22TravelLogEntry.create(g22utils).scanProject(g22utils).action("First travel log entry")); printWithMS("Created travel log entry."); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "printWithMS(\"Creating travel log entry.\");\r\n registerConcept(concepts,..."; } }); for (var c : list(concepts)) fixFieldValues(c); makePrototypeParser(); g22utils.onSettingUpParser(__29 -> adaptLeftArrowParser(__29)); g22utils.projectActions(this); g22utils.onSettingUpScriptIDE(ide -> { ide.addGoToDefinitionHandler(tokPtr -> { String prevToken = _get(tokPtr.list(), tokPtr.idx() - 2); String token = tokPtr.get(); if (eq(prevToken, "callScript") && isInteger(token)) { var script = g22utils.getScript(parseLong(token)); if (script != null) return () -> g22utils.editScript(script); } return null; }); ide.addGoToDefinitionHandler(tokPtr -> { String token = tokPtr.get(); if (!isIdentifier(token)) return null; var def = findDefinition(token); return def == null ? null : () -> goToSource(def); }); if (!devMode()) return; var scp = scp(); addInFront(ide.buttons(), scp); ide.varCompileResult().onChange(cr -> { AutoCloseable __19 = enter(); try { var e = innerExceptionOfType(GazelleV_LeftArrowScriptParser.UnknownObject.class, cr == null ? null : cr.compileError); if (e != null) { if (isStandardFunction(e.name)) { var btn = jbuttonWithDisable("Add function " + e.name, new Runnable() { public void run() { try { infoBoxAndCompile(addFunctionNameToInclude(functionsIncludeID(), e.name)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "infoBoxAndCompile(addFunctionNameToInclude(functionsIncludeID(), e.name));"; } }); componentPopupMenuItem(btn, "Add but don't recompile", runnableThread(new Runnable() { public void run() { try { addFunctionNameToInclude(functionsIncludeID(), e.name); infoBox("Added"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addFunctionNameToInclude(functionsIncludeID(), e.name);\r\n info..."; } })); { scp.set(btn); return; } } if (isStandardClass(e.name)) { scp.set(jbuttonWithDisable("Add class " + e.name, new Runnable() { public void run() { try { infoBoxAndCompile(addClassNameToInclude(functionsIncludeID(), e.name)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "infoBoxAndCompile(addClassNameToInclude(functionsIncludeID(), e.name));"; } })); return; } } scp.clear(); } finally { _close(__19); } }); }); g22utils.autoStarter().init(); uiURLs.owner = me(); uiURLs.uiURL = dm_fieldLiveValue("uiURL"); uiURLs.addPreferredUIURL("Main Tabs"); dm_watchFieldAndNow("enabled", () -> backgroundProcessesUI.addOrRemove(enabled, bgScreenCam)); scriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue("script", me())); printWithMS("Making image stream"); imageStream.onNewElement(img -> { fpsCounter.inc(); setField("fps", iround(fpsCounter.get())); assertTrue("meta", getMetaSrc(img) instanceof ScreenShotMeta); if (screenCamAnalyzer != null) { { if (imageStreamForAnalyzer != null) imageStreamForAnalyzer.newElement(img); } } else { Gazelle22_ImageToRegions itr = new Gazelle22_ImageToRegions(functionTimings, img, screenCamSnPSettings); itr.run(); imageToRegions_finished = itr; if (shouldRunScript()) rstRunScript.go(); if (screenCamScriptIDE != null && screenCamScriptIDE.visible()) try { g22_runPostAnalysisLeftArrowScript(itr, runningScreenCamScript); } catch (Throwable e) { printStackTrace(e); screenCamScriptIDE.showRuntimeError(e); } String text = nRegions(itr.regions.regionCount()); setField("screenCamRecognitionOutput", text); g22_renderPosterizedHighlightedImage(isPosterized, itr, showRegionsAsOutline); } }); if (watchTarget == null) { watchTarget = defaultWatchTarget(); change(); } watchTargetSelector = new WatchTargetSelector(); watchTargetSelector.visualize(); isPosterized = g22utils.stdImageSurface(); varScreenCamAnalyzer().onChangeAndNow(analyzer -> q().add(() -> { if (analyzer == null) { runningScreenCamAnalyzer = null; imageStreamForAnalyzer = null; scpScreenCamImage.set(withTools(isPosterized)); } else { runningScreenCamAnalyzer = analyzer.compileForAutoRun(); imageStreamForAnalyzer = new SourceTriggeredStream(); G22AnalysisContext context = new G22AnalysisContext(g22utils, imageStreamForAnalyzer); Object analyzerResult = runningScreenCamAnalyzer.get(context); print("analyzerResult", analyzerResult); scpScreenCamImage.set(new G22JavaObjectVisualizer(g22utils, analyzerResult)); } })); printWithMS("Starting screen cam"); ownResource(screenCamTimer = new FlexibleRateTimer(fpsTarget, new Runnable() { public void run() { try { AutoCloseable __20 = enter(); try { if (!enabled) return; { if (watchTargetSelector != null) watchTargetSelector.updateScreenCount(); } Timestamp deadline = tsNowPlusMS(1000 / fpsTarget); { if (watchTarget != null) watchTarget.mainWindow(getWindow(urlBar)); } { if (watchTarget != null) watchTarget.configureScreenCamStream(imageStream); } imageStream.step(); long remaining = deadline.minus(tsNow()); remainingMSPerFrame.add(remaining); setField("remainingMS", iround(remainingMSPerFrame.get())); } finally { _close(__20); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); \r\n if (!enabled) return;\r\n watchTargetSelector?.updat..."; } })); screenCamTimer.start(); dm_onFieldChange("fpsTarget", () -> screenCamTimer.setFrequencyImmediately(fpsTarget)); printWithMS("Gathering images from disk"); addDirToGallery(conceptsDir(concepts)); printWithMS("Got dem images"); transpileRaw_makeTranslator = () -> hotwire("#7"); } catch (Exception __e) { throw rethrow(__e); } } public void addDirToGallery(File dir) { watchDirForGallery(dir); for (var f : allImageFiles(dir)) addToGallery(f); } public void watchDirForGallery(File dir) { g22utils.onProjectFileChanged(file -> { if (isImageFile(file)) addToGallery(file); }); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { imageSurfaceOnHover(isPosterized, pt -> { if (!enabled && imageToRegions_finished != null) g22_renderPosterizedHighlightedImage(isPosterized, imageToRegions_finished, showRegionsAsOutline); }); labelCRUD = new SimpleCRUD_v2(concepts, G22Label.class); labelCRUD.hideFields("globalID"); labelCRUD.itemToMap_inner2 = l -> litorderedmap("Name", l.name, "# Examples", n2(countConcepts(concepts, Example.class, "label", l))); galleryCRUD = new SimpleCRUD_v2(concepts, G22GalleryImage.class); galleryCRUD.itemToMap_inner2 = img -> litorderedmap("File", fileName(img.path), "Folder", dirPath(img.path)); galleryCRUD.defaultAction(img -> { { startThread(new Runnable() { public void run() { try { showImage(img.path); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showImage(img.path)"; } }); } }); galleryCRUDVis = galleryCRUD.visualize(); galleryCRUD.addButton(jPopDownButton_noText("Forget missing images", runnableThread(new Runnable() { public void run() { try { AutoCloseable __33 = enter(); try { forgetMissingImages(); } finally { _close(__33); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); forgetMissingImages();"; } }))); galleryCRUD.addButton("Back to gallery", runnableThread(new Runnable() { public void run() { try { AutoCloseable __21 = enter(); try { uiURLs.showUIURL("Gallery"); } finally { _close(__21); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); showUIURL(\"Gallery\")"; } })); galleryCRUD.newConcept = () -> { JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Add image to gallery"); fc.setCurrentDirectory(conceptsDir(concepts)); fc.setFileFilter(new ImageFileFilter().allowDirectories(true)); addToGallery(execFileChooser(fc)); }; var screenCamSnPSelector = new G22SnPSelector(screenCamSnPSettings).allowDecolorizerSelection(true); screenCamSnPSelector.onChange(() -> change()); linkVars(varScreenCamShowDecolorizerSelection(), screenCamSnPSelector.varShowDecolorizerSelection()); watchScreenPane = jHigherScrollPane_borderless_center(vstack(withLeftAndRightMargin(hstack(dm_rcheckBox("enabled", "Watch"), watchTargetSelector.visualize(), jlabel(" in "), screenCamSnPSelector, jlabel(" Analyzer "), bindComboBoxToVar(varScreenCamAnalyzer(), swing(() -> new ConceptsComboBox(g22utils.concepts(), G22Analyzer.class).allowNull(true))))), verticalStrut(2), withSideMargins(centerAndEastWithMargin(dm_fieldLabel("screenCamRecognitionOutput"), dm_transientCalculatedToolTip(() -> speedInfo_long(), rightAlignLabel(dm_transientCalculatedLabel(() -> speedInfo()))))))); topStack = dynamicVStack(); topStack.spacing(0); initUIURLs(); mainTabs = scrollingTabs(jTopOrLeftTabs(horizontalLayout)); addUIURLToMainTabs("Project Overview"); addUIURLToMainTabs("Showcase"); addUIURLToMainTabs("Scripts"); if (imageRecognitionEnabled) { addUIURLToMainTabs("Masks"); addUIURLToMainTabs("Shape Collector"); addUIURLToMainTabs("Points of interest"); } addUIURLToMainTabs("Gallery"); addUIURLToMainTabs("Scratchpad"); addUIURLToMainTabs("Paint"); if (imageRecognitionEnabled) { addUIURLToMainTabs("Analyzers"); } addUIURLToMainTabs("Projects"); for (String tab : tabNames(mainTabs)) { var _tab_31 = dropTrailingBracketedCount(tab); uiURLs.put(_tab_31, () -> { int i = indexOfTabNameWithoutTrailingCount(mainTabs, _tab_31); if (i < 0) return jcenteredlabel("Hmm. Tab not found"); selectTab(mainTabs, i); return mainTabs; }); } onTabSelected(mainTabs, () -> { if (!isShowing(mainTabs)) return; String tabName = dropTrailingBracketedCount(selectedTabName(mainTabs)); if (!eqicOneOf(uiURL, "Main Tabs", tabName)) uiURLs.showUIURL("Main Tabs"); }); var cbEnabled = toolTip("Switch screen cam on or off", dm_checkBox("enabled", "")); var lblScreenCam = setToolTip("Show scaled down and color-reduced screen image", jlabel("Screen Cam")); tabComponentClickFixer(lblScreenCam); screenCamTab = hstackWithSpacing(cbEnabled, lblScreenCam); addActionListener(cbEnabled, () -> { if (enabled) selectTabComponent(mainTabs, screenCamTab); }); replaceTabTitleComponent(mainTabs, "Screen Cam", screenCamTab); persistSelectedTabAsLiveValue(mainTabs, dm_fieldLiveValue("selectedTab")); urlBar = uiURLs.urlBar(); focusOnFirstShow(urlBar); setToolTip(uiURLs.comboBox, "UI navigation system"); scpMain = singleComponentPanel(); uiURLs.scp(scpMain); uiURLs.go(); var projectSelector = new JG22ProjectSelector(g22utils); generalInfoPanel.add(backgroundProcessesUI.shortLabel()); topStack.addComponent(verticalStrut(6)); topStack.addComponent(westCenterAndEast(withLabelToTheRight(projectSelector.visualize(), "| "), urlBar, withLeftMargin(generalInfoPanel))); var vis = northAndCenter(withSideMargin(topStack), scpMain); g22utils.autoStarter().start(); if (autoRunSelfTests) { autoRunSelfTests = false; onFirstShow(vis, () -> runSelfTests()); } return vis; } public void runSelfTests() { startThread("Self-Tests", new Runnable() { public void run() { try { selfTests = new G22SelfTests(g22utils); selfTests.run(); selfTestsDone(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "selfTests = new G22SelfTests(g22utils);\r\n selfTests.run();\r\n selfTe..."; } }); } transient public Set onSelfTestsDone; public GazelleScreenCam onSelfTestsDone(Runnable r) { onSelfTestsDone = createOrAddToSyncLinkedHashSet(onSelfTestsDone, r); return this; } public GazelleScreenCam removeSelfTestsDoneListener(Runnable r) { loadableUtils.utils.remove(onSelfTestsDone, r); return this; } public void selfTestsDone() { if (onSelfTestsDone != null) for (var listener : onSelfTestsDone) pcallF_typed(listener); } transient public Set onProjectErrorsChanged; public GazelleScreenCam onProjectErrorsChanged(Runnable r) { onProjectErrorsChanged = createOrAddToSyncLinkedHashSet(onProjectErrorsChanged, r); return this; } public GazelleScreenCam removeProjectErrorsChangedListener(Runnable r) { loadableUtils.utils.remove(onProjectErrorsChanged, r); return this; } public void projectErrorsChanged() { if (onProjectErrorsChanged != null) for (var listener : onProjectErrorsChanged) pcallF_typed(listener); } transient public Set> onProjectErrorOccurred; public GazelleScreenCam onProjectErrorOccurred(IVF1 f) { onProjectErrorOccurred = createOrAddToSyncLinkedHashSet(onProjectErrorOccurred, f); return this; } public GazelleScreenCam removeProjectErrorOccurredListener(IVF1 f) { loadableUtils.utils.remove(onProjectErrorOccurred, f); return this; } public void projectErrorOccurred(PersistableThrowable error) { if (onProjectErrorOccurred != null) for (var listener : onProjectErrorOccurred) pcallF_typed(listener, error); } public JComponent screenCamPanel() { return centerAndSouthOrEast(horizontalLayout, scpScreenCamImage, watchScreenPane); } public JComponent screenCamPlusScriptPanel() { AutoCloseable __22 = enter(); try { print("screenCamPlusScriptPanel"); try { var ide = screenCamScriptIDE = leftArrowScriptIDE(); ide.runButtonShouldBeEnabled = () -> eq(getText(ide.btnRun), "Stop") || ide.runButtonShouldBeEnabled_base(); ide.runScript = () -> { if (eq(getText(ide.btnRun), "Stop")) runningScreenCamScript = null; else { runningScreenCamScript = screenCamScriptIDE.parsedScript(); ide.showStatus("Running"); } setText(ide.btnRun, runningScreenCamScript == null ? "Run" : "Stop"); }; return centerAndSouthOrEast(horizontalLayout, jhsplit(jscroll_centered_borderless(isPosterized), screenCamScriptIDE.lvScript(dm_fieldLiveValue("screenCamScript")).visualize()), watchScreenPane); } catch (Throwable e) { print(e); throw rethrow(e); } } finally { _close(__22); } } public String speedInfo() { return "FPS " + fps + " idle " + remainingMS + " ms"; } public String speedInfo_long() { return "Screen cam running at " + nFrames(fps) + "/second. " + n2(remainingMS) + " ms remaining per frame in first core" + " (of targeted " + fpsTarget + " FPS)"; } public boolean useErrorHandling() { return false; } public String renderFunctionTimings() { return lines(ciSorted(map(functionTimings.get(), (f, avg) -> firstToUpper(f) + ": " + n2(iround(nsToMicroseconds(avg.get()))) + " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")"))); } transient public long _runScript_idx; public void _runScript() { scriptRunner.parseAndRunOn(imageToRegions_finished.ii); } public boolean shouldRunScript() { return isShowing(scriptRunner.scpScriptResult); } public JComponent testScreenPanel() { return withSideAndTopMargin(testScreen.visualize()); } public JComponent timingsPanel() { JTextArea taTimings = jTextArea_noUndo(); awtEveryAndNow(taTimings, .5, new Runnable() { public void run() { try { setText(taTimings, renderFunctionTimings()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setText(taTimings, renderFunctionTimings())"; } }); return withRightAlignedButtons(taTimings, "Reset", new Runnable() { public void run() { try { resetTimings(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "resetTimings();"; } }); } public List popDownItems() { return ll(jCheckBoxMenuItem_dyn("Horizontal Layout", () -> horizontalLayout, b -> setField("horizontalLayout", b))); } public void unvisualize() { } public void resetTimings() { functionTimings.reset(); } public JComponent withTools(ImageSurface is) { return withTools(jscroll_centered_borderless(is), is); } public JComponent withTools(JComponent component, ImageSurface is) { return centerAndEastWithMargin(component, vstack(verticalStrut(5), jimageButtonScaledToWidth(16, "#1103054", "Save screenshot in gallery", runnableThread(new Runnable() { public void run() { try { saveScreenshotToGallery(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveScreenshotToGallery();"; } })))); } public class WatchTargetSelector implements Swingable { public JComboBox cb = jComboBox(); public int screenCount, camCount; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { updateList(); selectItem(cb, watchTarget); loadableUtils.utils.onChangeAndNow(cb, watchTarget -> { setField("watchTarget", watchTarget); toolTip(cb, watchTarget == null ? null : watchTarget.toolTip()); }); return cb; } public void updateScreenCount() { if (screenCount != screenCount()) updateList(); } public void updateList() { swing(() -> { setComboBoxItems(cb, makeWatchTargets()); }); } public List makeWatchTargets() { return flattenToList(countIteratorAsList_incl(1, screenCount = screenCount(), i -> new WatchScreen(i)), new WatchMouse(), new WatchScreenWithMouse(), new WatchOtherScreen()); } } public JComponent wrapCRUD(String title, SimpleCRUD_v2 crud) { return wrapCRUD(title, crud, crud.visualize()); } public JComponent wrapCRUD(String title, SimpleCRUD_v2 crud, JComponent vis) { return crud == null ? null : withTopAndBottomMargin(jCenteredRaisedSection(title, withMargin(vis))); } public File galleryDir() { return picturesDir(gazelle22_imagesSubDirName()); } public void saveScreenshotToGallery() { AutoCloseable __23 = enter(); try { var img = imageStream.get(); addToGallery(saveImageWithCounter(galleryDir(), "Screenshot", img)); } finally { _close(__23); } } public G22GalleryImage addToGallery(BufferedImage image) { return addToGallery("Unnamed Image", image); } public G22GalleryImage addToGallery(String name, BufferedImage image) { return addToGallery(saveImageWithCounter(g22utils.dbDir(), name, image)); } public void saveWebCamImageToGallery() { AutoCloseable __24 = enter(); try { var img = webCamPanel.getImage(); addToGallery(saveImageWithCounter(galleryDir(), "Webcam", img)); } finally { _close(__24); } } public G22GalleryImage addToGallery(File imgFile) { if (!isImageFile(imgFile)) return null; var img = uniq(concepts, G22GalleryImage.class, "path", imgFile); printVars("addToGallery", "imgFile", imgFile, "img", img); return img; } public class StudyPanel { public G22SnPSelector snpSelector = new G22SnPSelector(); public G22GalleryImage image; public BufferedImage originalImage; public ImageSurface isOriginalWithRegions = g22utils.stdImageSurface(); public ImageSurface isPosterized = g22utils.stdImageSurface(); public SingleComponentPanel scp = singleComponentPanel(); public SingleComponentPanel analysisPanel = singleComponentPanel(); public SingleComponentPanel scpExampleCRUD = singleComponentPanel(); public ConceptsComboBox cbImage = g22utils.galleryImagesComboBox(); public Gazelle22_ImageToRegions itr; public int iSelectedRegion; public SimpleCRUD_v2 regionCRUD; public SimpleCRUD_v2 exampleCRUD; public StudyPanel() { print("Making StudyPanel " + this); cbImage.sortTheList = l -> sortedByComparator(l, (a, b) -> cmpAlphanumIC(fileName(a.path), fileName(b.path))); loadableUtils.utils.onChangeAndNow(cbImage, img -> { dm_q(me(), new Runnable() { public void run() { try { print("Image selected: " + img); image = img; scp.setComponent(studyImagePanel()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "print(\"Image selected: \" + img);\r\n image = img;\r\n scp.setCo..."; } }); }); isPosterized.removeAllTools(); isPosterized.onMousePositionChanged(r_dm_q(me(), () -> regionUpdate())); imageSurfaceOnLeftMouseDown(isPosterized, pt -> dm_q(me(), new Runnable() { public void run() { try { chooseRegionAt(pt); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "chooseRegionAt(pt)"; } })); snpSelector.onChange(r_dm_q(me(), () -> runSnP())); } public void chooseRegionAt(Pt p) { if (itr == null) return; iSelectedRegion = itr.regions.regionAt(p); if (iSelectedRegion > 0) { var savedRegion = uniq_returnIfNew(concepts, SavedRegion.class, "image", image, "snpSettings", snpSelector.settings.cloneMe(), "regionIndex", iSelectedRegion); if (savedRegion != null) { print("Saved new region!"); var bitMatrix = toScanlineBitMatrix(itr.regions.regionBitMatrix(iSelectedRegion)); cset(savedRegion, "bitMatrix", bitMatrix); } } regionUpdate(); } public JComponent studyImagePanel() { if (image == null) return null; originalImage = loadImage2(image.path); if (originalImage == null) return jcenteredlabel("Image not found"); isOriginalWithRegions.setImage(originalImage); iSelectedRegion = 0; itr = new Gazelle22_ImageToRegions(functionTimings, originalImage, snpSelector.settings); runSnP(); regionCRUD = new SimpleCRUD_v2(concepts, SavedRegion.class); regionCRUD.addFilter("image", image); regionCRUD.showSearchBar(false).showAddButton(false).showEditButton(false).iconButtons(true); regionCRUD.itemToMap_inner2 = region -> { var examples = conceptsWhere(concepts, Example.class, "item", region); return litorderedmap("Pixels", region.bitMatrix == null ? "-" : n2(region.bitMatrix.pixelCount()), "Labels", joinWithComma(map(examples, e -> e.label)), "Position", region.bitMatrix == null ? "-" : region.bitMatrix.boundingBoxOfTrueBits()); }; var regionCRUDComponent = regionCRUD.visualize(); regionCRUD.onSelectionChanged(() -> updateExampleCRUD()); return hsplit(jtabs("Image + regions", jscroll_centered_borderless(isOriginalWithRegions), "Posterized", jscroll_centered_borderless(isPosterized)), northAndCenterWithMargin(analysisPanel, hsplit(jCenteredSection("Saved regions", regionCRUDComponent), scpExampleCRUD))); } public void runSnP() { if (itr == null) return; itr.run(); regionUpdate(); } public void regionUpdate() { if (itr == null) return; var pixels = itr.posterized.getRGBPixels(); g22_highlightRegion(pixels, isPosterized, itr, showRegionsAsOutline); itr.regions.markRegionInPixelArray(pixels, iSelectedRegion, 0xFFADD8E6); var highlighted = bufferedImage(pixels, itr.posterized.getWidth(), itr.posterized.getHeight()); isPosterized.setImage(highlighted); isPosterized.performAutoZoom(); updateAnalysis(); } public void updateAnalysis() { } public void updateExampleCRUD() { var region = regionCRUD.selected(); if (region == null) { scpExampleCRUD.clear(); return; } exampleCRUD = new SimpleCRUD_v2(concepts, Example.class); exampleCRUD.entityName = () -> "label for region"; exampleCRUD.addFilter("item", region); exampleCRUD.showSearchBar(false); exampleCRUD.iconButtons(true); scpExampleCRUD.set(jCenteredSection("Labels for region", exampleCRUD.visualize())); } public void importImage() { JFileChooser fc = new JFileChooser(); if (fc.showOpenDialog(cbImage) == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile().getAbsoluteFile(); if (!isImageFile(file)) { infoMessage("Not an image file"); return; } var img = addToGallery(file); waitUntil(250, 5.0, () -> comboBoxContainsItem(cbImage, img)); setSelectedItem(cbImage, img); } } public JComponent visualize() { return jRaisedSection(northAndCenterWithMargins(centerAndEast(withLabel("Study", cbImage), hstack(jlabel(" in "), snpSelector.visualize(), horizontalStrut(10), jPopDownButton_noText("Import image...", runnableThread(new Runnable() { public void run() { try { AutoCloseable __34 = enter(); try { importImage(); } finally { _close(__34); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); importImage();"; } })))), scp)); } } public void initUIURLs() { uiURLs.put("Main Tabs", () -> horizontalLayout ? withMargin(mainTabs) : withSideMargin(mainTabs)); uiURLs.put("Screen Cam FPS", () -> jFullCenter(vstackWithSpacing(jCenteredLabel("FPS target (frames per second) for screen cam:"), jFullCenter(dm_spinner("fpsTarget", 1, 60)), jCenteredLabel("(You can lower this value if you have a slower computer)")))); uiURLs.put("Timings", () -> timingsPanel()); uiURLs.put("Test Screen", () -> testScreenPanel()); uiURLs.put("Settings", () -> settingsPanel()); uiURLs.put("System Info", () -> systemInfoPanel()); uiURLs.put("Web Cam", () -> webCamPanel()); uiURLs.put("Labels", () -> wrapCRUD("Labels", labelCRUD)); uiURLs.put(new WithToolTip("Screen Cam + Linear Script", "Run a simple (linear) Gazelle V script"), () -> withBottomMargin(scriptRunner.scriptAndResultPanel())); uiURLs.put(new WithToolTip("Scratchpad", "Write and run a \"left-arrow script\""), () -> withBottomMargin(jOnDemand(() -> scratchpad()))); uiURLs.put("Screen Cam + Script", () -> jOnDemand(() -> screenCamPlusScriptPanel())); uiURLs.put(new WithToolTip("Gallery CRUD", "Gallery view with more functions (delete etc)"), () -> wrapCRUD("Images", galleryCRUD, galleryCRUDVis)); uiURLs.put(new WithToolTip("Paint", "Paint a picture for Gazelle with your mouse!"), () -> withBottomMargin(jOnDemand(() -> paintPanel()))); uiURLs.put(new WithToolTip("Video", "A little video player (Note: no sound and doesn't handle some videos)"), () -> withBottomMargin(videoPanel())); uiURLs.put(new WithToolTip("Analyzers", "Manage image analyzers here"), () -> withBottomMargin(analyzersPanel().visualize())); uiURLs.put(new WithToolTip("Scripts", "Manage all left-arrow scripts here"), () -> withBottomMargin(scriptsPanel().visualize())); uiURLs.put(new WithToolTip("Shape Collector", "Looks at your screen live"), () -> withBottomMargin(shapeCollectorPanel().visualize())); uiURLs.put(new WithToolTip("Points of interest", "Points in random images you have clicked on"), () -> withBottomMargin(poisPanel().visualize())); uiURLs.put(new WithToolTip("Networks", "Manage recognition networks"), () -> withBottomMargin(networksPanel().visualize())); uiURLs.put("Screen Cam", () -> jOnDemand(() -> screenCamPanel())).put(new WithToolTip("Study", "Here you can analyze gallery images"), () -> withTopAndBottomMargin(studyPanel().visualize())).put(new WithToolTip("Java", "Write & run actual Java code"), () -> withBottomMargin(jOnDemand(() -> javaPanel()))).put(new WithToolTip("Gallery", "Gallery view with preview images"), () -> galleryPanel().visualize()).put(new WithToolTip("Challenges", "Gazelle's self-tests"), () -> challengesPanel()).put(new WithToolTip("Projects", "Manage/load Gazelle projects"), () -> databasesPanel().visualize()).put(new WithToolTip("Entities", "Define entities (meta-level)"), () -> entitiesPanel()).put("Local Fonts", () -> localFontsPanel().visualize()).put("Points of interest", () -> new G22POIsPanel().g22utils(g22utils).visualize()).put("Scripts from all projects", () -> new G22ScriptsFromAllDBsPanel(g22utils).visualize()).put("Networks from all projects", () -> new G22NetworksFromAllDBsPanel(g22utils).visualize()).put("Files in project", () -> new G22DBFileBrowser(g22utils).visualize()).put("Project Overview", () -> new G22ProjectOverviewPanel(g22utils).visualize()).put("Showcase", () -> withTopMargin(new G22ShowCasePanel(g22utils).visualize())).put("Story", () -> new G22ProjectStoryEditor(g22utils).visualize()).put("All objects by ID", () -> new G22AllConceptsPanel(g22utils).visualize()).put("Variables", () -> g22utils.makeVariablesPanel().visualize()).put("Connectivity", () -> new G22ConnectivityPanel().g22utils(g22utils).visualize()).put("Travel Log", () -> new G22TravelLogPanel(g22utils).visualize()).put("Screen parts", () -> screenPartsPanel().g22utils(g22utils).visualize()).put("Masks", () -> masksPanel().g22utils(g22utils).visualize()); } transient public G22LocalFontsPanel localFontsPanel_cache; public G22LocalFontsPanel localFontsPanel() { if (localFontsPanel_cache == null) localFontsPanel_cache = localFontsPanel_load(); return localFontsPanel_cache; } public G22LocalFontsPanel localFontsPanel_load() { return new G22LocalFontsPanel(g22utils); } public JComponent settingsPanel() { var cbMinimizeToTray = jCheckBox(isTrue(getOpt(dm_stem(), "minimizeToTray"))); onUpdate(cbMinimizeToTray, () -> dm_callStem(me(), "setMinimizeToTray", isChecked(cbMinimizeToTray))); return jscroll_vertical(makeForm3("Minimize to tray", toolTip("Remove Gazelle from task bar when minimized (click Gazelle icon in system tray to reactivate)", cbMinimizeToTray), "Access web cams", dm_checkBox("webCamAccessEnabled"))); } public JComponent operatorsPanel() { return jcenteredlabel("TODO"); } public JLeftArrowScriptIDE leftArrowScriptIDE() { return g22utils.leftArrowIDE(); } public void makePrototypeParser() { prototypeParser = new GazelleV_LeftArrowScriptParser(); prototypeParser.allowTheWorld(me(), new G22MaskUtils(g22utils), g22utils, mc(), utils.class); prototypeParser.isBlockedFunctionContainerMethod = (fc, name) -> fc == this && eqOneOf(name, "onChange", "onChangeAndNow", "removeChangeListener"); } public void adaptLeftArrowParser(GazelleV_LeftArrowScriptParser parser) { parser.copyFunctionContainersFrom(prototypeParser); } public JComponent scratchpad() { var scratchpad = uniq(concepts(), G22LAScratchpad.class); if (nempty(newScript)) { scratchpad.text(newScript); newScript(null); } return scratchpad.visualize(); } public void saveAsNewScript(String text) { inputText("Name for this script", description -> { AutoCloseable __25 = enter(); try { uiURLs.showUIURL("Scripts"); var script = cnewUnlisted(G22LeftArrowScript.class, "description", description, "text", text); scriptsPanel().selectAfterUpdate(script); concepts.register(script); } finally { _close(__25); } }); } public JComponent javaPanel() { AutoCloseable __26 = enter(); try { var scpResult = singleComponentPanel(); JMiniJavaIDE ide = new JMiniJavaIDE(); ide.stringifier(g22utils.stringifier); ide.extraClassMembers = script -> { List tok = javaTok(script); if (contains(tok, "draw")) return "\r\n import java.awt.*;\r\n import java.awt.image.*;\r\n \r\n interface SimpleRenderable {\r\n void renderOn(Graphics2D g);\r\n }\r\n \r\n static BufferedImage draw(int w, int h, SimpleRenderable r) {\r\n BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);\r\n Graphics2D g = img.createGraphics();\r\n g.setColor(Color.white);\r\n g.fillRect(0, 0, w, h);\r\n g.setColor(Color.black);\r\n r.renderOn(g);\r\n return img;\r\n }\r\n "; return ""; }; ide.callCompiledObject = o -> { Object result = ide.callCompiledObject_base(o); if (result instanceof BufferedImage) scpResult.set(jscroll_centered_borderless(g22utils.stdImageSurface((BufferedImage) result))); return result; }; ide.lvScript(dm_fieldLiveValue("javaCode")); return jhsplit(jCenteredSection("Image will show here", scpResult), ide.visualize()); } finally { _close(__26); } } public JComponent webCamPanel() { if (cbWebCam == null) { var cams = listWebCams(); cbWebCam = jTypedComboBox(cams, findWebCamByName(cams, webCamName)); } if (scpWebCamImage == null) scpWebCamImage = singleComponentPanel(); return northAndCenterWithMargins(centerAndEastWithMargin(withLabel("Cam", cbWebCam), jline(jbutton("Start", runnableThread(new Runnable() { public void run() { try { AutoCloseable __35 = enter(); try { startWebCam(); } finally { _close(__35); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); startWebCam();"; } })), jbutton("Stop", runnableThread(new Runnable() { public void run() { try { AutoCloseable __36 = enter(); try { stopWebCam(); } finally { _close(__36); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); stopWebCam();"; } })))), scpWebCamImage); } public void stopWebCam() { if (webCamPanel != null) { webCamPanel.stop(); webCamPanel = null; { if (scpWebCamImage != null) scpWebCamImage.clear(); } backgroundProcessesUI.remove(bgWebCam); } } public void startWebCam() { AutoCloseable __27 = tempInfoBox("Starting Web Cam"); try { stopWebCam(); var cam = getSelectedItem_typed(cbWebCam); setField("webCamName", cam == null ? null : cam.getName()); if (cam != null) { scpWebCamImage.set(northAndCenterWithMargin(rightAlignedLine(jimageButtonScaledToWidth(16, "#1103054", "Save web cam image in gallery", runnableThread(new Runnable() { public void run() { try { saveWebCamImageToGallery(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveWebCamImageToGallery();"; } }))), webCamPanel = new WebcamPanel(cam, true))); backgroundProcessesUI.add(bgWebCam); } } finally { _close(__27); } } public void forgetMissingImages() { int n = l(deleteConcepts(concepts, G22GalleryImage.class, img -> !img.imageExists())); infoBox(n == 0 ? "Nothing to forget" : "Forgot " + nImages(n)); } public boolean hasUIURL(String url) { return uiURLs.hasURL(url); } public void addUIURLToMainTabs(String url) { swing(() -> { if (containsTabNameWithoutTrailingCount(mainTabs, url)) return; if (!hasUIURL(url)) { print("URL not found: " + url); return; } addTab(mainTabs, new WithToolTip(uiURLs.toolTipForURL(url), url), uiURLs.renderUIURL(url)); }); } public void showScreenCam() { uiURLs.showUIURL("Screen Cam"); } public void showWebCam() { uiURLs.showUIURL("Web Cam"); } transient public G22NetworksPanel networksPanel_cache; public G22NetworksPanel networksPanel() { if (networksPanel_cache == null) networksPanel_cache = networksPanel_load(); return networksPanel_cache; } public G22NetworksPanel networksPanel_load() { return uniq(concepts, G22NetworksPanel.class).g22utils(g22utils); } public JComponent challengesPanel() { if (challengesPanel == null) challengesPanel = new G22ChallengesPanel().g22utils(g22utils); return challengesPanel.visualize(); } transient public G22GalleryPanel galleryPanel_cache; public G22GalleryPanel galleryPanel() { if (galleryPanel_cache == null) galleryPanel_cache = galleryPanel_load(); return galleryPanel_cache; } public G22GalleryPanel galleryPanel_load() { return new G22GalleryPanel().g22utils(g22utils); } public JComponent entitiesPanel() { if (entityCRUD == null) entityCRUD = new SimpleCRUD_v2(concepts, Entity.class); return wrapCRUD("Entities", entityCRUD); } public Gazelle22_ImageToRegions imageToRegions(BufferedImage inputImage, SnPSettings snpSettings) { return new Gazelle22_ImageToRegions(functionTimings, inputImage, snpSettings); } public Gazelle22_ImageToRegions imageToRegionsWithDiagonals(BufferedImage inputImage, SnPSettings snpSettings) { return imageToRegions(inputImage, snpSettings).withDiagonals(true); } public G22DatabasesPanel databasesPanel() { return new G22DatabasesPanel(g22utils); } transient public JComponent paintPanel_cache; public JComponent paintPanel() { if (paintPanel_cache == null) paintPanel_cache = paintPanel_load(); return paintPanel_cache; } public JComponent paintPanel_load() { if (paintToolGallery == null) { paintToolGallery = new JGallery().horizontal(false); paintToolGallery.openImage = img -> paintTool.loadImageProtected(img); paintToolGallery.imageLoader().imageHeight(50); new AWTOnConceptChangesByClass(concepts, G22GalleryImage.class, paintToolGallery.visualize(), () -> { var images = galleryImagesIn(conceptsDir(concepts)); print("Paint tool images: " + l(images)); paintToolGallery.setImageFiles(sortFilesAlphaNumIC(images)); }).install(); } if (paintTool == null) paintTool(new JPaintTool()); ownResource(paintTool); loadableUtils.utils.onChange(paintTool, me()); paintTool.createAutoPersistFile = () -> makeFileNameUnique_beforeExtension_startWith1_noDot(conceptsDir(concepts, "Painting.png")); JG22Labels labelsView = new JG22Labels(); paintTool.bottomLeftControls = () -> labelsView.visualize(); var paintToolVis = paintTool.visualize(); paintTool.imageSurface().defaultImageDir = () -> g22utils.dbDir(); if (!isDeepContainedInDir_canonical(paintTool.autoPersistFile(), conceptsDir(concepts))) paintTool.newImage(); paintTool.varAutoPersistFile().onChangeAndNow(imageFile -> { labelsView.setLabels(g22utils.labelsForFile(imageFile)); paintToolGallery.selectFile(imageFile); }); labelsView.addLabel = text -> { var imageFile = paintTool.autoPersistFile(); var labels = g22utils.labelsForFile(imageFile); labels.add(g22utils.getLabel(text)); print("labels", labels); g22utils.setLabelsForFile(imageFile, labels); labelsView.setLabels(labels); }; labelsView.removeLabel = label -> { var imageFile = paintTool.autoPersistFile(); var labels = g22utils.labelsForFile(imageFile); labels = listWithout(labels, label); g22utils.setLabelsForFile(imageFile, labels); labelsView.setLabels(labels); }; if (paintAnalysisPanel == null) paintAnalysisPanel = new G22AnalysisPanel(); paintAnalysisPanel.editAnalyzer = __30 -> editAnalyzer(__30); paintAnalysisPanel.g22utils(g22utils).imageSurface(paintTool.imageSurface()); ownResource(paintAnalysisPanel); loadableUtils.utils.onChange(paintAnalysisPanel, me()); paintTool.onImageChanged(img -> paintAnalysisPanel.setImage(img)); paintAnalysisPanel.setImage(paintTool.getImage()); var collapsiblePanel = new CollapsibleLeftPanel(false, "Paintings", paintToolGallery.visualize(), paintToolVis); linkVars(varPaintToolGalleryExpanded(), collapsiblePanel.varExpanded()); paintToolGallery.varFiles().onChangeAndNow(files -> collapsiblePanel.sidePanelName(n2(files, "Painting"))); return jvsplit(0.75, collapsiblePanel.visualize(), jRaisedCenteredSection("Image Analysis", paintAnalysisPanel.visualize())); } public JComponent videoPanel() { if (videoLibDownloader == null) { videoLibDownloader = new JVideoLibDownloader(); videoLibDownloader.forward(() -> videoPlayer().visualize()); } return videoLibDownloader.visualize(); } public JFFMPEGVideoPlayer videoPlayer() { if (videoPlayer == null) videoPlayer = new JFFMPEGVideoPlayer(); return videoPlayer; } transient public G22AnalyzersPanel analyzersPanel_cache; public G22AnalyzersPanel analyzersPanel() { if (analyzersPanel_cache == null) analyzersPanel_cache = analyzersPanel_load(); return analyzersPanel_cache; } public G22AnalyzersPanel analyzersPanel_load() { return uniq(concepts, G22AnalyzersPanel.class).g22utils(g22utils); } transient public G22ScriptsPanel scriptsPanel_cache; public G22ScriptsPanel scriptsPanel() { if (scriptsPanel_cache == null) scriptsPanel_cache = scriptsPanel_load(); return scriptsPanel_cache; } public G22ScriptsPanel scriptsPanel_load() { return uniq(concepts, G22ScriptsPanel.class).g22utils(g22utils); } transient public G22ScreenPartsPanel screenPartsPanel_cache; public G22ScreenPartsPanel screenPartsPanel() { if (screenPartsPanel_cache == null) screenPartsPanel_cache = screenPartsPanel_load(); return screenPartsPanel_cache; } public G22ScreenPartsPanel screenPartsPanel_load() { return uniq(concepts, G22ScreenPartsPanel.class).g22utils(g22utils); } transient public G22MasksPanel masksPanel_cache; public G22MasksPanel masksPanel() { if (masksPanel_cache == null) masksPanel_cache = masksPanel_load(); return masksPanel_cache; } public G22MasksPanel masksPanel_load() { return uniq(concepts, G22MasksPanel.class).g22utils(g22utils); } transient public G22POIsPanel poisPanel_cache; public G22POIsPanel poisPanel() { if (poisPanel_cache == null) poisPanel_cache = poisPanel_load(); return poisPanel_cache; } public G22POIsPanel poisPanel_load() { return uniq(concepts, G22POIsPanel.class).g22utils(g22utils); } public G22ShapeCollectorPanel shapeCollectorPanel() { return G22ShapeCollectorPanel.fullyConfigured(g22utils); } public Collection galleryImagesIn(File dir) { return mapNonNulls(list(concepts, G22GalleryImage.class), i -> isDeepContainedInDir_absolute(i.path, dir) ? i.path : null); } public void editAnalyzer(G22Analyzer analyzer) { if (analyzer == null) return; analyzersPanel().edit(analyzer); uiURLs.showUIURL("Analyzers"); } public void editScript(G22LeftArrowScript script) { if (script == null) return; uiURLs.showUIURL("Scripts"); scriptsPanel().edit(script); } public void editScreenPart(G22ScreenPart screenPart) { screenPartsPanel().edit(screenPart); uiURLs.showUIURL("Screen parts"); } public Object inlineScript(long scriptID, VarContext varContext) { var script = getConcept(concepts, G22LeftArrowScript.class, scriptID); if (script == null) throw fail("Script ID " + scriptID + " not found"); GazelleV_LeftArrowScript.Script parsedScript = script.compileSaved().parsedScript; return parsedScript.get(varContext); } transient public StudyPanel studyPanel_cache; public StudyPanel studyPanel() { if (studyPanel_cache == null) studyPanel_cache = studyPanel_load(); return studyPanel_cache; } public StudyPanel studyPanel_load() { return new StudyPanel(); } public SingleComponentPanel jOnDemand(IF0 makeComponent) { return loadableUtils.utils.jOnDemand(() -> { AutoCloseable __28 = enter(); try { return makeComponent == null ? null : makeComponent.get(); } finally { _close(__28); } }); } public void editScripts() { uiURLs.showUIURL("Scripts"); } public void editProjectStory() { uiURLs.showUIURL("Story"); } public void openObjectInProject(long id) { var c = getConcept(concepts, id); if (c == null) infoBox("Object ID not found in project: " + id); else openConcept(c); } public void openConcept(Concept c) { if (c instanceof G22Analyzer) { uiURLs.showUIURL("Analyzers"); analyzersPanel().setSelected((G22Analyzer) c); } else if (c instanceof G22LeftArrowScript) { editScript((G22LeftArrowScript) c); } else if (c instanceof G22PointOfInterest) { uiURLs.showUIURL("Points of interest"); poisPanel().setSelected((G22PointOfInterest) c); } else if (c instanceof G22GalleryImage) { showInGallery((G22GalleryImage) c); } else if (c instanceof G22Network) { showNetwork((G22Network) c); } else infoBox("Don't know how to show " + c); } public void showNetwork(G22Network network) { if (network == null) return; uiURLs.showUIURL("Networks"); networksPanel().setSelected(network); } public void openUIURL(String url) { uiURLs.showUIURL(url); } public boolean openPathInProject(String path) { path = trim(path); String path2; if ((path2 = dropPrefixOrNull("../", path)) != null) { masterStuff().openDB(path2, false); return true; } if (isInteger(path)) { openObjectInProject(parseLong(path)); return true; } if (hasUIURL(path)) { openUIURL(path); return true; } File f = newFile(g22utils.dbDir(), path); print("f", f); if (isFile(f)) { if (isImageFile(f)) { showInGallery(addToGallery(f)); return true; } else { infoBox("Unknown file type: " + fileName(f)); return false; } } infoBox("Not a UI URL, object ID or project file: " + path); return false; } public void showInGallery(G22GalleryImage img) { if (img == null) return; uiURLs.showUIURL("Gallery"); galleryPanel().selectImage(img); } public G22GalleryImage galleryImageConcept(long id) { return getConcept(concepts, G22GalleryImage.class, id); } public BufferedImage getGalleryImage(long id) { var img = galleryImageConcept(id); if (img == null) throw fail("Image not found: " + id); return img.load(); } public void cleanMeUp_g22utils() { g22utils.close(); } final public void waitForAutoStart() { waitUntilStarted(); } public void waitUntilStarted() { g22utils.autoStarter().waitUntilDone(); } public String functionsIncludeID() { return "#1034034"; } public void infoBoxAndCompile(String msg) { infoBox(msg); if (cic(msg, "edited")) dm_callOS("compile"); } public boolean devMode() { return g22_devMode(); } public G22WatchTarget defaultWatchTarget() { return screenCount() > 1 ? new WatchOtherScreen() : new WatchScreen(1); } public G22MasterStuff masterStuff() { return g22utils.masterStuff(); } public void addProjectLibs(Collection libs) { if (addAll(projectLibs, libs)) change(); } public void removeProjectLibs(Collection libs) { if (removeAll(projectLibs, libs)) change(); } public void addUIURL(String url, IF0 maker) { uiURLs.put(url, maker); } public List> quickRegions(BufferedImage image, int colors) { return imageToRegions(image, new SnPSettings(image, colors)).get().get(); } public List> quickRegionsWithDiagonals(BufferedImage image, int colors) { return imageToRegionsWithDiagonals(image, new SnPSettings(image, colors)).get().get(); } public WebcamListener webcamImageObtainedListener(IVF1 r) { return new WebcamListener() { public void webcamOpen(WebcamEvent we) { } public void webcamClosed(WebcamEvent we) { } public void webcamDisposed(WebcamEvent we) { } public void webcamImageObtained(WebcamEvent we) { { if (r != null) r.get(we); } } }; } public void restartGazelle() { masterStuff().restart(); } public void closeProject() { masterStuff().closeDatabase(g22utils.projectDir()); } public A addProjectError(A e) { if (e == null) return null; printStackTrace(e); var persistable = toPersistableThrowable(e); addToListWithMaxSize(projectErrors, persistable, maxProjectErrors); change(); projectErrorOccurred(persistable); projectErrorsChanged(); return e; } public void clearProjectErrors() { if (syncClear_trueIfChanged(projectErrors)) { change(); projectErrorsChanged(); } } public JComponent systemInfoPanel() { return new G22SystemInfoPanel(g22utils).visualize(); } public void goToSource(TokenRangeWithSrc src) { if (src == null) return; var script = src.sourceInfo(); if (script instanceof G22LeftArrowScript) { uiURLs.showUIURL("Scripts"); scriptsPanel().edit(((G22LeftArrowScript) script), src.startLineAndCol()); } } public TokenRangeWithSrc findDefinition(String id) { var fd = g22utils.projectWideFunctionDefs.get(id); if (fd != null) return fd.tokenRangeWithSrc(); Class c = g22utils.projectWideClassDefs.get(id); if (c != null) return (TokenRangeWithSrc) getOpt(c, "__srcRef"); return null; } } static public boolean _moduleClass_GazelleScreenCam = true; static public class SavedRegion extends Concept { static final public String _fieldOrder = "image snpSettings regionIndex bitMatrix"; public Ref image = new Ref(); public SnPSettings snpSettings; public int regionIndex; public ScanlineBitMatrix bitMatrix; } static public class Example extends Concept { static final public String _fieldOrder = "label item confidence"; public Ref label = new Ref(); public Ref item = new Ref(); public double confidence = 1; } static public class IfThenTheory extends Concept { public Ref if_ = new Ref(); public Ref then = new Ref(); } static public class Entity extends NamedConcept { } abstract static public class AbstractJavaObjectEntity extends Entity { abstract public A object(); public String toString() { String s = super.toString(); Object o = object(); if (o != null) s += " " + str_pcall(o); return s; } } static public class TransientJavaObjectEntity extends AbstractJavaObjectEntity { final public A getObject() { return object(); } public A object() { return object; } transient public A object; } static public class PersistentJavaObjectEntity extends AbstractJavaObjectEntity { final public A getObject() { return object(); } public A object() { return object; } public A object; } static public class ConceptEntity extends AbstractJavaObjectEntity { public Ref concept = new Ref(); public ConceptEntity(A concept) { this.concept.set(concept); } public A object() { return concept.get(); } } static public class FieldInObjectEntity extends Entity { static final public String _fieldOrder = "objectEntity fieldName"; public Ref> objectEntity = new Ref(); public String fieldName; public FieldInObjectEntity(AbstractJavaObjectEntity objectEntity, String fieldName) { this.objectEntity.set(objectEntity); this.fieldName = fieldName; } public Object value() { return !objectEntity.has() ? null : getOpt(objectEntity.get().object(), fieldName); } public String toString() { String s = super.toString() + " " + fieldName + " in " + objectEntity; Object value = value(); if (value != null) s += appendBracketed("value of type " + className(value)); return s; } } static public class DeclaredFieldEntity extends Entity { static final public String _fieldOrder = "theClass fieldName"; public Class theClass; public String fieldName; public DeclaredFieldEntity(Class theClass, String fieldName) { this.fieldName = fieldName; this.theClass = theClass; } public Field fieldObject() { return findFieldOfClass(theClass, fieldName); } public String toString() { var fieldObject = fieldObject(); return super.toString() + " " + (fieldObject != null ? str(fieldObject) : "[field not found: " + className(theClass) + "." + fieldName + "]"); } } static public TimestampRange joinTimestampRanges(TimestampRange a, TimestampRange b) { if (a == null) return b; if (b == null) return a; return new TimestampRange(min(a.start, b.start), max(a.end, b.end)); } static public TimestampRange joinTimestampRanges(Iterable l) { return fold((__83, __84) -> joinTimestampRanges(__83, __84), l); } static public long unixDay() { return unixDay(now()); } static public long unixDay(long timestamp) { return unixHour(timestamp) / 24; } static public long unixDay(Timestamp timestamp) { return unixDay(timestamp.toLong()); } static public List takeLastFromIterator(int n, Iterator it) { SimpleCircularBuffer buf = new SimpleCircularBuffer(n); if (it != null) while (it.hasNext()) buf.add(it.next()); return buf.asList(); } static public void closeOpt(Object c) { if (c instanceof AutoCloseable) _close((AutoCloseable) c); } static public List iotaList(final int n) { return intRangeList(1, n + 1); } static public List havingFieldNotNull(Iterable l, String field) { return filter(l, o -> getOpt(o, field) != null); } static public List havingFieldNotNull(String field, Iterable l) { return havingFieldNotNull(l, field); } static public void removeComponent(final Container cc, final Component c) { if (cc != null && c != null) { swing(() -> { cc.remove(c); }); } } static public Reader utf8ZipReader(ZipFile zipFile, String path) { return utf8reader(zipInputStream(zipFile, path)); } static public JPanel westAndCenterWithMargins(Component w, Component c) { return applyDefaultMargin(westAndCenter(withRightMargin(w), c)); } static public JPanel westAndCenterWithMargins(int margin, Component w, Component c) { return addMargin(margin, westAndCenter(withRightMargin(margin, w), c)); } static public String buySellText(double direction) { return direction > 0 ? "BUY" : direction < 0 ? "SELL" : ""; } static public int parseIntOpt(String s) { return parseIntOpt(s, 0); } static public int parseIntOpt(String s, int defValue) { return isInteger(s) ? parseInt(s) : defValue; } static public A updateChain(ChangeTriggerable b, A a) { return onChange(a, b); } static public A updateChain(Updateable b, A a) { return onChange(a, b); } static public A updateChain(Runnable b, A a) { return onChange(a, b); } static public A updateChain(Object b, A a) { onChange(a, changeReceiverToRunnable(b)); return a; } static public A updateChain(Object b, A a) { onChange(a, changeReceiverToRunnable(b)); return a; } static public A updateChain(Object b, A l) { for (var a : unnullForIteration(l)) preciseCall(main.class, "updateChain", b, a); return l; } static public void drawTextWithOutline(Graphics2D g2, String text, float x, float y, Color fillColor, Color outlineColor) { BasicStroke outlineStroke = new BasicStroke(2.0f); g2.translate(x, y); Stroke originalStroke = g2.getStroke(); RenderingHints originalHints = g2.getRenderingHints(); GlyphVector glyphVector = g2.getFont().createGlyphVector(g2.getFontRenderContext(), text); Shape textShape = glyphVector.getOutline(); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setColor(outlineColor); g2.setStroke(outlineStroke); g2.draw(textShape); g2.setColor(fillColor); g2.fill(textShape); g2.setStroke(originalStroke); g2.setRenderingHints(originalHints); g2.translate(-x, -y); } static public double negateIf(boolean negate, double x) { return negate ? -x : x; } static public int negateIf(boolean negate, int x) { return negate ? -x : x; } static public JComponent jLines(Iterable lines) { return jText(lines(lines)); } static public A shallowNonTransientClone(A o) { return o == null ? null : (A) shallowNonTransientCloneToClass(o.getClass(), o); } static public List conceptsSortedByID(Collection c) { return sortedByConceptID(c); } static public List uniquifyAndSort(Collection l) { return sorted(uniquify(l)); } static public boolean firstBytesOfFileAre(File f, String hex) { byte[] bytes = bytesFromHex(hex); return byteArraysEqual(bytes, loadFirstBytes(f, l(bytes))); } static public ImageSurface zoomedImageSurface(MakesBufferedImage image, final double zoom) { return zoomedImageSurface(toBufferedImage(image), zoom); } static public ImageSurface zoomedImageSurface(BufferedImage image, final double zoom) { return swing(new F0() { public ImageSurface get() { try { ImageSurface is = new ImageSurface(image); is.setZoom(zoom); return is; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ImageSurface is = new(image);\r\n is.setZoom(zoom);\r\n ret is;"; } }); } static public ImageSurface zoomedImageSurface(double zoom, MakesBufferedImage image) { return zoomedImageSurface(zoom, toBufferedImage(image)); } static public ImageSurface zoomedImageSurface(double zoom, BufferedImage image) { return zoomedImageSurface(image, zoom); } static public String shortenNumbers(String s) { return shortenNumbers(s, 2); } static public String shortenNumbers(String s, int decimals) { return reformatFloatingPointNumbers(s, decimals); } static public String shortenNumbers(int decimals, String s) { return shortenNumbers(s, decimals); } static public int minutesInADay() { return 24 * 60; } static public > B longestList(Iterable l) { return highestBy(__55 -> l(__55), l); } static public DoubleRange bollingerRange(AverageAndStandardDeviation as) { return bollingerRange(as, 2); } static public DoubleRange bollingerRange(AverageAndStandardDeviation as, double size) { return doubleRangeAround(as.avg, as.standardDeviation * size); } static public double smoothedMovingAverage(double period, double... a) { int n = l(a); if (n == 0) return Double.NaN; double alpha = reciprocal(period); double value = first(a); for (int i = 1; i < n; i++) value = blend(value, a[i], alpha); return value; } static public AverageAndStandardDeviation averageAndStandardDeviation(double... a) { AverageAndStandardDeviation out = new AverageAndStandardDeviation(); if (empty(a)) return out; double avg = doubleAverage(a); double sum = 0; for (int i = 0; i < l(a); i++) sum += sqr(a[i] - avg); out.avg = avg; out.standardDeviation = sqrt(sum / l(a)); return out; } static public List syncTakeLast(List l, int n) { if (l == null) return takeLast(l, n); synchronized (collectionMutex(l)) { return takeLast(l, n); } } static public List syncTakeLast(int n, List l) { return syncTakeLast(l, n); } static public List llNotNulls(A... a) { ArrayList l = new ArrayList(l(a)); if (a != null) for (A x : a) if (x != null) l.add(x); return l; } static public Duration totalLengthOfTimestampRanges(Iterable l) { long sum = 0; for (var r : unnullForIteration(l)) sum += r.length(); return msToDuration(sum); } static public A copyField(Object x, A y, String field) { return copyFields(x, y, field); } static public List lastNLinesOfFile(File f, int n) { return lastNLines(f, n); } static public List lastNLinesOfFile(int n, File f) { return lastNLines(n, f); } static public int copyConceptFields(Concept a, Concept b) { int changes = 0; for (String field : conceptFields(a)) changes += cset(b, field, cget(a, field)); return changes; } static public int copyConceptFields(Concept a, Concept b, String... fields) { int changes = 0; for (String field : fields) changes += cset(b, field, cget(a, field)); return changes; } static public boolean isMap(Object o) { return o instanceof Map; } static public boolean isJSON(String s) { try { return jsonDecode_quickFail(s) != null; } catch (Throwable e) { handleHardError(e); } return false; } static public String nErrors(long n) { return n2(n, "error"); } static public String nErrors(Collection l) { return nErrors(l(l)); } static public String nErrors(Map map) { return nErrors(l(map)); } static public java.nio.file.attribute.BasicFileAttributes fileAttributes(String f) { return fileAttributes(toFile(f)); } static public java.nio.file.attribute.BasicFileAttributes fileAttributes(File f) { try { return f == null ? null : java.nio.file.Files.readAttributes(f.toPath(), java.nio.file.attribute.BasicFileAttributes.class); } catch (Exception __e) { throw rethrow(__e); } } static public JWindow infoBoxConcat(Object... l) { return infoBox(concat(l)); } static public JWindow infoBoxConcat(Iterable l) { return infoBox(concat(l)); } static public A assertEqualsV(Object x, A y) { return assertEqualsVerbose(x, y); } static public A assertEqualsV(String msg, Object x, A y) { return assertEqualsVerbose(msg, x, y); } static public void assertEqualsV(Scorer scorer, Object x, Object y) { assertEqualsV(scorer, "", x, y); } static public void assertEqualsV(Scorer scorer, String msg, Object x, Object y) { assertEqualsVerbose(scorer, msg, x, y); } static public AutoCloseable afterwards(final Object r) { return tempAfterwards(r); } static public AutoCloseable tempRestoreSCP(SingleComponentPanel scp) { if (scp == null) return null; var contents = scp.get(); return () -> scp.set(contents); } static public String onlyChars(String chars, String s) { if (empty(chars)) return ""; int n = l(s); StringBuilder buf = new StringBuilder(); char c; for (int i = 0; i < n; i++) if (contains(chars, c = s.charAt(i))) buf.append(c); return str(buf); } static public char[] chars(String s) { return asChars(s); } static public String replace_multi(String s, Collection a, String b) { if (s == null || empty(a) || b == null) return s; for (String aa : a) s = s.replace(aa, b); return s; } static public String replace_multi(String s, String... replacements) { if (empty(s) || empty(replacements)) return s; for (int i = 0; i + 1 < l(replacements); i += 2) s = s.replace(replacements[i], replacements[i + 1]); return s; } static public boolean fileNameContainsIC(File f, String s) { return cic(fileName(f), s); } static public boolean fileNameContainsIC(String s, File f) { return fileNameContainsIC(f, s); } static public A rightAlignTextField(A tf) { if (tf != null) { swing(() -> { tf.setHorizontalAlignment(JTextField.RIGHT); }); } return tf; } static public JFrame setFrameHeight(JFrame frame, int h) { if (frame != null) { swing(() -> { frame.setSize(frame.getWidth(), h); }); } return frame; } static public JFrame setFrameHeight(int h, JFrame frame) { return setFrameHeight(frame, h); } static public String hsmall(Object contents, Object... params) { return tag("small", contents, params); } static public String formatHours_roundUp(long ms) { return formatHours_roundUp(ms, 1); } static public String formatHours_roundUp(long ms, int decimals) { return formatHours_roundUp(toHours(ms), decimals); } static public String formatHours_roundUp(double hours) { return formatHours_roundUp(hours, 1); } static public String formatHours_roundUp(double hours, int decimals) { String formatted = formatDouble_roundUp(hours, decimals); return eq(formatted, "1") ? "1 hour" : formatted + " hours"; } static public Color candleColorOnWhite(double direction) { return direction == 0 ? Color.black : directionToCandleColor(direction); } static public String brCombine(Object... l) { return joinNemptiesWithBR(flattenCollectionsAndArrays(l)); } static public String spanTitle(String title, Object contents) { return empty(title) ? str(contents) : span(contents, "title", title); } static public String span(Object contents, Object... params) { return hfulltag("span", contents, params); } static public String span() { return span(""); } static public A jMaxHeight(A c, int h) { return jMaxHeight(h, c); } static public A jMaxHeight(int h, A c) { return jPreferHeight(h, jMaxHeight_pure(h, c)); } static public JComponent vscrollingCenteredLine_noGaps(Component... components) { return jscroll_vertical_borderless(jpanel(new VScrollingWrapLayout().centeredHorizontally(true), components)); } static public JComponent vscrollingCenteredLine_noGaps(List components) { return vscrollingCenteredLine_noGaps(asArray(Component.class, components)); } static public String str_toM_round(long l) { return n2(toM_round(l)) + " MB"; } static public AutoCloseable vmBus_onMessageAndNow(String msg, Runnable onMessage) { var closeable = vmBus_onMessage(msg, runnableToVF1(onMessage)); pcallF(onMessage); return closeable; } static public void dumpHeap(File file) { try { MBeanServer server = ManagementFactory.getPlatformMBeanServer(); Object bean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", classForName("com.sun.management.HotSpotDiagnosticMXBean")); file.delete(); mkdirsForFile(file); AutoCloseable __1 = tempInfoBoxForever("Dumping heap..."); try { long time = sysNow(); call(bean, "dumpHeap", f2s(file), true); done2_always(time, "Done. " + fileInfo(file)); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } static public Component contentsOfTabNamed(JTabbedPane tabs, String tabName) { return swing(() -> { return contentsOfTab(tabs, indexOfTabName(tabs, tabName)); }); } static public long oneGigabyte() { return 1024 * 1024 * 1024; } static public List methods(Object o) { return allLiveMethods(o); } static public SingleComponentPanel jOnDemandInQ(Q q, IF0 makeComponent) { SingleComponentPanel scp = singleComponentPanel(); bindToComponent(scp, () -> { if (!scp.isEmpty()) return; runInQ(q, () -> { if (!scp.isEmpty()) return; try { var c = makeComponent == null ? null : makeComponent.get(); { swing(() -> { if (!scp.isEmpty()) return; scp.setComponent(c); }); } } catch (Throwable e) { printStackTrace(e); scp.setComponent(jscroll(jFastLogView_noWrap(renderStackTrace(e)))); } }); }, null); return scp; } static public JPanel hvgrid(List> components) { if (empty(components)) return new JPanel(); int h = l(components), w = l(first(components)); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(h, w)); for (List row : components) smartAdd(panel, row); return panel; } static public JPanel hvgrid(List> components, int gap) { JPanel panel = hvgrid(components); GridLayout g = (GridLayout) (panel.getLayout()); g.setHgap(gap); g.setVgap(gap); return panel; } static public List addAllAndReturnNew(Collection c, Collection b) { if (c == null || b == null) return emptyList(); List newEntries = new ArrayList(); for (A a : b) if (c.add(a)) newEntries.add(a); return newEntries; } static public JTextComponent looselyBindLiveValueToTextComponent(IVarWithNotify lv, JTextComponent c) { onChange(c, () -> lv.set(getText(c))); bindToComponent(c, () -> { String value = lv.get(); if (value != null) setText(c, value); else lv.set(getText(c)); }); return c; } static public JComponent withLabelLeftAndRight(String label1, JComponent component, String label2) { return withLabel(label1, withLabelToTheRight(component, label2)); } static public String str_toGB(long l) { return n2(toG(l)) + " GB"; } static public String toM_str(long l) { return str_toM(l); } static public List mapOdds(List l, IF1 f) { int n = l(l); List out = emptyList(n); for (int i = 0; i < n; i++) { A a = l.get(i); if (odd(i)) a = f.get(a); out.add(a); } return out; } static public List mapOdds(IF1 f, List l) { return mapOdds(l, f); } static public List splitAtSpace_trim(String s) { return nempties(trimAll(splitAtSpace(s))); } static public IF0 if0_const(final A a) { return () -> a; } static public A recursiveFontSize(A c, float fontSize) { return recursiveFontSize(c, fontSize, null); } static public A recursiveFontSize(A c, float fontSize, IF1 componentFilter) { return setAllStandardFontSizesRecursively(c, fontSize, componentFilter); } static public A recursiveFontSize(float fontSize, A c) { return recursiveFontSize(c, fontSize); } static public String myIP() { return getMyIP(); } static public boolean ne(Object a, Object b) { return neq(a, b); } static public A strongestSignal(Collection l) { return highestBy(l, s -> s.strength()); } static public String targetBlank(String link, Object contents, Object... params) { return hrefBlank(link, contents, params); } static public A ifThenElse(boolean b, A trueValue, A falseValue) { return b ? trueValue : falseValue; } static public ImageSurface showZoomedImage(final RGBImage image) { return showZoomedImage(image, 2); } static public ImageSurface showZoomedImage(String title, RGBImage image) { return showZoomedImage(title, image, 2); } static public ImageSurface showZoomedImage(String title, BufferedImage image) { return showZoomedImage(title, image, 2); } static public ImageSurface showZoomedImage(String title, RGBImage image, double zoom) { return setFrameTitle(showZoomedImage(image, zoom), title); } static public ImageSurface showZoomedImage(String title, BufferedImage image, double zoom) { return setFrameTitle(showZoomedImage(image, zoom), title); } static public ImageSurface showZoomedImage(RGBImage image, double zoom) { return showZoomedImage(image.getBufferedImage(), zoom); } static public ImageSurface showZoomedImage(BufferedImage image) { return showZoomedImage(image, 2); } static public ImageSurface showZoomedImage(double zoom, MakesBufferedImage image) { return showZoomedImage(toBufferedImage(image), zoom); } static public ImageSurface showZoomedImage(double zoom, BufferedImage image) { return showZoomedImage(image, zoom); } static public ImageSurface showZoomedImage(BufferedImage image, double zoom) { return (ImageSurface) swingAndWait(new F0() { public Object get() { try { ImageSurface is = showImage(image); is.setZoom(zoom); packFrame(is); return is; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "ImageSurface is = showImage(image);\r\n is.setZoom(zoom);\r\n packFrame(is)..."; } }); } static public ImageSurface showZoomedImage(BWImage image) { return showZoomedImage(image.getBufferedImage()); } static public ImageSurface showZoomedImage(BWImage image, double zoom) { return showZoomedImage(image.getBufferedImage(), zoom); } static public ImageSurface showZoomedImage(RGBImage img, ImageSurface surface) { if (surface == null) return showZoomedImage(img); else { surface.setImage(img); return surface; } } static public ImageSurface showZoomedImage(ImageSurface surface, BufferedImage img, String title) { return setFrameTitle(showZoomedImage(img, surface), title); } static public ImageSurface showZoomedImage(ImageSurface surface, RGBImage img, String title) { return setFrameTitle(showZoomedImage(img, surface), title); } static public ImageSurface showZoomedImage(ImageSurface surface, String title, RGBImage img) { return showZoomedImage(surface, img, title); } static public ImageSurface showZoomedImage(ImageSurface surface, String title, MakesBufferedImage img) { return showZoomedImage(surface, img.getBufferedImage(), title); } static public ImageSurface showZoomedImage(BufferedImage img, ImageSurface surface) { if (surface == null) return showZoomedImage(img); else { surface.setImage(img); return surface; } } static public Average multiSetAverage(MultiSet ms) { Average a = new Average(); for (var key : keys(ms)) a.add(toDouble(key), ms.get(key)); return a; } static public B mapGetOrCreate(Map map, A key, Class c) { return getOrCreate(map, key, c); } static public B mapGetOrCreate(Map map, A key, Object f) { return getOrCreate(map, key, f); } static public B mapGetOrCreate(Map map, A key, IF0 f) { return getOrCreate(map, key, (Object) f); } static public B mapGetOrCreate(Class c, Map map, A key) { return getOrCreate(c, map, key); } static public NavigableMap syncTreeMap() { return synchroTreeMap(); } static public void joinThread(Thread t) { try { if (t != null) t.join(); } catch (Exception __e) { throw rethrow(__e); } } static public void joinThread(Thread t, long ms) { try { if (t != null) t.join(ms); } catch (Exception __e) { throw rethrow(__e); } } static public long parseLocalDateWithMilliseconds(String s) { try { if (s == null) return 0; return simpleDateFormat_local("yyyy/MM/dd HH:mm:ss''SSSS").parse(s).getTime(); } catch (Exception __e) { throw rethrow(__e); } } static public void drawText(Graphics2D g, String text, int p_x, int p_y, Color color) { drawText(g, text, pt(p_x, p_y), color); } static public void drawText(Graphics2D g, String text, Pt p, Color color) { g.setColor(color); g.drawString(text, p.x, p.y); } static public void drawCenteredText(Graphics2D g, String text, int x, int y, int w, int h, Color color) { g.setColor(color); FontMetrics fm = g.getFontMetrics(); Pt p = centerTextInRect(fm, text, rect(x, y, w, h)); g.drawString(text, p.x, p.y); } static public BufferedImage drawCenteredText(BufferedImage image, String text) { return drawCenteredText(image, text, black()); } static public BufferedImage drawCenteredText(BufferedImage image, String text, Color color) { if (image != null) drawCenteredText(antiAliasGraphics(image), text, 0, 0, image.getWidth(), image.getHeight(), color); return image; } static public BufferedImage drawCenteredText(BufferedImage image, String text, Font font) { return drawCenteredText(image, text, black(), font); } static public BufferedImage drawCenteredText(BufferedImage image, String text, Color color, Font font) { if (image != null) { var g = antiAliasGraphics(image); if (font != null) g.setFont(font); drawCenteredText(g, text, 0, 0, image.getWidth(), image.getHeight(), color); } return image; } static public IterableIterator allUpDownSequencesOfLength(int length) { return mapI(allWordsOfAlphabetWithLength(length, "UD"), s -> new UpDownSequence(s)); } static public String reformatFloatingPointNumbers(String s) { return reformatFloatingPointNumbers(s, 2); } static public String reformatFloatingPointNumbers(String s, int decimals) { return regexpReplace(s, "\\b" + regexpForFloatingPointWithoutSign(), matcher -> formatDouble(parseDouble(matcher.group()), decimals)); } static public String reformatFloatingPointNumbers(int decimals, String s) { return reformatFloatingPointNumbers(s, decimals); } static public IterableIterator allUpDownSequencesOfMaxLength(int maxLength) { return mapI(allWordsOfAlphabet_maxLength(maxLength, "UD"), s -> new UpDownSequence(s)); } static public String formatDollarProfit(double x) { return withDollar(formatMarginProfit(x)); } static public AutoCloseable tempInstanceCounter(AtomicLong counter) { return tempInc(counter); } static public String formatDollarPrice(double x) { return withDollar(formatWith2OrZeroDecimals(x)); } static public String withDollar(String s) { if (empty(s)) return ""; if (startsWithOneOf(s, "$", "+$", "-$")) return s; int i = 0; if (startsWithOneOf(s, "+", "-")) ++i; return insertStringAt(s, i, "$"); } static public List sortedByFieldDesc(Collection c, String field) { List l = new ArrayList(c); sort(l, descFieldComparator(field)); return l; } static public List sortedByFieldDesc(String field, Collection c) { return sortedByFieldDesc(c, field); } static public String js_setTitle(String title) { return js_dollarVars("document.title = $title;", "title", unnull(title)); } static public FixedRateTimer doEvery_stopOnException(double delaySeconds, Runnable r) { return doEvery_stopOnException(delaySeconds, delaySeconds, r); } static public FixedRateTimer doEvery_stopOnException(double initialSeconds, double delaySeconds, Runnable r) { return doEvery_stopOnException(initialSeconds, delaySeconds, r, null); } static public FixedRateTimer doEvery_stopOnException(double delaySeconds, Runnable r, Runnable onStop) { return doEvery_stopOnException(delaySeconds, delaySeconds, r, onStop); } static public FixedRateTimer doEvery_stopOnException(double initialSeconds, double delaySeconds, Runnable r, Runnable onStop) { if (r == null) return null; FixedRateTimer timer = new FixedRateTimer(shorten(programID() + ": " + r, 80)); Runnable r2 = new Runnable() { public void run() { try { try { r.run(); } catch (Throwable e) { printStackTrace(e); print("Cancelling timer due to error."); timer.cancel(); pcallF(onStop); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "try { r.run(); } catch (Throwable e) { printStackTrace(e);\r\n print(\"Canc..."; } }; timer.scheduleAtFixedRate(smartTimerTask(r2, timer, toMS_int(delaySeconds)), toMS_int(initialSeconds), toMS_int(delaySeconds)); return timer; } static public String js_setDivContents(String divID, String contents) { return replaceDollarVars_js("\r\n {\r\n var div = document.getElementById($divID);\r\n if (div)\r\n div.innerHTML = $contents;\r\n }\r\n ", "divID", divID, "contents", contents); } static public String hdiv(Object contents, Object... params) { return hfulltag("div", contents, params); } static public String hdiv() { return hdiv(""); } static public String jsonEvalMsg(String code, Object... __) { return jsonEncodeMap("eval", jsDollarVars(code, __)); } static public String js_appendToDiv(String divID, String contents) { return replaceDollarVars_js("\r\n {\r\n var div = document.getElementById($divID);\r\n if (div)\r\n div.insertAdjacentHTML('beforeend', $contents);\r\n }\r\n ", "divID", divID, "contents", contents); } static public String hhtml(Object contents) { return containerTag("html", contents); } static public String hhead(Object contents) { return tag("head", contents); } static public String htitle(String title) { return hfulltag("title", htmlencode_noQuotes(title)); } static public String hbody(Object contents, Object... params) { return tag("body", contents, params); } static public String hsansserif() { return hcss("body { font-family: Sans-Serif; }"); } static public String hmobilefix() { return ""; } static public String hmobilefix(String html) { return hAddToHead(html, hmobilefix()); } static public String p(Object contents, Object... params) { return hfulltag("p", contents, params) + "\n"; } static public String p() { return p(""); } static public String himg(String src, Object... params) { return tag("img", "", arrayPlus(params, "src", isSnippetID(src) ? snippetImageLink(src) : src)); } static public String himg(BufferedImage img, Object... params) { return himg(dataURL(jpegMimeType(), toJPEG(img)), params); } static public String htmlCombine(Object... l) { return nemptyLines_extractLists(l); } static public String hfullcenter(Object contents, Object... __) { return tag("table", tr(td(contents, "align", "center")), paramsPlus(__, "width", "100%", "height", "100%")); } static public SNIKeyManager serverSocketFactory_botCompanyEtc_keyManager; static public String serverSocketFactory_botCompanyEtc_passphrase = "botcompany"; static public File serverSocketFactory_botCompanyEtc_trustKeyStoreFile; static public char[] serverSocketFactory_botCompanyEtc_getPassphrase() { return getChars(serverSocketFactory_botCompanyEtc_passphrase); } static public SNIKeyManager serverSocketFactory_botCompanyEtc_makeSNIKeyManager() { return new SNIKeyManager(serverSocketFactory_botCompanyEtc_makeKeyManagerMap()); } static public Map> serverSocketFactory_botCompanyEtc_makeKeyManagerMap() { List dirs = sortByFileName(listDirsContainingFileNamed(javaxSecretDir(), "keystore.p12")); char[] serverSocketFactory_botCompanyEtc_passphrase = serverSocketFactory_botCompanyEtc_getPassphrase(); return (Map) mapToOrderedMap(dirs, dir -> pair(fileName(dir), pair(keyManagerFromKeyStore(newFile(dir, "keystore.p12"), serverSocketFactory_botCompanyEtc_passphrase), fileName(dir)))); } static public SSLServerSocketFactory serverSocketFactory_botCompanyEtc() { try { serverSocketFactory_botCompanyEtc_trustKeyStoreFile = anyKeyStore(); if (serverSocketFactory_botCompanyEtc_trustKeyStoreFile == null) return (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); KeyStore trustKeyStore = keyStoreFromFile(serverSocketFactory_botCompanyEtc_trustKeyStoreFile, serverSocketFactory_botCompanyEtc_getPassphrase()); SNIKeyManager wrappedKeyManager = serverSocketFactory_botCompanyEtc_makeSNIKeyManager(); serverSocketFactory_botCompanyEtc_keyManager = wrappedKeyManager; TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustKeyStore); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[] { wrappedKeyManager }, trustManagerFactory.getTrustManagers(), null); return ctx.getServerSocketFactory(); } catch (Exception __e) { throw rethrow(__e); } } static public void serverSocketFactory_botCompanyEtc_update() { serverSocketFactory_botCompanyEtc_keyManager.keyManagersByDomain = serverSocketFactory_botCompanyEtc_makeKeyManagerMap(); } static public ReliableSingleThread rstWithPreDelay_v2(int delay, Runnable r) { var rst = new ReliableSingleThread(r); rst.preSleep = () -> sleep(delay); return rst; } static public ReliableSingleThread rstWithPreDelay_v2(double seconds, Runnable r) { return rstWithPreDelay_v2(toMS_int(seconds), r); } static public JLabel jAnimation(String imageID) { return jAnimation(imageID, ""); } static public JLabel jAnimation(final String imageID, final String text) { return swing(new F0() { public JLabel get() { try { JLabel label = new SmoothLabel(imageIcon(imageID)); label.setText(text); label.setVerticalTextPosition(SwingConstants.BOTTOM); label.setHorizontalTextPosition(SwingConstants.CENTER); return label; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "JLabel label = new SmoothLabel(imageIcon(imageID));\r\n label.setText(text);..."; } }); } static public JComponent withBoldLabelToTheRight(JComponent component, String label) { return centerAndEast(component, jBoldLabel(" " + label)); } static public JComponent withBoldLabelToTheRight(String label, JComponent component) { return withBoldLabelToTheRight(component, label); } static public JComboBox looselyBindLiveValueToComboBox(IVarWithNotify lv, JComboBox cb) { onChange(cb, () -> lv.set(getText(cb))); bindToComponent(cb, () -> { String value = lv.get(); if (value != null) selectItem(cb, value); else lv.set(getText(cb)); }); return cb; } static public Duration parseDaysOrHours(String s) { Double d = parseDays(s); if (d != null) return daysToDuration(d); d = parseHours(s); if (d != null) return hoursToDuration(d); return null; } static public RandomAccessFile randomAccessFileForReading(File path) { try { return newRandomAccessFile(path, "r"); } catch (Exception __e) { throw rethrow(__e); } } static public Set fields(Object c) { return listFields(c); } static public List fieldContainingIC(Iterable l, String field, String substring) { return filter(l, o -> cic(strOrEmpty(getOpt(o, field)), substring)); } static public double naNToZero(double x) { return isNaN(x) ? 0.0 : x; } static public JFrame showCenterPackedFrame(String title, Component c) { return setFrameTitle(title, showCenterPackedFrame(c)); } static public JFrame showCenterPackedFrame(Component c) { return centerFrame(showPackedFrame(c)); } static public Object getIfIF0(Object o) { return getVarOpt(o); } static public String enclosedInSpaces(String s) { return " " + unnull(s) + " "; } static public BigInteger over(BigInteger a, BigInteger b) { return div(a, b); } static public BigInteger over(BigInteger a, int b) { return div(a, b); } static public Complex over(Complex a, double b) { return div(a, b); } static public double over(double a, double b) { return div(a, b); } static public double over(double a, int b) { return div(a, b); } static public long over(long a, long b) { return div(a, b); } static public int over(int a, int b) { return div(a, b); } static public A bindAutoCloseableToComponent(IF0 f, A component) { Var var = new Var(); return bindToComponent(component, new Runnable() { public void run() { try { var.set(callF(f)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "var.set(callF(f));"; } }, new Runnable() { public void run() { try { close(getAndClearVar(var)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "close(getAndClearVar(var))"; } }); } static public SingleThread awtCalcEveryAndNow(JFrame f, int delay, final Object runnable) { return awtCalcRegularly(f, delay, 0, runnable); } static public SingleThread awtCalcEveryAndNow(JComponent c, int delay, final Object runnable) { return awtCalcRegularly(c, delay, 0, runnable); } static public SingleThread awtCalcEveryAndNow(JComponent c, double delaySeconds, final Object runnable) { return awtCalcRegularly(c, toMS_int(delaySeconds), 0, runnable); } static public String infoBoxAndReturn(String s) { infoBox(s); return s; } static public boolean inclusiveIntRangeContains(IntRange r, int i) { return r != null && i >= r.start && i <= r.end; } static public int oneMegabyte_int() { return 1024 * 1024; } static public long recursiveObjectSize(Object o) { return recursiveObjectSize(new RecursiveObjectSize(), o); } static public long recursiveObjectSize(RecursiveObjectSize ros, Object o) { ros.recurse(o); return ros.size; } static public boolean notSame(Object a, Object b) { return a != b; } static public List intDeltas(List l) { int n = l(l); List deltas = new ArrayList(); for (int i = 0; i < n - 1; i++) deltas.add(l.get(i + 1) - l.get(i)); return deltas; } static public Map> runLengthStats(List list) { Map> map = new HashMap(); int n = l(list), i = 0; while (i < n) { A a = list.get(i); int j = i + 1; while (j < n && eq(a, list.get(j))) ++j; MultiSet ms = getOrCreate(map, a, () -> new MultiSet()); ms.add(j - i); i = j; } return map; } static public double daysToMinutes(double days) { return round(days * 24 * 60); } static volatile public long gc_memoryUsedAfterGC; static volatile public long gc_lastStart; static volatile public long gc_duration; static public Lock gc_lock = lock(); static public void gc() { callOpt(javax(), "cleanWeakMaps"); { Lock __0 = gc_lock; lock(__0); try { gc_lastStart = sysNow(); System.gc(); gc_duration = sysNow() - gc_lastStart; gc_memoryUsedAfterGC = usedMemory(); } finally { unlock(__0); } } vmBus_send("gcDone"); } static public long fromHours(double hours) { return hoursToMS(hours); } static public String localTimeWithSeconds(long time) { return simpleDateFormat_local("HH:mm:ss").format(time); } static public String localTimeWithSeconds() { return localTimeWithSeconds(now()); } static public int removeTab(JTabbedPane tabs, String tabName) { { return swing(() -> { if (tabs == null) return -1; int idx = indexOfTabName(tabs, tabName); if (idx < 0) return -1; tabs.removeTabAt(idx); return idx; }); } } static public String loadPageWithParams(String url, Object... params) { return loadPage(appendQueryToURL(url, params)); } static public String loadPageWithParams(String url, Map params) { return loadPage(appendQueryToURL(url, params)); } static public F2 if2ToF2(IF2 f) { return f == null ? null : new F2() { public C get(A a, B b) { try { return f.get(a, b); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f.get(a, b)"; } }; } static public List jextractAll(String pat, String s) { return jextractAll(pat, javaTok(s)); } static public List jextractAll(String pat, List tok) { List tokpat = javaTok(pat); jfind_preprocess(tokpat); return map(jfindAll(tok, tokpat), i -> joinSubList(tok, i, i + l(tokpat) - 2)); } static public List jextractAll(List tok, String pat) { return jextractAll(pat, tok); } static public byte[] loadBinaryFileFromZip(File inZip, String fileName) { return loadBinaryFromZip(inZip, fileName); } static public File desktopDir() { return userDir_oneOf_createFirstIfNone("Desktop", "Schreibtisch"); } static public File desktopDir(String sub) { return newFile(desktopDir(), sub); } static public JComponent jText(Object o) { return wrap(uneditableWordWrappedTextArea(strOrEmpty(o))); } static public JFrame showPackedCenterFrame(Component c) { return centerFrame(showPackedFrame(c)); } static public JFrame showPackedCenterFrame(String title, Component c) { return centerFrame(showPackedFrame(title, c)); } static public JComponent jVerticalCenter(Component c) { return c == null ? null : customLayoutPanel(new VerticalCenterLayout(), c); } static public double daysToSeconds(double days) { return round(days * 24 * 60 * 60); } static public JButton tableDependentButton_extraCondition(JTable table, String text, Object action, F0 extraCondition) { final JButton b = jbutton(text, action); onTableSelectionChangedAndNow(table, new Runnable() { public void run() { try { b.setEnabled(table.getSelectedRow() >= 0 && isTrue(callF(extraCondition))); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "b.setEnabled(table.getSelectedRow() >= 0 && isTrue(callF(extraCondition)))"; } }); return b; } static public JButton tableDependentButton_extraCondition(JTable table, IF0 extraCondition, String text, Runnable action) { JButton b = jbutton(text, action); onTableSelectionChangedAndNow(table, new Runnable() { public void run() { try { b.setEnabled(table.getSelectedRow() >= 0 && (extraCondition == null || extraCondition.get())); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "b.setEnabled(table.getSelectedRow() >= 0 && (extraCondition == null || extraC..."; } }); return b; } static public JComponent jStruct(Object o) { return jStruct(new structure_Data(), o); } static public JComponent jStruct(structure_Data data, Object o) { return uneditableWordWrappedTextArea(indentedStruct(o, data)); } static public List withoutStartingWithIC(Collection l, final String prefix) { return notStartingWithIC(l, prefix); } static public List withoutStartingWithIC(String prefix, Collection l) { return notStartingWithIC(prefix, l); } static public String formatDays(Duration d) { return formatDays(d, 1); } static public String formatDays(Duration d, int decimals) { return formatDays(toMS(d), decimals); } static public String formatDays(long ms) { return formatDays(ms, 1); } static public String formatDays(long ms, int decimals) { return formatDays(toDays(ms), decimals); } static public String formatDays(double days) { return formatDays(days, 1); } static public String formatDays(double days, int decimals) { String formatted = formatDouble(days, decimals); return eq(formatted, "1") ? "1 day" : formatted + " days"; } static public A checkCast(Class c, Object o) { return castTo(c, o); } static public A checkCast(Object o, Class c) { return castTo(o, c); } static public void assertEqic(String x, String y) { assertEqic(null, x, y); } static public void assertEqic(String msg, String x, String y) { if (!eqic(x, y)) throw fail((msg != null ? msg + ": " : "") + quote(x) + " != " + quote(y) + " [ic]"); } static public LinkedHashMap mapValuesToLinkedHashMap(Object func, Map map) { LinkedHashMap m = new LinkedHashMap(); for (Object key : keys(map)) m.put(key, callF(func, map.get(key))); return m; } static public LinkedHashMap mapValuesToLinkedHashMap(Map map, IF1 f) { return mapValuesToLinkedHashMap(f, map); } static public LinkedHashMap mapValuesToLinkedHashMap(IF1 f, Map map) { return mapValuesToLinkedHashMap((Object) f, map); } static public LinkedHashMap mapValuesToLinkedHashMap(Map map, Object func) { return mapValuesToLinkedHashMap(func, map); } static public String dropMinusFromZero(String s) { String g = regexpFirstGroup("^-([0-9\\.]+)", s); return nempty(g) && !regexpFind("[1-9]", g) ? dropPrefix("-", s) : s; } static public A onHover(IVF1 action, A c) { if (c != null && action != null) { swing(() -> { MouseAdapter ma = new MouseAdapter() { public void mouseMoved(MouseEvent e) { pick(e); } public void mouseEntered(MouseEvent e) { pick(e); } public void mouseExited(MouseEvent e) { pick(null); } public void pick(MouseEvent e) { try { action.get(ptFromEvent(e)); } catch (Throwable __e) { pcallFail(__e); } } }; c.addMouseMotionListener(ma); c.addMouseListener(ma); }); } return c; } static public A onHover(A c, IVF1 action) { return onHover(action, c); } static public A bold(A c) { return makeBold(c); } static public String addPlusIfStartsWithDigit(String s) { return startsWithDigit(s) ? "+" + s : s; } static public String assertURL(String s) { if (!isURL(s)) throw fail("Not a URL: " + quote(s)); return s; } static public File downloadsDir() { return userDir("Downloads"); } static public File downloadsDir(String sub) { return newFile(downloadsDir(), sub); } static public List fontSizes(List fontSizes, List l) { for (int i = 0; i < l(l); i++) { Number fontSize = get(fontSizes, i); if (fontSize != null) fontSize(toFloat(fontSize), l.get(i)); } return l; } static public double secondsToDays(double sec) { return sec / (60.0 * 60 * 24); } static public long computerUptime() { return oshi_systemUptime(); } static public File mkdir(File dir) { if (dir != null) dir.mkdirs(); return dir; } static public JScrollPane jBorderlessHigherHorizontalScrollPane(JComponent c) { var sp = borderlessScrollPane(jHigherScrollPane(c)); sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); return sp; } static public String stream2string(InputStream in) { return utf8streamToString(in); } static public String doPostJSON(String json, String url) { try { URL _url = new URL(url); ping(); URLConnection conn = _url.openConnection(); conn.setRequestProperty("Content-Type", "application/json"); return doPost(json, conn, _url); } catch (Exception __e) { throw rethrow(__e); } } static public String postPageWithHeaders(String url, List headers, Object... postData) { AutoCloseable __1 = tempSetTL(doPost_extraHeaders, litmap(asObjectArray(headers))); try { return postPage(url, postData); } finally { _close(__1); } } static public String postPageWithHeaders(String url, Map headers, Object... postData) { AutoCloseable __2 = tempSetTL(doPost_extraHeaders, headers); try { return postPage(url, postData); } finally { _close(__2); } } static public JPanel jLine(Component... components) { return jline(components); } static public JPanel jLine(List components) { return jline(components); } static public Pair pairIfBNotNull(A a, B b) { return b == null ? null : pair(a, b); } static public boolean lessOrEq(int a, int b) { return lessThanOrEqual(a, b); } static public boolean lessOrEq(double a, double b) { return lessThanOrEqual(a, b); } static public > boolean lessOrEq(A a, A b) { return lessThanOrEqual(a, b); } static public A printWithPrecedingNL(A o) { return printWithPrecedingNL("", o); } static public A printWithPrecedingNL(String prefix, A o) { return nlPrint(prefix, o); } static public String joinWithSlash(Iterable l) { return join("/", l); } static public String joinWithSlash(A... l) { return joinWithSlash(asList(l)); } static public boolean isZip(byte[] data) { return isJAR(data); } static public boolean isZip(File f) { return isJAR(f); } static public byte[] doPostBinary(String urlParameters, URLConnection conn) throws IOException { setHeaders(conn); conn.setDoOutput(true); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(urlParameters); writer.flush(); byte[] contents = loadBinaryPage_noHeaders(conn); writer.close(); return contents; } static public String postPageWithGazAICredentials(GazAICredentials cred, String url, Object... params) { return doPost(cred == null ? paramsToMap(params) : mapPlus(cred.asParams(), params), url); } static public String joinContentsOfContainerTag(List tok) { return tok == null ? null : join(contentsOfContainerTag(tok)); } static public List> findContainerTagWithClass(List tok, String tag, String className) { return filter(findContainerTag(tok, tag), t -> tagHasClass(t, className)); } static public List> findContainerTagWithClass(String html, String tag, String className) { return findContainerTagWithClass(htmlTok(html), tag, className); } static public Object postJSONPage(String url, Object... params) { return jsonDecode(postPage(url, params)); } static public ReliableSingleThread rstDoNow(Runnable r) { var rst = rst(r); rst.trigger(); return rst; } static public A getSingleton(List l) { assertEquals(1, l(l)); return first(l); } static public A getSingleton(A[] l) { assertEquals(1, l(l)); return first(l); } static public JPasswordField jPasswordField() { return jPasswordField(""); } static public JPasswordField jPasswordField(String text) { return swing(() -> { JPasswordField tf = new JPasswordField(unnull(text)); return tf; }); } static public JTabbedPane jRightTabs(Object... x) { JTabbedPane tabs = jtabs(x); tabs.setTabPlacement(JTabbedPane.RIGHT); return tabs; } static public JTabbedPane jRightTabs(Collection c) { return jRightTabs(toObjectArray(c)); } static public JTextArea uneditableWordWrappedTextArea() { return uneditableWordWrappedTextArea(""); } static public JTextArea uneditableWordWrappedTextArea(String text) { return enableWordWrapForTextArea(uneditableTextArea(text)); } static public JTextArea jWordWrapTextArea(JTextArea ta) { return wrappedTextArea(ta); } static public JTextArea jWordWrapTextArea() { return wrappedTextArea(); } static public JTextArea jWordWrapTextArea(String text) { return wrappedTextArea(text); } static public long fromMinutes(double minutes) { return (long) (minutes * 60000); } static public DoubleRange toDoubleRange(IntRange r) { return intToDoubleRange(r); } static public DoubleRange toDoubleRange(TimestampRange r) { return r == null ? null : doubleRange(r.start.unixDate(), r.end.unixDate()); } static public TimestampRange growTimestampRange(TimestampRange r, long amount) { return r == null ? null : new TimestampRange(r.start.unixDate() - amount, r.end.unixDate() + amount); } static public String formatMinutesColonSeconds(long ms) { long seconds = iround(toSeconds(ms)); return seconds / 60 + ":" + formatInt(mod(seconds, 60), 2); } static public DoubleRange zeroToOne_value = new DoubleRange(0, 1); static public DoubleRange zeroToOne() { return zeroToOne_value; } static public JSlider doubleRangeLiveValueSlider(IVarWithNotify lv) { return rangeSliderZeroToOne(lv.get(), new VF1() { public void get(DoubleRange r) { try { lv.set(r); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "lv.set(r)"; } }); } static public long elapsedMS_timestamp(long time) { ping(); return now() - time; } static public String formatHoursColonMinutes(long ms) { long minutes = iround(toMinutes(ms)); return minutes / 60 + ":" + formatInt(mod(minutes, 60), 2); } static public JButtonWithInset jButtonWithInset(final String text, final Object action) { return swing(new F0() { public JButtonWithInset get() { try { String text2 = dropPrefix("[disabled] ", text); final JButtonWithInset btn = new JButtonWithInset(text2); if (l(text2) < l(text)) btn.setEnabled(false); if (newButton_autoToolTip) { btn.setToolTipText(btn.getText()); } if (action != null) btn.addActionListener(actionListener(action, btn)); return btn; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "S text2 = dropPrefix(\"[disabled] \", text);\r\n final JButtonWithInset btn = ..."; } }); } static public JButton jButtonWithInset(String text) { return jButtonWithInset(text, null); } static public JButton jButtonWithInset(Action action) { return swingNu(JButtonWithInset.class, action); } static public JButton jButton(String text, Object action) { return newButton(text, action); } static public JButton jButton(String text) { return newButton(text, null); } static public JButton jButton(BufferedImage img, Object action) { return setButtonImage(img, jbutton("", action)); } static public JButton jButton(Action action) { return swingNu(JButton.class, action); } static public JComponent withBoldLabel(String label, JComponent component) { return westAndCenter(jBoldLabel(label + " "), component); } static public String withExplicitPlus(int i) { return intToStringWithExplicitPlus(i); } static public String firstLine(String text) { if (text == null) return null; int i = text.indexOf('\n'); return i >= 0 ? text.substring(0, i) : text; } static public TailFile tailFileLinewiseFromStart(File file, int interval, VF1 onData) { return tailFileFromStart(file, interval, toIVF1(vfAppendToLineBuffer(new LineBuffer(onData)))); } static public TailFile tailFileLinewiseFromStart(File file, int interval, IVF1 onData) { return tailFileLinewiseFromStart(file, interval, toVF1(onData)); } static public File deleteFileIfZippedVersionExists(File f) { File zipFile = appendToFileName(f, ".zip"); if (isFile(f) && isFile(zipFile)) { deleteFile_assertSuccess(f); return zipFile; } return null; } static public TreeMap asTreeMap(Map map) { return map instanceof TreeMap ? (TreeMap) map : map == null ? new TreeMap() : new TreeMap(map); } static public List sortedBy(IF1 f, Iterable c) { return sortedBy(c, f); } static public List sortedBy(Iterable c, IF1 f) { List l = cloneList(c); sort(l, new Comparator() { public int compare(A a, A b) { return stdcompare(f.get(a), f.get(b)); } }); return l; } static public double combinePercentChanges(Iterable l) { double product = 1; for (var i : unnull(l)) if (i != null) product *= (i + 100) / 100; return product * 100 - 100; } static public double combinePercentChanges(double... l) { double product = 1; for (var i : unnull(l)) product *= (i + 100) / 100; return product * 100 - 100; } static public String formatHours(long ms) { return formatHours(ms, 1); } static public String formatHours(long ms, int decimals) { return formatHours(toHours(ms), decimals); } static public String formatHours(double hours) { return formatHours(hours, 1); } static public String formatHours(double hours, int decimals) { String formatted = formatDouble(hours, decimals); return eq(formatted, "1") ? "1 hour" : formatted + " hours"; } static public String formatMinutes(long ms) { return formatMinutes(ms, 1); } static public String formatMinutes(long ms, int decimals) { double minutes = toMinutes(ms); String formatted = formatDouble(minutes, decimals); return eq(formatted, "1") ? "1 minute" : formatted + " minutes"; } static public JSlider looselyBindLiveValueToSliderWithFactor(double increment, IVarWithNotify lv, JSlider slider) { onChange(slider, () -> lv.set(intFromSlider(slider) / increment)); bindToComponent(slider, () -> { Double value = lv.get(); if (value != null) setSliderValue(slider, iround(value * increment)); else lv.set(intFromSlider(slider) / increment); }); return slider; } static public double doubleAvg(int... a) { return doubleAverage(a); } static public double doubleAvg(double... l) { return doubleAverage(l); } static public double doubleAvg(Iterable l) { return doubleAverage(l); } static public double hoursToSeconds(double hours) { return hours * 60 * 60; } static public long exhaustIterator(Iterator it) { long n = 0; if (it != null) while (it.hasNext()) { ping(); ++n; it.next(); } return n; } static public String nPositions(long n) { return n2(n, "position"); } static public String nPositions(Collection l) { return nPositions(l(l)); } static public String nPositions(Map map) { return nPositions(l(map)); } static public A lookupDynamicInterface_v2(Class intrface, Object o) { Object implementation = metaGet(o, intrface); if (isInstance(intrface, implementation)) return (A) implementation; if (isInstance(intrface, o)) return (A) o; return null; } static public A lookupDynamicInterface_v2(Object o, Class intrface) { return lookupDynamicInterface_v2(intrface, o); } static public int roundUpTo(int n, int x) { return (x + n - 1) / n * n; } static public long roundUpTo(long n, long x) { return (x + n - 1) / n * n; } static public double roundUpTo(double n, double x) { return floor((x + n - 1) / n) * n; } static public double exponentialRandom(double min, double max) { return exp(random(log(min), log(max))); } static public double exp(double d) { return Math.exp(d); } static public float[] removePlateausFromArray(float[] array) { if (array == null) return null; FloatBuffer buf = new FloatBuffer(array.length); for (int i = 0; i < array.length; i++) { var value = array[i]; buf.add(value); while (i + 1 < array.length && array[i + 1] == value) ++i; } return l(buf) == array.length ? array : buf.toArray(); } static public float[] toFloatArray(List l) { float[] a = new float[l(l)]; for (int i = 0; i < a.length; i++) a[i] = l.get(i); return a; } static public float[] toFloatArray(double[] l) { float[] a = new float[l(l)]; for (int i = 0; i < a.length; i++) a[i] = (float) l[i]; return a; } static public double doubleMax(Iterable l) { double max = negativeInfinity(); for (double d : unnullForIteration(l)) max = Math.max(max, d); return max; } static public double doubleMax(double[] l) { double max = negativeInfinity(); for (double d : unnullForIteration(l)) max = Math.max(max, d); return max; } static public double doubleMax(double[] l, int from, int to) { double max = negativeInfinity(); for (int i = from; i < to; i++) max = Math.max(max, l[i]); return max; } static public > int binarySearch_insertionPoint(List l, A a) { int i = Collections.binarySearch(l, a); return i < 0 ? -i - 1 : i; } static public long minutesToMS(double minutes) { return round(minutes * 60 * 1000); } static public boolean isAllLettersAndDigits(String s) { for (int i = 0; i < l(s); i++) if (!isLetterOrDigit(s.charAt(i))) return false; return true; } static public Map indexByField(Iterable c, String field) { HashMap map = new HashMap(); for (Object a : c) { Object val = getOpt(a, field); if (val != null) map.put(val, a); } return map; } static public Map indexByField(String field, Iterable c) { return indexByField(c, field); } static public JPanel jCenteredSection_fontSizePlus(int fontPlus, Swingable c) { return jCenteredSection_fontSizePlus(fontPlus, toComponent(c)); } static public JPanel jCenteredSection_fontSizePlus(int fontPlus, Component c) { return jCenteredSection_fontSizePlus(fontPlus, "", c); } static public JPanel jCenteredSection_fontSizePlus(int fontPlus, String title, Swingable c) { return jCenteredSection_fontSizePlus(fontPlus, title, toComponent(c)); } static public JPanel jCenteredSection_fontSizePlus(int fontPlus, String title, Component c) { return swing(() -> { JPanel p = jCenteredSection(title, c); TitledBorder border = (TitledBorder) (p.getBorder()); Font font = border.getTitleFont(); border.setTitleFont(font.deriveFont(font.getSize2D() + fontPlus)); return p; }); } static public JPanel jCenteredSection_fontSizePlus(int fontPlus, String title) { return jCenteredSection_fontSizePlus(fontPlus, title, jpanel()); } static public TailFile tailFileLinewiseFromPosition(File file, int interval, long position, IVF1 onData) { return tailFileLinewiseFromPosition(file, interval, position, onData, defaultSleeper()); } static public TailFile tailFileLinewiseFromPosition(File file, int interval, long position, IVF1 onData, ISleeper_v2 sleeper) { if (file == null) return null; TailFile tf = new TailFile(file, interval, vfAppendToLineBuffer(new LineBuffer(toVF1(onData)))); tf.sleeper(sleeper); tf.l = position; tf.start(); return tf; } static public TailFile tailFileLinewise(File file, int interval, IVF1 onData) { return tailFileLinewise(file, interval, toVF1(onData)); } static public TailFile tailFileLinewise(File file, int interval, VF1 onData) { return tailFile_newOnly(file, interval, vfAppendToLineBuffer(new LineBuffer(onData))); } static public String lastLineOfFile(File f) { return first(lastNLines(f, 1)); } static public File latestFile(Iterable l) { Best best = new Best(); for (File f : unnull(l)) if (f != null) best.put(f, f.lastModified()); return best.get(); } static public File latestFile(File[] l) { return latestFile(asList(l)); } static public Object parseDoubleOrKeepObject(Object o) { if (o instanceof String) { var __1 = parseDoubleOpt((String) o); if (__1 != null) return __1; } return o; } static public int indexOfAnySubstring(String s, String... strings) { for (int i = 0; i <= l(s); i++) for (String b : strings) if (substringAtIs(s, i, b)) return i; return -1; } static public int drawArrowBetweenPoints_width = 4; static public double drawArrowBetweenPoints_headScale = 2; static public void drawArrowBetweenPoints(Graphics2D g, Pt p1, Pt p2, Color color) { int x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y; double dist = pointDistance(x1, y1, x2, y2); double headSize = drawArrowBetweenPoints_width * drawArrowBetweenPoints_headScale * drawArrowHead_length + 2; DoublePt v = blendDoublePts(new DoublePt(x2, y2), new DoublePt(x1, y1), headSize / dist); DoublePt p = blendDoublePts(new DoublePt(x2, y2), new DoublePt(x1, y1), 0); g.setColor(color); g.setStroke(new BasicStroke(drawArrowBetweenPoints_width)); g.draw(new Line2D.Double(x1, y1, v.x, v.y)); drawArrowHead(g, x1, y1, p.x, p.y, drawArrowBetweenPoints_width * drawArrowBetweenPoints_headScale); } static public Rect rectAroundPt(Pt p, int w) { return rectAroundPt(p, w, w); } static public Rect rectAroundPt(Pt p, int w, int h) { return rectAround(p, w, h); } static public Rect rectAroundPt(int x, int y, int w) { return rectAroundPt(x, y, w, w); } static public Rect rectAroundPt(int x, int y, int w, int h) { return rectAround(x, y, w, h); } static public Rect growRectBottom(Rect r, int pixels) { return new Rect(r.x, r.y, r.w, r.h + pixels); } static public Rect growRectBottom(int pixels, Rect r) { return growRectBottom(r, pixels); } static public double transformBetweenDoubleRanges(double x, DoubleRange src, DoubleRange dest) { return dest.start + dest.length() * doubleRatio(x - src.start, src.length()); } static public DoubleRange transformBetweenDoubleRanges(DoubleRange r, DoubleRange src, DoubleRange dest) { return r == null ? null : new DoubleRange(transformBetweenDoubleRanges(r.start, src, dest), transformBetweenDoubleRanges(r.end, src, dest)); } static public boolean forgetCompiledSrcLib(String snippetID) { File f = loadableUtils.utils.DiskSnippetCache_file(psI(snippetID)); return deleteFile(f); } static public String reverseDNSLookup(String ip) { return ipToHost(ip); } static public String dnsLookup(String host) { return hostToIP(host); } static public JLabel bigLabel(Object text) { return fontSize(bigFontSize(), jCenteredLabel(strOrEmpty(text))); } static public BufferedReader utf8reader(InputStream in) { return utf8BufferedReader(in); } static public BufferedReader utf8reader(File f) { return utf8BufferedReader(f); } static public String escapeSpaces(String s) { return replace(s, " ", "\\ "); } static public File loadCompiledSrcLib(String snippetID) { File f = loadableUtils.utils.DiskSnippetCache_file(psI(snippetID)); if (fileSize(f) != 0) return f; String url = jarBotURL(snippetID); loadBinaryPageToFile(url, f); return f; } static public File zipSingleFile(File f) { assertIsFile(f); File zipFile = appendToFileName(f, ".zip"); if (isValidZipFile(zipFile)) return zipFile; var zipOut = newZipOutputStream(zipFile); try { addFileToZip(zipOut, f); return zipFile; } finally { _close(zipOut); } } static public List structAll(Iterable l) { return allToStruct(l); } static public String listToStringWithLength(Collection l) { return n2(l) + " " + l; } static public String nCoins(long n) { return n2(n, "coin"); } static public String nCoins(Collection l) { return nCoins(l(l)); } static public String nCoins(Map map) { return nCoins(l(map)); } static public Map filterKeys(Map map, Object f) { return filterMapByFunctionOnKey(map, f); } static public Map filterKeys(Object f, Map map) { return filterMapByFunctionOnKey(f, map); } static public Map filterKeys(IF1 f, Map map) { return filterMapByFunctionOnKey((Object) f, map); } static public Map filterKeys(Map map, IF1 f) { return filterKeys(f, map); } static public Object parseJSON(String text) { return jsonDecode(text); } static public > C assertContains(C c, A y) { return assertContains(null, c, y); } static public > C assertContains(String msg, C c, A y) { if (!contains(c, y)) throw fail((msg != null ? msg + ": " : "") + y + " not contained in " + c); return c; } static public String assertContains(String a, String b) { if (!contains(a, b)) throw fail(quote(b) + " not contained in " + quote(a)); return a; } static public java.lang.Module javaModule(Class c) { return c == null ? null : c.getModule(); } static public Map loadJSONMapPage(String url) { return jsonDecodeMap(loadPage(url)); } static public Map loadJSONMapPage(URLConnection urlConnection) { return jsonDecodeMap(loadPage(urlConnection)); } static public SecretValue toSecretValue(A a) { return secretValueOrNull(a); } static public Map parseColonPropertyCIMap(String text) { return parseColonProperties(text, ciMap()); } static public BufferedImage shootLeftScreen() { return shootScreen2(first(allScreenBounds())); } static public List> pairsSortedByBDesc(Collection> l) { return sortedByComparator(l, new Comparator>() { public int compare(Pair a, Pair b) { return cmp(b.b, a.b); } }); } static public Rect parseRect(String s) { List tok = javaTokC(s); assertEquals(7, l(tok)); return new Rect(parseInt(tok.get(0)), parseInt(tok.get(2)), parseInt(tok.get(4)), parseInt(tok.get(6))); } static public double transformFromZeroToOne(double x, DoubleRange dest) { return dest.start + x * dest.length(); } static public double transformFromZeroToOne(double destStart, double destEnd, double x) { return destStart + x * (destEnd - destStart); } static public double secondsToHours(double seconds) { return seconds / 3600; } static public Rect combinedScreenRect() { return joinRects(screenRects()); } static public List screenRects() { return map(screens(), screen -> toRect(screen.getDefaultConfiguration().getBounds())); } static public List screens() { return screenDevices(); } static public Dimension screenSize() { return getScreenSize(); } static public Image2B randomBinaryImage(int w) { return randomBinaryImage(w, w); } static public Image2B randomBinaryImage(int w, int h) { return randomImage2B(w, h); } static public com.sun.management.OperatingSystemMXBean advancedOSMXBean() { return optCast(com.sun.management.OperatingSystemMXBean.class, osMXBean()); } static public long longAverage(long... a) { long sum = 0; for (int i = 0; i < l(a); i++) sum += a[i]; return ldiv_round(sum, l(a)); } static public long longAverage(Iterable l) { long sum = 0; long n = 0; for (Long i : unnullForIteration(l)) if (i != null) { sum += i; ++n; } return ldiv_round(sum, n); } static public Image2B binaryImageOutline(IBinaryImage image) { int w = image.w(), h = image.h(); return image == null ? null : binaryImageFromFunction(w + 2, h + 2, (x, y) -> !(getBoolPixelDefaultTrue(image, x, y) ? false : (getBoolPixelDefaultTrue(image, x - 1, y - 1) || getBoolPixelDefaultTrue(image, x, y - 1) || getBoolPixelDefaultTrue(image, x + 1, y - 1) || getBoolPixelDefaultTrue(image, x - 1, y) || getBoolPixelDefaultTrue(image, x + 1, y) || getBoolPixelDefaultTrue(image, x - 1, y + 1) || getBoolPixelDefaultTrue(image, x, y + 1) || getBoolPixelDefaultTrue(image, x + 1, y + 1)))); } static public void g22drawScaledMask(BufferedImage g, IG22Mask mask, Rect bounds, Color color) { g22drawScaledMask(graphics(g), mask, bounds, color); } static public void g22drawScaledMask(Graphics2D g, IG22Mask mask, Rect bounds, Color color) { var img = mask.image(); var transparentImage = twoColorImageWithAlpha(img, color, transparentColor()); drawScaledPixelatedImage(g, transparentImage, bounds); } static public void drawPixelSet(Graphics2D img, IPixelSet pixelSet, Color color) { if (pixelSet != null) drawPixels(img, pixelSet.pixelIterator(), color); } static public void drawPixelSet(BufferedImage img, IPixelSet pixelSet, Color color) { if (pixelSet != null) drawPixels(img, pixelSet.pixelIterator(), color); } static public double baseDownZeroToOne(double min, double p) { return 1 - doubleRatio(1 - p, 1 - min); } static public List takeFirstShuffled(int n, List l) { return takeFirst(n, shuffledIterator(l)); } static public List takeFirstShuffled(List l, int n) { return takeFirstShuffled(n, l); } static public BufferedImage twoColorImage(Color bg, Color fg, IBinaryImage image) { int fgInt = colorToInt(fg), bgInt = colorToInt(bg); return image == null ? null : bufferedImageFromFunctionWithoutAlpha(image.getWidth(), image.getHeight(), (x, y) -> image.getBoolPixel_noRangeCheck(x, y) ? fgInt : bgInt); } static public long oneBillion() { return 1000000000; } static public String strRatioToPercent(double x) { return strRatioToPercent(x, 1); } static public String strRatioToPercent(double x, double y) { return ratioToIntPercent(x, y) + "%"; } static public List> mapProbabilisticList(IF1 f, Iterable> l) { return map(l, a -> a == null ? null : withProbability(a.probability(), f.get(a.get()))); } static public List> mapProbabilisticList(Iterable> l, IF1 f) { return mapProbabilisticList(f, l); } static public double plusPercent(double a, double percent) { return a * (1 + percent / 100); } static public JPanel vgridWithSpacing(Object... _parts) { return swing(() -> { List parts = flattenToList(_parts); int spacing = 6; if (first(parts) instanceof Integer) { spacing = (Integer) first(parts); parts = dropFirst(parts); } JPanel panel = vgrid(parts); GridLayout gl = (GridLayout) (panel.getLayout()); gl.setHgap(spacing); gl.setVgap(spacing); return panel; }); } static public BufferedImage blurImage(BufferedImage img) { return blurFilterBufferedImage(img); } static public BufferedImage blurImage(int hradius, BufferedImage img) { return blurImage(hradius, hradius, img); } static public BufferedImage blurImage(int hradius, int vradius, BufferedImage img) { return blurFilterBufferedImage(hradius, vradius, img); } static public BufferedImage blurImage(BufferedImage img, int hradius) { return blurImage(img, hradius, hradius); } static public BufferedImage blurImage(BufferedImage img, int hradius, int vradius) { return blurFilterBufferedImage(hradius, vradius, img); } static public String renderMultiSet(MultiSet ms) { if (ms == null) return "-"; List l = new ArrayList(); for (Object o : ms.highestFirst()) l.add(str(o) + " (" + ms.get(o) + ")"); return joinWithComma(l); } static public String renderMultiSet(Iterable l) { return renderMultiSet(toMultiSet(l)); } static public boolean dir2zip_recurse_honorDontBackupFiles_verbose = false; static public int dir2zip_recurse_honorDontBackupFiles(File inDir, File zip) { return dir2zip_recurse_honorDontBackupFiles(inDir, zip, ""); } static public int dir2zip_recurse_honorDontBackupFiles(File inDir, File zip, String outPrefix) { try { mkdirsForFile(zip); FileOutputStream fout = newFileOutputStream(zip); ZipOutputStream outZip = new ZipOutputStream(fout); try { int count = dir2zip_recurse_honorDontBackupFiles(inDir, outZip, outPrefix, 0); if (count == 0) zip_addDummyFile(outZip); return count; } finally { outZip.close(); } } catch (Exception __e) { throw rethrow(__e); } } static public int dir2zip_recurse_honorDontBackupFiles(File inDir, ZipOutputStream outZip) { return dir2zip_recurse_honorDontBackupFiles(inDir, outZip, "", 0); } static public int dir2zip_recurse_honorDontBackupFiles(File inDir, ZipOutputStream outZip, String outPrefix, int level) { try { if (++level >= 20) throw fail("woot? 20 levels in zip?"); Set dontBackup = asSet(tlft(loadTextFile(newFile(inDir, standardNameOfDontBackupFile())))); List files = new ArrayList(); for (File f : listFiles(inDir)) if (!contains(dontBackup, f.getName())) files.add(f); int n = 0; sortFilesByName(files); for (File f : files) { if (f.isDirectory()) { print("dir2zip_recurse_honorDontBackupFiles: Scanning " + f.getAbsolutePath()); n += dir2zip_recurse_honorDontBackupFiles(f, outZip, outPrefix + f.getName() + "/", level); } else { if (dir2zip_recurse_honorDontBackupFiles_verbose) print("Copying " + f.getName()); outZip.putNextEntry(new ZipEntry(outPrefix + f.getName())); InputStream fin = new FileInputStream(f); copyStream(fin, outZip); fin.close(); ++n; } } return n; } catch (Exception __e) { throw rethrow(__e); } } static public String indentedSFU(Object o) { return indentedStructureForUser(o); } static public Collection orIfEmpty(Collection a, Collection b) { return empty(a) ? b : a; } static public String l_str(Map map) { return lstr(map); } static public String l_str(Collection c) { return lstr(c); } static public String l_str(String s) { return lstr(s); } static public List sortedByField(Collection c, final String field) { List l = new ArrayList(c); sort(l, new Comparator() { public int compare(A a, A b) { return cmp(getOpt(a, field), getOpt(b, field)); } }); return l; } static public List sortedByField(String field, Collection c) { return sortedByField(c, field); } static public String ymdWithSlashes() { return ymdWithSlashes(now()); } static public String ymdWithSlashes(long time) { return simpleDateFormat_local("YYYY/MM/dd").format(time); } static public String ymdWithSlashes(long time, TimeZone tz) { return simpleDateFormat("YYYY/MM/dd", tz).format(time); } static public void imageSurfaceOnLeftClick(ImageSurface is, VF1 onClick) { if (is == null || onClick == null) return; { swing(() -> { MouseAdapter ma = new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() == 1) pcallF(onClick, is.pointFromEvent(e)); } }; is.addMouseListener(ma); }); } } static public void imageSurfaceOnLeftClick(ImageSurface is, IVF1 onClick) { imageSurfaceOnLeftClick(is, toVF1(onClick)); } static public List g22_allBorderTraces_autoDiagonals(IImageRegion region) { return region.createdWithDiagonals() ? g22_allBorderTraces_withDiagonals(region) : g22_allBorderTraces(region); } static public void zoomGraphics(Graphics2D g, double scaleX) { zoomGraphics(g, scaleX, scaleX); } static public void zoomGraphics(Graphics2D g, double scaleX, double scaleY) { AffineTransform at = g.getTransform(); at.scale(scaleX, scaleY); g.setTransform(at); } static public File qoify(File imageFile) { if (isQOIFile(imageFile)) return imageFile; { AutoCloseable __1 = tempShowLoadingAnimation("QOIfy"); try { BufferedImage img = loadImage2(imageFile); File destFile = replaceExtension(imageFile, ".qoi"); File atticFile = newFile(javaxDataDir("QOIfied original pictures"), imageFile.getName()); atticFile = makeFileNameUnique(atticFile); saveQOIVerbose(destFile, img); moveFileVerbose(imageFile, atticFile); print("Conversion done."); return destFile; } finally { _close(__1); } } } static public byte[] isQOI_magic = toASCII("qoif"); static public boolean isQOI(byte[] data) { return byteArrayStartsWith(data, isQOI_magic); } static public boolean isQOI(File f) { return isQOI(loadBeginningOfBinaryFile(f, l(isQOI_magic))); } static public A looselyBindLiveValueToCheckBox(A cb, IVarWithNotify lv) { onChange(cb, () -> lv.set(isChecked(cb))); bindToComponent(cb, () -> { var value = lv.get(); if (value != null) setChecked(cb, value); else lv.set(isChecked(cb)); }); return cb; } static public A looselyBindLiveValueToCheckBox(IVarWithNotify lv, A cb) { return looselyBindLiveValueToCheckBox(cb, lv); } static public ThreadLocal renderText_fg = new ThreadLocal(); static public ThreadLocal renderText_bg = new ThreadLocal(); static public boolean renderText_withLeading = true; static public BufferedImage renderText(String fontName, float fontSize, String text) { return renderText(loadFont_cached(fontName), fontSize, text); } static public BufferedImage renderText(float fontSize, String text) { return renderText(sansSerif(), fontSize, text); } static public BufferedImage renderText(Font font, float fontSize, String text) { return renderText(font.deriveFont(fontSize), text); } static public BufferedImage renderText(Object _text) { return renderText(sansSerif(), _text); } static public BufferedImage renderText(Font font, Object _text) { String text = str(_text); Color background = optPar(renderText_bg, Color.white); Color foreground = optPar(renderText_fg, Color.black); FontMetrics fm = fontMetrics(font); int width = fm.stringWidth(text); if (width <= 0) return null; int height = fm.getHeight(); int y = renderText_withLeading ? fm.getLeading() + fm.getMaxAscent() : fm.getAscent(); BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = imageGraphics(img); g.setColor(background); g.fillRect(0, 0, width, height); g.setColor(foreground); g.setFont(font); g.drawString(text, 0, y); g.dispose(); return img; } static public Hi15Image hi15_imageMinusImage(Hi15Image img1, Hi15Image img2) { return hi15_imageMinusImage(img1, img2, 1); } static public Hi15Image hi15_imageMinusImage(Hi15Image img1, Hi15Image img2, double scale) { assertSameSize(img1, img2); short[] pixels1 = img1.pixels, pixels2 = img2.pixels; int n = pixels1.length; short[] pixels3 = new short[n]; double shift = 16; for (int i = 0; i < n; i++) { short p1 = pixels1[i], p2 = pixels2[i]; int r = iround((hi15_r(p1) - hi15_r(p2)) * scale + shift); int g = iround((hi15_g(p1) - hi15_g(p2)) * scale + shift); int b = iround((hi15_b(p1) - hi15_b(p2)) * scale + shift); pixels3[i] = hi15_clamp(r, g, b); } return new Hi15Image(img1.w(), img1.h(), pixels3); } static public BufferedImage rotate180(BufferedImage img) { int[] pixels = imageToPixels(img); int[] pixels2 = reverseIntArray(pixels); return bufferedImage(img.getWidth(), img.getHeight(), pixels2); } static public int ihc(Object o) { return identityHashCode(o); } static public void test_restructure_MRUCache() { MRUCache o = new MRUCache(); o.maxSize = 5; o.put("a", true); print(structure(o)); MRUCache o2 = (MRUCache) (restructure(o)); assertEqualsVerbose(ll(pair("a", true)), mapToPairs(o2)); assertEqualsVerbose(5, o2.maxSize); } static public String wordWrappedStruct(Object o) { return structWordWrap(o); } static public JLabel simpleCenteredLabel() { return simpleCenteredLabel(""); } static public JLabel simpleCenteredLabel(String text) { return centerLabel(jSimpleLabel(text)); } static public String nColors(long n) { return n2(n, "color"); } static public String nColors(Collection l) { return nColors(l(l)); } static public String nColors(Map map) { return nColors(l(map)); } static public List showingAWTObjectsOfType(Class theClass) { return swing(() -> { return filter(c -> isShowing((Component) c), awtObjectsOfType(theClass)); }); } static public String nPlayers(long n) { return n2(n, "player"); } static public String nPlayers(Collection l) { return nPlayers(l(l)); } static public String nPlayers(Map map) { return nPlayers(l(map)); } static public boolean moreThanOne(Collection l) { return l(l) > 1; } static public void disassembleClass(Object o) { printClassByteCode(o); } static public Class disassembleClass(String name) { Class c = classForName(name); disassembleClass(c); return c; } static public String printConcat(Object... l) { return print(concat(l)); } static public String printConcat(Iterable l) { return print(concat(l)); } static public String periodCombine(Object... l) { return customSeparatorCombine(". ", l); } static public BufferedImage rotateImageClockwise90(BufferedImage img) { int w = img.getWidth(), h = img.getHeight(); BufferedImage canvas = newBufferedImage(h, w); Graphics2D g = canvas.createGraphics(); g.translate((h - w) / 2, (h - w) / 2); g.rotate(Math.PI / 2, h / 2, w / 2); g.drawRenderedImage(img, null); return canvas; } static public List awtObjectsOfType(Class theClass) { return allSwingComponentsOfType(theClass); } static public byte[] toQOI(BufferedImage image) { try { if (image == null) return null; ByteArrayOutputStream stream = new ByteArrayOutputStream(); var imageWriter = new QOIImageWriterSPI().createWriterInstance(); try { imageWriter.setOutput(new javax.imageio.stream.MemoryCacheImageOutputStream(stream)); imageWriter.write(image); } finally { imageWriter.dispose(); } return stream.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } static public String str_megapixels(BufferedImage img) { return formatDouble(megapixels(img), 1) + " MP"; } static public String str_megapixels(WidthAndHeight img) { return formatDouble(megapixels(img), 1) + " MP"; } static public long benchFor1(String desc, Runnable r) { return benchFor1Second(desc, r); } static public long benchFor1(Runnable r) { return benchFor1Second(r); } static public A benchFor1(IF0 f) { return benchFor1(str(f), f); } static public A benchFor1(String desc, IF0 f) { return benchFor1Second(desc, f); } static public BufferedImage imageOnBackground(Color bg, BufferedImage img) { return renderImageOnBackground(bg, img); } static public BufferedImage imageOnBackground(BufferedImage img, Color bg) { return renderImageOnBackground(img, bg); } static public byte[] toJPEGWithQuality(double quality, BufferedImage img) { try { img = dropAlphaChannelFromBufferedImage(img); ByteArrayOutputStream stream = new ByteArrayOutputStream(); var jpgWriter = first(ImageIO.getImageWritersByFormatName("jpg")); try { var params = jpgWriter.getDefaultWriteParam(); params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); params.setCompressionQuality(toFloat(quality / 100)); jpgWriter.setOutput(new javax.imageio.stream.MemoryCacheImageOutputStream(stream)); jpgWriter.write(null, new IIOImage(img, null, null), params); } finally { jpgWriter.dispose(); } return stream.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } static public BufferedImage fromJPEG(byte[] data) { return decodeImage(data); } static public byte[] toJPEG(BufferedImage img) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ImageIO.write(dropAlphaChannelFromBufferedImage(img), "jpeg", stream); return stream.toByteArray(); } catch (Exception __e) { throw rethrow(__e); } } static public byte[] toJPEG(File f) { return toJPEG(loadImage2(f)); } static public long jpegSize(BufferedImage img) { try { JustCountingOutputStream stream = new JustCountingOutputStream(); ImageIO.write(dropAlphaChannelFromBufferedImage(img), "jpeg", stream); return stream.get(); } catch (Exception __e) { throw rethrow(__e); } } static public long huffmanSize(byte[] data) { return new HuffmanByteArray(data).byteIOLength(); } static public byte[] byteArrayFromShorts_littleEndian(short[] a) { return byteArrayFromShorts_littleEndian(a, 0, l(a)); } static public byte[] byteArrayFromShorts_littleEndian(short[] a, int from, int to) { byte[] b = new byte[(to - from) * 2]; for (int i = 0; i < a.length; i++) { short s = a[from + i]; b[i * 2] = (byte) s; b[i * 2 + 1] = (byte) (s >> 8); } return b; } static public JSpinner looselyBindLiveValueToSpinner(IVarWithNotify lv, JSpinner spinner) { onChange(spinner, () -> lv.set(intFromSpinner(spinner))); bindToComponent(spinner, () -> { Integer value = lv.get(); if (value != null) setSpinnerValue(spinner, value); else lv.set(intFromSpinner(spinner)); }); return spinner; } static public float arrayGet(float[] array, int i) { return array[i]; } static public double arrayGet(double[] array, int i) { return array[i]; } static public byte arrayGet(byte[] array, int i) { return array[i]; } static public boolean arrayGet(boolean[] array, int i) { return array[i]; } static public short arrayGet(short[] array, int i) { return array[i]; } static public int arrayGet(int[] array, int i) { return array[i]; } static public long arrayGet(long[] array, int i) { return array[i]; } static public int ptToIndex(Pt p, int w) { return p.y * w + p.x; } static public List pstackComputeAll(VStack.Computable f) { PStack stack = new PStack(); List results = new ArrayList(); stack.add(f, result -> results.add(result)); stepAll(stack); return results; } static public File saveJPEG(BufferedImage img, File file) { saveJPG(img, file); return file; } static public File saveJPEG(File file, BufferedImage img) { saveJPG(img, file); return file; } static public File saveJPEG(String path, BufferedImage img) { return saveJPEG(img, newFile(path)); } static public List firstTatoebaEnglishSentences(int n) { var stream = gzipInputStream(loadLibrary("#1400585")); CloseableIterableIterator it = linesFromReader(inputStreamReader(stream)); try { return map(s -> dropFirstSpacedColumns(2, s), takeFirst(n, it)); } finally { _close(it); } } static public List uniquifyBinaryImages(Iterable l) { return new UniquifyUsingHasher(__1 -> hashBinaryImage(__1), (__2, __3) -> binaryImagesIdentical(__2, __3)).addAll(l).get(); } static public G22Mesh g22cloneMesh(G22Mesh m1) { G22Mesh m2 = new G22Mesh(); Map anchorMap = new HashMap(); for (var a1 : m1.anchors()) anchorMap.put(a1, m2.newAnchor(a1.pt)); for (var c1 : m1.curves()) m2.addCurve(new G22Mesh.Curve(anchorMap.get(c1.start), anchorMap.get(c1.end), new OnePathWithOrigin(c1.path))); return m2; } static public G22Mesh.Curve g22connectAnchors(G22Mesh mesh, int iAnchor1, int iAnchor2) { var a1 = mesh.getAnchor(iAnchor1); var a2 = mesh.getAnchor(iAnchor2); return mesh.addCurve(new G22Mesh.Curve(a1, a2, new BresenhamLineDrawer(a1.pt, a2.pt).points())); } static public void g22drawConnectingCurve(Graphics2D g, Pt start, Pt end) { g22drawConnectingCurve(g, start, end, 4); } static public void g22drawConnectingCurve(Graphics2D g, Pt start, Pt end, int clipAmount) { var controlY = random(0, 40); var control = doublePt(avg(start.x, end.x), controlY); var path = new Path2D.Float(); path.moveTo(start.x, start.y); path.quadTo(control.x, control.y, end.x, end.y); var color = oneOf(ll((Color.black), (Color.gray), (Color.red))); var g2 = (Graphics2D) g.create(); g2.setColor(color); if (clipAmount != 0) { Rect clip = rectFromPoints(start.x + clipAmount, 0, end.x - clipAmount, max(end.y, start.y) - clipAmount); print("clip", clip); g2.clipRect(clip.x, clip.y, clip.w, clip.h); } g2.draw(path); } static public OnePathWithOrigin g22_regionOutline(IImageRegion region) { List outlines = g22_allBorderTraces_autoDiagonals(region); return new OnePathWithOrigin(first(outlines), false); } static public IImageRegion g22_biggestRegionByBounds(Iterable> regions) { return highestBy(regions, r -> r.bounds().area()); } static public GazelleV_LeftArrowScript.Script leftArrowParse(String script) { GazelleV_LeftArrowScriptParser parser = new GazelleV_LeftArrowScriptParser(); parser.allowTheWorld(); return parser.parse(script); } static public List g22_parseCharRanges(String s) { return concatMap_lists(splitAtComma_trim(s), item -> isQuoted(item) ? map(characters(unquote(item)), c -> intRange_incl(c, c)) : ll(parseHexRange(item))); } static public List> g22_darkRegions(Iterable> regions) { return g22_darkRegions(regions, 128); } static public List> g22_darkRegions(Iterable> regions, int threshold) { return filter(regions, r -> r.brightness() < threshold); } static public double g22_squareness(Rect r) { return doubleRatio(min(r.w, r.h), max(r.w, r.h)); } static public double g22_regionFilledness(IImageRegion region) { return doubleRatio(region.numberOfPixels(), area(region.bounds())); } static public IImageRegion g22_darkestRegion(IImageRegions regions) { return regions == null ? null : lowest(regions.regions(), r -> r.brightness()); } static public Class javax() { return getJavaX(); } static public void defineRewrite(String token, String replacement) { definedRewrites().put(token, replacement); } static public Concepts concepts(Concept c) { return c == null ? null : c._concepts; } static public G22Utils g22utils(Concepts cc) { return (G22Utils) cc.miscMapGet(G22Utils.class); } static public G22Utils g22utils(Concept cc) { return g22utils(concepts(cc)); } static public List syncLinkedList() { return synchroLinkedList(); } static public void ensureConceptClassesAreIndexed(Collection classes) { ensureConceptClassesAreIndexed(db_mainConcepts(), classes); } static public void ensureConceptClassesAreIndexed(Concepts cc, Collection classes) { for (Class c : unnullForIteration(classes)) ensureConceptClassIsIndexed(cc, c); } static public void ensureConceptClassesAreIndexed(Class... classes) { ensureConceptClassesAreIndexed(db_mainConcepts(), classes); } static public void ensureConceptClassesAreIndexed(Concepts cc, Class... classes) { ensureConceptClassesAreIndexed(cc, asList(classes)); } static public void g22_runPostAnalysisLeftArrowScript(Gazelle22_ImageToRegions itr, GazelleV_LeftArrowScript.Script script) { if (script == null) return; var fScore = script.getFunction("score"); if (fScore != null) { List> regions = itr.regions.regions(); int n = l(regions); Map, Double> scores = new HashMap(); for (var region : regions) scores.put(region, toDouble(fScore.call(null, region))); itr.scoredRegions = mapSortedByValue(scores); } } static public void g22_renderPosterizedHighlightedImage(ImageSurface isPosterized, Gazelle22_ImageToRegions itr, boolean showRegionsAsOutline) { if (isPosterized == null) return; var mouse = mouseLocationPt(); if (!isScreenCoordinateInWindow(mouse, isPosterized)) { var mouse2 = itr.coordinatesFromScreen(mouse); mouse = mouse2; } else mouse = isPosterized.mousePosition; var pixels = itr.posterized.getRGBPixels(); g22_highlightRegion(pixels, isPosterized, itr, mouse, showRegionsAsOutline); if (itr.scoredRegions != null) for (Map.Entry __0 : _entrySet(itr.scoredRegions)) { IImageRegion region = __0.getKey(); double score = __0.getValue(); if (score >= .5) { int color = colorToIntOpaque(blendColors(lightBlue(), Color.blue, (score - .5) * 2)); g22_highlightRegion(pixels, itr, region.indexInCreator(), color, false); } } isPosterized.setImage(bufferedImage(pixels, itr.posterized)); } static public JScrollPane jHigherScrollPane_borderless_center(JComponent c) { return borderlessScrollPane(jHigherScrollPane(jfullcenter(c))); } static public DynamicVStack dynamicVStack() { return swingNu(DynamicVStack.class); } static public DynamicVStack dynamicVStack(Component... components) { DynamicVStack stack = dynamicVStack(); stack.addComponents(asList(components)); return stack; } static public String gazelle22_imagesSubDirName() { return "Gazelle"; } static public void g22_highlightRegion(int[] pixels, ImageSurface is, Gazelle22_ImageToRegions itr, boolean showRegionsAsOutline) { g22_highlightRegion(pixels, is, itr, is.mousePosition, showRegionsAsOutline); } static public void g22_highlightRegion(int[] pixels, ImageSurface is, Gazelle22_ImageToRegions itr, Pt mouse, boolean showRegionsAsOutline) { if (mouse != null && itr != null && itr.regions != null) { int iHighlightedRegion = itr.regions.regionAt(mouse); g22_highlightRegion(pixels, itr, iHighlightedRegion, showRegionsAsOutline); } } static public void g22_highlightRegion(int[] pixels, Gazelle22_ImageToRegions itr, int iRegion, boolean showRegionsAsOutline) { g22_highlightRegion(pixels, itr, iRegion, 0xFF00C000, showRegionsAsOutline); } static public void g22_highlightRegion(int[] pixels, Gazelle22_ImageToRegions itr, int iRegion, int color, boolean showRegionsAsOutline) { if (iRegion == 0) return; if (showRegionsAsOutline) { RegionBorder_innerPoints x = new RegionBorder_innerPoints(itr.regions, iRegion); gazelle22_highlightRegionOutline(pixels, itr, x); } else itr.regions.markRegionInPixelArray(pixels, iRegion, color); } static public Class mc() { return main.class; } static public boolean g22_devMode() { return eq(standardCredentialsUser(), "stefan") && haveTranspilationPassword(); } static public PersistableThrowable toPersistableThrowable(Throwable e) { return persistableThrowable(e); } static public void addToListWithMaxSize(List l, A a, int maxSize) { if (l == null || maxSize <= 0) return; synchronized (collectionMutex(l)) { int n; while ((n = l.size()) >= maxSize) { l.remove(0); if (l.size() != n - 1) throw fail("List remove failed!? " + l.size() + " / " + n + " / " + objectToStringWithClassName(l)); } l.add(a); } } static public boolean syncClear_trueIfChanged(Collection c) { if (c == null) return false; synchronized (collectionMutex(c)) { if (c.isEmpty()) return false; c.clear(); return true; } } static public A fold(F2 f, Iterable l) { return foldl_noSeed(f, l); } static public A fold(IF2 f, Iterable l) { return foldl_noSeed(f, l); } static public A fold(IF2 f, A... l) { return foldl_noSeed(f, l); } static public A fold(Object f, Iterable l) { return foldl_noSeed(f, l); } static public long unixHour() { return unixHour(now()); } static public long unixHour(long timestamp) { return unixTime(timestamp) / (60 * 60); } static public List intRangeList(int b) { return intRangeList(0, b); } static public List intRangeList(final int a, final int b) { final int l = max(0, b - a); return new RandomAccessAbstractList() { public int size() { return l; } public Integer get(int i) { return i >= 0 && i < l ? a + i : null; } }; } static public InputStream zipInputStream(ZipFile zip, String fileName) { try { ZipEntry entry = zip.getEntry(fileName); return entry == null ? null : zip.getInputStream(entry); } catch (Exception __e) { throw rethrow(__e); } } static public Runnable changeReceiverToRunnable(Object o) { if (o instanceof Updateable) return new UpdateTrigger((Updateable) o); if (o instanceof ChangeTriggerable) return new ChangeTrigger((ChangeTriggerable) o); return (Runnable) o; } static public boolean preciseCall_debug = false; static public Object preciseCall(Object o, String method, Object... args) { 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(m, args); if (score < Integer.MAX_VALUE) { if (preciseCall_debug) print("Method score: " + m + " " + score); best.put(m, score); } } Method m = best.get(); if (m != null) return invokeMethod(m, null, args); return call_withVarargs(((Class) o), method, args); } else throw todo(); } catch (Exception __e) { throw rethrow(__e); } } static public A shallowNonTransientCloneToClass(Class c, Object o) { if (o == null) return null; A a = nuInstance(c); copyNonTransientFields(o, a); return a; } static public List sortedByConceptID(Collection c) { return sortedByCalculatedField(__56 -> conceptID(__56), c); } static public boolean byteArraysEqual(byte[] a, byte[] b) { return Arrays.equals(a, b); } static public DoubleRange doubleRangeAround(double mid, double size) { return doubleRange(mid - size, mid + size); } static public double reciprocal(double x) { return 1 / x; } static public Duration msToDuration(double ms) { return Duration.ofNanos(lround(msToNanos(ms))); } static public List lastNLines(File f, int n) { try { try { ReversedLinesFileReader r = new ReversedLinesFileReader(f); try { List l = new ArrayList(); while (l(l) < n) { String s = r.readLine(); if (s == null) break; l.add(s); } return reversedList(l); } finally { r.close(); } } catch (FileNotFoundException e) { return emptyList(); } } catch (Exception __e) { throw rethrow(__e); } } static public List lastNLines(int n, File f) { return lastNLines(f, n); } static public String[] conceptFields_drop = { "className", "fieldValues", "id", "created", "_modified", "refs", "backRefs", "_concepts" }; static public Set conceptFields(Concept c) { return setMinus(mergeSets(allNonStaticNonTransientFields(c), keys(c.fieldValues)), conceptFields_drop); } static public Set conceptFields(Class c) { return setMinus(allNonStaticNonTransientFields(c), conceptFields_drop); } static public Object jsonDecode_quickFail(String text) { jsonDecode_Y y = new jsonDecode_Y(text); y.fail = __1 -> quickFail(__1); return y.parse(); } static public void handleHardError(Throwable e) { if (isHardError(e)) pcallFail(e); } static public AutoCloseable tempAfterwards(final Object r) { return new AutoCloseable() { public void close() { callF(r); } }; } static public char[] asChars(String s) { return s == null ? null : s.toCharArray(); } static public double toHours(long ms) { return ms / (60000.0 * 60); } static public String formatDouble_roundUp(double d, int digits) { String format = digits <= 0 ? "0" : "0." + rep(digits, '#'); java.text.DecimalFormat df = decimalFormatEnglish(format); df.setRoundingMode(RoundingMode.UP); return df.format(d); } static public Color directionToCandleColor(double direction) { return direction < 0 ? colorFromHex("f1493f") : direction > 0 ? colorFromHex("1da2b4") : Color.white; } static public String joinNemptiesWithBR(Iterable l) { return joinNempties("
\n", l); } static public String joinNemptiesWithBR(String... l) { return joinNemptiesWithBR(asList(l)); } static public
A jMaxHeight_pure(int h, A c) { { swing(() -> { Dimension size = c.getMaximumSize(); c.setMaximumSize(new Dimension(size.width, h)); }); } return c; } static public A jMaxHeight_pure(A c, int h) { return jMaxHeight_pure(h, c); } static public JScrollPane jscroll_vertical_borderless(JComponent c) { return borderlessScrollPane(jscroll_vertical(c)); } static public long toM_round(long l) { return lround(l / (1024 * 1024.0)); } static public AutoCloseable tempInfoBoxForever(String msg) { return tempInfoBox_noHide(msg); } static public Component contentsOfTab(JTabbedPane tabs, int idx) { if (tabs == null || idx < 0) return null; return swing(() -> idx < tabs.getTabCount() ? tabs.getComponentAt(idx) : null); } static public List allLiveMethods(Object o) { Class c = _getClass(o); boolean isInstance = c != o; List methods = new ArrayList(); while (c != null) { for (Method m : c.getDeclaredMethods()) if (isInstance != isStaticMethod(m)) methods.add(m); c = c.getSuperclass(); } return methods; } static public void runInQ(Q q, Runnable r) { if (r == null) return; if (isInQ(q)) { callF(r); return; } q.add(r); } static public long toG(long l) { return (l + 1024 * 1024 * 1024 - 1) / (1024 * 1024 * 1024); } static public String toG(long l, int digits) { return formatDouble(toG_double(l), digits); } static public A setAllStandardFontSizesRecursively(A c, float fontSize) { return setAllStandardFontSizesRecursively(c, fontSize, null); } static public A setAllStandardFontSizesRecursively(A c, float fontSize, IF1 componentFilter) { if (componentFilter != null && !componentFilter.get(c)) return c; if (c instanceof JComponent) { setFontSize(((JComponent) c), fontSize); setTitledBorderFontSize(((JComponent) c), fontSize); } if (c instanceof JTable) setTableFontSizesAndRowHeight(((JTable) c), fontSize); if (c instanceof Container) for (Component x : listChildren((Container) c)) setAllStandardFontSizesRecursively(x, fontSize, componentFilter); return c; } static public String hrefBlank(String link, Object contents, Object... params) { return empty(link) ? strOrEmpty(contents) : tag("a", contents, concatArrays(new Object[] { "href", link, "target", "_blank" }, params)); } static public NavigableMap synchroTreeMap() { return synchroNavigableMap(new TreeMap()); } static public Pt centerTextInRect(FontMetrics fm, String s, Rect r) { int tw = fm.stringWidth(s), th = fm.getHeight(); return pt(r.x + (r.w - tw) / 2, r.y + (r.h - th) / 2 + fm.getAscent()); } static public Color black() { return Color.black; } static public IterableIterator allWordsOfAlphabetWithLength(int length, String alphabet) { return mapI(__57 -> join(__57), outerProduct(rep(length, characters(alphabet)))); } static public String regexpForFloatingPointWithoutSign() { return "\\d+(\\.\\d*)?([eE][+-]?\\d+)?|\\.\\d+([eE][+-]?\\d+)?"; } static public IterableIterator allWordsOfAlphabet_maxLength(int maxLength, String alphabet) { return new IterableIterator() { public List l = new ArrayList(); public boolean hasNext() { return l(l) <= maxLength; } public String next() { String s = makeString(); int i = 0; while (i < l(l)) { int n = l.get(i); if (n + 1 < l(alphabet)) { l.set(i, n + 1); break; } l.set(i++, 0); } if (i >= l(l)) l.add(0); return s; } public String makeString() { StringBuilder buf = new StringBuilder(l(l)); for (int i = 0; i < l(l); i++) buf.append(alphabet.charAt(l.get(i))); return str(buf); } }; } static public String formatMarginProfit(double price) { return plusMinusFix(formatMarginPrice(price)); } static public AutoCloseable tempInc(AtomicLong v) { if (v == null) return null; inc(v); return () -> dec(v); } static public String formatWith2OrZeroDecimals(double x) { String s = formatDouble2X(x); return dropSuffix(".00", s); } static public String insertStringAt(String s, int i, String a) { return insertAt(s, i, a); } static public Comparator descFieldComparator(final String field) { return new Comparator() { public int compare(A a, A b) { return cmp(getOpt(b, field), getOpt(a, field)); } }; } static public String js_dollarVars(String s, Object... __) { return replaceDollarVars_js(s, __); } static public String programID() { return getProgramID(); } static public String programID(Object o) { return getProgramID(o); } static public String replaceDollarVars_js(String s, Object... __) { Map vars = paramsToMap_withNulls(__); if (empty(vars)) return s; var vars2 = mapKeys(__58 -> dropDollarPrefix(__58), vars); return replaceDollarVars_dyn(s, var -> { if (!vars2.containsKey(var)) return null; Object value = vars2.get(var); return jsonEncode_extended(value); }); } static public String jsonEncodeMap(Object... __) { return jsonEncode(paramsToMap(__)); } static public String jsDollarVars(String s, Object... __) { return replaceDollarVars_js(s, __); } static public String containerTag(String tag) { return containerTag(tag, ""); } static public String containerTag(String tag, Object contents, Object... params) { String openingTag = hopeningTag(tag, params); String s = str(contents); return openingTag + s + ""; } static public String hcss(Object contents) { if (contents instanceof String && isRelativeOrAbsoluteURL((String) contents)) return hstylesheetsrc((String) contents); else return htag("style", contents); } static public String hAddToHead(String html, String tag) { List tok = htmlTok(html); List head = first(findContainerTag(tok, "head")); if (head == null) return tag + html; head.set(2, addLineBreak(tag) + head.get(2)); return join(tok); } static public String snippetImageLink(String snippetID) { return snippetImageURL(snippetID); } static public String dataURL(String mimeType, byte[] data) { return "data:" + mimeType + ";base64," + base64(data); } static public String jpegMimeType() { return "image/jpeg"; } static public String tr(Object contents) { return tag("tr", contents); } static public String td(Object contents, Object... params) { return hfulltag("td", contents, params); } static public String td() { return td(""); } static public char[] getChars(String s) { return asChars(s); } static public List sortByFileName(List l) { return sortFilesByName(l); } static public LinkedHashMap mapToOrderedMap(Object f, Iterable l) { LinkedHashMap map = new LinkedHashMap(); for (Object o : unnullForIteration(l)) { Pair p = (Pair) (callF(f, o)); map.put(p.a, p.b); } return map; } static public LinkedHashMap mapToOrderedMap(IF1> f, Iterable l) { LinkedHashMap map = new LinkedHashMap(); for (A o : unnullForIteration(l)) { Pair p = callF(f, o); map.put(p.a, p.b); } return map; } static public LinkedHashMap mapToOrderedMap(Iterable l, IF1> f) { return mapToOrderedMap(f, l); } static public KeyManager keyManagerFromKeyStore(File keystoreFile, char[] passphrase) { try { KeyStore keystore = keyStoreFromFile(keystoreFile, passphrase); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, passphrase); return getSingleton(keyManagerFactory.getKeyManagers()); } catch (Exception __e) { throw rethrow(__e); } } static public File anyKeyStore() { for (File dir : listDirs(javaxSecretDir())) { File f = newFile(dir, "keystore.p12"); if (fileExists(f)) return f; } return null; } static public KeyStore keyStoreFromFile(File keystoreFile, char[] passphrase) { try { KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream keystoreStream = new FileInputStream(keystoreFile); try { keystore.load(keystoreStream, passphrase); return keystore; } finally { _close(keystoreStream); } } catch (Exception __e) { throw rethrow(__e); } } static public Double parseDays(String s) { if (eqic(s, "1 day")) return 1.0; s = dropSuffixICOrNull_trim(" days", s); return parseDoubleOpt(s); } static public Duration daysToDuration(double days) { return msToDuration(daysToMS(days)); } static public Double parseHours(String s) { if (eqic(s, "1 hour")) return 1.0; s = dropSuffixICOrNull_trim(" hours", s); return parseDoubleOpt(s); } static public Duration hoursToDuration(double days) { return msToDuration(hoursToMS(days)); } static public Object getVarOpt(Object o) { return o instanceof IF0 ? ((IF0) o).get() : o; } static public A getAndClearVar(IVar v) { return getAndClear(v); } static public long hoursToMS(double hours) { return round(hours * 60 * 60 * 1000); } static public List jfindAll(List tok, String pat) { return jfindAll(tok, pat, null); } static public List jfindAll(List tok, String pat, ITokCondition condition) { return jfindAll(tok, jfind_preprocess(javaTok(pat)), condition); } static public List jfindAll(List tok, List tokPat) { return jfindAll(tok, tokPat, null); } static public List jfindAll(List tok, List tokPat, ITokCondition condition) { TokCondition cond = toTokCondition(condition); String[] toks = toStringArray(codeTokensOnly(tokPat)); int i = -1; List l = new ArrayList(); while ((i = findCodeTokens(tok, i + 1, false, toks, cond)) >= 0) l.add(i); return l; } static public byte[] loadBinaryFromZip(File inZip, String fileName) { try { ZipFile zip = new ZipFile(inZip); try { ZipEntry entry = zip.getEntry(fileName); if (entry == null) return null; InputStream fin = zip.getInputStream(entry); ByteArrayOutputStream baos = new ByteArrayOutputStream(); copyStream(fin, baos); fin.close(); return baos.toByteArray(); } finally { zip.close(); } } catch (Exception __e) { throw rethrow(__e); } } static public void onTableSelectionChangedAndNow(final JTable table, final Runnable r) { { swing(() -> { table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { callF(r); } }); callF(r); }); } } static public List notStartingWithIC(Collection l, final String prefix) { return filter(unnull(l), new F1() { public Boolean get(String s) { try { return !startsWithIC(s, prefix); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "!startsWithIC(s, prefix)"; } }); } static public List notStartingWithIC(String prefix, Collection l) { return notStartingWithIC(l, prefix); } static public double toDays(long ms) { return ms / (60000.0 * 60 * 24); } static public String regexpFirstGroup(String pat, String s) { Matcher m = regexpMatcher(pat, s); if (m.find()) return m.group(1); else return null; } static public String regexpFirstGroup(java.util.regex.Pattern pat, String s) { Matcher m = regexpMatcher(pat, s); if (m.find()) return m.group(1); else return null; } static public String regexpFirstGroup(String pat, Iterable strings) { var compiled = compileRegexp(pat); for (String s : unnullForIteration(strings)) { String group = regexpFirstGroup(compiled, s); if (group != null) return group; } return null; } static public Pt ptFromEvent(MouseEvent e) { return e == null ? null : pt(e.getX(), e.getY()); } static public float toFloat(Object o) { if (o == null) return 0f; if (o instanceof Number) return ((Number) o).floatValue(); if (o instanceof Boolean) return ((Boolean) o).booleanValue() ? 1f : 0f; throw fail("Not convertible to float: " + _getClass(o)); } static public long oshi_systemUptime() { return oshi_operatingSystem().getSystemUptime(); } static public A nlPrint(A o) { return nlPrint("", o); } static public A nlPrint(String prefix, A o) { return print("\n" + unnull(prefix), o); } static public List contentsOfContainerTag(List tok) { return tok == null ? null : subList(tok, 2, l(tok) - 2); } static public List contentsOfContainerTag(List tok, String tagName) { return contentsOfContainerTag(first(findContainerTag(tok, tagName))); } static public List> findContainerTag(List tok, String tag) { List> l = new ArrayList(); for (int i = 1; i < l(tok); i += 2) if (isOpeningTag(tok.get(i), tag)) { int j, level = 1; for (j = i + 2; j < tok.size(); j += 2) if (isOpeningTag(tok.get(j), tag)) ++level; else if (isTag(tok.get(j), "/" + tag)) { --level; if (level == 0) { l.add(subList(tok, i - 1, j + 2)); break; } } i = j; } return l; } static public List> findContainerTag(String html, String tag) { return findContainerTag(htmlTok(html), tag); } static public boolean tagHasClass(List tok, String className) { String c = tagParam(tok, "class"); return cic(splitAtSpace(c), className); } static public boolean tagHasClass(String tag, String className) { String c = tagParam(tag, "class"); return cic(splitAtSpace(c), className); } static public List htmlTok(String s) { return htmlcoarsetok(s); } static public DoubleRange intToDoubleRange(IntRange r) { return intToDoubleRange(1, r); } static public DoubleRange intToDoubleRange(double factor, IntRange r) { return r == null ? null : doubleRange(r.start * factor, r.end * factor); } static public String intToStringWithExplicitPlus(int i) { return i > 0 ? "+" + i : str(i); } static public TailFile tailFileFromStart(File file, int interval, IVF1 onData) { return tailFile2(file, interval, onData); } static public VF1 vfAppendToLineBuffer(final LineBuffer buf) { return new VF1() { public void get(String s) { try { buf.append(s); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "buf.append(s)"; } }; } static public void deleteFile_assertSuccess(File file) { if (!deleteFile(file)) throw fail("Couldn't delete " + file); } static public int intFromSlider(JSlider slider) { return getSliderValue(slider); } static public A toComponent(A c) { return c; } static public Component toComponent(Swingable c) { return c == null ? null : c.visualize(); } static public ISleeper_v2 defaultSleeper() { return new ISleeper_v2() { public Sleeping doLater(Timestamp targetTime, Runnable r) { return new MultiSleeper().doLater(targetTime, r); } public void close() { try { } catch (Exception __e) { throw rethrow(__e); } } }; } static public TailFile tailFile_newOnly(File file, int interval, Object onData) { TailFile tf = new TailFile(file, interval, onData); tailFile_newOnly(tf); tf.start(); return tf; } static public void tailFile_newOnly(TailFile tf) { tf.l = l(tf.file); } static public boolean substringAtIs(String a, int i, String b) { return regionMatches(a, i, b, 0, l(b)); } static public DoublePt blendDoublePts(DoublePt x, DoublePt y, double yish) { double xish = 1 - yish; return new DoublePt(x.x * xish + y.x * yish, x.y * xish + y.y * yish); } static public float drawArrowHead_length = 2f; static public void drawArrowHead(Graphics2D g, double x1, double y1, double x2, double y2, double size) { if (y2 == y1 && x2 == x1) return; Path2D.Double arrowHead = new Path2D.Double(); arrowHead.moveTo(0, 0); double l = drawArrowHead_length * size; arrowHead.lineTo(-size, -l); arrowHead.lineTo(size, -l); arrowHead.closePath(); AffineTransform tx = new AffineTransform(); double angle = Math.atan2(y2 - y1, x2 - x1); tx.translate(x2, y2); tx.rotate(angle - Math.PI / 2); AffineTransform old = g.getTransform(); g.transform(tx); g.fill(arrowHead); g.setTransform(old); } static public Rect rectAround(Pt p, int w) { return rectAround(p, w, w); } static public Rect rectAround(Pt p, int w, int h) { return new Rect(p.x - w / 2, p.y - h / 2, w, h); } static public Rect rectAround(int x, int y, int w, int h) { return new Rect(x - w / 2, y - h / 2, w, h); } static public Class main() { return getMainClass(); } static public String ipToHost(String ip) { try { return InetAddress.getByName(ip).getCanonicalHostName(); } catch (Exception __e) { throw rethrow(__e); } } static public IF0 bigFontSize; static public float bigFontSize() { return bigFontSize != null ? bigFontSize.get() : bigFontSize_base(); } final static public float bigFontSize_fallback(IF0 _f) { return _f != null ? _f.get() : bigFontSize_base(); } static public float bigFontSize_base() { return 40; } static public String jarBotURL() { return "https://botcompany.de/jar/"; } static public String jarBotURL(String snippetID) { return jarBotURL() + psI(snippetID); } static public File assertIsFile(File f) { if (!isFile(f)) throw fail(isDir(f) ? "Directory, not file: " + f : "File not found: " + f); return f; } static public boolean isValidZipFile(File zip) { try { assertNempty(listZipFile(zip)); return true; } catch (Throwable e) { printStackTrace(e); return false; } } static public ZipOutputStream newZipOutputStream(String path) { return newZipOutputStream(new File(path)); } static public ZipOutputStream newZipOutputStream(File zip) { try { return new ZipOutputStream(newFileOutputStream(zip)); } catch (Exception __e) { throw rethrow(__e); } } static public void addFileToZip(ZipOutputStream outZip, File f, String name) { try { ping(); if (f == null || !f.isFile()) return; AutoCloseable __1 = smartZipCompressionLevel(outZip, f); try { outZip.putNextEntry(new ZipEntry(name)); copyFileToStream(f, outZip); } finally { _close(__1); } } catch (Exception __e) { throw rethrow(__e); } } static public void addFileToZip(ZipOutputStream outZip, File f) { if (f == null) return; addFileToZip(outZip, f, f.getName()); } static public Map filterMapByFunctionOnKey(Map map, Object f) { Map m2 = similarEmptyMap(map); for (A a : keys(map)) { if (isTrue(callF(f, a))) m2.put(a, map.get(a)); } return m2; } static public Map filterMapByFunctionOnKey(Object f, Map map) { return filterMapByFunctionOnKey(map, f); } static public SecretValue secretValueOrNull(A a) { return a == null ? null : new SecretValue(a); } static public Map parseColonProperties(String text) { return parseColonProperties(text, new LinkedHashMap()); } static public Map parseColonProperties(String text, Map map) { for (String s : tlft(text)) { int i = indexOf(s, ':'); if (i > 0) map.put(trimSubstring(s, 0, i), trimSubstring(s, i + 1)); } return map; } static public Rect joinRects(List l) { return mergeRects(l); } static public Rect joinRects(Rect a, Rect b) { return mergeRects(a, b); } static public Image2B randomImage2B(int w) { return randomImage2B(w, w); } static public Image2B randomImage2B(int w, int h) { return new Image2B(w, h, randomBytes((w * h + 7) / 8)); } static public java.lang.management.OperatingSystemMXBean osMXBean() { return ManagementFactory.getOperatingSystemMXBean(); } static public long ldiv_round(long a, long b) { return (a + b / 2) / b; } static public long ldiv_round(double a, double b) { return lround(a / b); } static public Image2B binaryImageFromFunction(int w, IIntIntPred f) { return binaryImageFromFunction(w, w, f); } static public Image2B binaryImageFromFunction(int w, int h, IIntIntPred f) { return image2BFromFunction(w, h, f); } static public Image2B binaryImageFromFunction(int w, IF0_Bool f) { return binaryImageFromFunction(w, w, f); } static public Image2B binaryImageFromFunction(int w, int h, IF0_Bool f) { return image2BFromFunction(w, h, f); } static public boolean getBoolPixelDefaultTrue(IBinaryImage image, int x, int y) { return x < 0 || y < 0 || x >= image.w() || y >= image.h() ? true : image.getBoolPixel_noRangeCheck(x, y); } static public BufferedImage twoColorImageWithAlpha(Color newBlack, Color newWhite, IBinaryImage image) { int fgInt = colorToRGBA(newWhite), bgInt = colorToRGBA(newBlack); return image == null ? null : bufferedImageFromFunctionWithAlpha(image.getWidth(), image.getHeight(), (x, y) -> image.getBoolPixel_noRangeCheck(x, y) ? fgInt : bgInt); } static public BufferedImage twoColorImageWithAlpha(IBinaryImage image, Color bg, Color fg) { return twoColorImageWithAlpha(bg, fg, image); } static public Color transparentColor_cache; static public Color transparentColor() { if (transparentColor_cache == null) transparentColor_cache = transparentColor_load(); return transparentColor_cache; } static public Color transparentColor_load() { return new Color(0, true); } static public void drawScaledPixelatedImage(BufferedImage g, BufferedImage img, Rect r) { drawScaledPixelatedImage(graphics(g), img, r); } static public void drawScaledPixelatedImage(Graphics2D g, BufferedImage img, Rect r) { if (g == null || img == null || r == null) return; g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); double scaleX = doubleRatio(r.w, img.getWidth()); double scaleY = doubleRatio(r.h, img.getHeight()); g.translate(r.x, r.y); g.scale(scaleX, scaleY); g.drawImage(img, 0, 0, null); } static public BufferedImage bufferedImageFromFunctionWithoutAlpha(int w, IF2_Int f) { return bufferedImageFromFunctionWithoutAlpha(w, w, f); } static public BufferedImage bufferedImageFromFunctionWithoutAlpha(int w, int h, IF2_Int f) { return imageFromFunctionWithoutAlpha(w, h, f); } static public JPanel vgrid(List parts) { return vgrid(asArray(parts)); } static public JPanel vgrid(Object... parts) { JPanel panel = new JPanel(); panel.setLayout(new GridLayout(parts.length, 1)); smartAdd(panel, parts); return panel; } static public void zip_addDummyFile(ZipOutputStream outZip) { zip_addTextFile(outZip, "empty.txt", "Empty!"); } static public String standardNameOfDontBackupFile() { return "dont-backup.txt"; } static public String lstr(Map map) { return str(l(map)); } static public String lstr(Collection c) { return str(l(c)); } static public String lstr(String s) { return str(l(s)); } static public List g22_allBorderTraces_withDiagonals(IImageRegion region) { RegionBorder_innerPoints_withDiagonals walker = new RegionBorder_innerPoints_withDiagonals(region); List out = new ArrayList(); walker.onNewTrace(hole -> out.add(new PtBuffer())); walker.onFoundPoint(p -> last(out).add(p)); walker.run(); return out; } static public List g22_allBorderTraces(IImageRegion region) { RegionBorder_innerPoints_v2 walker = new RegionBorder_innerPoints_v2(region); List out = new ArrayList(); walker.onNewTrace(hole -> out.add(new PtBuffer())); walker.onFoundPoint(p -> last(out).add(p)); walker.run(); return out; } static public boolean isQOIFile(byte[] data) { return isQOI(data); } static public boolean isQOIFile(File f) { return isQOI(f); } static public void saveQOIVerbose(BufferedImage img, File file) { try { saveQOI(img, file); print("Saved QOI: " + f2s(file)); } catch (Exception __e) { throw rethrow(__e); } } static public void saveQOIVerbose(File file, BufferedImage img) { saveQOIVerbose(img, file); } static public byte[] toASCII(String s) { return s.getBytes(java.nio.charset.StandardCharsets.US_ASCII); } static public byte toASCII(char c) { return toASCII(str(new char[] { c }))[0]; } static public int hi15_r(short hi15) { return (hi15 >> 10) & 0x1F; } static public int hi15_g(short hi15) { return (hi15 >> 5) & 0x1F; } static public int hi15_b(short hi15) { return hi15 & 0x1F; } static public short hi15_clamp(int r, int g, int b) { return hi15(clamp(r, 0, 31), clamp(g, 0, 31), clamp(b, 0, 31)); } static public int[] reverseIntArray(int[] a) { int n = l(a); int[] b = new int[n]; for (int i = 0; i < n; i++) b[n - 1 - i] = a[i]; return b; } static public void printClassByteCode(Object o) { if (o == null) return; JavaClass clz = classToBCEL(o); if (clz == null) { print("No class data found for " + _getClass(o)); return; } print("PRINTING BYTE CODE FOR: " + assertEquals("Disassembled class name", className(o), clz.getClassName())); print(); print(tabToSingleSpace(str(clz))); print(); for (org.apache.bcel.classfile.Method method : clz.getMethods()) { printWithNLBeforeAndAfter(method); printWithIndent(tabToSingleSpace(str(method.getCode()))); } print(); } static public String customSeparatorCombine(String separator, Object... l) { return joinNempties(separator, flattenCollectionsAndArrays(l)); } static public List allSwingComponentsOfType(Class theClass) { List frames = listAllFrames(); List l = new ArrayList(); for (JFrame f : frames) scanForComponents(f, theClass, l); return l; } static public long benchFor1Second(String desc, Runnable r) { return benchForNSeconds(desc, r, 1); } static public long benchFor1Second(Runnable r) { return benchFor1Second(str(r), r); } static public A benchFor1Second(IF0 f) { return benchFor1Second(str(f), f); } static public A benchFor1Second(String desc, IF0 f) { benchFor1Second(new Runnable() { public void run() { try { f.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "f!"; } }); return f.get(); } static public BufferedImage dropAlphaChannelFromBufferedImage(BufferedImage img) { if (img == null || img.getType() == BufferedImage.TYPE_INT_RGB) return img; int w = img.getWidth(), h = img.getHeight(); BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); int[] rgb = img.getRGB(0, 0, w, h, null, 0, w); newImage.setRGB(0, 0, w, h, rgb, 0, w); return newImage; } static public GZIPInputStream gzipInputStream(File f) { return newGZIPInputStream(f); } static public GZIPInputStream gzipInputStream(InputStream in) { return newGZIPInputStream(in); } static public BufferedReader inputStreamReader(InputStream in) { return utf8Reader(in); } static public BufferedReader inputStreamReader(File f) { return utf8Reader(f); } static public String dropFirstSpacedColumns(int n, String text) { String re = "^\\s*" + repString(n, "\\S+\\s*"); return mapEachLine(text, line -> regexpReplace_direct(line, re, "")); } static public IF1 dropFirstSpacedColumns(int n) { return text -> dropFirstSpacedColumns(n, text); } static public long hashBinaryImage(IBinaryImage img) { return new HashBinaryImage(img).get(); } static public boolean binaryImagesIdentical(IBinaryImage img1, IBinaryImage img2) { if (img1 == img2) return true; if (img1 == null) return img2 == null; if (img2 == null) return false; int w = img1.getWidth(), h = img1.getHeight(); if (w != img2.getWidth() || h != img2.getHeight()) return false; return binaryImagesIdentical(img1.toImage2B(), img2.toImage2B()); } static public boolean binaryImagesIdentical(Image2B img1, Image2B img2) { if (img1 == img2) return true; if (img1 == null) return img2 == null; if (img2 == null) return false; int w = img1.getWidth(), h = img1.getHeight(); if (w != img2.getWidth() || h != img2.getHeight()) return false; byte[] pixels1 = img1.pixels, pixels2 = img2.pixels; return Arrays.equals(pixels1, pixels2); } static public Class __javax; static public Class getJavaX() { try { return __javax; } catch (Exception __e) { throw rethrow(__e); } } static public void __setJavaX(Class j) { __javax = j; _onJavaXSet(); } static public Map definedRewrites_rewrites; static public Map definedRewrites() { return definedRewrites_rewrites = initHashMap(definedRewrites_rewrites); } static public void ensureConceptClassIsIndexed(Class c) { ensureConceptClassIsIndexed(db_mainConcepts(), c); } static public void ensureConceptClassIsIndexed(Concepts cc, Class c) { if (cc != null && c != null && !isConceptClassIndexed(cc, c)) indexRandomConceptField(cc, c); } static public void gazelle22_highlightRegionOutline(int[] pixels, Gazelle22_ImageToRegions itr, RegionBorder_innerPoints x) { class X { public boolean hole = false; public int n; public Gazelle22_GradientImage gradientImage = new Gazelle22_GradientImage(itr.posterized); public X() { gradientImage.init(); int color = 0xFF008000, holeColor = 0xFFFFB266; x.onNewTrace(isHole -> hole = isHole); x.onFoundPoint(p -> { ++n; boolean gradient = gradientImage.isGradientPoint(p.x, p.y); int col = hole ? holeColor : color; if (gradient) if (odd(n)) return; pixels[p.y * itr.regions.w + p.x] = col; }); x.run(); } } new X(); } static public String objectToStringWithClassName(Object o) { return toStringWithClass(o); } static public A foldl_noSeed(F2 f, Iterable l) { return foldl_noSeed((Object) f, l); } static public A foldl_noSeed(IF2 f, Iterable l) { Iterator it = iterator(l); if (!it.hasNext()) return null; A a = it.next(); while (it.hasNext()) a = f.get(a, it.next()); return a; } static public A foldl_noSeed(IF2 f, A... l) { return foldl_noSeed(f, asList(l)); } static public A foldl_noSeed(Object f, Iterable l) { Iterator it = iterator(l); if (!it.hasNext()) return null; A a = it.next(); while (it.hasNext()) a = (A) callF(f, a, it.next()); return a; } static public int methodApplicabilityScore(Method m, Object[] args) { Class[] types = m.getParameterTypes(); if (types.length != args.length) return Integer.MAX_VALUE; int score = 0; for (int i = 0; i < types.length; i++) { Object a = args[i]; Class c = types[i]; if (a == null) ++score; else if (c == a.getClass()) { } else if (isInstanceX(c, a)) ++score; else return Integer.MAX_VALUE; } return score; } static public A copyNonTransientFields(Object x, A y) { return copyFields(x, y, nonTransientNonStaticFields(x)); } static public long conceptID(Concept c) { return c == null ? 0 : c.id; } static public long conceptID(Concept.Ref ref) { return conceptID(cDeref(ref)); } static public long lround(double d) { return Math.round(d); } static public long lround(Number n) { return lround(toDouble(n)); } static public Set setMinus(Set set, Object... stuff) { Set s2 = cloneSet(set); for (Object o : stuff) s2.remove(o); return s2; } static public Set mergeSets(Collection... l) { return joinSets(l); } static public Set allNonStaticNonTransientFields(Object o) { TreeSet fields = new TreeSet(); Class _c = _getClass(o); do { for (Field f : _c.getDeclaredFields()) if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) fields.add(f.getName()); _c = _c.getSuperclass(); } while (_c != null); return fields; } static public boolean isHardError(Throwable e) { return innerExceptionOfType(Error.class, e) != null; } static public double toG_double(long l) { return l / (1024 * 1024 * 1024.0); } static public void setTitledBorderFontSize(JComponent c, float fontSize) { if (c == null) return; { swing(() -> { javax.swing.border.TitledBorder b = optCast(javax.swing.border.TitledBorder.class, c.getBorder()); if (b != null) { Font font = b.getTitleFont(); b.setTitleFont(font.deriveFont(fontSize)); } }); } } static public JTable setTableFontSizesAndRowHeight(float size, JTable table) { if (table == null) return null; { swing(() -> { setTableFontSizes(size, table); setRowHeight(table, fontSizeToRowHeight(size, table)); }); } return table; } static public JTable setTableFontSizesAndRowHeight(JTable table, float size) { return setTableFontSizesAndRowHeight(size, table); } static public String plusMinusFix(String s) { return dropMinusFromZero(addPlusIfPositive(s)); } static public String formatMarginPrice(double price) { return formatDouble2X(price); } static public String getProgramID() { return nempty(programID) ? formatSnippetIDOpt(programID) : "?"; } static public String getProgramID(Class c) { String id = (String) getOpt(c, "programID"); if (nempty(id)) return formatSnippetID(id); return "?"; } static public String getProgramID(Object o) { return getProgramID(getMainClass(o)); } static public Map paramsToMap_withNulls(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) map.put(params[i], params[i + 1]); return map; } static public String dropDollarPrefix(String s) { return dropPrefix("$", s); } static public String replaceDollarVars_dyn(String s, IF1 f) { if (f == null) return s; return regexpReplaceIC(s, "\\$(\\w+)", matcher -> { String var = matcher.group(1); String val = f.get(var); return val == null ? matcher.group() : str(val); }); } static public String jsonEncode_extended(Object o) { StringBuilder buf = new StringBuilder(); jsonEncode_extended(o, buf); return str(buf); } static public void jsonEncode_extended(Object o, StringBuilder buf) { if (o == null) buf.append("null"); else if (o instanceof JS) buf.append(((JS) o).get()); 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_extended(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_extended(element, buf); } buf.append("]"); } else throw fail("Unknown object for JSON encoding: " + className(o)); } static public boolean isRelativeOrAbsoluteURL(String s) { return isAbsoluteURL(s) || isRelativeURL(s); } static public String hstylesheetsrc(String src) { return tag("link", "", "rel", "stylesheet", "href", src); } static public String addLineBreak(String s) { return addSuffix(s, "\n"); } static public String base64(byte[] a) { return base64encode(a); } static public String dropSuffixICOrNull_trim(String suffix, String s) { return !ewic(s, suffix) ? null : trimSubstring(s, 0, l(s) - l(suffix)); } static public long daysToMS(double days) { return round(days * 24 * 60 * 60 * 1000); } static public TokCondition toTokCondition(ITokCondition condition) { return condition == null ? null : condition instanceof TokCondition ? (TokCondition) condition : new TokCondition() { public boolean get(List tok, int i) { return condition.get(tok, i); } }; } static public boolean startsWithIC(String a, String b) { return startsWithIgnoreCase(a, b); } static public Cache oshi_operatingSystem_cache = new Cache<>(() -> oshi_operatingSystem_load()); static public OperatingSystem oshi_operatingSystem() { return oshi_operatingSystem_cache.get(); } static public OperatingSystem oshi_operatingSystem_load() { return oshi_systemInfo().getOperatingSystem(); } static public boolean isOpeningTag(String token, String tag) { return isTag(token, tag) && !token.endsWith("/>"); } static public boolean isOpeningTag(String token) { return token.startsWith("<") && token.endsWith(">") && !token.endsWith("/>") && isLetter(token.charAt(1)); } static public boolean isTag(String token, String tag) { return token.regionMatches(true, 0, "<" + tag + " ", 0, tag.length() + 2) || token.regionMatches(true, 0, "<" + tag + ">", 0, tag.length() + 2); } static public String tagParam(String tag, String key) { return getHtmlTagParameter(tag, key); } static public String tagParam(List tok, String key) { return getHtmlTagParameter(second(tok), key); } static public List htmlcoarsetok(String s) { List tok = new ArrayList(); int l = s == null ? 0 : s.length(); int i = 0; while (i < l) { int j = i; char c; while (j < l) { if (s.charAt(j) != '<') ++j; else if (s.substring(j, Math.min(j + 4, l)).equals("")); j = Math.min(j + 3, l); } else { char d = charAt(s, j + 1); if (d == '/' || isLetter(d)) break; else ++j; } } tok.add(s.substring(i, j)); i = j; if (i >= l) break; c = s.charAt(i); if (c == '<') { ++j; while (j < l && s.charAt(j) != '>') ++j; if (j < l) ++j; } tok.add(s.substring(i, j)); i = j; } if ((tok.size() & 1) == 0) tok.add(""); return tok; } static public boolean isDir(File f) { return isDirectory(f); } static public boolean isDir(String path) { return isDirectory(path); } static public ThreadLocal smartZipCompressionLevel_on = new ThreadLocal(); static public AutoCloseable smartZipCompressionLevel(ZipOutputStream zip, File f) { return smartZipCompressionLevel(zip, fileName(f)); } static public AutoCloseable smartZipCompressionLevel(final ZipOutputStream zip, String fileName) { if (!isTrue(smartZipCompressionLevel_on.get())) return null; int level = Deflater.DEFAULT_COMPRESSION; if (isImageFileName(fileName) || eqicOneOf(fileExtension(fileName), ".zip", ".jar", ".gz", ".bin")) level = Deflater.NO_COMPRESSION; zip.setLevel(level); return new AutoCloseable() { public String toString() { return "zip.setLevel(Deflater.DEFAULT_COMPRESSION);"; } public void close() throws Exception { zip.setLevel(Deflater.DEFAULT_COMPRESSION); } }; } static public void copyFileToStream(File src, OutputStream out) { try { file2stream(src, out); } catch (Exception __e) { throw rethrow(__e); } } static public byte[] randomBytes(int n) { byte[] l = new byte[n]; for (int i = 0; i < n; i++) l[i] = randomByte(); return l; } static public int colorToRGBA(Color c) { return c.getRGB(); } static public BufferedImage bufferedImageFromFunctionWithAlpha(int w, IF2_Int f) { return bufferedImageFromFunctionWithAlpha(w, w, f); } static public BufferedImage bufferedImageFromFunctionWithAlpha(int w, int h, IF2_Int f) { return imageFromFunctionWithAlpha(w, h, f); } static public BufferedImage imageFromFunctionWithoutAlpha(int w, IF2_Int f) { return imageFromFunctionWithoutAlpha(w, w, f); } static public BufferedImage imageFromFunctionWithoutAlpha(int w, int h, IF2_Int f) { int[] pixels = new int[w * h]; int i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) pixels[i++] = f.get(x, y); return intArrayToBufferedImageWithoutAlpha(pixels, w, h); } static public void zip_addTextFile(ZipOutputStream outZip, String name, String text) { try { if (text == null) return; byte[] utf8 = toUtf8(text); ZipEntry e = new ZipEntry(name); e.setSize(l(utf8)); outZip.putNextEntry(e); outZip.write(utf8, 0, l(utf8)); } catch (Exception __e) { throw rethrow(__e); } } static public void saveQOI(BufferedImage img, File file) { try { QOIImageWriterSPI spi = new QOIImageWriterSPI(); var imageWriter = spi.createWriterInstance(); try { var stream = ImageIO.createImageOutputStream(file); imageWriter.setOutput(stream); imageWriter.write(img); } finally { imageWriter.dispose(); } vmBus_send("wroteFile", file); } catch (Exception __e) { throw rethrow(__e); } } static public void saveQOI(File file, BufferedImage img) { saveQOI(img, file); } static public short hi15(int r, int g, int b) { return (short) ((r << 10) | (g << 5) | b); } static public JavaClass classToBCEL(Class c) { try { InputStream in = inputStreamForClass(c); try { return in == null ? null : new ClassParser(in, c.getName() + ".class").parse(); } finally { _close(in); } } catch (Exception __e) { throw rethrow(__e); } } static public JavaClass classToBCEL(Object o) { return classToBCEL(_getClass(o)); } static public void printWithNLBeforeAndAfter(Object o) { print_doubleNL(o); } static public BufferedReader utf8Reader(InputStream in) { return utf8BufferedReader(in); } static public BufferedReader utf8Reader(File f) { return utf8BufferedReader(f); } static public String repString(int n, String s) { return repeatString(s, n); } static public String repString(String s, int n) { return repeatString(s, n); } static public Map initHashMap(Map map) { return map != null ? map : new HashMap(); } static public boolean isConceptClassIndexed(Class c) { return isConceptClassIndexed(db_mainConcepts(), c); } static public boolean isConceptClassIndexed(Concepts concepts, Class c) { return concepts.conceptCounterForClass(c) != null; } static public void indexRandomConceptField(Class c) { indexRandomConceptField(db_mainConcepts(), c); } static public void indexRandomConceptField(Concepts cc, Class c) { String field = or(first(conceptFields(c)), "_dummy"); print("Indexing " + c + "." + field); indexConceptField(cc, c, field); assertTrue("Concept class indexed", isConceptClassIndexed(cc, c)); { long _startTime_0 = sysNow(); try { print("Got " + nConcepts(countConcepts(cc, c))); } finally { _startTime_0 = sysNow() - _startTime_0; saveTiming(_startTime_0); } } } static public Set nonTransientNonStaticFields(Object o) { return allNonStaticNonTransientFields(o); } static public Set cloneSet(Collection set) { if (set == null) return new HashSet(); synchronized (collectionMutex(set)) { Set s = similarEmptySet(set); s.addAll(set); return s; } } static public JTable setTableFontSizes(float size, JTable table) { if (table == null) return null; { swing(() -> { setFontSize(table.getTableHeader(), size); setFontSize(table, size); }); } return table; } static public JTable setTableFontSizes(JTable table, float size) { return setTableFontSizes(size, table); } static public JTable setRowHeight(final int h, final JTable t) { if (t != null) { swing(() -> { t.setRowHeight(h); }); } return t; } static public JTable setRowHeight(JTable t, int h) { return setRowHeight(h, t); } static public int fontSizeToRowHeight(float fontSize, JTable table) { return iround(fontSize * 1.5); } static public String addPlusIfPositive(String s) { return isPositiveNumberString(s) ? addPrefix("+", s) : s; } static public String regexpReplaceIC(String s, String pat, Object f) { return regexReplaceIC(s, pat, f); } static public String regexpReplaceIC(String s, String pat, String replacement) { return regexReplaceIC(s, pat, replacement); } static public String regexpReplaceIC(String s, String pat, IF1 f) { return regexReplaceIC(s, pat, f); } static public boolean isRelativeURL(String s) { return startsWithOneOf(s, "/", "./", "../"); } static public Cache oshi_systemInfo_cache = new Cache<>(() -> oshi_systemInfo_load()); static public SystemInfo oshi_systemInfo() { return oshi_systemInfo_cache.get(); } static public SystemInfo oshi_systemInfo_load() { return new SystemInfo(); } static public String getHtmlTagParameter(String tag, String key) { return getHtmlTagParameters(tag).get(key); } static public byte randomByte() { return (byte) random(256); } static public int randomByte(Random random) { return (byte) random(random, 256); } static public BufferedImage imageFromFunctionWithAlpha(int w, IF2_Int f) { return imageFromFunctionWithAlpha(w, w, f); } static public BufferedImage imageFromFunctionWithAlpha(int w, int h, IF2_Int f) { int[] pixels = new int[w * h]; int i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) pixels[i++] = f.get(x, y); return intArrayToBufferedImageWithAlpha(pixels, w, h); } static public InputStream inputStreamForClass(Class c) { try { if (c == null) return null; ClassLoader cl = getClassLoader(c); if (cl instanceof InMemoryClassLoader) { byte[] bytes = ((InMemoryClassLoader) cl).getClassBytes(c); if (bytes != null) return byteArrayInputStream(bytes); } Collection files = (Collection) (getOpt(cl, "files")); if (files != null) { String name = c.getName().replace('.', '/') + ".class"; for (File location : files) { InputStream in = inputStreamForFileInDirOrZip(location, name); if (in != null) return in; } throw fail(name + " not found in: " + files); } return null; } catch (Exception __e) { throw rethrow(__e); } } static public void print_doubleNL(Object o) { print("\n" + str(o) + "\n"); } static public String repeatString(String s, int n) { StringBuilder buf = new StringBuilder(l(s) * n); for (int i = 0; i < n; i++) buf.append(s); return str(buf); } static public String nConcepts(long n) { return n2(n, "concept"); } static public String nConcepts(Collection l) { return nConcepts(l(l)); } static public String nConcepts(Map map) { return nConcepts(l(map)); } static public ThreadLocal saveTiming_last = new ThreadLocal(); static public void saveTiming(long ms) { print(ms + " ms"); saveTiming_noPrint(ms); } static public void saveTiming_noPrint(long ms) { saveTiming_last.set(ms); } static public ThreadLocal saveTiming_tl() { return saveTiming_last; } static public boolean isPositiveNumberString(String s) { return regexpFind("^\\+|^0*[1-9]|^0*\\.0*[1-9]", s); } static public String regexReplaceIC(String s, String pat, Object f) { return regexReplace(regexpMatcherIC(pat, s), f); } static public String regexReplaceIC(String s, String pat, String replacement) { return regexpReplaceIC_direct(s, pat, replacement); } static public boolean getHtmlTagParameters_debug = false; static public Map getHtmlTagParameters(String tag) { if (empty(tag)) return null; List tok = codeTokens(tok_joinMinusIdentifiers(htmlFineTok(tag))); if (getHtmlTagParameters_debug) printStruct(tok); assertEquals("<", tok.get(0)); int i = 1; if (eq(tok.get(1), "/")) ++i; String name = tok.get(i++); if (!isMinusIdentifier(name)) throw fail(tag + " (" + name + ")"); Map map = new HashMap(); while (i < l(tok)) { String t = tok.get(i); if (eqOneOf(t, "/", ">")) break; if (!isMinusIdentifier(t)) throw fail(tag + " (" + t + ")"); ++i; String value = "1"; if (eq(tok.get(i), "=")) { ++i; value = htmlunquote(tok.get(i++)); } map.put(t, value); } return map; } static public BufferedImageWithMeta intArrayToBufferedImageWithAlpha(int[] pixels, int w) { return intArrayToBufferedImageWithAlpha(pixels, w, pixels.length / w); } static public BufferedImageWithMeta intArrayToBufferedImageWithAlpha(int[] pixels, int w, int h) { return intArrayToBufferedImage(pixels, w, h); } static public BufferedImageWithMeta intArrayToBufferedImageWithAlpha(int w, int... pixels) { return intArrayToBufferedImage(w, pixels); } static public ByteArrayInputStream byteArrayInputStream(byte[] data) { return new ByteArrayInputStream(data); } static public InputStream inputStreamForFileInDirOrZip(File location, String subPath) { try { if (location.isDirectory()) { File f = new File(location, subPath); return f.exists() ? newFileInputStream(f) : null; } else if (location.isFile()) { InputStream in = zipFileInputStream(location, subPath); if (in != null) return in; } return null; } catch (Exception __e) { throw rethrow(__e); } } static public Matcher regexpMatcherIC(String pat, String s) { return compileRegexpIC(pat).matcher(unnull(s)); } static public String regexpReplaceIC_direct(String s, String pat, String replacement) { Matcher m = regexpIC(pat, s); StringBuffer buf = new StringBuffer(); while (m.find()) m.appendReplacement(buf, replacement); m.appendTail(buf); return str(buf); } static public List tok_joinMinusIdentifiers(List tok) { for (int i = 1; i + 4 < l(tok); i += 2) if (isMinusIdentifier(get(tok, i)) && eq(get(tok, i + 2), "-") && isIdentifier(get(tok, i + 4))) { replaceSublist(tok, i, i + 5, ll(join(subList(tok, i, i + 5)))); i -= 2; } return tok; } static public List htmlFineTok(String s) { List tok = new ArrayList(); int l = s.length(); int i = 0, n = 0; while (i < l) { int j = i; char c, d; while (j < l) { c = s.charAt(j); d = j + 1 >= l ? '\0' : s.charAt(j + 1); if (c == ' ' || c == '\t' || c == '\r' || c == '\n') ++j; else break; } tok.add(quickSubstring(s, i, j)); ++n; i = j; if (i >= l) break; c = s.charAt(i); d = i + 1 >= l ? '\0' : s.charAt(i + 1); if (c == '\'' || c == '"') { char opener = c; ++j; while (j < l) { if (s.charAt(j) == opener) { ++j; break; } else if (s.charAt(j) == '\\' && j + 1 < l) j += 2; else ++j; } } else if (Character.isJavaIdentifierStart(c)) do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); else if (Character.isDigit(c)) { do ++j; while (j < l && Character.isDigit(s.charAt(j))); if (j < l && s.charAt(j) == 'L') ++j; } else ++j; tok.add(quickSubstring(s, i, j)); ++n; i = j; } if ((tok.size() % 2) == 0) tok.add(""); return tok; } static public boolean isMinusIdentifier(String s) { if (empty(s)) return false; if (!Character.isJavaIdentifierStart(s.charAt(0)) && !s.startsWith("-")) return false; for (int i = 1; i < s.length(); i++) if (!Character.isJavaIdentifierPart(s.charAt(i)) && s.charAt(i) != '-') return false; return true; } static public String htmlunquote(String s) { if (s.startsWith("'") && s.endsWith("'") && s.length() >= 2 || s.startsWith("\"") && s.endsWith("\"") && s.length() >= 2) s = s.substring(1, s.length() - 1); return htmldecode(s); } static public InputStream zipFileInputStream(File inZip, String fileName) { try { ZipFile zip = new ZipFile(inZip); return zipInputStream(zip, fileName); } catch (Exception __e) { throw rethrow(__e); } } static public class HashBinaryImage implements IFieldsToList { public IBinaryImage img; public HashBinaryImage() { } public HashBinaryImage(IBinaryImage img) { this.img = img; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + img + ")"; } public Object[] _fieldsToList() { return new Object[] { img }; } public long hash; public long get() { if (img == null) return hash; var img = this.img.toImage2B(); int w = img.getWidth(), h = img.getHeight(); int n = w * h; byte[] pixels = img.pixels; addToHash(w); addToHash(h); for (int i = 0; i < n; i++) addToHash((pixels[i / 8] & (1 << (i & 7))) != 0 ? 0xFFFFFFFF : 0xFF000000); return hash; } public void addToHash(long x) { hash = boostHashCombine64(hash, x); } } static public class G22LAScratchpad extends ConceptWithChangeListeners { static final public String _fieldOrder = "text ide"; public transient FieldVar varText_cache; public FieldVar varText() { if (varText_cache == null) varText_cache = varText_load(); return varText_cache; } public FieldVar varText_load() { return new FieldVar(this, "text", () -> text(), text -> text(text)); } final public G22LAScratchpad setText(String text) { return text(text); } public G22LAScratchpad text(String text) { if (!eq(this.text, text)) { this.text = text; change(); } return this; } final public String getText() { return text(); } public String text() { return text; } public String text; transient public JLeftArrowScriptIDE ide; public G22Utils g22utils() { return main.g22utils(this); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { ide = g22utils().leftArrowScriptIDE(); ide.sourceInfo("Scratchpad"); var btnSave = jImageButton("#1103084", "Save script", runnableThread(new Runnable() { public void run() { try { saveAsNewScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveAsNewScript();"; } })); int idx = 0; while (getComponentAtIndex(ide.buttons(), idx) instanceof SingleComponentPanel) idx++; addComponentAtIndex(ide.buttons(), idx, btnSave); ide.sectionTitle("Left Arrow Script Scratchpad"); ide.lvScript(varText()); return withTopMargin(ide.visualize()); } public void saveAsNewScript() { g22utils().projectActions().saveAsNewScript(text); } } static public class G22MakeMaskCorrelationMatrix implements MakesBufferedImage { final public G22MakeMaskCorrelationMatrix setImagesH(long[][] imagesH) { return imagesH(imagesH); } public G22MakeMaskCorrelationMatrix imagesH(long[][] imagesH) { this.imagesH = imagesH; return this; } final public long[][] getImagesH() { return imagesH(); } public long[][] imagesH() { return imagesH; } public long[][] imagesH; final public G22MakeMaskCorrelationMatrix setImagesW(long[][] imagesW) { return imagesW(imagesW); } public G22MakeMaskCorrelationMatrix imagesW(long[][] imagesW) { this.imagesW = imagesW; return this; } final public long[][] getImagesW() { return imagesW(); } public long[][] imagesW() { return imagesW; } public long[][] imagesW; final public int[] getMatrix() { return matrix(); } public int[] matrix() { return matrix; } public int[] matrix; public G22MakeMaskCorrelationMatrix images(long[][] images) { return imagesW(images).imagesH(images); } public G22MakeMaskCorrelationMatrix images(List images) { return images(toArray(long[].class, images)); } public int w() { return imagesH.length; } public int h() { return imagesW.length; } public int maxPixelDiff() { return l(first(imagesW)) * 64; } public boolean symmetrical() { return imagesW == imagesH; } public void run() { try { int w = w(), h = h(); var matrix = this.matrix = new int[w * h]; int i = 0; if (symmetrical()) for (int y = 0; y < h; y++) { long[] imageH = imagesH[y]; int x = 0, i2 = y; for (; x < y; x++, i2 += w) matrix[i++] = matrix[i2]; for (; x < w; x++) matrix[i++] = countDifferingBits(imageH, imagesW[x]); } else for (int y = 0; y < h; y++) { long[] imageH = imagesH[y]; for (int x = 0; x < w; x++) matrix[i++] = countDifferingBits(imageH, imagesW[x]); } } catch (Exception __e) { throw rethrow(__e); } } public FloatBWImage get() { if (matrix == null) run(); int w = w(), h = h(); float max = maxPixelDiff(); return floatBWImageFromFunction(w, h, (x, y) -> 1f - matrix[y * w + x] / max); } public BufferedImage getBufferedImage() { return toBufferedImage(get()); } } static public class G22ScreenPart extends ConceptWithChangeListeners { static final public String _fieldOrder = "name bounds"; public String name; public Rect bounds; public String toString() { return commaCombine(name, str_megapixels(bounds)); } } static public class G22LetterRecognizer1 implements IFieldsToList { public SnPSettings snpSettings; public IMultiMap thumbnailToUnicode; public G22LetterRecognizer1() { } public G22LetterRecognizer1(SnPSettings snpSettings, IMultiMap thumbnailToUnicode) { this.thumbnailToUnicode = thumbnailToUnicode; this.snpSettings = snpSettings; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + snpSettings + ", " + thumbnailToUnicode + ")"; } public Object[] _fieldsToList() { return new Object[] { snpSettings, thumbnailToUnicode }; } public HashedBWImage exampleImage() { return firstKey(thumbnailToUnicode); } } static public class G22MaskUtils implements IFieldsToList { public G22Utils g22utils; public G22MaskUtils() { } public G22MaskUtils(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public IG22SimpleMasksHolder simpleMaskSet() { return new G22HashedMasks(); } public IG22MasksHolder optimizedMaskSet(IG22MasksHolder masks) { var search = new G22CriticalPixelSearch(masks); return search.bestTree(); } } static public class G22GalleryImage extends ConceptWithChangeListeners { public transient FieldVar varPath_cache; public FieldVar varPath() { if (varPath_cache == null) varPath_cache = varPath_load(); return varPath_cache; } public FieldVar varPath_load() { return new FieldVar(this, "path", () -> path(), path -> path(path)); } final public G22GalleryImage setPath(File path) { return path(path); } public G22GalleryImage path(File path) { if (!eq(this.path, path)) { this.path = path; change(); } return this; } final public File getPath() { return path(); } public File path() { return path; } public File path; public String toString() { return fileName(path); } public boolean imageExists() { return fileExists(path); } final public BufferedImage image() { return load(); } final public BufferedImage getImage() { return load(); } public BufferedImage load() { return loadImage2(path); } public File imageFile() { return path; } } static public class AllThreadsProfiler extends AbstractProfiler { public String toString() { return shortClassName(this); } public void stepImpl() { Map map = runnableThreadsWithStackTraces(); Lock __1 = lock; lock(__1); try { samples++; for (var __0 : _entrySet(map)) { var t = __0.getKey(); var stackTrace = __0.getValue(); if (!isSystemThread(t)) addSample(stackTrace); } } finally { unlock(__1); } } } static public class MPM { final public PositionSet getImaginaryPositions() { return imaginaryPositions(); } public PositionSet imaginaryPositions() { return imaginaryPositions; } public PositionSet imaginaryPositions = new PositionSet(); final public PositionSet getRealPositions() { return realPositions(); } public PositionSet realPositions() { return realPositions; } public PositionSet realPositions = new PositionSet(); final public MPM setCryptoPrice(double cryptoPrice) { return cryptoPrice(cryptoPrice); } public MPM cryptoPrice(double cryptoPrice) { this.cryptoPrice = cryptoPrice; return this; } final public double getCryptoPrice() { return cryptoPrice(); } public double cryptoPrice() { return cryptoPrice; } public double cryptoPrice; public DoubleBuffer cryptoPriceLog = new DoubleBuffer(); final public MPM setCryptoDirection(int cryptoDirection) { return cryptoDirection(cryptoDirection); } public MPM cryptoDirection(int cryptoDirection) { this.cryptoDirection = cryptoDirection; return this; } final public int getCryptoDirection() { return cryptoDirection(); } public int cryptoDirection() { return cryptoDirection; } public int cryptoDirection; transient public Set onCryptoDirectionChanged; public MPM onCryptoDirectionChanged(Runnable r) { onCryptoDirectionChanged = createOrAddToSyncLinkedHashSet(onCryptoDirectionChanged, r); return this; } public MPM removeCryptoDirectionChangedListener(Runnable r) { loadableUtils.utils.remove(onCryptoDirectionChanged, r); return this; } public void cryptoDirectionChanged() { if (onCryptoDirectionChanged != null) for (var listener : onCryptoDirectionChanged) pcallF_typed(listener); } final public MPM setCurrentTime(double currentTime) { return currentTime(currentTime); } public MPM currentTime(double currentTime) { this.currentTime = currentTime; return this; } final public double getCurrentTime() { return currentTime(); } public double currentTime() { return currentTime; } public double currentTime; final public MPM setMaxAllowedLoss(double maxAllowedLoss) { return maxAllowedLoss(maxAllowedLoss); } public MPM maxAllowedLoss(double maxAllowedLoss) { this.maxAllowedLoss = maxAllowedLoss; return this; } final public double getMaxAllowedLoss() { return maxAllowedLoss(); } public double maxAllowedLoss() { return maxAllowedLoss; } public double maxAllowedLoss = 1; public Position newShort() { return new Position().direction(-1); } public Position newLong() { return new Position().direction(1); } abstract public class CloseReason { } public class LossClose extends CloseReason { } public class HappyClose extends CloseReason { } public class RegularClose extends CloseReason { } public class KillClose extends CloseReason { } final public MPM setFees(double fees) { return fees(fees); } public MPM fees(double fees) { this.fees = fees; return this; } final public double getFees() { return fees(); } public double fees() { return fees; } public double fees = 0.12; final public MPM setExpectedSlippage(double expectedSlippage) { return expectedSlippage(expectedSlippage); } public MPM expectedSlippage(double expectedSlippage) { this.expectedSlippage = expectedSlippage; return this; } final public double getExpectedSlippage() { return expectedSlippage(); } public double expectedSlippage() { return expectedSlippage; } public double expectedSlippage = .1; public class Position { final public Position setReal(boolean real) { return real(real); } public Position real(boolean real) { this.real = real; return this; } final public boolean getReal() { return real(); } public boolean real() { return real; } public boolean real = false; final public Position setDirection(int direction) { return direction(direction); } public Position direction(int direction) { this.direction = direction; return this; } final public int getDirection() { return direction(); } public int direction() { return direction; } public int direction; final public Position setOpeningTime(double openingTime) { return openingTime(openingTime); } public Position openingTime(double openingTime) { this.openingTime = openingTime; return this; } final public double getOpeningTime() { return openingTime(); } public double openingTime() { return openingTime; } public double openingTime; final public Position setOpeningPrice(double openingPrice) { return openingPrice(openingPrice); } public Position openingPrice(double openingPrice) { this.openingPrice = openingPrice; return this; } final public double getOpeningPrice() { return openingPrice(); } public double openingPrice() { return openingPrice; } public double openingPrice; final public Position setLastPrice(double lastPrice) { return lastPrice(lastPrice); } public Position lastPrice(double lastPrice) { this.lastPrice = lastPrice; return this; } final public double getLastPrice() { return lastPrice(); } public double lastPrice() { return lastPrice; } public double lastPrice; final public Position setClosingTime(double closingTime) { return closingTime(closingTime); } public Position closingTime(double closingTime) { this.closingTime = closingTime; return this; } final public double getClosingTime() { return closingTime(); } public double closingTime() { return closingTime; } public double closingTime; final public Position setClosingPrice(double closingPrice) { return closingPrice(closingPrice); } public Position closingPrice(double closingPrice) { this.closingPrice = closingPrice; return this; } final public double getClosingPrice() { return closingPrice(); } public double closingPrice() { return closingPrice; } public double closingPrice; public Double openingPriceWithFeesAndSlippage_cache; public double openingPriceWithFeesAndSlippage() { if (openingPriceWithFeesAndSlippage_cache == null) openingPriceWithFeesAndSlippage_cache = openingPriceWithFeesAndSlippage_load(); return openingPriceWithFeesAndSlippage_cache; } public double openingPriceWithFeesAndSlippage_load() { return openingPrice * (1 + (fees + expectedSlippage) / 100 * direction); } final public Position setRelativeValue(double relativeValue) { return relativeValue(relativeValue); } public Position relativeValue(double relativeValue) { this.relativeValue = relativeValue; return this; } final public double getRelativeValue() { return relativeValue(); } public double relativeValue() { return relativeValue; } public double relativeValue; final public Position setMaxRelativeValue(double maxRelativeValue) { return maxRelativeValue(maxRelativeValue); } public Position maxRelativeValue(double maxRelativeValue) { this.maxRelativeValue = maxRelativeValue; return this; } final public double getMaxRelativeValue() { return maxRelativeValue(); } public double maxRelativeValue() { return maxRelativeValue; } public double maxRelativeValue = negativeInfinity(); final public Position setMinRelativeValue(double minRelativeValue) { return minRelativeValue(minRelativeValue); } public Position minRelativeValue(double minRelativeValue) { this.minRelativeValue = minRelativeValue; return this; } final public double getMinRelativeValue() { return minRelativeValue(); } public double minRelativeValue() { return minRelativeValue; } public double minRelativeValue = infinity(); final public Position setPullbackThreshold(double pullbackThreshold) { return pullbackThreshold(pullbackThreshold); } public Position pullbackThreshold(double pullbackThreshold) { this.pullbackThreshold = pullbackThreshold; return this; } final public double getPullbackThreshold() { return pullbackThreshold(); } public double pullbackThreshold() { return pullbackThreshold; } public double pullbackThreshold; final public Position setCloseReason(CloseReason closeReason) { return closeReason(closeReason); } public Position closeReason(CloseReason closeReason) { this.closeReason = closeReason; return this; } final public CloseReason getCloseReason() { return closeReason(); } public CloseReason closeReason() { return closeReason; } public CloseReason closeReason; public PositionSet motherList() { return real ? realPositions : imaginaryPositions; } public void close(CloseReason reason) { closingTime(time()); closingPrice(cryptoPrice); closeReason(reason); motherList().wasClosed(this); } public void imagine() { real(false); launch(); } public void launch() { update(cryptoPrice); motherList().add(this); } public void update(double cryptoPrice) { lastPrice(cryptoPrice); relativeValue((cryptoPrice / openingPriceWithFeesAndSlippage() - 1) * direction * 100); maxRelativeValue(max(maxRelativeValue, relativeValue)); minRelativeValue(min(minRelativeValue, relativeValue)); pullbackThreshold(maxRelativeValue - pullback(this)); } public String toString() { return renderVars("direction", direction, "openingPrice", openingPrice, "openingPriceWithFeesAndSlippage", openingPriceWithFeesAndSlippage(), "lastPrice", lastPrice, "relativeValue", relativeValue, "maxRelativeValue", maxRelativeValue); } public void autoClose() { if (relativeValue < -maxAllowedLoss) { close(new LossClose()); return; } if (relativeValue >= 0 && relativeValue < pullbackThreshold) { close(new RegularClose()); return; } } public boolean isOpen() { return closeReason == null; } } public class PositionSet { public LinkedHashSet positionsByDate = new LinkedHashSet(); public LinkedHashSet openPositions = new LinkedHashSet(); public LinkedHashSet closedPositions = new LinkedHashSet(); public void add(Position p) { positionsByDate.add(p); (p.isOpen() ? openPositions : closedPositions).add(p); } public void remove(Position p) { positionsByDate.remove(p); openPositions.remove(p); closedPositions.remove(p); } public void wasClosed(Position p) { openPositions.remove(p); closedPositions.add(p); } } transient public IF1 pullback; public double pullback(Position p) { return pullback != null ? pullback.get(p) : pullback_base(p); } final public double pullback_fallback(IF1 _f, Position p) { return _f != null ? _f.get(p) : pullback_base(p); } public double pullback_base(Position p) { return 0.5; } public double time() { return currentTime; } public void addTickerSequence(TickerSequence ts) { int n = l(ts); for (int i = 0; i < n; i++) newCryptoPrice(ts.prices.get(i), ts.timestamps.get(i)); } public void newCryptoPrice(double price) { newCryptoPrice(price, currentTime + 1); } public void newCryptoPrice(double price, double time) { currentTime(time); if (price == cryptoPrice) return; int direction = sign(cryptoPrice - price); cryptoPriceLog.add(price); cryptoPrice(price); for (var p : allOpenPositions()) { p.update(cryptoPrice); p.autoClose(); } if (direction != cryptoDirection) { cryptoDirection(direction); cryptoDirectionChanged(); } } public List allPositions() { return concatLists(realPositions().positionsByDate, imaginaryPositions().positionsByDate); } public List allOpenPositions() { return concatLists(realPositions().openPositions, imaginaryPositions().openPositions); } { init(); } public void init() { onCryptoDirectionChanged(() -> { for (var p : ll(newLong(), newShort())) p.openingTime(time()).openingPrice(cryptoPrice).imagine(); }); } public void printStatus() { print(toString()); } public String toString() { return combineWithSeparator(" + ", n2(realPositions.positionsByDate, "real position"), n2(imaginaryPositions.positionsByDate, "imaginary position")); } } static public class G22ProjectInfo extends Concept { static final public String _fieldOrder = "projectID projectDir defaultMaskSize compilationDate historicalProjectDirs useFirefox"; final public String getProjectID() { return projectID(); } public String projectID() { return projectID; } public String projectID = aGlobalID(); public File projectDir; final public G22MaskSize getDefaultMaskSize() { return defaultMaskSize(); } public G22MaskSize defaultMaskSize() { return defaultMaskSize; } public G22MaskSize defaultMaskSize = new G22MaskSize(); public String compilationDate; public List historicalProjectDirs = new ArrayList(); final public boolean getUseFirefox() { return useFirefox(); } public boolean useFirefox() { return useFirefox; } public boolean useFirefox = false; public void addHistoricalProjectDir(File dir) { if (syncSetAdd(historicalProjectDirs, dir)) change(); } } public interface G22ProjectActions { public void openObjectInProject(long id); public boolean openPathInProject(String path); public void editProjectStory(); public void editScripts(); public void editScript(G22LeftArrowScript script); public void openUIURL(String url); public IVarWithNotify varShowCasedScript(); public G22DatabasesPanel databasesPanel(); public void closeProject(); public G22Utils g22utils(); public DynamicVStack topStack(); public void saveAsNewScript(String text); public Set projectLibs(); public G22SelfTests selfTests(); public List projectErrors(); public void goToSource(TokenRangeWithSrc src); } static public class G22VisualizeMeshes implements IFieldsToList { public WidthAndHeight originalImage; public List meshes; public G22VisualizeMeshes() { } public G22VisualizeMeshes(WidthAndHeight originalImage, List meshes) { this.meshes = meshes; this.originalImage = originalImage; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + originalImage + ", " + meshes + ")"; } public Object[] _fieldsToList() { return new Object[] { originalImage, meshes }; } final public G22VisualizeMeshes setAnchorColor(Color anchorColor) { return anchorColor(anchorColor); } public G22VisualizeMeshes anchorColor(Color anchorColor) { this.anchorColor = anchorColor; return this; } final public Color getAnchorColor() { return anchorColor(); } public Color anchorColor() { return anchorColor; } public Color anchorColor = withAlpha(0.5, Color.red); final public G22VisualizeMeshes setAnchorSize(int anchorSize) { return anchorSize(anchorSize); } public G22VisualizeMeshes anchorSize(int anchorSize) { this.anchorSize = anchorSize; return this; } final public int getAnchorSize() { return anchorSize(); } public int anchorSize() { return anchorSize; } public int anchorSize = 5; final public G22VisualizeMeshes setCurveColor(Color curveColor) { return curveColor(curveColor); } public G22VisualizeMeshes curveColor(Color curveColor) { this.curveColor = curveColor; return this; } final public Color getCurveColor() { return curveColor(); } public Color curveColor() { return curveColor; } public Color curveColor = Color.blue; public BufferedImage get() { var markedImage = whiteImage(imageSize(originalImage)); drawOn(createGraphics(markedImage)); return markedImage; } public void drawOn(Graphics2D g) { for (var mesh : meshes) for (var curve : mesh.curves()) drawCurve(g, curve); for (var mesh : meshes) for (var p : mesh.anchorPts()) drawAnchor(g, p); } public void drawCurve(Graphics2D g, G22Mesh.Curve curve) { drawPixels(g, curve.path().pointIterator(), curveColor); } public void drawAnchor(Graphics2D g, Pt p) { fillRect(g, p.x - anchorSize / 2, p.y - anchorSize / 2, anchorSize, anchorSize, anchorColor); } } static public class JOnDemandWithReloadButton implements Swingable, IFieldsToList { public IF0 makeComponent; public JOnDemandWithReloadButton() { } public JOnDemandWithReloadButton(IF0 makeComponent) { this.makeComponent = makeComponent; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + makeComponent + ")"; } public Object[] _fieldsToList() { return new Object[] { makeComponent }; } public SingleComponentPanel scp = singleComponentPanel(); public ReliableSingleThread rstReload = rst(() -> reloadImpl()); public JButton btnReload; final public JOnDemandWithReloadButton setControls(JPanel controls) { return controls(controls); } public JOnDemandWithReloadButton controls(JPanel controls) { this.controls = controls; return this; } final public JPanel getControls() { return controls(); } public JPanel controls() { return controls; } public JPanel controls = rightAlignedLine(); public SingleComponentPanel scpControlsMain = scp(); final public JOnDemandWithReloadButton setLoadingScreenWhenReloading(boolean loadingScreenWhenReloading) { return loadingScreenWhenReloading(loadingScreenWhenReloading); } public JOnDemandWithReloadButton loadingScreenWhenReloading(boolean loadingScreenWhenReloading) { this.loadingScreenWhenReloading = loadingScreenWhenReloading; return this; } final public boolean getLoadingScreenWhenReloading() { return loadingScreenWhenReloading(); } public boolean loadingScreenWhenReloading() { return loadingScreenWhenReloading; } public boolean loadingScreenWhenReloading = false; final public JOnDemandWithReloadButton setShowControls(boolean showControls) { return showControls(showControls); } public JOnDemandWithReloadButton showControls(boolean showControls) { this.showControls = showControls; return this; } final public boolean getShowControls() { return showControls(); } public boolean showControls() { return showControls; } public boolean showControls = true; public void reload() { rstReload.trigger(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { bindToComponent(scp, () -> { if (scp.isEmpty()) reload(); }, null); if (!showControls) return scp; makeControls(); return northAndCenter(withMargin(centerAndEastWithMargin(scpControlsMain, controls)), scp); } public void makeControls() { if (!showControls) return; btnReload = jReloadButton(() -> reload()); controls.add(btnReload); } public void reloadImpl() { AutoCloseable __1 = tempDisableButton(btnReload); try { if (loadingScreenWhenReloading() || !scp.hasComponent()) scp.setComponent(jCenteredLabel("Loading...")); try { scp.setComponent(makeComponent == null ? null : makeComponent.get()); } catch (Throwable e) { printStackTrace(e); scp.setComponent(jscroll(jFastLogView_noWrap(renderStackTrace(e)))); } } finally { _close(__1); } } public JOnDemandWithReloadButton function(IF0 f) { makeComponent = () -> wrap(f == null ? null : f.get()); return this; } } static public class G22NetworksPanel extends G22CRUDAndDetailPanel { public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22Network.class); crud.iconButtons(true); crud.excludeFieldsFromEditing("elements"); crud.createDuplicate = network -> (G22Network) g22utils.restructure(network); crud.entityName = () -> "Network"; crud.addButton(new JPopDownButton().content("Browse networks in other projects", (Runnable) () -> g22utils.openUIURL("Networks from all projects")).visualize()); return crud; } public JComponent makeDetailView(G22Network network) { return new JG22Network(g22utils, network).visualize(); } public SimpleCRUD_v2 networkCRUD() { return crud(); } public G22NetworksPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } } static public class G22TickerFile extends ConceptWithChangeListeners { static final public String _fieldOrder = "file creationDate modificationDate fileSize format markets timeRanges dateAnalyzed slowAnalysis"; public transient FieldVar varFile_cache; public FieldVar varFile() { if (varFile_cache == null) varFile_cache = varFile_load(); return varFile_cache; } public FieldVar varFile_load() { return new FieldVar(this, "file", () -> file(), file -> file(file)); } final public G22TickerFile setFile(File file) { return file(file); } public G22TickerFile file(File file) { if (!eq(this.file, file)) { this.file = file; change(); } return this; } final public File getFile() { return file(); } public File file() { return file; } public File file; public transient FieldVar varCreationDate_cache; public FieldVar varCreationDate() { if (varCreationDate_cache == null) varCreationDate_cache = varCreationDate_load(); return varCreationDate_cache; } public FieldVar varCreationDate_load() { return new FieldVar(this, "creationDate", () -> creationDate(), creationDate -> creationDate(creationDate)); } final public G22TickerFile setCreationDate(Timestamp creationDate) { return creationDate(creationDate); } public G22TickerFile creationDate(Timestamp creationDate) { if (!eq(this.creationDate, creationDate)) { this.creationDate = creationDate; change(); } return this; } final public Timestamp getCreationDate() { return creationDate(); } public Timestamp creationDate() { return creationDate; } public Timestamp creationDate; public transient FieldVar varModificationDate_cache; public FieldVar varModificationDate() { if (varModificationDate_cache == null) varModificationDate_cache = varModificationDate_load(); return varModificationDate_cache; } public FieldVar varModificationDate_load() { return new FieldVar(this, "modificationDate", () -> modificationDate(), modificationDate -> modificationDate(modificationDate)); } final public G22TickerFile setModificationDate(Timestamp modificationDate) { return modificationDate(modificationDate); } public G22TickerFile modificationDate(Timestamp modificationDate) { if (!eq(this.modificationDate, modificationDate)) { this.modificationDate = modificationDate; change(); } return this; } final public Timestamp getModificationDate() { return modificationDate(); } public Timestamp modificationDate() { return modificationDate; } public Timestamp modificationDate; public transient FieldVar varFileSize_cache; public FieldVar varFileSize() { if (varFileSize_cache == null) varFileSize_cache = varFileSize_load(); return varFileSize_cache; } public FieldVar varFileSize_load() { return new FieldVar(this, "fileSize", () -> fileSize(), fileSize -> fileSize(fileSize)); } final public G22TickerFile setFileSize(Long fileSize) { return fileSize(fileSize); } public G22TickerFile fileSize(Long fileSize) { if (!eq(this.fileSize, fileSize)) { this.fileSize = fileSize; change(); } return this; } final public Long getFileSize() { return fileSize(); } public Long fileSize() { return fileSize; } public Long fileSize; public transient FieldVar varFormat_cache; public FieldVar varFormat() { if (varFormat_cache == null) varFormat_cache = varFormat_load(); return varFormat_cache; } public FieldVar varFormat_load() { return new FieldVar(this, "format", () -> format(), format -> format(format)); } final public G22TickerFile setFormat(String format) { return format(format); } public G22TickerFile format(String format) { if (!eq(this.format, format)) { this.format = format; change(); } return this; } final public String getFormat() { return format(); } public String format() { return format; } public String format; public transient FieldVar> varMarkets_cache; public FieldVar> varMarkets() { if (varMarkets_cache == null) varMarkets_cache = varMarkets_load(); return varMarkets_cache; } public FieldVar> varMarkets_load() { return new FieldVar>(this, "markets", () -> markets(), markets -> markets(markets)); } final public G22TickerFile setMarkets(Collection markets) { return markets(markets); } public G22TickerFile markets(Collection markets) { if (!eq(this.markets, markets)) { this.markets = markets; change(); } return this; } final public Collection getMarkets() { return markets(); } public Collection markets() { return markets; } public Collection markets; public transient FieldVar> varTimeRanges_cache; public FieldVar> varTimeRanges() { if (varTimeRanges_cache == null) varTimeRanges_cache = varTimeRanges_load(); return varTimeRanges_cache; } public FieldVar> varTimeRanges_load() { return new FieldVar>(this, "timeRanges", () -> timeRanges(), timeRanges -> timeRanges(timeRanges)); } final public G22TickerFile setTimeRanges(List timeRanges) { return timeRanges(timeRanges); } public G22TickerFile timeRanges(List timeRanges) { if (!eq(this.timeRanges, timeRanges)) { this.timeRanges = timeRanges; change(); } return this; } final public List getTimeRanges() { return timeRanges(); } public List timeRanges() { return timeRanges; } public List timeRanges; public transient FieldVar varDateAnalyzed_cache; public FieldVar varDateAnalyzed() { if (varDateAnalyzed_cache == null) varDateAnalyzed_cache = varDateAnalyzed_load(); return varDateAnalyzed_cache; } public FieldVar varDateAnalyzed_load() { return new FieldVar(this, "dateAnalyzed", () -> dateAnalyzed(), dateAnalyzed -> dateAnalyzed(dateAnalyzed)); } final public G22TickerFile setDateAnalyzed(Timestamp dateAnalyzed) { return dateAnalyzed(dateAnalyzed); } public G22TickerFile dateAnalyzed(Timestamp dateAnalyzed) { if (!eq(this.dateAnalyzed, dateAnalyzed)) { this.dateAnalyzed = dateAnalyzed; change(); } return this; } final public Timestamp getDateAnalyzed() { return dateAnalyzed(); } public Timestamp dateAnalyzed() { return dateAnalyzed; } public Timestamp dateAnalyzed; transient volatile public IVF1 slowAnalysis; public String toString() { return or(fileName(file), super.toString()); } } abstract static public class G22WatchTarget { public void mainWindow(Window window) { } abstract public void configureScreenCamStream(ScreenCamStream stream); public String toolTip() { return null; } } static public class WatchScreen extends G22WatchTarget implements IFieldsToList { public int screenNr; public WatchScreen() { } public WatchScreen(int screenNr) { this.screenNr = screenNr; } public boolean equals(Object o) { if (!(o instanceof WatchScreen)) return false; WatchScreen __1 = (WatchScreen) o; return screenNr == __1.screenNr; } public int hashCode() { int h = -1787428357; h = boostHashCombine(h, _hashCode(screenNr)); return h; } public Object[] _fieldsToList() { return new Object[] { screenNr }; } public String toString() { return "Screen " + screenNr; } public void configureScreenCamStream(ScreenCamStream stream) { stream.useScreen(screenNr - 1); } } static public class WatchMouse extends G22WatchTarget implements IFieldsToList { static final public String _fieldOrder = "width height"; public int width; public int height; public WatchMouse(int width, int height) { this.height = height; this.width = width; } public boolean equals(Object o) { if (!(o instanceof WatchMouse)) return false; WatchMouse __2 = (WatchMouse) o; return width == __2.width && height == __2.height; } public int hashCode() { int h = 1876823350; h = boostHashCombine(h, _hashCode(width)); h = boostHashCombine(h, _hashCode(height)); return h; } public Object[] _fieldsToList() { return new Object[] { width, height }; } public WatchMouse() { height = 256; width = iround(height * 16.0 / 9); } public String toString() { return "Mouse"; } public void configureScreenCamStream(ScreenCamStream stream) { stream.area(mouseArea(width, height)); } @Override public String toolTip() { return "Watch an area of " + str_px(width, height) + " around the mouse pointer"; } } static public class WatchScreenWithMouse extends G22WatchTarget implements IFieldsToList { public WatchScreenWithMouse() { } public boolean equals(Object o) { return o instanceof WatchScreenWithMouse; } public int hashCode() { int h = -1449766972; return h; } public Object[] _fieldsToList() { return null; } public String toString() { return "Screen w/mouse"; } public void configureScreenCamStream(ScreenCamStream stream) { stream.useScreen(screenNrContaining(mouseLocationPt())); } @Override public String toolTip() { return "Watch the screen the mouse pointer is in"; } } static public class WatchOtherScreen extends G22WatchTarget implements IFieldsToList { public WatchOtherScreen() { } public boolean equals(Object o) { return o instanceof WatchOtherScreen; } public int hashCode() { int h = 1734016877; return h; } public Object[] _fieldsToList() { return null; } public String toString() { return "Other Screen"; } final public void setMainWindow(Window mainWindow) { mainWindow(mainWindow); } public void mainWindow(Window mainWindow) { this.mainWindow = mainWindow; } final public Window getMainWindow() { return mainWindow(); } public Window mainWindow() { return mainWindow; } transient public Window mainWindow; public void configureScreenCamStream(ScreenCamStream stream) { stream.useScreen(mod(screenNrOfWindow(mainWindow) + 1, numberOfScreens())); } @Override public String toolTip() { return "Watch the first screen the Gazelle window is NOT in"; } } static public class SmoothLabel extends JLabel { public SmoothLabel() { } public SmoothLabel(String text) { super(text); } public SmoothLabel(Icon icon) { super(icon); } public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); super.paintComponent(g2d); } } static public class TunableParameters> { final public TunableParameters setScoreFunction(IF1, Sc> scoreFunction) { return scoreFunction(scoreFunction); } public TunableParameters scoreFunction(IF1, Sc> scoreFunction) { this.scoreFunction = scoreFunction; return this; } final public IF1, Sc> getScoreFunction() { return scoreFunction(); } public IF1, Sc> scoreFunction() { return scoreFunction; } public IF1, Sc> scoreFunction; final public GenericallyScored, Sc> getBest() { return best(); } public GenericallyScored, Sc> best() { return best; } public GenericallyScored, Sc> best; public LinkedHashMap parameters = new LinkedHashMap(); public List parameterList = new ArrayList(); final public long getInstancesTested() { return instancesTested(); } public long instancesTested() { return instancesTested; } volatile public long instancesTested; transient public Set, Sc>>> onNewBest; public TunableParameters onNewBest(IVF1, Sc>> f) { onNewBest = createOrAddToSyncLinkedHashSet(onNewBest, f); return this; } public TunableParameters removeNewBestListener(IVF1, Sc>> f) { loadableUtils.utils.remove(onNewBest, f); return this; } public void newBest(GenericallyScored, Sc> instance) { if (onNewBest != null) for (var listener : onNewBest) pcallF_typed(listener, instance); } transient public Set, Sc>>> onInstanceScored; public TunableParameters onInstanceScored(IVF1, Sc>> f) { onInstanceScored = createOrAddToSyncLinkedHashSet(onInstanceScored, f); return this; } public TunableParameters removeInstanceScoredListener(IVF1, Sc>> f) { loadableUtils.utils.remove(onInstanceScored, f); return this; } public void fireInstanceScored(GenericallyScored, Sc> scored) { if (onInstanceScored != null) for (var listener : onInstanceScored) pcallF_typed(listener, scored); } abstract public class Parameter { final public Parameter setName(String name) { return name(name); } public Parameter name(String name) { this.name = name; return this; } final public String getName() { return name(); } public String name() { return name; } public String name; final public Parameter setDefaultValue(A defaultValue) { return defaultValue(defaultValue); } public Parameter defaultValue(A defaultValue) { this.defaultValue = defaultValue; return this; } final public A getDefaultValue() { return defaultValue(); } public A defaultValue() { return defaultValue; } public A defaultValue; abstract public A randomValue(); public A get(Map instance) { return (A) instance.get(name); } } public class IntRangeParameter extends Parameter { final public IntRangeParameter setRange(IntRange range) { return range(range); } public IntRangeParameter range(IntRange range) { this.range = range; return this; } final public IntRange getRange() { return range(); } public IntRange range() { return range; } public IntRange range; public Integer randomValue() { return random(range); } } public class DoubleRangeParameter extends Parameter { final public DoubleRangeParameter setRange(DoubleRange range) { return range(range); } public DoubleRangeParameter range(DoubleRange range) { this.range = range; return this; } final public DoubleRange getRange() { return range(); } public DoubleRange range() { return range; } public DoubleRange range; public Double randomValue() { return random(range); } } public TunableParameters add(Parameter p) { parameters.put(p.name(), p); parameterList.add(p); return this; } public Map randomInstance() { Map map = new LinkedHashMap(); for (var param : parameterList) map.put(param.name(), param.randomValue()); return map; } public GenericallyScored, Sc> tryARandomCombination() { return tryInstance(randomInstance()); } public List, Sc>> varyEachParameterOnce(Map instance) { if (instance == null) return null; List, Sc>> out = new ArrayList(); for (var param : parameterList) { Object value = param.randomValue(); if (eq(param.get(instance), value)) continue; Map instance2 = cloneMap(instance); instance2.put(param.name(), value); out.add(tryInstance(instance2)); } return out; } public Sc score(Map instance) { ++instancesTested; return scoreFunction.get(instance); } public GenericallyScored, Sc> scored(Map instance) { GenericallyScored, Sc> scored = new GenericallyScored<>(instance, score(instance)); fireInstanceScored(scored); return scored; } public GenericallyScored, Sc> tryInstance(Map instance) { GenericallyScored, Sc> scored = scored(instance); tryInstance(scored); return scored; } public void tryInstance(GenericallyScored, Sc> scored) { if (scored == null) return; if (best == null || cmp(scored.score(), best.score()) > 0) { best = scored; newBest(scored); } } public String toString() { return "Best: " + best + " (parameters: " + keys(parameters) + ")"; } } static public class TickerSequences implements ByteIO, IntSize { public TickerSequences() { } final public String getMarket() { return market(); } public String market() { return market; } public String market; final public List getTickers() { return tickers(); } public List tickers() { return tickers; } public List tickers = new ArrayList(); public TickerSequences(Iterable sequences) { loadableUtils.utils.addAll(tickers, sequences); } public TickerSequences(TickerSequence... sequences) { loadableUtils.utils.addAll(tickers, sequences); } public void add(TickerSequence ticker) { tickers.add(ticker); } public TickerSequence get(int i) { return tickers.get(i); } public void sort() { sortInPlaceByCalculatedField(tickers, __1 -> __1.startTime()); } public int size() { return tickers.size(); } public String toString() { return commaCombine(spaceCombine(n2(tickers, " ticker sequence"), empty(market) ? null : "for " + market), formatDays(totalTime()), n2(nPricePoints(), "price point")); } public long nPricePoints() { return longSum(map(tickers, t -> (long) t.size())); } public long totalTime() { return longSum(map(tickers, ticker -> { var tr = ticker.timeRange(); return tr == null ? 0 : tr.length(); })); } public TickerSequences dropOverlaps() { sort(); for (int i = 0; i + 1 < l(tickers); i++) { var t1 = tickers.get(i); var t2 = tickers.get(i + 1); long time2 = t2.startTime(); while (!t1.isEmpty() && t1.endTime() >= time2) t1.dropLastPricePoint(); t1.trimToSize(); } return this; } public TickerSequences merge() { return merge(120); } public TickerSequences merge(double maximumGapSeconds) { sort(); for (int i = 0; i + 1 < l(tickers); i++) { var t1 = tickers.get(i); var t2 = tickers.get(i + 1); if (t2.startTime() - t1.endTime() <= fromSeconds(maximumGapSeconds)) { t1.add(t2); tickers.remove(i + 1); --i; } } return this; } public double firstPrice() { var ticker = first(tickers); return ticker == null ? Double.NaN : ticker.firstPrice(); } public IterableIterator prices() { return nestedIterator(tickers, ticker -> ticker.prices.iterator()); } public long startTime() { return empty(tickers) ? null : first(tickers).startTime(); } public long endTime() { return empty(tickers) ? null : last(tickers).endTime(); } public TickerSequence longest() { return highestBy(tickers(), ticker -> duration(ticker.timeRange())); } public TickerSequences mapTickers(IF1 f) { TickerSequences ts = new TickerSequences(); for (var t : tickers()) ts.add(f.get(t)); return ts; } public TickerSequences filterTickers(IF1 pred) { TickerSequences ts = new TickerSequences(); for (var t : tickers()) if (pred.get(t)) ts.add(t); return ts; } public TickerSequences marketIfEmpty(String market) { if (empty(this.market)) market(market); return this; } public TickerSequences market(String market) { this.market = market; for (var t : tickers) t.market(market); return this; } public void write(ByteHead head) { for (var t : tickers) t.write(head); } public void read(ByteHead head) { TickerSequence t; while ((t = TickerSequence.read(head)) != null) add(t); if (empty(market) && nempty(tickers)) market(first(tickers).market); } public void readWrite(ByteHead head) { if (head.readMode()) read(head); if (head.writeMode()) write(head); } } static public class RSI extends CandleBasedIndicator { final public RSI setSmoothingPeriod(int smoothingPeriod) { return smoothingPeriod(smoothingPeriod); } public RSI smoothingPeriod(int smoothingPeriod) { this.smoothingPeriod = smoothingPeriod; return this; } final public int getSmoothingPeriod() { return smoothingPeriod(); } public int smoothingPeriod() { return smoothingPeriod; } public int smoothingPeriod = 14; final public RSI setUpSum(double upSum) { return upSum(upSum); } public RSI upSum(double upSum) { this.upSum = upSum; return this; } final public double getUpSum() { return upSum(); } public double upSum() { return upSum; } public double upSum; final public RSI setDownSum(double downSum) { return downSum(downSum); } public RSI downSum(double downSum) { this.downSum = downSum; return this; } final public double getDownSum() { return downSum(); } public double downSum() { return downSum; } public double downSum; final public RSI setSteps(long steps) { return steps(steps); } public RSI steps(long steps) { this.steps = steps; return this; } final public long getSteps() { return steps(); } public long steps() { return steps; } public long steps; final public RSI setUp(SmoothedMovingAverage up) { return up(up); } public RSI up(SmoothedMovingAverage up) { this.up = up; return this; } final public SmoothedMovingAverage getUp() { return up(); } public SmoothedMovingAverage up() { return up; } public SmoothedMovingAverage up; final public RSI setDown(SmoothedMovingAverage down) { return down(down); } public RSI down(SmoothedMovingAverage down) { this.down = down; return this; } final public SmoothedMovingAverage getDown() { return down(); } public SmoothedMovingAverage down() { return down; } public SmoothedMovingAverage down; final public RSI setPostSmoother(SimpleMovingAverage postSmoother) { return postSmoother(postSmoother); } public RSI postSmoother(SimpleMovingAverage postSmoother) { this.postSmoother = postSmoother; return this; } final public SimpleMovingAverage getPostSmoother() { return postSmoother(); } public SimpleMovingAverage postSmoother() { return postSmoother; } public SimpleMovingAverage postSmoother; final public RSI setRsi(double rsi) { return rsi(rsi); } public RSI rsi(double rsi) { this.rsi = rsi; return this; } final public double getRsi() { return rsi(); } public double rsi() { return rsi; } public double rsi = Double.NaN; final public RSI setRsiSmoothed(double rsiSmoothed) { return rsiSmoothed(rsiSmoothed); } public RSI rsiSmoothed(double rsiSmoothed) { this.rsiSmoothed = rsiSmoothed; return this; } final public double getRsiSmoothed() { return rsiSmoothed(); } public double rsiSmoothed() { return rsiSmoothed; } public double rsiSmoothed = Double.NaN; final public TickerSequence getRsiHistory() { return rsiHistory(); } public TickerSequence rsiHistory() { return rsiHistory; } public TickerSequence rsiHistory = new TickerSequence("RSI"); final public TickerSequence getRsiSmoothedHistory() { return rsiSmoothedHistory(); } public TickerSequence rsiSmoothedHistory() { return rsiSmoothedHistory; } public TickerSequence rsiSmoothedHistory = new TickerSequence("RSI Smoothed"); public Double value() { return rsiSmoothed(); } public boolean complete() { return steps >= length(); } { length = 25; onCandleAdded((IVF1) candle -> { var x = candle.move(); var u = max(x, 0.0); var d = neg(min(x, 0.0)); if (!complete()) { upSum += u; downSum += d; } else { if (up == null) { up = new SmoothedMovingAverage(length()); down = new SmoothedMovingAverage(length()); up.add(upSum / steps); down.add(downSum / steps); } else { up().add(u); down().add(d); } var rs = div(up().get(), down().get()); rsi(100 - 100 / (1 + rs)); long time = candle.endTime().toLong(); { if (rsiHistory != null) rsiHistory.addIfPriceChanged(rsi, time); } if (postSmoother == null) postSmoother = new SimpleMovingAverage(smoothingPeriod); postSmoother.add(rsi); rsiSmoothed(postSmoother.get()); { if (rsiSmoothedHistory != null) rsiSmoothedHistory.addIfPriceChanged(rsiSmoothed, time); } } ++steps; }); } public TickerSequence asTicker(List candles) { feed(candles); return rsiHistory; } public void reset() { super.reset(); resetFields(this, "upSum downSum steps up down postSmoother rsi rsiSmoothed rsiHistory rsiSmoothedHistory"); } } static public class G22CriticalPixelSearch implements Steppable { final public G22CriticalPixelSearch setMasksHolder(IG22MasksHolder masksHolder) { return masksHolder(masksHolder); } public G22CriticalPixelSearch masksHolder(IG22MasksHolder masksHolder) { this.masksHolder = masksHolder; return this; } final public IG22MasksHolder getMasksHolder() { return masksHolder(); } public IG22MasksHolder masksHolder() { return masksHolder; } public IG22MasksHolder masksHolder; final public G22CriticalPixelSearch setKeepAllEntries(boolean keepAllEntries) { return keepAllEntries(keepAllEntries); } public G22CriticalPixelSearch keepAllEntries(boolean keepAllEntries) { this.keepAllEntries = keepAllEntries; return this; } final public boolean getKeepAllEntries() { return keepAllEntries(); } public boolean keepAllEntries() { return keepAllEntries; } public boolean keepAllEntries = false; final public G22CriticalPixelSearch setSortPixelsFirst(boolean sortPixelsFirst) { return sortPixelsFirst(sortPixelsFirst); } public G22CriticalPixelSearch sortPixelsFirst(boolean sortPixelsFirst) { this.sortPixelsFirst = sortPixelsFirst; return this; } final public boolean getSortPixelsFirst() { return sortPixelsFirst(); } public boolean sortPixelsFirst() { return sortPixelsFirst; } public boolean sortPixelsFirst = true; public int w, h; public Iterator pixelIterator; public Best bestPixel = new Best(); public Entry bestEntry; public Pt lastPixelLookedAt; public Entry lastEntry; public Entry[] pixelEntries; public float[] pixelScores; public int nPixelsTested; public CompactHashSet subSets; public G22CriticalPixelSearch() { } public G22CriticalPixelSearch(IG22MasksHolder masksHolder) { this.masksHolder = masksHolder; } public class Entry { public Pt pixel; final public List getDarkMasks() { return darkMasks(); } public List darkMasks() { return darkMasks; } public List darkMasks; final public List getBrightMasks() { return brightMasks(); } public List brightMasks() { return brightMasks; } public List brightMasks; public G22GhostImage darkGhost; public G22GhostImage brightGhost; public IG22MasksHolder darkHolder_cache; public IG22MasksHolder darkHolder() { if (darkHolder_cache == null) darkHolder_cache = darkHolder_load(); return darkHolder_cache; } public IG22MasksHolder darkHolder_load() { return new G22HashedMasks(darkMasks, darkGhost); } public IG22MasksHolder brightHolder_cache; public IG22MasksHolder brightHolder() { if (brightHolder_cache == null) brightHolder_cache = brightHolder_load(); return brightHolder_cache; } public IG22MasksHolder brightHolder_load() { return new G22HashedMasks(brightMasks, brightGhost); } public void calcGhosts() { if (l(darkMasks) < l(brightMasks)) { darkGhost = new G22GhostImage(lmapMethod(__123 -> __123.image(), darkMasks)); brightGhost = masksHolder().ghost().minus(darkGhost); } else { brightGhost = new G22GhostImage(lmapMethod(__124 -> __124.image(), brightMasks)); darkGhost = masksHolder().ghost().minus(brightGhost); } } public String toString() { return commaCombine("Split at " + pixel, "dark=" + darkHolder().renderCountAndCertainty(), "bright=" + brightHolder().renderCountAndCertainty()); } } public boolean step() { if (w == 0) { if (!masksHolder.canSplit()) return false; w = masksHolder.maskSize().w(); h = masksHolder.maskSize().h(); pixelEntries = new Entry[w * h]; pixelScores = new float[w * h]; arrayfill(pixelScores, -1); pixelIterator = makePixelIterator(); } if (!pixelIterator.hasNext()) return false; lastPixelLookedAt = pixelIterator.next(); testPixel(lastPixelLookedAt); return true; } public int idx(Pt p) { return p.y * w + p.x; } public void testPixel(Pt p) { double score; Entry e = null; ++nPixelsTested; float ghostBrightness = masksHolder.ghost().getFloatPixel(p); if (ghostBrightness == 0 || ghostBrightness == 1) score = -2; else { e = new Entry(); e.pixel = p; lastEntry = e; if (keepAllEntries) pixelEntries[idx(p)] = e; List masks = wideningListCast(masksHolder.masks()); int n = l(masks); byte[] brightBits = byteArrayForNBits(n); for (int i = 0; i < n; i++) if (masks.get(i).image().getBoolPixel(p)) setBit(brightBits, i); { if (subSets != null) subSets.add(new HashedByteArray(brightBits)); } var splitMasks = filterAntiFilterByBitSet(masks, brightBits); e.brightMasks = splitMasks.a; e.darkMasks = splitMasks.b; e.calcGhosts(); score = scoreEntry(e); } pixelScores[idx(p)] = (float) score; if (score > 0 && bestPixel.put(p, score)) bestEntry = e; } transient public IF1 scoreEntry; public double scoreEntry(Entry e) { return scoreEntry != null ? scoreEntry.get(e) : scoreEntry_base(e); } final public double scoreEntry_fallback(IF1 _f, Entry e) { return _f != null ? _f.get(e) : scoreEntry_base(e); } public double scoreEntry_base(Entry e) { double c1 = e.darkGhost.certainty(); double c2 = e.brightGhost.certainty(); return min(c1, c2); } public double bestScore() { return bestPixel.score(); } public BWImage scoreImage() { double min = masksHolder.certainty(); double max = bestPixel.score(); return bwImageFromFunction(w, h, (x, y) -> transformToZeroToOne(pixelScores[y * w + x], max, min)); } public G22PixelSplitMasks splitMasksHolder() { if (!bestPixel.has()) return null; return new G22PixelSplitMasks().splitPixel(bestPixel.get()).darkHolder(bestEntry.darkHolder()).brightHolder(bestEntry.brightHolder()); } final public IG22MasksHolder bestTree() { return makeBestTree(); } public IG22MasksHolder makeBestTree() { stepAll(this); G22PixelSplitMasks split = splitMasksHolder(); if (split == null) return masksHolder; split.transformSubHolders(subHolder -> new G22CriticalPixelSearch(subHolder).makeBestTree()); return split; } public void collectSubSets() { if (subSets == null) subSets = new CompactHashSet(); } public Iterator makePixelIterator() { if (sortPixelsFirst) return iterator(pixelsByBrightness(masksHolder().ghost().certaintyImage())); else return new WeightlessShuffledIterator(pixelsInImage(w, h)); } } static public class G22TravelLogPanel implements Swingable, IFieldsToList { public G22Utils g22utils; public G22TravelLogPanel() { } public G22TravelLogPanel(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public SimpleCRUD_v2 crud; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { crud = new SimpleCRUD_v2(g22utils.concepts(), G22TravelLogEntry.class); return jCenteredSection("Project Travel Log [" + g22utils.projectName() + "]", crud.visualize()); } } static public class TreeSetWithChangeListeners extends SetWithChangeListeners { public TreeSetWithChangeListeners() { super(new TreeSet()); } } static public class GazAICredentials { final public GazAICredentials setUser(String user) { return user(user); } public GazAICredentials user(String user) { this.user = user; return this; } final public String getUser() { return user(); } public String user() { return user; } public String user; final public GazAICredentials setPassword(String password) { return password(password); } public GazAICredentials password(String password) { this.password = password; return this; } final public String getPassword() { return password(); } public String password() { return password; } public String password; public String toString() { return joinNempties(" with ", shortClassName(this), nempty(user) ? "user " + user : null, nempty(password) ? "password" : null); } static public GazAICredentials fromFile(File f) { var credMap = parseColonPropertyCIMap(loadTextFile(f)); var cred = new GazAICredentials(); cred.user(credMap.get("user")); cred.password(credMap.get("password")); return cred; } public void save(File f) { saveTextFile(f, formatColonProperties(litorderedmap("user", user, "password", password))); } public Map asParams() { return litorderedmap("user", user, "pw", password); } } static public class G22ScriptsFromAllDBsPanel { public G22Utils g22utils; public JObjectTable table; public ReliableSingleThread rstUpdate = new ReliableSingleThread(new Runnable() { public void run() { try { _updateTable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_updateTable();"; } }); transient public SingleComponentPanel scpDetail = singleComponentPanel(); public G22ScriptsFromAllDBsPanel(G22Utils g22utils) { this.g22utils = g22utils; } public JComponent visualize() { table = new JObjectTable(); table.itemToMap = (script) -> { return joinMaps(litorderedmap("Project", fileName(scriptToDBDir(script)), "ID", str(script.id)), g22utils.scriptToMap(script)); }; var tbl = table.visualize(); rstUpdate.get(); tablePopupMenuItem_top(table.table, "Open database", runnableThread(new Runnable() { public void run() { try { g22utils.masterStuff.openDatabase(table.selected()._concepts.conceptsDir()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.masterStuff.openDatabase(table.selected()._concepts.conceptsDir());"; } })); table.onSelect(script -> { if (script == null) scpDetail.clear(); else { var tabs = jtabs(); String editedText = script.editedText(); if (editedText != null) addTab(tabs, "Editing", makeDisabledTextArea(editedText)); if (script.text != null) addTab(tabs, "Saved", makeDisabledTextArea(script.text)); String codeForAutoRun = script.codeForAutoRun(); if (codeForAutoRun != null) addTab(tabs, "Clear for auto-run", makeDisabledTextArea(codeForAutoRun)); scpDetail.set(tabs); } }); return withTopAndBottomMargin(jCenteredRaisedSection("Scripts from all databases", jvsplit(withRightAlignedButtons(tbl, "Show all scripts as one long text", runnableThread(new Runnable() { public void run() { try { showHugeText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showHugeText();"; } })), scpDetail))); } public File scriptToDBDir(G22LeftArrowScript script) { return script == null ? null : script._concepts.conceptsDir(); } public JComponent makeDisabledTextArea(String text) { var ta = g22utils.newSyntaxTextArea(); ta.setText(text); uneditableBlack(ta.textArea()); return ta.visualize(); } public void _updateTable() { table.setData_force(concatLists(mapCloseables_pcall(g22utils.peekAllProjectsConcepts(), cc -> list(cc, G22LeftArrowScript.class)))); } public String makeHugeText() { return g22utils.evalRegisteredCode("Make text from all scripts", () -> { rstUpdate.waitUntilDone(); return new G22ScriptUtil(g22utils).makeHugeText(table.getList()); }); } public void showHugeText() { String text = makeHugeText(); showFrame("Scripts from all DBs", g22utils.newSyntaxTextArea(text)); } } static public class SignalWithStrength { public SignalWithStrength() { } final public SignalWithStrength setType(String type) { return type(type); } public SignalWithStrength type(String type) { this.type = type; return this; } final public String getType() { return type(); } public String type() { return type; } public String type; final public SignalWithStrength setReason(String reason) { return reason(reason); } public SignalWithStrength reason(String reason) { this.reason = reason; return this; } final public String getReason() { return reason(); } public String reason() { return reason; } public String reason; final public SignalWithStrength setStrength(double strength) { return strength(strength); } public SignalWithStrength strength(double strength) { this.strength = strength; return this; } final public double getStrength() { return strength(); } public double strength() { return strength; } public double strength; final public SignalWithStrength setCreatedBy(Object createdBy) { return createdBy(createdBy); } public SignalWithStrength createdBy(Object createdBy) { this.createdBy = createdBy; return this; } final public Object getCreatedBy() { return createdBy(); } public Object createdBy() { return createdBy; } public Object createdBy; public String toString() { return or2(type, "Unspecified ") + " signal " + appendRoundBracketed(commaCombine(reason, iround(strength) + "%")); } public boolean isTrigger() { return strength >= 100; } public boolean nonNegative() { return strength >= 0; } public boolean positive() { return strength > 0; } } static public class JLeftArrowScriptIDE extends MetaWithChangeListeners implements Swingable { final public JLeftArrowScriptIDE setLvScript(IVarWithNotify lvScript) { return lvScript(lvScript); } public JLeftArrowScriptIDE lvScript(IVarWithNotify lvScript) { this.lvScript = lvScript; return this; } final public IVarWithNotify getLvScript() { return lvScript(); } public IVarWithNotify lvScript() { return lvScript; } public IVarWithNotify lvScript = stringLiveValue(); final public JLeftArrowScriptIDE setSectionTitle(String sectionTitle) { return sectionTitle(sectionTitle); } public JLeftArrowScriptIDE sectionTitle(String sectionTitle) { this.sectionTitle = sectionTitle; return this; } final public String getSectionTitle() { return sectionTitle(); } public String sectionTitle() { return sectionTitle; } public String sectionTitle = "Left arrow script"; final public JLeftArrowScriptIDE setWithResultPanel(boolean withResultPanel) { return withResultPanel(withResultPanel); } public JLeftArrowScriptIDE withResultPanel(boolean withResultPanel) { this.withResultPanel = withResultPanel; return this; } final public boolean getWithResultPanel() { return withResultPanel(); } public boolean withResultPanel() { return withResultPanel; } public boolean withResultPanel = true; final public JLeftArrowScriptIDE setCompileDelay(double compileDelay) { return compileDelay(compileDelay); } public JLeftArrowScriptIDE compileDelay(double compileDelay) { this.compileDelay = compileDelay; return this; } final public double getCompileDelay() { return compileDelay(); } public double compileDelay() { return compileDelay; } public double compileDelay = 0.1; static public String helpText = "Gazelle 22 \"Left Arrow Script\"\r\n------------------------------\r\n\r\n\"Left arrow script\" is one of Gazelle 22's two scripting languages. It is the powerful one of the two. It can do anything Java can do except for defining classes or lambdas.\r\n\r\n-Usually, you write one command per line\r\n-Each command contains at most one action and at most one assignment\r\n-The language is case-sensitive\r\n-You can add comments like in Java with /* */ or //\r\n-You can write multiple commands in one line by separating them with a semicolon\r\n-Arguments to functions are separated by spaces\r\n-You can use integer and string literals like in Java\r\n-You can use true, false and null\r\n\r\nIt's called \"left arrow script\" because the left arrow (variable assignment) is its only actual operator (not counting ; and {}).\r\n\r\n\r\nOperations\r\n----------\r\n\r\nYou can call any global function defined in Gazelle. Example:\r\n\r\n infoBox \"hello\" // show a popup with the text \"hello\"\r\n \r\nYou can assign the result of a function call to a variable:\r\n\r\n time <- tsNow // get current time as a Timestamp object\r\n infoBox time // show as popup\r\n \r\nNote that this script requires 2 lines because only one operation is allowed per command.\r\n \r\nVariables can be overwritten and don't have to be declared.\r\n\r\n\r\nCreating objects\r\n----------------\r\n\r\nYou can create an instance of any Java class and call methods on the object:\r\n\r\n list <- new ArrayList\r\n list add \"hello\"\r\n list add \"world\"\r\n infoBox list // shows [hello, world]\r\n \r\n(Currently you can also say \"list <- ArrayList\", but this is ambiguous and may be removed in a future version.)\r\n \r\nYou can pass parameters to the constructor:\r\n\r\n pair <- new Pair \"hello\" \"world\"\r\n infoBox pair // shows \r\n \r\n\r\nJava operators (+, * etc)\r\n-------------------------\r\n \r\nJava operators can't be used directly but we have functions that do the same thing (if we don't, we'll add them):\r\n\r\n x <- plus 1 2\r\n infoBox x\r\n\r\n\r\nFunction definitions\r\n--------------------\r\n\r\nYou can define functions in your script, with arguments. The function can return a value (which is the result of the last command in the function).\r\n\r\n def doubleMe x { mul x 2 }\r\n\r\n x <- doubleMe 5\r\n infoBox x // shows 10\r\n"; public transient FieldVar varCompileResult_cache; public FieldVar varCompileResult() { if (varCompileResult_cache == null) varCompileResult_cache = varCompileResult_load(); return varCompileResult_cache; } public FieldVar varCompileResult_load() { return new FieldVar(this, "compileResult", () -> compileResult(), compileResult -> compileResult(compileResult)); } final public JLeftArrowScriptIDE setCompileResult(LASCompileResult compileResult) { return compileResult(compileResult); } public JLeftArrowScriptIDE compileResult(LASCompileResult compileResult) { if (!eq(this.compileResult, compileResult)) { this.compileResult = compileResult; change(); } return this; } final public LASCompileResult getCompileResult() { return compileResult(); } public LASCompileResult compileResult() { return compileResult; } transient public LASCompileResult compileResult; transient volatile public RSyntaxTextAreaWithSearch taScript; transient public RSTADummyParser dummyParser = new RSTADummyParser(); transient public ReliableSingleThread rstCompile = new ReliableSingleThread(() -> compile()); final public JPanel getButtons() { return buttons(); } public JPanel buttons() { return buttons; } transient public JPanel buttons = jline(); transient public JButton btnRun; transient public CollapsibleLeftPanel collapsibleResultPanel; transient public G22ScriptResultPanel resultPanel; transient public JPopDownButton popDownButton; transient public LeftArrowCompletionProvider completionProvider; final public JLeftArrowScriptIDE setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public JLeftArrowScriptIDE g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; final public JLeftArrowScriptIDE setScriptTimeout(double scriptTimeout) { return scriptTimeout(scriptTimeout); } public JLeftArrowScriptIDE scriptTimeout(double scriptTimeout) { this.scriptTimeout = scriptTimeout; return this; } final public double getScriptTimeout() { return scriptTimeout(); } public double scriptTimeout() { return scriptTimeout; } public double scriptTimeout = 10.0; final public JLeftArrowScriptIDE setShowTitle(boolean showTitle) { return showTitle(showTitle); } public JLeftArrowScriptIDE showTitle(boolean showTitle) { this.showTitle = showTitle; return this; } final public boolean getShowTitle() { return showTitle(); } public boolean showTitle() { return showTitle; } transient public boolean showTitle = true; final public JLeftArrowScriptIDE setSourceInfo(Object sourceInfo) { return sourceInfo(sourceInfo); } public JLeftArrowScriptIDE sourceInfo(Object sourceInfo) { this.sourceInfo = sourceInfo; return this; } final public Object getSourceInfo() { return sourceInfo(); } public Object sourceInfo() { return sourceInfo; } transient public Object sourceInfo; transient public Runnable rRecompileIfError = () -> recompileIfError(); transient public IF0 makeParser; public GazelleV_LeftArrowScriptParser makeParser() { return makeParser != null ? makeParser.get() : makeParser_base(); } final public GazelleV_LeftArrowScriptParser makeParser_fallback(IF0 _f) { return _f != null ? _f.get() : makeParser_base(); } public GazelleV_LeftArrowScriptParser makeParser_base() { return g22utils.leftArrowParser().sourceInfo(sourceInfo); } public interface GoToDefinitionHandler { public Runnable get(ListAndIndex tokPtr); } final public List getGoToDefinitionHandlers() { return goToDefinitionHandlers(); } public List goToDefinitionHandlers() { return goToDefinitionHandlers; } transient public List goToDefinitionHandlers = syncL(); public class LeftArrowCompletionProvider extends DefaultCompletionProvider { @Override public List getCompletionsImpl(JTextComponent comp) { try { String text = loadableUtils.utils.getText(comp); GazelleV_LeftArrowScriptParser parser = makeParser(); LeftArrowScriptAutoCompleter completer = new LeftArrowScriptAutoCompleter(g22utils, parser); completer.onAdaptingSearcher(() -> g22utils.addingAdditionalAutoCompletes(completer)); enableScaffolding(completer); completer.seek(text, getCaretPosition(comp)); return map(completer.searcher().withScores(), completion -> { BasicCompletion c = new BasicCompletion(this, completion.get()); c.setRelevance((int) completion.score()); return c; }); } catch (Throwable e) { printStackTrace(e); return ll(); } } } public void goToPosition_noFocus(LineAndColumn lineAndCol) { if (lineAndCol == null) return; try { moveCaretAndScroll(textArea(), lineAndCol); } catch (Throwable e) { print("Trying again: " + e); awtLater(1.0, () -> { moveCaretAndScroll(textArea(), lineAndCol); }); } } public void goToPosition(LineAndColumn lineAndCol) { focus(textArea()); goToPosition_noFocus(lineAndCol); } public JComponent wrapStatusLabel(JComponent lbl) { onLeftClick(lbl, () -> goToPosition(compileResult == null ? null : compileResult.errorLineAndCol())); popDownButton = swing(() -> new JPopDownButton("Help")); popDownButton.onFillingMenu(menu -> addMenuItems(menu, "Show Scripting Help", runnableThread(new Runnable() { public void run() { try { showTextWordWrapped("Gazelle 'Left arrow script' Help", helpText); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showTextWordWrapped(\"Gazelle 'Left arrow script' Help\", helpText)"; } }), "Show Global Class Names", runnableThread(new Runnable() { public void run() { try { showGlobalClassNames(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showGlobalClassNames();"; } }), "Convert to Java", runnableThread(new Runnable() { public void run() { try { convertToJava(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "convertToJava();"; } }))); return centerAndEastWithMargin(jBorderlessHigherScrollPane(lbl), jfullcenter(buttons)); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return swing(() -> { taScript = g22utils.newSyntaxTextArea(__3 -> wrapStatusLabel(__3)); bindToComponent(textArea(), () -> g22utils.masterStuff().onNewClassesDefined(rRecompileIfError), () -> g22utils.masterStuff().removeNewClassesDefinedListener(rRecompileIfError)); bindTextComponentToVarWithNotify_noInitialUndo(textArea(), lvScript); dummyParser.install(textArea()); addKeyListener(textArea(), functionKeyListener(5, runnableThread(new Runnable() { public void run() { try { runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "runScript();"; } }))); addKeyListener(textArea(), ctrlLetterKeyListener('b', runnableThread(new Runnable() { public void run() { try { goToDefinition(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "goToDefinition();"; } }))); awtCalcEvery(textArea(), compileDelay, rstCompile); installCompletionProvider(completionProvider = new LeftArrowCompletionProvider(), textArea()); JComponent vis = taScript.visualize(); if (showTitle) vis = jCenteredSection(sectionTitle, vis); vis = wrapSection(vis); addAll(buttons, btnRun = toolTip("Run script (F5)", jbutton("Run", runnableThread(new Runnable() { public void run() { try { runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "runScript();"; } }))), popDownButton); if (withResultPanel) { resultPanel = new G22ScriptResultPanel(); collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), vis); collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c); return collapsibleResultPanel.visualize(); } else return vis; }); } transient public IF1 wrapSection; public JComponent wrapSection(JComponent c) { return wrapSection != null ? wrapSection.get(c) : wrapSection_base(c); } final public JComponent wrapSection_fallback(IF1 _f, JComponent c) { return _f != null ? _f.get(c) : wrapSection_base(c); } public JComponent wrapSection_base(JComponent c) { return c; } public RSyntaxTextArea textArea() { if (taScript == null) visualize(); return taScript.textArea(); } public void setText(String text) { loadableUtils.utils.setText(textArea(), text); } private void compile() { var script = lvScript.get(); var result = compileResult; if (!g22utils().compileResultValid(result, script)) { result = newCompileResult(); result.script = script; result.makeParser = () -> makeParser(); result.compile(); compileResult(result); showStatus(str(compileResult)); updateRunButtonState(); List errors = new ArrayList(); if (result.compileError != null) { LineAndColumn lineAndCol = result.errorLineAndCol(); if (lineAndCol != null) errors.add(new RSTADummyParser.Error().msg(result.errorToString()).start(lineAndCol).end(new LineAndColumn(lineAndCol.line + 1, 1))); } dummyParser.setErrors(result.script, errors, textArea()); } } public void updateRunButtonState() { setEnabled(btnRun, runButtonShouldBeEnabled()); } transient public IF0 runButtonShouldBeEnabled; public boolean runButtonShouldBeEnabled() { return runButtonShouldBeEnabled != null ? runButtonShouldBeEnabled.get() : runButtonShouldBeEnabled_base(); } final public boolean runButtonShouldBeEnabled_fallback(IF0 _f) { return _f != null ? _f.get() : runButtonShouldBeEnabled_base(); } public boolean runButtonShouldBeEnabled_base() { return compileResult != null && compileResult.runnable(); } public LASCompileResult freshCompileResult() { rstCompile.triggerAndWait(); return compileResult; } public GazelleV_LeftArrowScript.Script parsedScript() { return freshCompileResult().parsedScript; } transient public Runnable runScript; public void runScript() { if (runScript != null) runScript.run(); else runScript_base(); } final public void runScript_fallback(Runnable _f) { if (_f != null) _f.run(); else runScript_base(); } public void runScript_base() { var result = freshCompileResult(); if (result.parsedScript != null) { var value = runResultWithTimestamps(() -> callCompiledObjectWithTimeout(result.parsedScript)); showScriptResult(value); } } public void showScriptResult(OKOrError result) { if (result instanceof RunResultWithTimestamps) { if (resultPanel != null) resultPanel.logView.setText(str(((RunResultWithTimestamps) result).printOutput())); } if (result.isOK()) { setStatus(shorten(g22utils.stringify(result.get()))); var objVisualizer = makeObjectVisualizer(result.get()); if (result instanceof RunResultWithTimestamps) { var duration = ((RunResultWithTimestamps) result).duration(); if (duration != null) { long nanos = ((RunResultWithTimestamps) result).duration().toNanos(); objVisualizer.nanos(nanos); } } if (collapsibleResultPanel != null) objVisualizer.withTypeAndTime(false); { if (resultPanel != null) resultPanel.scpResult.set(objVisualizer); } if (collapsibleResultPanel != null) collapsibleResultPanel.sidePanelName("Output" + appendBracketed(objVisualizer.objectInfos())); } else { setStatus(exceptionToStringShorter(result.error())); { if (resultPanel != null) resultPanel.scpResult.set(jErrorView(result.getError())); } } { if (collapsibleResultPanel != null) collapsibleResultPanel.expand(); } } final public void showStatus(String status) { setStatus(status); } public void setStatus(String status) { { if (taScript != null) taScript.setStatus(" " + unnull(status)); } } public void showRuntimeError(Throwable e) { showStatus(exceptionToStringShorter(e)); } transient public IF0 makeVarContextForExecution; public VarContext makeVarContextForExecution() { return makeVarContextForExecution != null ? makeVarContextForExecution.get() : makeVarContextForExecution_base(); } final public VarContext makeVarContextForExecution_fallback(IF0 _f) { return _f != null ? _f.get() : makeVarContextForExecution_base(); } public VarContext makeVarContextForExecution_base() { return new FlexibleVarContext(); } public Object callCompiledObjectWithTimeout(GazelleV_LeftArrowScript.Script script) { return callCompiledObjectWithTimeout(scriptTimeout, script); } public Object callCompiledObjectWithTimeout(double timeoutSeconds, GazelleV_LeftArrowScript.Script script) { return callCompiledObjectWithTimeout(timeoutSeconds, script, makeVarContextForExecution()); } public Object callCompiledObjectWithTimeout(GazelleV_LeftArrowScript.Script script, VarContext ctx) { return callCompiledObjectWithTimeout(scriptTimeout, script, ctx); } public Object callCompiledObjectWithTimeout(double timeoutSeconds, GazelleV_LeftArrowScript.Script script, VarContext ctx) { return g22utils.evalRegisteredCode(timeoutSeconds, str(script), () -> script.get(ctx)); } public void showGlobalClassNames() { showText("Global Class Names", pnlToString(toCIMap(makeParser().globalClassNames()))); } public void setEditable(boolean b) { loadableUtils.utils.setEditable(textArea(), b); } transient public IF0 newCompileResult; public LASCompileResult newCompileResult() { return newCompileResult != null ? newCompileResult.get() : newCompileResult_base(); } final public LASCompileResult newCompileResult_fallback(IF0 _f) { return _f != null ? _f.get() : newCompileResult_base(); } public LASCompileResult newCompileResult_base() { return new LASCompileResult(); } public void convertToJava() { try { ConvertLASToJava converter = new ConvertLASToJava(); enableScaffolding(converter); showText("Java conversion - " + sectionTitle(), strOrNull(converter.get(parsedScript(), true))); } catch (Throwable __e) { infoBox(__e); } } public void goToDefinition() { String text; int iChar; Pair __2 = textAndCaretPosition(textArea()); text = __2.a; iChar = __2.b; List tok = lasTok(text); int iTok = charToTokenIndex_left(tok, iChar); ListAndIndex tokPtr = new ListAndIndex(tok, iTok); var action = goToDefinitionAction(tokPtr); if (action != null) pcallF(action); else flatInfoBox("No definition found"); } public Runnable goToDefinitionAction(ListAndIndex tokPtr) { for (var handler : cloneList(goToDefinitionHandlers())) { var __1 = handler.get(tokPtr); if (__1 != null) return __1; } List tok = tokPtr.list(); int iTok = tokPtr.idx(); String id = lastIdentifier(subList(tok, iTok - 2, iTok + 1)); if (id != null) { String name = lookupStandardFunctionOrClassNameIC(id); if (name != null) { String snippetID = sfOrSCSnippet(id); if (snippetID != null) { return () -> { infoBox("Opening " + quote(name)); g22utils.openInBrowser(snippetURL(snippetID)); }; } } } return null; } public void recompile() { compileResult = null; rstCompile.trigger(); } public void recompileIfError() { var result = compileResult; if (result != null && result.hasError()) recompile(); } transient public IF1 makeObjectVisualizer; public G22JavaObjectVisualizer makeObjectVisualizer(Object result) { return makeObjectVisualizer != null ? makeObjectVisualizer.get(result) : makeObjectVisualizer_base(result); } final public G22JavaObjectVisualizer makeObjectVisualizer_fallback(IF1 _f, Object result) { return _f != null ? _f.get(result) : makeObjectVisualizer_base(result); } public G22JavaObjectVisualizer makeObjectVisualizer_base(Object result) { return new G22JavaObjectVisualizer(g22utils, result).allowDescendingIntoListElements(true); } public void addGoToDefinitionHandler(GoToDefinitionHandler handler) { goToDefinitionHandlers.add(handler); } final public boolean isShowing() { return visible(); } public boolean visible() { var ta = taScript; return ta != null && loadableUtils.utils.isShowing(ta.textArea); } public String getText() { var ta = taScript; if (ta == null) return null; return loadableUtils.utils.getText(ta.textArea); } } static public class G22SystemInfoPanel implements Swingable, IFieldsToList { public G22Utils g22utils; public G22SystemInfoPanel() { } public G22SystemInfoPanel(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { var gazelleJar = g22utils.gazelleJar(); File conceptsFile = g22utils.concepts().conceptsFile(); var projectLibs = g22utils.projectActions().projectLibs(); var selfTests = g22utils.projectActions().selfTests(); return jscrollVertical(makeForm3("Java Version", jlabel(javaVersion()), "Gazelle Jar", new JFilePathLabel(gazelleJar).visualize(), "Gazelle Jar Size", str_toMB_oneDigit(fileSize(gazelleJar)), "Memory use (objects)", jline(jLabelShortCalcedEvery(1.0, () -> str_toMB(usedMemory())), jThreadedButton("Collect garbage", () -> gc())), "Max heap", jLabelShortCalcedEvery(1.0, () -> str_toMB(maxMemory())), "Threads", jReloadEvery(1.0, () -> jLabel(n2(threadCount()))), "Java VM arguments", joinWithSpace(vmArguments()), "Using Custom Classloader", yesNoShort(usingStarter(mc())), "Compilation Date", jlabel(g22utils.compilationDate()), "Project Libraries", joinWithCommaOr(projectLibs, "-"), "Project Database", new JFilePathLabel(conceptsFile).visualize(), "Project Database Size", str_toKB(fileSize(conceptsFile)), "Self-Tests", jlabel(selfTests == null ? "Not run" : selfTests.status()), "Gazelle Count", toolTip("How many Gazelles are running in the world", jLiveValueLabel((LiveValue) dm_callOSOpt("lvComputerCount"))))); } } static public class MakerAndTakerGame { public Boolean priceIsUp; public int takersCurrentBet; public int takersScore; public int roundsPlayed; public boolean takersTurn = true; public List protocol = new ArrayList(); transient public IF0 nextCryptoMove; public boolean nextCryptoMove() { return nextCryptoMove != null ? nextCryptoMove.get() : nextCryptoMove_base(); } final public boolean nextCryptoMove_fallback(IF0 _f) { return _f != null ? _f.get() : nextCryptoMove_base(); } public boolean nextCryptoMove_base() { throw fail("Put something here"); } public void make() { priceIsUp = nextCryptoMove(); takersScore += takersCurrentBet * (priceIsUp ? 1 : -1); ++roundsPlayed; protocol.add((MakerAndTakerGame) unstructure(print(structure(this)))); takersTurn = true; } transient public Runnable magicJuice; public void magicJuice() { if (magicJuice != null) magicJuice.run(); else magicJuice_base(); } final public void magicJuice_fallback(Runnable _f) { if (_f != null) _f.run(); else magicJuice_base(); } public void magicJuice_base() { } public void take() { magicJuice(); takersTurn = false; } public void step() { if (takersTurn) take(); else make(); } } static public class RegularPriceCells implements PriceCells { public RegularPriceCells() { } final public RegularPriceCells setInterval(double interval) { return interval(interval); } public RegularPriceCells interval(double interval) { this.interval = interval; return this; } final public double getInterval() { return interval(); } public double interval() { return interval; } public double interval; final public RegularPriceCells setBase(double base) { return base(base); } public RegularPriceCells base(double base) { this.base = base; return this; } final public double getBase() { return base(); } public double base() { return base; } public double base; public RegularPriceCells(double interval) { this.interval = interval; } public RegularPriceCells(double base, double interval) { this.interval = interval; this.base = base; } public double remainder(double price) { return mod(price - base, interval); } public boolean isCellLimit(double price) { return remainder(price) == 0; } public double nextCellLimit(double price) { double r = remainder(price); return price + interval - r; } public double previousCellLimit(double price) { double r = remainder(price); return price - (r == 0 ? interval : r); } public double nCellLimitsDown(double price, int n) { return previousCellLimit(price) - (n - 1) * interval; } public double nCellLimitsUp(double price, int n) { return nextCellLimit(price) + n * interval; } public double priceToCellNumber(double price) { return (price - base) / interval; } public double cellNumberToPrice(double cellNumber) { return cellNumber * interval + base; } } static public class G22DatabasesPanel implements IFieldsToList { public G22Utils g22utils; public G22DatabasesPanel() { } public G22DatabasesPanel(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public JObjectTable table; public FileWatchService dirWatcher; public ReliableSingleThread rstUpdate = new ReliableSingleThread(new Runnable() { public void run() { try { _updateTable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_updateTable();"; } }); public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { table = swing(() -> new JObjectTable()); table.defaultAction(runnableToIVF1(runnableThread(new Runnable() { public void run() { try { openDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "openDB();"; } }))); table.itemToMap = db -> { IG22LoadedDB loaded = db.loadedDB(); return litorderedmap("Name", db.name, "Directory", f2s(db.dir), "Loaded", loaded == null ? "No" : (loaded.hidden() ? "Yes (hidden)" : "Yes")); }; var tbl = table.visualize(); bindToComponent(tbl, () -> { dirWatcher = new FileWatchService(); dirWatcher.addNonRecursiveListener(g22utils.databasesMotherDir(), file -> { rstUpdate.get(); }); g22utils.masterStuff().onLoadedDBsChange(rstUpdate); rstUpdate.get(); }, () -> { g22utils.masterStuff().removeLoadedDBsChangeListener(rstUpdate); { cleanUp(dirWatcher); dirWatcher = null; } }); return withTopAndBottomMargin(jCenteredRaisedSection("Gazelle projects on this computer", northAndCenterWithMargins(jline(toolTip("Create a new Gazelle project", jbutton("New project...", runnableThread(new Runnable() { public void run() { try { newDatabase(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newDatabase();"; } })))), centerAndEastWithMargin(tbl, jscroll_vertical_borderless(vstackWithSpacing_fixed(new DefaultButtonBorder(toolTip("Open selected project, keep other projects open too", tableDependentButton(table.table, "Open project", runnableThread(new Runnable() { public void run() { try { openDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "openDB();"; } })))), toolTip("Open selected project in hidden mode [without a window]", tableDependentButton(table.table, "Open hidden", runnableThread(new Runnable() { public void run() { try { openDBHidden(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "openDBHidden();"; } }))), toolTip("Open selected project, close all other projects", tableDependentButton(table.table, "Switch to project", runnableThread(new Runnable() { public void run() { try { switchToDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "switchToDB();"; } }))), tableDependentButton(table.table, "Close project", runnableThread(new Runnable() { public void run() { try { closeDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "closeDB();"; } })), tableDependentButton(table.table, "Rename project", runnableThread(new Runnable() { public void run() { try { renameDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "renameDB();"; } })), tableDependentButton(table.table, "Delete project...", runnableThread(new Runnable() { public void run() { try { deleteDB(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "deleteDB();"; } })), tableDependentButton(table.table, "Browse files", runnableThread(new Runnable() { public void run() { try { browse(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "browse();"; } })), tableDependentButton(table.table, "Export project as zip...", runnableThread(new Runnable() { public void run() { try { exportAsZip(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "exportAsZip();"; } })), jThreadedButton("Import project from zip...", runnableThread(new Runnable() { public void run() { try { importZip(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "importZip();"; } })))))))); } public void newDatabase() { AutoCloseable __1 = g22utils.enter(); try { var tf = jtextfield(); var lblDir = jlabel(" "); var lblStatus = jlabel(" "); var button = jThreadedButton("Create project", () -> { AutoCloseable __2 = g22utils.enter(); try { String name = trim(tf.getText()); File dir = newFile(g22utils.databasesMotherDir(), name); createEmptyConceptsFileInDir(dir); disposeFrame(tf); g22utils.masterStuff().openDatabase(dir); } finally { _close(__2); } }); disableButton(button); onEnter(tf, button); onChange(tf, new Runnable() { public void run() { try { String name = trim(tf.getText()); boolean ok = false; String status = " ", path = " "; if (isValidFileName(name)) { File dir = newFile(g22utils.databasesMotherDir(), name); path = f2s(dir); if (dirExists(dir)) status = "A project with that name exists"; else ok = true; } else if (!empty(name)) status = "Project name must be a valid file name"; setEnabled(button, ok); setText(lblStatus, status); setText(lblDir, path); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "String name = trim(tf.getText());\r\n boolean ok;\r\n String status = \"..."; } }); showForm_makeFrame("New Gazelle Project", vstackWithSpacing(withLabel("Name for new project", tf), lblDir, lblStatus, button)); } finally { _close(__1); } } public void _updateTable() { table.setData_force(g22utils.gazelleDBs()); } public void browse() { desktopOpen(table.selected().dir); } public void openDB() { g22utils.masterStuff().openDatabase(table.selected().dir); } public void openDBHidden() { g22utils.masterStuff().openDatabase(table.selected().dir, true); } public void switchToDB() { g22utils.masterStuff().switchToDatabase(table.selected().dir); } public void closeDB() { g22utils.masterStuff().closeDatabase(table.selected().dir); } public void deleteDB() { var db = table.selected(); if (db == null) return; var dir = db.dir(); if (g22utils.isConceptsDir(dir)) { messageBox("Can't delete current project"); return; } g22utils.masterStuff().closeDatabase(dir); new DeleteFilesDialog("Delete Gazelle project " + db.name()).wholeDirectory(dir).show(); } public void exportAsZip() { File dir = table.selected().dir; JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Export project as zip"); fileChooser.setSelectedFile(javaxBackupDir(dir.getName() + "-" + ymdMinusHMS() + ".zip")); if (fileChooser.showSaveDialog(visualize()) == JFileChooser.APPROVE_OPTION) { File zip = fileChooser.getSelectedFile(); dir2zip(dir, zip, dir.getName() + "/"); fileSavedInfoBox(zip); desktopOpen(dirOfFile(zip)); } } public void importZip() { try { JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Import project from zip"); fc.setCurrentDirectory(javaxBackupDir()); if (fc.showOpenDialog(visualize()) == JFileChooser.APPROVE_OPTION) { File zip = fc.getSelectedFile(); g22utils.importProjectFromZip(zip); } } catch (Throwable __e) { messageBox(__e); } } public void renameDB() { File dir = table.selected().dir; inputText("New name", fileName(dir), newName -> { assertValidFileName(newName); if (!eq(newName, fileName(dir))) { boolean open = g22utils.masterStuff().isConceptDirLoaded(dir); if (open) g22utils.masterStuff().closeDatabase(dir); renameFileVerbose(dir, newName); if (open) g22utils.masterStuff().openDatabase(dir); } }); } } static public class JMultiColorBar extends JComponentWithChangeListeners { public class Entry { final public Entry setValue(double value) { return value(value); } public Entry value(double value) { this.value = value; return this; } final public double getValue() { return value(); } public double value() { return value; } public double value; final public Entry setColor(Color color) { return color(color); } public Entry color(Color color) { this.color = color; return this; } final public Color getColor() { return color(); } public Color color() { return color; } public Color color; final public Entry setText(String text) { return text(text); } public Entry text(String text) { this.text = text; return this; } final public String getText() { return text(); } public String text() { return text; } public String text; final public Entry setToolTip(String toolTip) { return toolTip(toolTip); } public Entry toolTip(String toolTip) { this.toolTip = toolTip; return this; } final public String getToolTip() { return toolTip(); } public String toolTip() { return toolTip; } public String toolTip; public Entry previous() { return elementBefore(entries, this); } public double relativeValue() { Entry p = previous(); return p == null ? value : value - p.value; } } public List entries = notifyingList(() -> repaint()); public transient FieldVar varMax_cache; public FieldVar varMax() { if (varMax_cache == null) varMax_cache = varMax_load(); return varMax_cache; } public FieldVar varMax_load() { return new FieldVar(this, "max", () -> max(), max -> max(max)); } final public JMultiColorBar setMax(double max) { return max(max); } public JMultiColorBar max(double max) { if (!eq(this.max, max)) { this.max = max; change(); } return this; } final public double getMax() { return max(); } public double max() { return max; } public double max = 100; final public JMultiColorBar setDefaultColors(List defaultColors) { return defaultColors(defaultColors); } public JMultiColorBar defaultColors(List defaultColors) { this.defaultColors = defaultColors; return this; } final public List getDefaultColors() { return defaultColors(); } public List defaultColors() { return defaultColors; } public List defaultColors = ll(Color.red, Color.blue); public InstantNeverHideToolTip toolTipMaker; transient public IF1 defaultColor; public Color defaultColor(int index) { return defaultColor != null ? defaultColor.get(index) : defaultColor_base(index); } final public Color defaultColor_fallback(IF1 _f, int index) { return _f != null ? _f.get(index) : defaultColor_base(index); } public Color defaultColor_base(int index) { return getCyclic(defaultColors, index); } public Entry makeEntry(double relativeValue) { Entry prev = last(entries); double value = prev == null ? relativeValue : relativeValue + prev.value; return new Entry().value(value).color(defaultColor(l(entries))); } final public Entry add(String text, double relativeValue) { return addEntry(text, relativeValue); } public Entry addEntry(String text, double relativeValue) { return addAndReturn(entries, makeEntry(relativeValue).text(text)); } final public Entry add(double relativeValue, Color color) { return addEntry(relativeValue, color); } public Entry addEntry(double relativeValue, Color color) { return addAndReturn(entries, makeEntry(relativeValue).color(color)); } public String toolTipForEntry(Entry e) { return e == null ? null : spaceCombine(or2(e.toolTip, e.text), renderValue(e.relativeValue())); } transient public IF1 renderValue; public String renderValue(double value) { return renderValue != null ? renderValue.get(value) : renderValue_base(value); } final public String renderValue_fallback(IF1 _f, double value) { return _f != null ? _f.get(value) : renderValue_base(value); } public String renderValue_base(double value) { return str(value); } public String toolTipForPosition(Pt p) { if (metaGet("scaffolding") != null) scaffoldCalled(this, "toolTipForPosition", p); int w = getWidth(); Entry e = firstThat(entries, _e -> p.x < xForEntry(_e, w)); if (scaffolded()) printVars("e", e, "xs", map(entries, _e -> xForEntry(_e, w))); return toolTipForEntry(e); } public JMultiColorBar() { varMax().onChange(() -> repaint()); jMinSize(50, 10, this); toolTipMaker = new InstantNeverHideToolTip(__1 -> toolTipForPosition(__1), this); } public int xForEntry(Entry e, int w) { return iround(w * clampZeroToOne(doubleRatio(e.value, max))); } public void paintComponent(Graphics g) { super.paintComponent(g); int w = getWidth(), h = getHeight(); int x = 0; for (var e : entries) { int x2 = loadableUtils.utils.max(x, xForEntry(e, w)); if (x2 > x) fillRect(g, x + 1, 0, x2 - x, h, e.color); x = x2; } } } static public class FollowTickerFile implements AutoCloseable, IFieldsToList { public File tickerFile; public FollowTickerFile() { } public FollowTickerFile(File tickerFile) { this.tickerFile = tickerFile; } public Object[] _fieldsToList() { return new Object[] { tickerFile }; } final public FollowTickerFile setHistoryEntriesToGrab(int historyEntriesToGrab) { return historyEntriesToGrab(historyEntriesToGrab); } public FollowTickerFile historyEntriesToGrab(int historyEntriesToGrab) { this.historyEntriesToGrab = historyEntriesToGrab; return this; } final public int getHistoryEntriesToGrab() { return historyEntriesToGrab(); } public int historyEntriesToGrab() { return historyEntriesToGrab; } public int historyEntriesToGrab; final public FollowTickerFile setInterval(int interval) { return interval(interval); } public FollowTickerFile interval(int interval) { this.interval = interval; return this; } final public int getInterval() { return interval(); } public int interval() { return interval; } public int interval = 250; final public FollowTickerFile setSleeper(ISleeper_v2 sleeper) { return sleeper(sleeper); } public FollowTickerFile sleeper(ISleeper_v2 sleeper) { this.sleeper = sleeper; return this; } final public ISleeper_v2 getSleeper() { return sleeper(); } public ISleeper_v2 sleeper() { return sleeper; } public ISleeper_v2 sleeper = defaultSleeper(); public TailFile tailFile; transient public Set> onHistoricLine; public FollowTickerFile onHistoricLine(IVF1 f) { onHistoricLine = createOrAddToSyncLinkedHashSet(onHistoricLine, f); return this; } public FollowTickerFile removeHistoricLineListener(IVF1 f) { loadableUtils.utils.remove(onHistoricLine, f); return this; } public void historicLine(String line) { if (onHistoricLine != null) for (var listener : onHistoricLine) pcallF_typed(listener, line); } transient public Set> onLiveLine; public FollowTickerFile onLiveLine(IVF1 f) { onLiveLine = createOrAddToSyncLinkedHashSet(onLiveLine, f); return this; } public FollowTickerFile removeLiveLineListener(IVF1 f) { loadableUtils.utils.remove(onLiveLine, f); return this; } public void liveLine(String line) { if (onLiveLine != null) for (var listener : onLiveLine) pcallF_typed(listener, line); } final public long getLiveTimestamp() { return liveTimestamp(); } public long liveTimestamp() { return liveTimestamp; } volatile public long liveTimestamp; final public String getLastLiveLine() { return lastLiveLine(); } public String lastLiveLine() { return lastLiveLine; } volatile public String lastLiveLine; final public FollowTickerFile setStarted(boolean started) { return started(started); } public FollowTickerFile started(boolean started) { this.started = started; return this; } final public boolean getStarted() { return started(); } public boolean started() { return started; } transient public boolean started = false; final public FollowTickerFile setMaxLineLengthForTickerEntry(int maxLineLengthForTickerEntry) { return maxLineLengthForTickerEntry(maxLineLengthForTickerEntry); } public FollowTickerFile maxLineLengthForTickerEntry(int maxLineLengthForTickerEntry) { this.maxLineLengthForTickerEntry = maxLineLengthForTickerEntry; return this; } final public int getMaxLineLengthForTickerEntry() { return maxLineLengthForTickerEntry(); } public int maxLineLengthForTickerEntry() { return maxLineLengthForTickerEntry; } public int maxLineLengthForTickerEntry = 200; public Q q = startQ(); public boolean isLive() { return liveTimestamp != 0; } public void start() { q.add(new Runnable() { public void run() { try { if (started()) return; started(true); onLiveLine(line -> { lastLiveLine = line; liveTimestamp = now(); }); long fileSize = l(tickerFile); long start = max(0, fileSize - maxLineLengthForTickerEntry * historyEntriesToGrab); if (historyEntriesToGrab > 0) { String text = loadTextFilePart(tickerFile, start, fileSize); List lastTickerLines = takeLast(historyEntriesToGrab, lines(text)); print("Have historic lines: " + l(lastTickerLines) + "/" + historyEntriesToGrab); for (var line : lastTickerLines) historicLine(line); } makeTailFile(fileSize); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (started()) return;\r\n started(true);\r\n \r\n onLiveLine(line -..."; } }); } public void makeTailFile(long fileSize) { started(true); print("Following " + tickerFile + " (" + n2(l(tickerFile)) + " bytes) from position " + n2(fileSize)); tailFile = tailFileLinewiseFromPosition(tickerFile, interval, fileSize, __1 -> liveLine(__1), sleeper); } public void close() { try { started(false); if (tailFile != null) { print("Done " + tailFile); { cleanUp(tailFile); tailFile = null; } } } catch (Exception __e) { throw rethrow(__e); } } public void switchToFile(File newFile) { if (eq(tickerFile, newFile)) return; q.add(new Runnable() { public void run() { try { if (eq(tickerFile, newFile)) return; print("Switching to ticker file: " + newFile); if (started()) { close(); tickerFile = newFile; started(true); makeTailFile(0); } else tickerFile = newFile; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(tickerFile, newFile)) return;\r\n print(\"Switching to ticker file: ..."; } }); } public FollowTickerFile onLine(IVF1 l) { onHistoricLine(l); return onLiveLine(l); } public String toString() { return commaCombine("FollowTickerFile", stringIf(started(), "started"), !isLive() ? null : "Last live line at " + formatLocalDateWithSeconds(liveTimestamp), tickerFile); } } static public class MountainsAndValleys { final public MountainsAndValleys setValues(double[] values) { return values(values); } public MountainsAndValleys values(double[] values) { this.values = values; return this; } final public double[] getValues() { return values(); } public double[] values() { return values; } public double[] values; final public IntBuffer getHighs() { return highs(); } public IntBuffer highs() { return highs; } public IntBuffer highs = new IntBuffer(); final public IntBuffer getLows() { return lows(); } public IntBuffer lows() { return lows; } public IntBuffer lows = new IntBuffer(); public void run() { try { int n = l(values); if (n == 0) return; highs.add(0); lows.add(0); int i = 1; while (i < n) { var value = values[i]; int j = i + 1; while (j < n && values[j] == value) ++j; var last = values[i - 1]; var list = value > last ? highs : lows; if (values[list.last()] == last) list.popLast(); list.add(i); i = j; } } catch (Exception __e) { throw rethrow(__e); } } public int prev(IntBuffer highsOrLows, int idx) { int j = intBufferBinarySearch(highsOrLows, idx - 1); if (j >= 0) return idx - 1; j = -j - 1; j--; return j >= 0 ? highsOrLows.get(j) : -1; } public int next(IntBuffer highsOrLows, int idx) { int j = intBufferBinarySearch(highsOrLows, idx + 1); if (j >= 0) return idx + 1; j = -j - 1; return j < l(highsOrLows) ? highsOrLows.get(j) : -1; } public int prevHigh(int idx) { return prev(highs, idx); } public int nextHigh(int idx) { return next(highs, idx); } public int prevLow(int idx) { return prev(lows, idx); } public int nextLow(int idx) { return next(lows, idx); } } static public Object jsonDecode(String text) { return new jsonDecode_Y(text).parse(); } static public class jsonDecode_Y { public String text; public List tok; public boolean useOrderedMaps = false; public int i = 1; public jsonDecode_Y(String text) { this.text = text; tok = jsonTok(text); } transient public IF1 fail; public RuntimeException fail(String msg) { return fail != null ? fail.get(msg) : fail_base(msg); } final public RuntimeException fail_fallback(IF1 _f, String msg) { return _f != null ? _f.get(msg) : fail_base(msg); } public RuntimeException fail_base(String msg) { return loadableUtils.utils.fail(msg); } public Object parse() { if (l(tok) == 1) return null; return parseExpr(); } public Object parseExpr() { String t = tok.get(i); if (t.startsWith("\"") || t.startsWith("'")) { String s = unquote(tok.get(i)); i += 2; return s; } if (t.equals("{")) return parseMap(); if (t.equals("[")) return this.parseList(); if (t.equals("null")) { i += 2; return null; } if (t.equals("false")) { i += 2; return false; } if (t.equals("true")) { i += 2; return true; } boolean minus = false; if (t.equals("-")) { minus = true; i += 2; t = get(tok, i); } if (isInteger(t)) { int j = i; i += 2; if (eqOneOf(get(tok, i), ".", "e", "E")) { while (isInteger(get(tok, i)) || eqOneOf(get(tok, i), ".", "e", "E", "-")) i += 2; double d = parseDouble(joinSubList(tok, j, i - 1)); if (minus) d = -d; return d; } else { long l = parseLong(t); return boxedIntOrLong(minus ? -l : l); } } throw fail("Unknown token " + (i + 1) + ": " + t + ": " + text); } public Object parseList() { consume("["); List list = new ArrayList(); while (!tok.get(i).equals("]")) { list.add(parseExpr()); if (tok.get(i).equals(",")) i += 2; } consume("]"); return list; } public Object parseMap() { consume("{"); Map map = useOrderedMaps ? new LinkedHashMap() : new TreeMap(); while (!tok.get(i).equals("}")) { String key = unquote(tok.get(i)); i += 2; consume(":"); Object value = parseExpr(); map.put(key, value); if (tok.get(i).equals(",")) i += 2; } consume("}"); return map; } public void consume(String s) { if (!tok.get(i).equals(s)) { String prevToken = i - 2 >= 0 ? tok.get(i - 2) : ""; String nextTokens = join(tok.subList(i, Math.min(i + 4, tok.size()))); throw fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")"); } i += 2; } } static public class GazelleV_LeftArrowScript { abstract static public class Base extends HasTokenRangeWithSrc { public RuntimeException rethrowWithSrc(Throwable e) { return rethrowWithSrc("", e); } public RuntimeException rethrowWithSrc(String msg, Throwable e) { if (tokenRangeWithSrc() != null) throw new ScriptError(tokenRangeWithSrc(), msg, e); else throw rethrow(e); } public String indented() { return indentedScriptStruct(this); } } static public class ScriptError extends RuntimeException implements IHasTokenRangeWithSrc { public ScriptError(TokenRangeWithSrc src, Throwable reason) { super(reason); tokenRangeWithSrc(src); } public ScriptError(TokenRangeWithSrc src, String msg, Throwable reason) { super(msg, reason); tokenRangeWithSrc(src); } final public ScriptError setTokenRangeWithSrc(TokenRangeWithSrc tokenRangeWithSrc) { return tokenRangeWithSrc(tokenRangeWithSrc); } public ScriptError tokenRangeWithSrc(TokenRangeWithSrc tokenRangeWithSrc) { this.tokenRangeWithSrc = tokenRangeWithSrc; return this; } final public TokenRangeWithSrc getTokenRangeWithSrc() { return tokenRangeWithSrc(); } public TokenRangeWithSrc tokenRangeWithSrc() { return tokenRangeWithSrc; } public TokenRangeWithSrc tokenRangeWithSrc; public TokenRangeWithSrc src() { return tokenRangeWithSrc(); } public String toString() { return super.toString() + "\n " + src() + " {{ " + shorten(nlToSpace(src().text())) + " }}"; } } public interface Evaluable extends IF0, IHasTokenRangeWithSrc { public default Object get() { return get(new FlexibleVarContext()); } public Object get(VarContext ctx); public default LASValueDescriptor returnType() { return null; } public default Evaluable optimize() { return this; } public default Evaluable optimizeForReturnValueNotNeeded() { return this; } } abstract static public class EvaluableBase extends Base implements Evaluable { final public EvaluableBase setReturnType(LASValueDescriptor returnType) { return returnType(returnType); } public EvaluableBase returnType(LASValueDescriptor returnType) { this.returnType = returnType; return this; } final public LASValueDescriptor getReturnType() { return returnType(); } public LASValueDescriptor returnType() { return returnType; } public LASValueDescriptor returnType; public boolean returnValueNeeded = true; public Evaluable optimizeForReturnValueNotNeeded() { returnValueNeeded = false; return optimize(); } } static public AtomicLong scriptIDCounter = new AtomicLong(); static public long scriptID() { return incAtomicLong(scriptIDCounter); } static public class ListFromScript extends EvaluableBase implements IFieldsToList { public Script script; public ListFromScript() { } public ListFromScript(Script script) { this.script = script; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + script + ")"; } public Object[] _fieldsToList() { return new Object[] { script }; } public Object get(VarContext ctx) { return script.getAsList(ctx); } } static public class Script extends EvaluableBase { transient public long id = scriptID(); public Map functionDefs; public Evaluable[] steps; final public Script setScope(LASScope scope) { return scope(scope); } public Script scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public Map params; public Script() { } public Script(List steps) { this.steps = toTypedArray(Evaluable.class, steps); } public Object get(VarContext ctx) { Object result = null; var pingSource = pingSource(); for (var step : steps) { ping(pingSource); result = step.get(ctx); var exiting = ctx.exitFromScript; if (exiting != null) { if (exiting == this) { ctx.exitFromScript = null; result = ctx.returnValue; ctx.returnValue(null); return result; } return null; } } return result; } public Object getAsList(VarContext ctx) { Object result = null; var pingSource = pingSource(); List list = new ArrayList(); for (var step : steps) { ping(pingSource); list.add(step.get(ctx)); var exiting = ctx.exitFromScript; if (exiting != null) { if (exiting == this) { ctx.exitFromScript = null; result = ctx.returnValue; ctx.returnValue(null); list.add(result); return list; } return null; } } return list; } public String toStringLong() { return pnlToLines(steps); } public String toString() { return "Script " + n2(id); } public FunctionDef getFunction(String name) { return mapGet(functionDefs, name); } final public Script optimize() { return optimizeScript(); } public Script optimizeScript() { int n = returnValueNeeded ? steps.length - 1 : steps.length; for (int i = 0; i < n; i++) steps[i] = steps[i].optimizeForReturnValueNotNeeded(); for (var f : values(functionDefs)) f.optimize(); return this; } } static public class FunctionDef extends Base implements IFieldsToList { public String name; public String[] args; public Script body; public FunctionDef() { } public FunctionDef(String name, String[] args, Script body) { this.body = body; this.args = args; this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + args + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { name, args, body }; } final public FunctionDef setScope(LASScope scope) { return scope(scope); } public FunctionDef scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; final public FunctionDef setReturnType(Type returnType) { return returnType(returnType); } public FunctionDef returnType(Type returnType) { this.returnType = returnType; return this; } final public Type getReturnType() { return returnType(); } public Type returnType() { return returnType; } public Type returnType = Object.class; final public FunctionDef setArgTypes(LASValueDescriptor[] argTypes) { return argTypes(argTypes); } public FunctionDef argTypes(LASValueDescriptor[] argTypes) { this.argTypes = argTypes; return this; } final public LASValueDescriptor[] getArgTypes() { return argTypes(); } public LASValueDescriptor[] argTypes() { return argTypes; } public LASValueDescriptor[] argTypes; public FunctionDef(String name, List args, Script body) { this.args = toStringArray(args); this.body = body; this.name = name; } public Object callFromOutside(Object... args) { return call(new FlexibleVarContext(), args); } public Object call(VarContext ctx, Object... args) { VarContext ctx2 = scope != null && scope.useFixedVars ? new FixedVarContext(ctx, scope.names) : new FlexibleVarContext(ctx); int n = min(l(args), l(this.args)); for (int i = 0; i < n; i++) ctx2.put(this.args[i], args[i]); return body.get(ctx2); } public void optimize() { body = body.optimize(); } public boolean isConstructor() { return eq(name, ""); } } static public class Assignment extends EvaluableBase implements IFieldsToList { public String var; public Evaluable expression; public Assignment() { } public Assignment(String var, Evaluable expression) { this.expression = expression; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, expression }; } public Object get(VarContext ctx) { Object o = expression.get(ctx); ctx.set(var, o); return o; } public String toString() { return var + " <- " + expression; } } abstract static public class FixedVarBase extends EvaluableBase { final public FixedVarBase setScope(LASScope scope) { return scope(scope); } public FixedVarBase scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public String var; public int varIdx; public String varToStr() { return var + " [" + varIdx + "]"; } public void assertResolved() { if (varIdx < 0) throw fail("Unresolved variable access: " + var); } public void resolve() { varIdx = scope.resolveVar(var); } } static public class FixedVarAssignment extends FixedVarBase { public FixedVarAssignment() { } public Evaluable expression; public FixedVarAssignment(LASScope scope, String var, Evaluable expression) { this.expression = expression; this.var = var; this.scope = scope; } public Object get(VarContext ctx) { Object o = expression.get(ctx); ((FixedVarContext) ctx).set(varIdx, o); return o; } public String toString() { return varToStr() + " <- " + expression; } } static public class VarDeclaration extends EvaluableBase implements IFieldsToList { public String var; public Class type; public Evaluable expression; public VarDeclaration() { } public VarDeclaration(String var, Class type, Evaluable expression) { this.expression = expression; this.type = type; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, type, expression }; } public Object get(VarContext ctx) { Object o = expression == null ? null : expression.get(ctx); ctx.set(var, o); return o; } public String toString() { return "var " + var + " <- " + expression; } } static public class AssignmentToOuterVar extends EvaluableBase implements IFieldsToList { public String var; public Evaluable expression; public AssignmentToOuterVar() { } public AssignmentToOuterVar(String var, Evaluable expression) { this.expression = expression; this.var = var; } public Object[] _fieldsToList() { return new Object[] { var, expression }; } public Object get(VarContext ctx) { var parent = ctx.parent(); assertNotNull("No outer variable context", parent); Object o = expression.get(ctx); parent.set(var, o); return o; } public String toString() { return "outer " + var + " <- " + expression; } } static public class NewObject extends EvaluableBase { public NewObject() { } public Class c; public Evaluable[] args; public NewObject(Class c) { this.c = c; } public NewObject(Class c, Evaluable[] args) { this.args = args; this.c = c; } public Object get(VarContext ctx) { try { return preciseNuObject(c, evalArgs(args, ctx)); } catch (Throwable e) { throw rethrowWithSrc(e); } } public String toString() { return "new " + formatFunctionCall(className(c), args); } } static public class NewObject_LASClass extends NewObject { public NewObject_LASClass() { } public ResolvableLASClass lasClass; public NewObject_LASClass(ResolvableLASClass lasClass) { this.lasClass = lasClass; } public NewObject_LASClass(ResolvableLASClass lasClass, Evaluable[] args) { this.args = args; this.lasClass = lasClass; } public void resolve() { if (c == null) c = lasClass.get(); } public Object get(VarContext ctx) { resolve(); return super.get(ctx); } public String toString() { return "new " + formatFunctionCall(str(lasClass), args); } } static public class NewObject_UnknownClass extends NewObject implements IFieldsToList { public Evaluable classExpr; public Evaluable[] args; public NewObject_UnknownClass() { } public NewObject_UnknownClass(Evaluable classExpr, Evaluable[] args) { this.args = args; this.classExpr = classExpr; } public Object[] _fieldsToList() { return new Object[] { classExpr, args }; } public Object get(VarContext ctx) { try { Class c = (Class) (classExpr.get(ctx)); return preciseNuObject(c, evalArgs(args, ctx)); } catch (Throwable e) { throw rethrowWithSrc(e); } } public String toString() { return "new " + formatFunctionCall(classExpr, args); } } static public class CallFunction extends EvaluableBase implements IFieldsToList { public FunctionDef f; public Evaluable[] args; public CallFunction() { } public CallFunction(FunctionDef f, Evaluable[] args) { this.args = args; this.f = f; } public Object[] _fieldsToList() { return new Object[] { f, args }; } public Object get(VarContext ctx) { var evaledArgs = evalArgs(args, ctx); if (ctx.exiting()) return null; return f.call(ctx, evaledArgs); } public String toString() { return formatFunctionCall(f.name, args); } } static public class GetVar extends EvaluableBase implements IFieldsToList { public String var; public GetVar() { } public GetVar(String var) { this.var = var; } public Object[] _fieldsToList() { return new Object[] { var }; } public Object get(VarContext ctx) { return ctx.get(var); } public String toString() { return var; } } static public class GetFixedVar extends FixedVarBase { public GetFixedVar() { } public GetFixedVar(LASScope scope, String var) { this.var = var; this.scope = scope; } public Object get(VarContext ctx) { assertResolved(); try { return ((FixedVarContext) ctx).get(varIdx); } catch (ArrayIndexOutOfBoundsException e) { assertResolved(); throw e; } } public String toString() { return var + " [" + varIdx + "]"; } } static public class Const extends EvaluableBase implements IFieldsToList { public Object value; public Const() { } public Const(Object value) { this.value = value; } public Object[] _fieldsToList() { return new Object[] { value }; } public Object get(VarContext ctx) { return value; } public String toString() { return strOrClassName(value); } public LASValueDescriptor returnType() { return new LASValueDescriptor.KnownValue(value); } public Object _serialize() { boolean ok = isUnproblematicValue(value); return ok ? this : toStringWithClass(value); } } static public class GetStaticField extends EvaluableBase implements IFieldsToList { public Field field; public GetStaticField() { } public GetStaticField(Field field) { this.field = field; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + field + ")"; } public Object[] _fieldsToList() { return new Object[] { field }; } public Object get(VarContext ctx) { try { return field.get(null); } catch (Exception __e) { throw rethrow(__e); } } public String _serialize() { return str(field); } } abstract static public class CallOnTarget extends EvaluableBase implements IFieldsToList { public Evaluable target; public CallOnTarget() { } public CallOnTarget(Evaluable target) { this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ")"; } public Object[] _fieldsToList() { return new Object[] { target }; } final public CallOnTarget setAllowNullReference(boolean allowNullReference) { return allowNullReference(allowNullReference); } public CallOnTarget allowNullReference(boolean allowNullReference) { this.allowNullReference = allowNullReference; return this; } final public boolean getAllowNullReference() { return allowNullReference(); } public boolean allowNullReference() { return allowNullReference; } public boolean allowNullReference = false; public Object handleNullReference() { if (allowNullReference) return null; else throw new NullPointerException(); } abstract public Object evalOnTarget(VarContext ctx, Object object); public Object get(VarContext ctx) { try { Object object = target.get(ctx); if (object == null) return handleNullReference(); return evalOnTarget(ctx, object); } catch (Throwable e) { throw rethrowWithSrc(e); } } } static public class CallMethodOrGetField extends CallOnTarget { public CallMethodOrGetField() { } public String name; public CallMethodOrGetField(Evaluable target, String name) { this.name = name; this.target = target; } public Object evalOnTarget(VarContext ctx, Object object) { try { return preciseGetOrCallMethod(object, name); } catch (Throwable e) { throw rethrowWithSrc("Was getting " + name, e); } } } static public class GetField extends CallOnTarget { public GetField() { } public String name; public GetField(Evaluable target, String name) { this.name = name; this.target = target; } public Object evalOnTarget(VarContext ctx, Object object) { try { return _get(object, name); } catch (Throwable e) { throw rethrowWithSrc("Was getting " + name, e); } } } static public class GetVarContext extends EvaluableBase { public Object get(VarContext ctx) { return ctx; } } static public class ThrowMethodNotFoundException extends EvaluableBase implements IFieldsToList { public CallMethod instruction; public ThrowMethodNotFoundException() { } public ThrowMethodNotFoundException(CallMethod instruction) { this.instruction = instruction; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + instruction + ")"; } public Object[] _fieldsToList() { return new Object[] { instruction }; } public Object get(VarContext ctx) { throw fail("Method not found: " + instruction); } } static public class ThrowNullPointerException extends EvaluableBase implements IFieldsToList { public CallMethod instruction; public ThrowNullPointerException() { } public ThrowNullPointerException(CallMethod instruction) { this.instruction = instruction; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + instruction + ")"; } public Object[] _fieldsToList() { return new Object[] { instruction }; } public Object get(VarContext ctx) { throw fail("Null pointer exception: " + instruction); } } static public class CallMethod extends CallOnTarget { public CallMethod() { } public String methodName; public Evaluable[] args; public CallMethod(Evaluable target, String methodName, Evaluable[] args) { this.args = args; this.methodName = methodName; this.target = target; } public Object evalOnTarget(VarContext ctx, Object object) { return newPreciseCall(object, methodName, evalArgs(args, ctx)); } public String toString() { return target + "." + formatFunctionCall(methodName, args); } public Evaluable optimize() { var targetType = target.returnType(); if (targetType != null && targetType.knownValue()) { Object o = targetType.value(); if (o == null) return allowNullReference ? _const(null) : new ThrowNullPointerException(this); Class[] argTypes = new Class[l(args)]; for (int i = 0; i < l(args); i++) { var type = args[i].returnType(); if (type == null || !type.javaClassIsExact()) return this; argTypes[i] = type.javaClass(); } List methods = findMethodsNamed_cached(o, methodName); if (any(methods, m -> m.isVarArgs())) return this; var __4 = findMethod_withPrimitiveWidening_onTypes(o, methodName, argTypes); var method = __4.a; var widening = __4.b; if (method == null) return new ThrowMethodNotFoundException(this); return new DirectMethodCallOnKnownTarget(widening, o instanceof Class ? null : o, method, args); } return this; } } static public Object[] evalArgs(Evaluable[] args, VarContext ctx) { return mapToArrayOrNull(args, arg -> arg.get(ctx)); } static public class CallMethodOrGlobalFunction extends CallMethod { public CallMethodOrGlobalFunction() { } public MethodOnObject globalFunction; static final public Object methodNotFoundSentinel = new Object(); public CallMethodOrGlobalFunction(Evaluable target, String methodName, MethodOnObject globalFunction, Evaluable[] args) { this.args = args; this.globalFunction = globalFunction; this.methodName = methodName; this.target = target; } public String toString() { return target + "." + formatFunctionCall(methodName + "+", args); } public Object evalOnTarget(VarContext ctx, Object o) { Object[] realArgs = evalArgs(args, ctx); Object result = newPreciseCall_sentinel(o, methodName, methodNotFoundSentinel, realArgs); if (result != methodNotFoundSentinel) return result; return newPreciseCall(globalFunction.object, globalFunction.method, itemPlusArray(o, realArgs)); } } static public class CallMethodOrGetFieldOrGlobalFunction extends CallMethodOrGetField { public CallMethodOrGetFieldOrGlobalFunction() { } public MethodOnObject globalFunction; static final public Object notFoundSentinel = new Object(); public CallMethodOrGetFieldOrGlobalFunction(Evaluable target, String name, MethodOnObject globalFunction) { this.globalFunction = globalFunction; this.name = name; this.target = target; } public String toString() { return target + "." + name + "+"; } public Object evalOnTarget(VarContext ctx, Object o) { Object result = preciseGetOrCallMethod_sentinel(o, name, notFoundSentinel); if (result != notFoundSentinel) return result; return newPreciseCall(globalFunction.object, globalFunction.method, o); } } abstract static public class LambdaBase extends EvaluableBase implements IFieldsToList { public Class intrface; public LambdaBase() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface }; } transient public Method implementedMethod; public LambdaBase(Class intrface) { this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); } } static public class LambdaMethodOnArgument extends LambdaBase { public String methodName; public Evaluable[] args; public LambdaMethodOnArgument(Class intrface, String methodName, Evaluable[] args) { super(intrface); this.args = args; this.methodName = methodName; } public Object get(VarContext ctx) { return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { if (method.getDeclaringClass() == intrface) return forwardCall(actualArgs[0], ctx); else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); }); } public Object forwardCall(Object target, VarContext ctx) { return call(target, methodName, evalArgs(args, ctx)); } } static public class LambdaDef extends EvaluableBase implements IFieldsToList { public Class intrface; public String[] args; public Evaluable body; public LambdaDef() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ", " + args + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface, args, body }; } transient public Method implementedMethod; public LambdaDef(Class intrface, String[] args, Evaluable body) { this.body = body; this.args = args; this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); if (implementedMethod.getParameterCount() != l(args)) throw fail("Bad parameter count for lambda: " + implementedMethod + " vs: " + joinWithComma(args)); } public Object get(VarContext ctx) { return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { ping(); if (method.getDeclaringClass() == intrface) { var ctx2 = new FlexibleVarContext(ctx); var argNames = args; for (int i = 0; i < l(args); i++) ctx2.put(argNames[i], actualArgs[i]); return body.get(ctx2); } else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); }); } } abstract static public class CurriedLambdaBase extends EvaluableBase implements IFieldsToList { public Class intrface; public Evaluable[] curriedArgs; public CurriedLambdaBase() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + intrface + ", " + curriedArgs + ")"; } public Object[] _fieldsToList() { return new Object[] { intrface, curriedArgs }; } transient public Method implementedMethod; public CurriedLambdaBase(Class intrface, Evaluable[] curriedArgs) { this.curriedArgs = curriedArgs; this.intrface = intrface; implementedMethod = findSingleInterfaceMethodOrFail(intrface); } public Object get(VarContext ctx) { try { Object[] curriedArguments = evalArgs(curriedArgs, ctx); return proxyFromInvocationHandler(intrface, (proxy, method, actualArgs) -> { try { if (method.getDeclaringClass() == intrface) return forwardCall(ctx, concatMethodArgs(curriedArguments, actualArgs)); else return handleObjectMethodsInProxyInvocationHandler(this, implementedMethod, method, proxy, actualArgs); } catch (Throwable e) { throw rethrowWithSrc(e); } }); } catch (Throwable e) { throw rethrowWithSrc(e); } } abstract public Object forwardCall(VarContext ctx, Object[] args); } static public class CurriedMethodLambda extends CurriedLambdaBase { public CurriedMethodLambda() { } public Object target; public String targetMethod; public CurriedMethodLambda(Class intrface, Object target, String targetMethod, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.targetMethod = targetMethod; this.target = target; } public Object forwardCall(VarContext ctx, Object[] args) { return call(target, targetMethod, args); } } static public class CurriedScriptFunctionLambda extends CurriedLambdaBase { public FunctionDef f; public CurriedScriptFunctionLambda(Class intrface, FunctionDef f, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.f = f; } public Object forwardCall(VarContext ctx, Object[] args) { return f.call(ctx, args); } } static public class CurriedConstructorLambda extends CurriedLambdaBase { public Constructor[] ctors; public CurriedConstructorLambda(Class intrface, Constructor[] ctors, Evaluable[] curriedArgs) { super(intrface, curriedArgs); this.ctors = ctors; } public Object forwardCall(VarContext ctx, Object[] args) { return preciseNuObject(ctors, args); } } static public class DirectMethodCallOnKnownTarget extends EvaluableBase implements IFieldsToList { public boolean widening = false; public Object target; public Method method; public Evaluable[] args; public DirectMethodCallOnKnownTarget() { } public DirectMethodCallOnKnownTarget(boolean widening, Object target, Method method, Evaluable[] args) { this.args = args; this.method = method; this.target = target; this.widening = widening; } public Object[] _fieldsToList() { return new Object[] { widening, target, method, args }; } public Object get(VarContext ctx) { var evaluatedArgs = evalArgs(args, ctx); return widening ? invokeMethodWithWidening(method, target, evaluatedArgs) : invokeMethod(method, target, evaluatedArgs); } public String toString() { return (target == null ? "" : target + ".") + formatFunctionCall(str(method), args); } public LASValueDescriptor returnType() { return LASValueDescriptor.fromClass(method.getReturnType()); } } static public class While extends EvaluableBase implements IFieldsToList { public Evaluable condition; public Evaluable body; public While() { } public While(Evaluable condition, Evaluable body) { this.body = body; this.condition = condition; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + condition + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { condition, body }; } public Object get(VarContext ctx) { while (!ctx.exiting() && (Boolean) condition.get(ctx)) { body.get(ctx); } return null; } } abstract static public class ForEachBase extends EvaluableBase implements IFieldsToList { public Evaluable collection; public Evaluable body; public ForEachBase() { } public ForEachBase(Evaluable collection, Evaluable body) { this.body = body; this.collection = collection; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + collection + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { collection, body }; } public Object get(VarContext ctx) { var coll = collection.get(ctx); Iterator iterator; List out; try { if (coll == null) out = new ArrayList(); else if (coll.getClass().isArray()) { if (coll instanceof Object[]) { var array = (Object[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof byte[]) { var array = (byte[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof short[]) { var array = (short[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof double[]) { var array = (double[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof float[]) { var array = (float[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof int[]) { var array = (int[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof long[]) { var array = (long[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof char[]) { var array = (char[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else if (coll instanceof boolean[]) { var array = (boolean[]) coll; out = emptyList(array.length); for (var element : array) { if (ctx.exiting()) return null; processElement(ctx, out, element); } } else throw fail("todo for each with: " + coll); } else if (coll instanceof Iterable) { out = emptyList((Iterable) coll); iterator = ((Iterable) coll).iterator(); try { while (iterator.hasNext()) { if (ctx.exiting()) return null; var element = iterator.next(); processElement(ctx, out, element); } } finally { if (iterator instanceof AutoCloseable) { try { ((AutoCloseable) iterator).close(); } catch (Exception __e) { throw rethrow(__e); } } } } else throw fail("Not iterable: " + className(coll)); } finally { loopDone(ctx); } return out; } abstract public void processElement(VarContext ctx, List out, Object o); abstract public void loopDone(VarContext ctx); } static public class ForEach extends ForEachBase { public ForEach() { } public String var; public ForEach(Evaluable collection, String var, Evaluable body) { this.body = body; this.var = var; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { ctx.set(var, o); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(var); } } static public class ForIterator extends EvaluableBase implements IFieldsToList { static final public String _fieldOrder = "iterable var body"; public Evaluable iterable; public String var; public Evaluable body; public ForIterator() { } public ForIterator(Evaluable iterable, String var, Evaluable body) { this.body = body; this.var = var; this.iterable = iterable; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + iterable + ", " + var + ", " + body + ")"; } public boolean equals(Object o) { if (!(o instanceof ForIterator)) return false; ForIterator __5 = (ForIterator) o; return eq(iterable, __5.iterable) && eq(var, __5.var) && eq(body, __5.body); } public int hashCode() { int h = -214906825; h = boostHashCombine(h, _hashCode(iterable)); h = boostHashCombine(h, _hashCode(var)); h = boostHashCombine(h, _hashCode(body)); return h; } public Object[] _fieldsToList() { return new Object[] { iterable, var, body }; } public Object get(VarContext ctx) { VarContext subContext = new FlexibleVarContext(ctx); var iterable = this.iterable.get(ctx); Iterator iterator = iterator_gen(iterable); return new MapI(value -> { subContext.set(var, value); return body.get(subContext); }, iterator); } } static public class ForNested extends EvaluableBase implements IFieldsToList { static final public String _fieldOrder = "iterable var body"; public Evaluable iterable; public String var; public Evaluable body; public ForNested() { } public ForNested(Evaluable iterable, String var, Evaluable body) { this.body = body; this.var = var; this.iterable = iterable; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + iterable + ", " + var + ", " + body + ")"; } public boolean equals(Object o) { if (!(o instanceof ForNested)) return false; ForNested __6 = (ForNested) o; return eq(iterable, __6.iterable) && eq(var, __6.var) && eq(body, __6.body); } public int hashCode() { int h = -1363247360; h = boostHashCombine(h, _hashCode(iterable)); h = boostHashCombine(h, _hashCode(var)); h = boostHashCombine(h, _hashCode(body)); return h; } public Object[] _fieldsToList() { return new Object[] { iterable, var, body }; } public Object get(VarContext ctx) { VarContext subContext = new FlexibleVarContext(ctx); var iterable = this.iterable.get(ctx); Iterator iterator = iterator_gen(iterable); return nestedIterator(iterator, value -> { subContext.set(var, value); return iterator_gen(body.get(subContext)); }); } } static public class ForPairs extends ForEachBase { public ForPairs() { } public String varA, varB; public ForPairs(Evaluable collection, Evaluable body, String varA, String varB) { this.varB = varB; this.varA = varA; this.body = body; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { Pair p = (Pair) o; ctx.set(varA, p.a); ctx.set(varB, p.b); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(varA); ctx.unset(varB); } } static public class ForKeyValue extends EvaluableBase implements IFieldsToList { public Evaluable map; public Evaluable body; public String varA; public String varB; public ForKeyValue() { } public ForKeyValue(Evaluable map, Evaluable body, String varA, String varB) { this.varB = varB; this.varA = varA; this.body = body; this.map = map; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + map + ", " + body + ", " + varA + ", " + varB + ")"; } public Object[] _fieldsToList() { return new Object[] { map, body, varA, varB }; } public Object get(VarContext ctx) { Map theMap = (Map) map.get(ctx); List out; try { if (theMap != null) { out = emptyList(theMap.size()); for (var entry : theMap.entrySet()) { if (ctx.exiting()) return null; ctx.set(varA, entry.getKey()); ctx.set(varB, entry.getValue()); out.add(body.get(ctx)); } } else out = new ArrayList(); } finally { ctx.unset(varA); ctx.unset(varB); } return out; } } static public class ForIntTo extends EvaluableBase implements IFieldsToList { public Evaluable endValue; public String var; public Evaluable body; public ForIntTo() { } public ForIntTo(Evaluable endValue, String var, Evaluable body) { this.body = body; this.var = var; this.endValue = endValue; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + endValue + ", " + var + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { endValue, var, body }; } public Evaluable optimize() { if (!returnValueNeeded) body = body.optimizeForReturnValueNotNeeded(); return this; } public Object get(VarContext ctx) { int n = (Integer) endValue.get(ctx), i = 0; List out = returnValueNeeded ? new ArrayList() : null; try { ctx.put(var, i); while (i < n) { if (ctx.exiting()) return null; Object o = body.get(ctx); { if (out != null) out.add(o); } ctx.set(var, i = (Integer) ctx.get(var) + 1); } } finally { ctx.unset(var); } return out; } } static public class ForIndex extends EvaluableBase { public ForIndex() { } public Evaluable collection, body; public String varIndex, varElement; public ForIndex(Evaluable collection, Evaluable body, String varIndex, String varElement) { this.varElement = varElement; this.varIndex = varIndex; this.body = body; this.collection = collection; } public Object get(VarContext ctx) { return new ForIndex_instance(collection, body, varIndex, varElement).get(ctx); } } static public class ForIndex_instance extends ForEachBase { public String varIndex, varElement; public int index; public ForIndex_instance(Evaluable collection, Evaluable body, String varIndex, String varElement) { this.varElement = varElement; this.varIndex = varIndex; this.body = body; this.collection = collection; } public void processElement(VarContext ctx, List out, Object o) { ctx.set(varIndex, index++); ctx.set(varElement, o); out.add(body.get(ctx)); } public void loopDone(VarContext ctx) { ctx.unset(varIndex); ctx.unset(varElement); } } static public class IfThen extends EvaluableBase implements IFieldsToList { public Evaluable condition; public Evaluable body; public Evaluable elseBranch; public IfThen() { } public IfThen(Evaluable condition, Evaluable body, Evaluable elseBranch) { this.elseBranch = elseBranch; this.body = body; this.condition = condition; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + condition + ", " + body + ", " + elseBranch + ")"; } public Object[] _fieldsToList() { return new Object[] { condition, body, elseBranch }; } public IfThen(Evaluable condition, Evaluable body) { this.condition = condition; this.body = body; } public Object get(VarContext ctx) { if ((Boolean) condition.get(ctx)) return body.get(ctx); else if (elseBranch != null) return elseBranch.get(ctx); else return null; } } static public class ReturnFromScript extends EvaluableBase implements IFieldsToList { public Script script; public Evaluable value; public ReturnFromScript() { } public ReturnFromScript(Script script, Evaluable value) { this.value = value; this.script = script; } public Object[] _fieldsToList() { return new Object[] { script, value }; } public Object get(VarContext ctx) { Object result = value.get(ctx); ctx.exitFromScript(script); ctx.returnValue(result); return null; } public String toString() { return formatFunctionCall("ReturnFromScript", script, value); } } static public class Continue extends EvaluableBase implements IFieldsToList { public Script loopBody; public Continue() { } public Continue(Script loopBody) { this.loopBody = loopBody; } public Object[] _fieldsToList() { return new Object[] { loopBody }; } public Object get(VarContext ctx) { ctx.exitFromScript(loopBody); ctx.returnValue(null); return null; } public String toString() { return formatFunctionCall("Continue", loopBody); } } static public class RepeatN extends EvaluableBase implements IFieldsToList { public Evaluable n; public Evaluable body; public RepeatN() { } public RepeatN(Evaluable n, Evaluable body) { this.body = body; this.n = n; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + n + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { n, body }; } public Object get(VarContext ctx) { long count = ((Number) n.get(ctx)).longValue(); for (int _repeat_0 = 0; _repeat_0 < count; _repeat_0++) { if (ctx.exiting()) return null; body.get(ctx); } return null; } } static public class BoolAnd extends EvaluableBase implements IFieldsToList { public Evaluable a; public Evaluable b; public BoolAnd() { } public BoolAnd(Evaluable a, Evaluable b) { this.b = b; this.a = a; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + a + ", " + b + ")"; } public boolean equals(Object o) { if (!(o instanceof BoolAnd)) return false; BoolAnd __7 = (BoolAnd) o; return eq(a, __7.a) && eq(b, __7.b); } public int hashCode() { int h = 1729330797; h = boostHashCombine(h, _hashCode(a)); h = boostHashCombine(h, _hashCode(b)); return h; } public Object[] _fieldsToList() { return new Object[] { a, b }; } public Object get(VarContext ctx) { if (!((Boolean) a.get(ctx))) return false; return b.get(ctx); } } static public class BoolOr extends EvaluableBase implements IFieldsToList { public Evaluable a; public Evaluable b; public BoolOr() { } public BoolOr(Evaluable a, Evaluable b) { this.b = b; this.a = a; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + a + ", " + b + ")"; } public boolean equals(Object o) { if (!(o instanceof BoolOr)) return false; BoolOr __8 = (BoolOr) o; return eq(a, __8.a) && eq(b, __8.b); } public int hashCode() { int h = 1995447949; h = boostHashCombine(h, _hashCode(a)); h = boostHashCombine(h, _hashCode(b)); return h; } public Object[] _fieldsToList() { return new Object[] { a, b }; } public Object get(VarContext ctx) { if (((Boolean) a.get(ctx))) return true; return b.get(ctx); } } static public class TempBlock extends EvaluableBase implements IFieldsToList { public Evaluable tempExpr; public Evaluable body; public TempBlock() { } public TempBlock(Evaluable tempExpr, Evaluable body) { this.body = body; this.tempExpr = tempExpr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + tempExpr + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { tempExpr, body }; } public Object get(VarContext ctx) { AutoCloseable __2 = (AutoCloseable) (tempExpr.get(ctx)); try { return body.get(ctx); } finally { _close(__2); } } } static public class WillReturn extends EvaluableBase implements IFieldsToList { public Evaluable exp; public Evaluable body; public WillReturn() { } public WillReturn(Evaluable exp, Evaluable body) { this.body = body; this.exp = exp; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + exp + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { exp, body }; } public Object get(VarContext ctx) { body.get(ctx); return exp.get(ctx); } } static public class ClassDef extends EvaluableBase implements IFieldsToList { public ResolvableLASClass lasClass; public ClassDef() { } public ClassDef(ResolvableLASClass lasClass) { this.lasClass = lasClass; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + lasClass + ")"; } public boolean equals(Object o) { if (!(o instanceof ClassDef)) return false; ClassDef __9 = (ClassDef) o; return eq(lasClass, __9.lasClass); } public int hashCode() { int h = 757052301; h = boostHashCombine(h, _hashCode(lasClass)); return h; } public Object[] _fieldsToList() { return new Object[] { lasClass }; } public Object get(VarContext ctx) { return lasClass.get(); } } static public class SetField extends EvaluableBase implements IFieldsToList { public Evaluable target; public String name; public Evaluable expr; public SetField() { } public SetField(Evaluable target, String name, Evaluable expr) { this.expr = expr; this.name = name; this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ", " + name + ", " + expr + ")"; } public Object[] _fieldsToList() { return new Object[] { target, name, expr }; } final public SetField setAllowNullReference(boolean allowNullReference) { return allowNullReference(allowNullReference); } public SetField allowNullReference(boolean allowNullReference) { this.allowNullReference = allowNullReference; return this; } final public boolean getAllowNullReference() { return allowNullReference(); } public boolean allowNullReference() { return allowNullReference; } public boolean allowNullReference = false; public Object handleNullReference() { if (allowNullReference) return null; else throw new NullPointerException(); } public Object get(VarContext ctx) { try { Object value = expr.get(ctx); Object object = target.get(ctx); if (object == null) handleNullReference(); else set(object, name, value); return value; } catch (Throwable e) { throw rethrowWithSrc(e); } } } static public class SetStaticField extends EvaluableBase implements IFieldsToList { public Field field; public Evaluable expr; public SetStaticField() { } public SetStaticField(Field field, Evaluable expr) { this.expr = expr; this.field = field; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + field + ", " + expr + ")"; } public Object[] _fieldsToList() { return new Object[] { field, expr }; } public Object get(VarContext ctx) { try { Object value = expr.get(ctx); field.set(null, value); return value; } catch (Throwable e) { throw rethrowWithSrc(e); } } } static public class Throw extends EvaluableBase implements IFieldsToList { public Evaluable expr; public Throw() { } public Throw(Evaluable expr) { this.expr = expr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + expr + ")"; } public Object[] _fieldsToList() { return new Object[] { expr }; } public Object get(VarContext ctx) { throw asRuntimeException((Throwable) expr.get(ctx)); } } static public class TryCatch extends EvaluableBase implements IFieldsToList { public Evaluable body; public String var; public Evaluable catchBlock; public TryCatch() { } public TryCatch(Evaluable body, String var, Evaluable catchBlock) { this.catchBlock = catchBlock; this.var = var; this.body = body; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + body + ", " + var + ", " + catchBlock + ")"; } public Object[] _fieldsToList() { return new Object[] { body, var, catchBlock }; } public Object get(VarContext ctx) { try { return body.get(ctx); } catch (Throwable e) { var addVar = var == null ? null : ctx.tempPut(var, e); AutoCloseable __3 = addVar; try { return catchBlock.get(ctx); } finally { _close(__3); } } } } static public class TryFinally extends EvaluableBase implements IFieldsToList { public Evaluable body; public Evaluable finallyBlock; public TryFinally() { } public TryFinally(Evaluable body, Evaluable finallyBlock) { this.finallyBlock = finallyBlock; this.body = body; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + body + ", " + finallyBlock + ")"; } public Object[] _fieldsToList() { return new Object[] { body, finallyBlock }; } public Object get(VarContext ctx) { try { return body.get(ctx); } finally { finallyBlock.get(ctx); } } } static public structure_Data structureDataForLAS() { structure_Data d = new structure_Data(); d.skipDefaultValues(true); d.shouldIncludeField = field -> { String c = shortClassName(field.getDeclaringClass()); String f = field.getName(); boolean shouldInclude = !(eq(c, "HasTokenRangeWithSrc") && eq(f, "src")); return shouldInclude; }; return d; } static public boolean isUnproblematicValue(Object o) { return o == null || o instanceof Number || o instanceof String || o instanceof Boolean || o instanceof Class; } static public String scriptStruct(Object o) { String s = struct(o, structureDataForLAS()); List tok = structTok(s); String prefix = shortName(GazelleV_LeftArrowScript.class) + "$"; for (int i = 1; i < l(tok); i += 2) tok.set(i, replacePrefix(prefix, "$", tok.get(i))); return join(tok); } static public String indentedScriptStruct(Object o) { return indentStructureString(scriptStruct(o)); } static public Evaluable _const(Object o) { return new Const(o); } static public class Then extends CallOnTarget { public CallOnTarget call1, call2; public Then(CallOnTarget call1, CallOnTarget call2) { this.call2 = call2; this.call1 = call1; target = call1.target; call1.target = null; } public Object evalOnTarget(VarContext ctx, Object object) { call1.evalOnTarget(ctx, object); return call2.evalOnTarget(ctx, object); } } } static public class G22MeshGroup implements MakesBufferedImage, IFieldsToList { public List meshes; public G22MeshGroup() { } public G22MeshGroup(List meshes) { this.meshes = meshes; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + meshes + ")"; } public Object[] _fieldsToList() { return new Object[] { meshes }; } public Rect bounds() { return mergeRects(map(meshes, m -> m.bounds())); } public int getWidth() { return bounds().w; } public int getHeight() { return bounds().h; } public BufferedImage getBufferedImage() { var r = bounds(); if (r == null) return null; return new G22VisualizeMeshes(widthAndHeight(r.x2(), r.y2()), meshes).get(); } } public interface G22MasterStuff { public RunnablesReferenceQueue runnablesReferenceQueue(); public EphemeralObjectIDs ephemeralObjectIDs(); public File databasesMotherDir(); default public IG22LoadedDB openDatabase(File dir) { return openDatabase(dir, false); } public IG22LoadedDB openDatabase(File dir, boolean hidden); default public IG22LoadedDB openDB(String dbName) { return openDB(dbName, false); } public IG22LoadedDB openDB(String dbName, boolean hidden); public void closeDatabase(File dir); public void switchToDatabase(File dir); public Collection openConceptDirs(); public IG22LoadedDB getLoadedDB(Concepts concepts); public IG22LoadedDB getLoadedDBForConceptDir(File dir); default public Collection openProjects() { return getLoadedDBs(); } public Collection getLoadedDBs(); public G22MasterStuff onLoadedDBsChange(Runnable r); public G22MasterStuff removeLoadedDBsChangeListener(Runnable r); public IF1 makeClassFinder(); public IF0WithChangeListeners lvGazelleUserCount(); public ILASClassLoader lasClassLoader(); public boolean devMode(); public void newClassesDefined(); public G22MasterStuff onNewClassesDefined(Runnable r); public G22MasterStuff removeNewClassesDefinedListener(Runnable r); default public boolean isConceptDirLoaded(File dir) { return getLoadedDBForConceptDir(dir) != null; } public void restart(); } static public class G22HolePaths implements IFieldsToList { public IImageRegion region; public G22HolePaths() { } public G22HolePaths(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } public List get() { List outlines = region.createdWithDiagonals() ? g22_allBorderTraces_withDiagonals(region) : g22_allBorderTraces(region); return map(dropFirst(outlines), points -> new OnePathWithOrigin(points, false)); } } static public class Gazelle22_GradientImage { public BWImage posterized; public double gradientThreshold = .25; public BWImage out; public PosterizeBWImage op; public BWImage unposterized; public int w, h, brightnessLevels, singleStep; public Gazelle22_GradientImage(BWImage posterized) { this.posterized = posterized; } public boolean init() { op = (PosterizeBWImage) getMetaSrc(posterized); if (op == null) return false; unposterized = op.img; brightnessLevels = op.brightnessLevels; assertSameSize(unposterized, posterized); w = posterized.getWidth(); h = posterized.getHeight(); singleStep = iceil(doubleRatio(255, brightnessLevels - 1)); return true; } public BWImage get() { init(); out = new BWImage(w * 2 + 1, h * 2 + 1); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (x < w - 1) checkPair(x, y, x + 1, y); if (y < h - 1) checkPair(x, y, x, y + 1); } return out; } public boolean isGradientPoint(int x, int y) { if (op == null) return false; IntMinMax posterizedMinMax = new IntMinMax(); IntMinMax unposterizedMinMax = new IntMinMax(); for (int y2 = max(0, y - 1); y2 <= min(h - 1, y + 1); y2++) for (int x2 = max(0, x - 1); x2 <= min(w - 1, x + 1); x2++) { posterizedMinMax.add(posterized.getInt(x2, y2)); unposterizedMinMax.add(unposterized.getInt(x2, y2)); } int posterizedContrast = posterizedMinMax.rangeLength(); if (posterizedContrast > singleStep) return false; if (posterizedContrast == 0) return true; int unposterizedContrast = unposterizedMinMax.rangeLength(); return unposterizedContrast <= posterizedContrast * gradientThreshold; } public void checkPair(int x, int y, int x2, int y2) { int posterizedContrast = absDiff(posterized.getInt(x, y), posterized.getInt(x2, y2)); if (posterizedContrast == 0) return; if (posterizedContrast > singleStep) return; int realContrast = absDiff(unposterized.getInt(x, y), unposterized.getInt(x2, y2)); double ratio = doubleRatio(realContrast, singleStep); float result = (float) ((.5 - ratio) * 2); { out.setPixel(x * 2 + 1 - (y2 - y), y * 2 + 1, result); out.setPixel(x * 2 + 1, y * 2 + 1 - (x2 - x), result); } } } static public class Welford implements IFieldsToList { static final public String _fieldOrder = "count mean m2"; public long count; public double mean; public double m2; public Welford() { } public Welford(long count, double mean, double m2) { this.m2 = m2; this.mean = mean; this.count = count; } public boolean equals(Object o) { if (!(o instanceof Welford)) return false; Welford __1 = (Welford) o; return count == __1.count && mean == __1.mean && m2 == __1.m2; } public int hashCode() { int h = -1397124871; h = boostHashCombine(h, _hashCode(count)); h = boostHashCombine(h, _hashCode(mean)); h = boostHashCombine(h, _hashCode(m2)); return h; } public Object[] _fieldsToList() { return new Object[] { count, mean, m2 }; } public void add(double newValue) { count++; double delta = newValue - mean; mean += delta / count; double delta2 = newValue - mean; m2 += delta * delta2; } public void remove(double valueToRemove) { guarantee(count > 0); double newValue = valueToRemove; double delta2 = newValue - mean; mean = (mean - newValue / count) / (1 - 1.0 / count); double delta = newValue - mean; m2 -= delta * delta2; --count; } public boolean isEmpty() { return count == 0; } final public double avg() { return average(); } final public double mean() { return average(); } public double average() { return count == 0 ? Double.NaN : mean; } public double variance() { return count == 0 ? Double.NaN : m2 / count; } public double sampleVariance() { return count < 2 ? Double.NaN : m2 / (count - 1); } public double standardDeviation() { return sqrt(variance()); } public String toString() { String s = nValues(count); if (!isEmpty()) s += ", avg: " + avg() + ", std dev: " + standardDeviation(); return s; } public AverageAndStandardDeviation get() { return new AverageAndStandardDeviation(avg(), standardDeviation()); } } static public class G22AnalyzersPanel extends G22CRUDAndDetailPanel { public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22Analyzer.class); crud.entityName = () -> "Analyzer"; g22utils.setupScriptCRUD(crud); return crud; } public void crudVisualized() { super.crudVisualized(); crud.addButton(jPopDownButton_noText("Copy to other project...", runnableThread(new Runnable() { public void run() { try { copyToOtherProject(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyToOtherProject();"; } }))); } public void copyToOtherProject() { var analyzer = crud.selected(); var srcProject = g22utils.getLoadedDB(); var projects = g22utils.masterStuff().getLoadedDBs(); var cbProject = jTypedComboBox(listMinus(projects, srcProject)); packFrame(showFormTitled3("Copy analyzer to other project", "Copy analyzer", str(analyzer), "From project", str(srcProject), "To project", cbProject, "", jThreadedButton("Copy", () -> copyToOtherProject(analyzer, getSelectedItem_typed(cbProject)))).visualize()); } public void copyToOtherProject(G22Analyzer src, IG22LoadedDB project) { G22Analyzer clone = new G22Analyzer(); clone.description(src.description).text(src.text).clearedForAutoRun(src.clearedForAutoRun).editingText(src.editingText).importNote("Copied from project " + quote(g22utils.masterStuff().getLoadedDB(src.concepts())) + " on " + localDateWithSeconds()); registerConcept(project.concepts(), clone); infoBox("Made clone: " + clone); } public JComponent makeDetailView(G22Analyzer script) { var scriptIDE = new G22AnalyzerIDE(g22utils); scriptIDE.setScript(script); return scriptIDE.visualize(); } public SimpleCRUD_v2 scriptCRUD() { return crud(); } public G22AnalyzersPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } } static public class G22StrategyRun { final public G22StrategyRun setStrategy(G22TradingStrategy strategy) { return strategy(strategy); } public G22StrategyRun strategy(G22TradingStrategy strategy) { this.strategy = strategy; return this; } final public G22TradingStrategy getStrategy() { return strategy(); } public G22TradingStrategy strategy() { return strategy; } public G22TradingStrategy strategy; final public G22StrategyRun setTicker(TickerSequence ticker) { return ticker(ticker); } public G22StrategyRun ticker(TickerSequence ticker) { this.ticker = ticker; return this; } final public TickerSequence getTicker() { return ticker(); } public TickerSequence ticker() { return ticker; } public TickerSequence ticker; final public G22StrategyRun setProfitTicker(TickerSequence profitTicker) { return profitTicker(profitTicker); } public G22StrategyRun profitTicker(TickerSequence profitTicker) { this.profitTicker = profitTicker; return this; } final public TickerSequence getProfitTicker() { return profitTicker(); } public TickerSequence profitTicker() { return profitTicker; } public TickerSequence profitTicker = new TickerSequence(); final public G22StrategyRun setFinalProfit(double finalProfit) { return finalProfit(finalProfit); } public G22StrategyRun finalProfit(double finalProfit) { this.finalProfit = finalProfit; return this; } final public double getFinalProfit() { return finalProfit(); } public double finalProfit() { return finalProfit; } public double finalProfit; public double totalProfit() { return finalProfit; } public void run() { try { strategy(strategy.emptyClone()); strategy.logToPrint(false); strategy.primed(true); strategy.active(true); for (var pricePoint : ticker.pricePoints()) { if (!strategy.active()) break; strategy.feed(pricePoint); double profit = strategy.coinProfit(); profitTicker.addIfPriceChanged(profit, pricePoint.timestamp); } strategy.closeMyself(); finalProfit(strategy.coinProfit()); } catch (Exception __e) { throw rethrow(__e); } } } static public class MouseInComponentMonitor extends BoolVarWithNotify implements MouseListener, MouseMotionListener { public JComponent component; final public MouseInComponentMonitor setVerbose(boolean verbose) { return verbose(verbose); } public MouseInComponentMonitor verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; public MouseInComponentMonitor() { } public MouseInComponentMonitor(JComponent component) { init(component); } public void init(JComponent component) { if (this.component != null) throw fail("Already initialized"); this.component = component; addMouseListener(component, this); addMouseMotionListener(component, this); } public void print(String s) { if (verbose) loadableUtils.utils.print(s); } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { print("mouseEntered"); set(true); } public void mouseExited(MouseEvent e) { print("mouseExited"); set(false); } public void mouseMoved(MouseEvent e) { print("mouseMoved"); set(true); } public void mouseDragged(MouseEvent e) { } } static public class G22Mesh extends Meta implements MakesBufferedImage { public G22Mesh() { } public LinkedHashMap anchorMap = new LinkedHashMap(); final public LinkedHashSet getCurves() { return curves(); } public LinkedHashSet curves() { return curves; } public LinkedHashSet curves = new LinkedHashSet(); public String cachedSignature; static public class Curve { public Curve() { } final public Anchor getStart() { return start(); } public Anchor start() { return start; } public Anchor start; final public Anchor getEnd() { return end(); } public Anchor end() { return end; } public Anchor end; final public OnePathWithOrigin getPath() { return path(); } public OnePathWithOrigin path() { return path; } public OnePathWithOrigin path; public Curve(Anchor start, Anchor end, List points) { this(start, end, new OnePathWithOrigin(points, false)); } public Curve(Anchor start, Anchor end, OnePathWithOrigin path) { this.path = path; this.end = end; this.start = start; start.outgoingCurves.add(this); end.incomingCurves.add(this); } public String toString() { return "Curve of length " + n2(path.nSteps()) + " connecting " + (start == null ? null : start.shortToString() + " and " + (end == null ? null : end.shortToString())); } public int length() { return path.nSteps(); } public List anchors() { return ll(start, end); } public boolean connectedTo(Anchor a) { return start == a || end == a; } public Anchor anchor(boolean endAnchor) { return endAnchor ? end : start; } public Anchor anchorOpposite(Anchor a) { return a == start ? end : a == end ? start : null; } } static public class Anchor { public Anchor() { } public int index; final public Pt getPt() { return pt(); } public Pt pt() { return pt; } public Pt pt; public List outgoingCurves = new ArrayList(); public List incomingCurves = new ArrayList(); public Anchor(int index, Pt pt) { this.pt = pt; this.index = index; } public int arity() { return l(outgoingCurves) + l(incomingCurves); } public String shortToString() { return "Anchor " + index + " at " + pt; } public String toString() { List connections = sorted(map(connectedToAnchors(), a -> a.index)); return shortToString() + ", arity " + arity() + stringIf(isRingAnchor(), " [arbitrarily chosen ring anchor]") + (empty(connections) ? "" : ", connected to " + joinWithComma(connections)); } public Set curves() { return joinSets(outgoingCurves, incomingCurves); } public Set connectedToAnchors() { return joinSets(map(outgoingCurves, c -> c.end), map(incomingCurves, c -> c.start)); } public boolean isRingAnchor() { return l(outgoingCurves) == 1 && l(incomingCurves) == 1 && first(outgoingCurves) == first(incomingCurves); } } public Collection anchorPts() { return keys(anchorMap); } public Collection anchors() { return values(anchorMap); } public int nAnchors() { return l(anchorMap); } public List anchorList() { return valuesList(anchorMap); } public Anchor getAnchor(Pt p) { return anchorMap.get(p); } public Anchor getAnchor(int idx) { return anchorList().get(idx); } public void checkArities() { MultiMap outgoing = new MultiMap(); MultiMap incoming = new MultiMap(); for (Curve curve : curves) { outgoing.add(curve.start, curve); if (!anchorMap.containsKey(curve.start.pt)) throw fail("Start of curve not found: " + curve); incoming.add(curve.end, curve); if (!anchorMap.containsKey(curve.end.pt)) throw fail("End of curve not found: " + curve); } for (Anchor anchor : anchors()) { assertSetEquals(anchor + " outgoing", outgoing.get(anchor), anchor.outgoingCurves); assertSetEquals(anchor + " incoming", incoming.get(anchor), anchor.incomingCurves); } } final public Anchor addAnchor(Pt p) { return newAnchor(p); } public Anchor newAnchor(Pt p) { Anchor anchor = new Anchor(l(anchorMap) + 1, p); anchorMap.put(p, anchor); _invalidateSignature(); return anchor; } public void removeAnchor(Anchor anchor) { anchorMap.remove(anchor.pt); } public Curve addCurve(Curve curve) { curves.add(curve); _invalidateSignature(); return curve; } public void removeCurve(Curve curve) { curves.remove(curve); curve.start.outgoingCurves.remove(curve); curve.end.incomingCurves.remove(curve); _invalidateSignature(); } public int[] sortedArities() { int[] array = mapToIntArray(anchors(), a -> a.arity()); return sortIntArrayInPlaceDesc(array); } final public String aritySignature() { return sortedAritiesToString(); } final public String signature() { return sortedAritiesToString(); } public String sortedAritiesToString() { { var __1 = cachedSignature; if (__1 != null) return __1; } int[] arities = sortedArities(); boolean compact = all(arities, arity -> arity < 10); return cachedSignature = compact ? join(asList(arities)) : roundBracket(joinWithComma(asList(arities))); } public String toString() { return "Mesh type " + sortedAritiesToString(); } public void renumberAnchors() { int i = 0; for (var anchor : anchors()) anchor.index = ++i; } public Rect bounds() { BoundsFinder bf = new BoundsFinder(); for (var p : keys(anchorMap)) bf.add(p); for (var curve : curves) for (var p : curve.path.pointIterator()) bf.add(p); return bf.get(); } public int getWidth() { return bounds().w; } public int getHeight() { return bounds().h; } public BufferedImage getBufferedImage() { var r = bounds(); return new G22VisualizeMeshes(widthAndHeight(r.x2() + 2, r.y2() + 2), ll(this)).get(); } public void _invalidateSignature() { cachedSignature = null; } public boolean containsAnchor(Anchor a) { return a != null && anchorMap.get(a.pt) == a; } public boolean containsCurve(Curve c) { return curves.contains(c); } public List curveList() { return asList(curves); } public void moveAnchor(Anchor a, Pt p) { if (eq(a.pt(), p)) return; assertNotNull(p); anchorMap.remove(a.pt); a.pt = p; anchorMap.put(p, a); } public void mergeAnchorInto(Anchor a1, Anchor a2) { mergeAnchors(a1, a2, a2.pt); } public void mergeAnchors(Anchor a1, Anchor a2, Pt newPosition) { if (scaffoldingEnabled()) printVars("mergeAnchors", "mesh", this, "a1", a1, "a2", a2, "newPosition", newPosition); assertNotSame(a1, a2); assertNotNull(a1); assertNotNull(a2); for (Curve curve : a1.outgoingCurves) { curve.path.insertStep(0, ptMinus(a1.pt, a2.pt)); curve.path.origin(a2.pt); curve.start = a2; a2.outgoingCurves.add(curve); } for (Curve curve : a1.incomingCurves) { curve.path.addStep(ptMinus(a2.pt, a1.pt)); curve.end = a2; a2.incomingCurves.add(curve); } moveAnchor(a2, newPosition); removeAnchor(a1); } } static public class G22_RegionToSSI implements IFieldsToList { public IImageRegion region; public G22_RegionToSSI() { } public G22_RegionToSSI(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } public SSI get() { if (region == null) return null; Rect r = region.bounds(); int x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2 - y1, w = r.w; SSI ssi = new SSI(y1, y2); ssi.color(region.color()); short[] data = new short[h * 2]; for (int y = y1; y < y2; y++) { var _y_1 = y; List streaks = genericStreaks(w, x -> region.contains(x1 + x, _y_1)); IntRange range = selectHorizontalPart(streaks); int i = (_y_1 - y1) * 2; data[i] = toShort_enforce(x1 + range.start); data[i + 1] = toShort_enforce(x1 + range.end); } ssi.data(data); return ssi; } transient public IF1, IntRange> selectHorizontalPart; public IntRange selectHorizontalPart(List parts) { return selectHorizontalPart != null ? selectHorizontalPart.get(parts) : selectHorizontalPart_base(parts); } final public IntRange selectHorizontalPart_fallback(IF1, IntRange> _f, List parts) { return _f != null ? _f.get(parts) : selectHorizontalPart_base(parts); } public IntRange selectHorizontalPart_base(List parts) { return first(parts); } } static public class JS implements IF0, Htmlable { public JS() { } public String code; public Set requiredLibraries; public Set requiredLibraries() { return requiredLibraries; } public JS(String code, Object... dollarVars) { this.code = jsDollarVars(code, dollarVars); } public String get() { return code; } public String toString() { return unnull(code); } public void requireJQuery() { require("jquery"); } public void require(Object library) { requiredLibraries = addToSet_create(requiredLibraries, library); } public String html() { return hjs(code); } } static public class MPM2 implements IFieldsToList { public float[] ticker; public long[] timestamps; public MPM2() { } public MPM2(float[] ticker, long[] timestamps) { this.timestamps = timestamps; this.ticker = ticker; } public Object[] _fieldsToList() { return new Object[] { ticker, timestamps }; } static public class Market implements IFieldsToList { public double adversity; public Market() { } public Market(double adversity) { this.adversity = adversity; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + adversity + ")"; } public boolean equals(Object o) { if (!(o instanceof Market)) return false; Market __2 = (Market) o; return adversity == __2.adversity; } public int hashCode() { int h = -1997438884; h = boostHashCombine(h, _hashCode(adversity)); return h; } public Object[] _fieldsToList() { return new Object[] { adversity }; } } static public class Position implements IFieldsToList { static final public String _fieldOrder = "openingTime direction"; public double openingTime; public double direction; public Position() { } public Position(double openingTime, double direction) { this.direction = direction; this.openingTime = openingTime; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + openingTime + ", " + direction + ")"; } public boolean equals(Object o) { if (!(o instanceof Position)) return false; Position __3 = (Position) o; return openingTime == __3.openingTime && direction == __3.direction; } public int hashCode() { int h = 812449097; h = boostHashCombine(h, _hashCode(openingTime)); h = boostHashCombine(h, _hashCode(direction)); return h; } public Object[] _fieldsToList() { return new Object[] { openingTime, direction }; } } public class ClosedPosition implements IFieldsToList { public Position p; public double closingTime; public ClosedPosition() { } public ClosedPosition(Position p, double closingTime) { this.closingTime = closingTime; this.p = p; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + p + ", " + closingTime + ")"; } public boolean equals(Object o) { if (!(o instanceof ClosedPosition)) return false; ClosedPosition __0 = (ClosedPosition) o; return eq(p, __0.p) && eq(closingTime, __0.closingTime); } public int hashCode() { int h = 1899462357; h = boostHashCombine(h, _hashCode(p)); h = boostHashCombine(h, _hashCode(closingTime)); return h; } public Object[] _fieldsToList() { return new Object[] { p, closingTime }; } final public ClosedPosition setTicker(Ticker ticker) { return ticker(ticker); } public ClosedPosition ticker(Ticker ticker) { this.ticker = ticker; return this; } final public Ticker getTicker() { return ticker(); } public Ticker ticker() { return ticker; } public Ticker ticker; final public ClosedPosition setProfit(double profit) { return profit(profit); } public ClosedPosition profit(double profit) { this.profit = profit; return this; } final public double getProfit() { return profit(); } public double profit() { return profit; } public double profit; public MPM2 mpm() { return MPM2.this; } public double openingPrice() { return MPM2.this.ticker(p.openingTime); } public double closingPrice() { return MPM2.this.ticker(closingTime); } } static public class Juicer implements IFieldsToList { public double lossTolerance; public double pullback; public Juicer() { } public Juicer(double lossTolerance, double pullback) { this.pullback = pullback; this.lossTolerance = lossTolerance; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + lossTolerance + ", " + pullback + ")"; } public boolean equals(Object o) { if (!(o instanceof Juicer)) return false; Juicer __4 = (Juicer) o; return lossTolerance == __4.lossTolerance && pullback == __4.pullback; } public int hashCode() { int h = -2065131726; h = boostHashCombine(h, _hashCode(lossTolerance)); h = boostHashCombine(h, _hashCode(pullback)); return h; } public Object[] _fieldsToList() { return new Object[] { lossTolerance, pullback }; } } abstract static public class Eye { abstract public double adviseDirection(Ticker ticker); } static public class Ticker implements IFieldsToList { public float[] data; public long[] timestamps; public int length; public long currentTime; public Ticker() { } public Ticker(float[] data, long[] timestamps, int length, long currentTime) { this.currentTime = currentTime; this.length = length; this.timestamps = timestamps; this.data = data; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + data + ", " + timestamps + ", " + length + ", " + currentTime + ")"; } public Object[] _fieldsToList() { return new Object[] { data, timestamps, length, currentTime }; } public double currentPrice() { return data[length - 1]; } public Double lookback(double time) { int index = binarySearch_insertionPoint(wrapLongArrayAsList(timestamps), lceil(currentTime - time)); return index >= 0 ? (double) data[index] : null; } } static public class LiveTicker extends Ticker { public void add(float value, long timestamp) { data = addToArrayWithDoublingStrategy(data, length, value); timestamps = addToArrayWithDoublingStrategy(timestamps, length, timestamp); length++; } } public Ticker ticker() { return new Ticker(ticker, timestamps, l(timestamps), last(timestamps)); } static public class SimpleEye extends Eye implements IFieldsToList { static final public String _fieldOrder = "time minMove"; public double time; public double minMove; public SimpleEye() { } public SimpleEye(double time, double minMove) { this.minMove = minMove; this.time = time; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + time + ", " + minMove + ")"; } public boolean equals(Object o) { if (!(o instanceof SimpleEye)) return false; SimpleEye __5 = (SimpleEye) o; return time == __5.time && minMove == __5.minMove; } public int hashCode() { int h = -120435969; h = boostHashCombine(h, _hashCode(time)); h = boostHashCombine(h, _hashCode(minMove)); return h; } public Object[] _fieldsToList() { return new Object[] { time, minMove }; } public double adviseDirection(Ticker ticker) { Double currentPrice = ticker.currentPrice(); if (currentPrice == null) return 0; Double before = ticker.lookback(time); if (before == null) return 0; double move = currentPrice / before * 100 - 100; if (abs(move) >= minMove) return (double) sign(move); return 0; } } public double ticker(double time) { return ticker[iceil(time)]; } public double openingPrice(Position p) { return ticker(p.openingTime); } public double profit(Position p, double time, Market m) { return (ticker(time) / openingPrice(p) * 100 - 100) * p.direction - m.adversity; } public Double closingTime(Position p, Juicer j, Market m) { int time = iceil(p.openingTime); double openingPrice = ticker(time); double crest = -infinity(); while (time < ticker.length - 1) { double profit = profit(p, time, m); crest = max(crest, profit); if (profit < (profit < 0 ? -j.lossTolerance : crest - j.pullback)) return (double) time; ++time; } return null; } public Double profit(Position p, Juicer j, Market m) { Double closingTime = closingTime(p, j, m); return closingTime == null ? null : profit(p, closingTime, m); } public Double profitability(double time, Juicer j, Market m) { return maxAllowingNull(profit(new Position(time, -1), j, m), profit(new Position(time, 1), j, m)); } public class Backtest extends Convergent implements IFieldsToList { public Eye eye; public Juicer j; public Market m; public Backtest() { } public Backtest(Eye eye, Juicer j, Market m) { this.m = m; this.j = j; this.eye = eye; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + eye + ", " + j + ", " + m + ")"; } public Object[] _fieldsToList() { return new Object[] { eye, j, m }; } public Iterator openingTimes = new WeightlessShuffledIterator(intRangeList(ticker.length)); public Average profitPerPosition = new Average(); public Average positionsOpenedPercentage = new Average(); public Average positionsClosedPercentage = new Average(); public List closedPositions = new ArrayList(); public Backtest(Juicer j, Market m) { this.m = m; this.j = j; } public void step() { if (!openingTimes.hasNext()) { done = true; return; } int openingTime = openingTimes.next(); Double profit = null; ClosedPosition closedPosition = null; if (eye == null) profit = profitability(openingTime, j, m); else { double direction = eye.adviseDirection(new Ticker(ticker, timestamps, openingTime, timestamps[openingTime])); positionsOpenedPercentage.addSample(direction != 0 ? 100 : 0); if (direction != 0) { Position position = new Position(openingTime, direction); Double closingTime = closingTime(position, j, m); if (closingTime != null) { profit = profit(position, closingTime, m); closedPosition = new ClosedPosition(position, closingTime).ticker(ticker()).profit(profit); closedPositions.add(closedPosition); } } } positionsClosedPercentage.addSample(profit != null ? 100 : 0); if (profit != null) { profitPerPosition.addSample(profit); } else profitPerPosition.addSample(0); value = profitPerPosition.get(); } } } static public class MPM3 { public MPM3() { } final public MPM3 setMarketAdversity(double marketAdversity) { return marketAdversity(marketAdversity); } public MPM3 marketAdversity(double marketAdversity) { this.marketAdversity = marketAdversity; return this; } final public double getMarketAdversity() { return marketAdversity(); } public double marketAdversity() { return marketAdversity; } public double marketAdversity = 0.12 + 0.08; final public double getMaxPositionDuration() { return maxPositionDuration(); } public double maxPositionDuration() { return maxPositionDuration; } public double maxPositionDuration = minutesToMS(60); public double minimalMaxDuration() { return minutesToMS(1); } public MPM3 maxPositionDuration(double whatUserWants) { maxPositionDuration = max(whatUserWants, minimalMaxDuration()); return this; } public class Position implements IFieldsToList { transient public TickerSequence ticker; public double openingTime; public double direction; public Position() { } public Position(TickerSequence ticker, double openingTime, double direction) { this.direction = direction; this.openingTime = openingTime; this.ticker = ticker; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + ticker + ", " + openingTime + ", " + direction + ")"; } public boolean equals(Object o) { if (!(o instanceof Position)) return false; Position __0 = (Position) o; return eq(ticker, __0.ticker) && eq(openingTime, __0.openingTime) && eq(direction, __0.direction); } public int hashCode() { int h = 812449097; h = boostHashCombine(h, _hashCode(ticker)); h = boostHashCombine(h, _hashCode(openingTime)); h = boostHashCombine(h, _hashCode(direction)); return h; } public Object[] _fieldsToList() { return new Object[] { ticker, openingTime, direction }; } final public Position setIrlInfo(Object irlInfo) { return irlInfo(irlInfo); } public Position irlInfo(Object irlInfo) { this.irlInfo = irlInfo; return this; } final public Object getIrlInfo() { return irlInfo(); } public Object irlInfo() { return irlInfo; } public Object irlInfo; final public Position setEye(Eye eye) { return eye(eye); } public Position eye(Eye eye) { this.eye = eye; return this; } final public Eye getEye() { return eye(); } public Eye eye() { return eye; } public Eye eye; public double openingPrice() { return ticker.priceAtTimestamp(openingTime); } public double profitAtTime(double time) { return (ticker.priceAtTimestamp(time) / openingPrice() * 100 - 100) * direction - marketAdversity; } public double openingTime() { return openingTime; } public String directionString() { return direction > 0 ? "long" : direction < 0 ? "short" : ""; } public void restoreTicker(TickerSequence ticker) { this.ticker = ticker; } public TickerPoint openingTickerPoint() { return new TickerPoint(ticker, lround(openingTime)); } } public class LivePosition implements IFieldsToList { public Position p; public LivePosition() { } public LivePosition(Position p) { this.p = p; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + p + ")"; } public boolean equals(Object o) { if (!(o instanceof LivePosition)) return false; LivePosition __1 = (LivePosition) o; return eq(p, __1.p); } public int hashCode() { int h = -1546561963; h = boostHashCombine(h, _hashCode(p)); return h; } public Object[] _fieldsToList() { return new Object[] { p }; } final public LivePosition setJuicer(Juicer juicer) { return juicer(juicer); } public LivePosition juicer(Juicer juicer) { this.juicer = juicer; return this; } final public Juicer getJuicer() { return juicer(); } public Juicer juicer() { return juicer; } public Juicer juicer; final public LivePosition setCrest(double crest) { return crest(crest); } public LivePosition crest(double crest) { this.crest = crest; return this; } final public double getCrest() { return crest(); } public double crest() { return crest; } public double crest = -infinity(); final public LivePosition setTime(double time) { return time(time); } public LivePosition time(double time) { this.time = time; return this; } final public double getTime() { return time(); } public double time() { return time; } public double time; final public LivePosition setProfit(double profit) { return profit(profit); } public LivePosition profit(double profit) { this.profit = profit; return this; } final public double getProfit() { return profit(); } public double profit() { return profit; } public double profit; public TickerSequence ticker() { return p.ticker; } public void restoreTicker(TickerSequence ticker) { p.restoreTicker(ticker); } public double direction() { return p.direction; } public String directionString() { return p.directionString(); } public double openingTime() { return p.openingTime; } public double openingPrice() { return p.openingPrice(); } public Eye eye() { return p.eye(); } public boolean update(double time) { if (time <= this.time) return false; this.time = time; profit = p.profitAtTime(time); crest = max(crest, profit); return true; } transient public Double maxClosingTime_cache; public double maxClosingTime() { if (maxClosingTime_cache == null) maxClosingTime_cache = maxClosingTime_load(); return maxClosingTime_cache; } public double maxClosingTime_load() { return p.ticker.live() ? infinity() : min(p.openingTime + maxPositionDuration, p.ticker.endTime()); } public boolean shouldClose() { return time >= maxClosingTime() || profit < (profit < 0 ? -juicer.lossTolerance : crest - juicer.pullback); } public double closeSignal() { CloseSignal strongestSignal = closeSignalWithDescription(); return strongestSignal == null ? 0 : strongestSignal.trigger; } public CloseSignal closeSignalWithDescription() { return highestBy(closeSignals(), signal -> signal.trigger); } public class CloseSignal implements IFieldsToList { public String reason; public double trigger; public CloseSignal() { } public CloseSignal(String reason, double trigger) { this.trigger = trigger; this.reason = reason; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + reason + ", " + trigger + ")"; } public Object[] _fieldsToList() { return new Object[] { reason, trigger }; } } public List closeSignals() { List signals = new ArrayList(); if (maxClosingTime() < infinity()) signals.add(new CloseSignal("Age", transformToZeroToOne(time, p.openingTime(), maxClosingTime()))); if (profit < 0) signals.add(new CloseSignal("Loss", doubleRatio(-profit, juicer.lossTolerance))); else signals.add(new CloseSignal("Profit", transformToZeroToOne(profit, crest, crest - juicer.pullback))); return signals; } } public class ClosedPosition implements IFieldsToList { public Position p; public double closingTime; public ClosedPosition() { } public ClosedPosition(Position p, double closingTime) { this.closingTime = closingTime; this.p = p; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + p + ", " + closingTime + ")"; } public boolean equals(Object o) { if (!(o instanceof ClosedPosition)) return false; ClosedPosition __2 = (ClosedPosition) o; return eq(p, __2.p) && eq(closingTime, __2.closingTime); } public int hashCode() { int h = 1899462357; h = boostHashCombine(h, _hashCode(p)); h = boostHashCombine(h, _hashCode(closingTime)); return h; } public Object[] _fieldsToList() { return new Object[] { p, closingTime }; } public double profit = Double.NaN; public MPM3 mpm() { return MPM3.this; } public TickerSequence ticker() { return p.ticker; } public void restoreTicker(TickerSequence ticker) { p.restoreTicker(ticker); } public double direction() { return p.direction; } public String directionString() { return p.directionString(); } public double openingTime() { return p.openingTime; } public double openingPrice() { return p.openingPrice(); } public Eye eye() { return p.eye(); } public double closingTime() { return closingTime; } public double closingPrice() { return ticker().priceAtTimestamp(closingTime); } public double duration() { return closingTime() - openingTime(); } public double profit() { if (isNaN(profit)) profit = p.profitAtTime(closingTime); return profit; } } static public class LivePositions { public List positions = syncL(); } static public class ClosedPositions { public List positions = syncL(); } static public class Juicer implements IFieldsToList { public double lossTolerance; public double pullback; public Juicer() { } public Juicer(double lossTolerance, double pullback) { this.pullback = pullback; this.lossTolerance = lossTolerance; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + lossTolerance + ", " + pullback + ")"; } public boolean equals(Object o) { if (!(o instanceof Juicer)) return false; Juicer __4 = (Juicer) o; return lossTolerance == __4.lossTolerance && pullback == __4.pullback; } public int hashCode() { int h = -2065131726; h = boostHashCombine(h, _hashCode(lossTolerance)); h = boostHashCombine(h, _hashCode(pullback)); return h; } public Object[] _fieldsToList() { return new Object[] { lossTolerance, pullback }; } } abstract static public class Eye { abstract public double adviseDirection(TickerPoint tickerPoint); } static public class SimpleEye extends Eye implements IFieldsToList { public long lookbackTime; public double minMove; public SimpleEye() { } public SimpleEye(long lookbackTime, double minMove) { this.minMove = minMove; this.lookbackTime = lookbackTime; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + lookbackTime + ", " + minMove + ")"; } public boolean equals(Object o) { if (!(o instanceof SimpleEye)) return false; SimpleEye __5 = (SimpleEye) o; return lookbackTime == __5.lookbackTime && minMove == __5.minMove; } public int hashCode() { int h = -120435969; h = boostHashCombine(h, _hashCode(lookbackTime)); h = boostHashCombine(h, _hashCode(minMove)); return h; } public Object[] _fieldsToList() { return new Object[] { lookbackTime, minMove }; } final public SimpleEye setRelativeVerificationTime(double relativeVerificationTime) { return relativeVerificationTime(relativeVerificationTime); } public SimpleEye relativeVerificationTime(double relativeVerificationTime) { this.relativeVerificationTime = relativeVerificationTime; return this; } final public double getRelativeVerificationTime() { return relativeVerificationTime(); } public double relativeVerificationTime() { return relativeVerificationTime; } public double relativeVerificationTime; final public SimpleEye setVerificationThreshold(double verificationThreshold) { return verificationThreshold(verificationThreshold); } public SimpleEye verificationThreshold(double verificationThreshold) { this.verificationThreshold = verificationThreshold; return this; } final public double getVerificationThreshold() { return verificationThreshold(); } public double verificationThreshold() { return verificationThreshold; } public double verificationThreshold; public double verificationTime() { return lookbackTime * relativeVerificationTime; } public double verificationMoveThreshold() { return minMove * relativeVerificationTime * verificationThreshold; } public double verificationMove(TickerPoint tickerPoint) { return calculateMove(tickerPoint, verificationTime()); } public double relativeVerificationMove(TickerPoint tickerPoint) { return doubleRatio(verificationMove(tickerPoint) * lookbackTime, verificationTime()); } public double verificationSignal(TickerPoint tickerPoint) { return doubleRatio(verificationMove(tickerPoint), verificationMoveThreshold()); } public boolean verificationEnabled() { return relativeVerificationTime != 0; } public double adviseDirection(TickerPoint tickerPoint) { double move = calculateMove(tickerPoint); if (isNaN(move)) return 0; double relativeMove = doubleRatio(move, minMove); int sign = sign(relativeMove); double absRelativeMove = abs(relativeMove); if (verificationEnabled()) { double verification = max(0, sign * verificationSignal(tickerPoint)); absRelativeMove = min(absRelativeMove, verification); } return sign * absRelativeMove; } public double calculateMove(TickerPoint tickerPoint) { return calculateMove(tickerPoint, this.lookbackTime); } public double calculateMove(TickerPoint tickerPoint, double lookbackTime) { if (!tickerPoint.canLookback(lround(lookbackTime))) return Double.NaN; double currentPrice = tickerPoint.currentPrice(); double before = tickerPoint.lookback(lround(lookbackTime)); return currentPrice / before * 100 - 100; } } static public class TradingBot implements IFieldsToList { public Eye eye; public Juicer juicer; public TradingBot() { } public TradingBot(Eye eye, Juicer juicer) { this.juicer = juicer; this.eye = eye; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + eye + ", " + juicer + ")"; } public boolean equals(Object o) { if (!(o instanceof TradingBot)) return false; TradingBot __6 = (TradingBot) o; return eq(eye, __6.eye) && eq(juicer, __6.juicer); } public int hashCode() { int h = -297894650; h = boostHashCombine(h, _hashCode(eye)); h = boostHashCombine(h, _hashCode(juicer)); return h; } public Object[] _fieldsToList() { return new Object[] { eye, juicer }; } public TradingBot(double lookbackMinutes, double minMove, double maxLoss, double pullback) { eye = new SimpleEye(minutesToMS(lookbackMinutes), minMove); juicer = new Juicer(maxLoss, pullback); } } public class BotInAction extends MetaWithChangeListeners { final public BotInAction setBotConfiguration(TradingBot botConfiguration) { return botConfiguration(botConfiguration); } public BotInAction botConfiguration(TradingBot botConfiguration) { this.botConfiguration = botConfiguration; return this; } final public TradingBot getBotConfiguration() { return botConfiguration(); } public TradingBot botConfiguration() { return botConfiguration; } public TradingBot botConfiguration; transient public TickerSequence ticker; public ListWithChangeListeners openPositions = new ListWithChangeListeners(); public ListWithChangeListeners closedPositions = new ListWithChangeListeners(); public LivePosition openPosition(TickerPoint tickerPoint, double direction) { var p = new Position(tickerPoint.ticker(), tickerPoint.time(), direction); var livePosition = new LivePosition(p).juicer(botConfiguration.juicer); livePosition.update(tickerPoint.time()); openPositions.add(livePosition); change(); return livePosition; } public void closePosition(LivePosition position) { if (openPositions.remove(position)) { change(); } } public void restoreTicker(TickerSequence ticker) { if (ticker == this.ticker) return; this.ticker = ticker; ticker.onPricePointAdded(time -> updatePositions(time)); for (var p : openPositions) p.restoreTicker(ticker); for (var p : closedPositions) p.restoreTicker(ticker); } public void updatePositions(double time) { boolean anyChange = false; for (var p : openPositions) anyChange |= p.update(time); if (anyChange) change(); } } public ClosedPosition runJuicer(Position p, Juicer j) { TickerSequence ticker = p.ticker; long time = lround(p.openingTime); double maxClosingTime = min(time + maxPositionDuration, ticker.endTime()); double crest = -infinity(); while (time < maxClosingTime) { time = ticker.nextTimestamp(time); double profit = p.profitAtTime(time); crest = max(crest, profit); if (profit < (profit < 0 ? -j.lossTolerance : crest - j.pullback)) break; } return new ClosedPosition(p, time); } public class Backtest extends Convergent implements IFieldsToList { public TickerSequence ticker; public TradingBot bot; public Backtest() { } public Backtest(TickerSequence ticker, TradingBot bot) { this.bot = bot; this.ticker = ticker; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + ticker + ", " + bot + ")"; } public Object[] _fieldsToList() { return new Object[] { ticker, bot }; } public List closedPositions = new ArrayList(); public long time; public double latestAllowedOpeningTime() { return ticker.endTime() - maxPositionDuration; } public void step() { if (time == 0) time = ticker.startTime(); if (time > latestAllowedOpeningTime()) { done = true; return; } TickerPoint tickerPoint = new TickerPoint(ticker, time); double direction = bot.eye.adviseDirection(tickerPoint); if (abs(direction) < 1) time = ticker.nextTimestamp(time); else { var position = new Position(ticker, time, direction).eye(bot.eye); var closedPosition = runJuicer(position, bot.juicer); closedPositions.add(closedPosition); time = ticker.nextTimestamp(closedPosition.closingTime); } } } } static public class GazelleV_LeftArrowScriptParser extends SimpleLeftToRightParser { final public GazelleV_LeftArrowScriptParser setMagicSwitch(boolean magicSwitch) { return magicSwitch(magicSwitch); } public GazelleV_LeftArrowScriptParser magicSwitch(boolean magicSwitch) { this.magicSwitch = magicSwitch; return this; } final public boolean getMagicSwitch() { return magicSwitch(); } public boolean magicSwitch() { return magicSwitch; } public boolean magicSwitch = true; public ClassNameResolver classNameResolver; public List functionContainers = new ArrayList(); final public GazelleV_LeftArrowScriptParser setLasClassLoader(ILASClassLoader lasClassLoader) { return lasClassLoader(lasClassLoader); } public GazelleV_LeftArrowScriptParser lasClassLoader(ILASClassLoader lasClassLoader) { this.lasClassLoader = lasClassLoader; return this; } final public ILASClassLoader getLasClassLoader() { return lasClassLoader(); } public ILASClassLoader lasClassLoader() { return lasClassLoader; } public ILASClassLoader lasClassLoader; final public GazelleV_LeftArrowScriptParser setClassDefPrefix(String classDefPrefix) { return classDefPrefix(classDefPrefix); } public GazelleV_LeftArrowScriptParser classDefPrefix(String classDefPrefix) { this.classDefPrefix = classDefPrefix; return this; } final public String getClassDefPrefix() { return classDefPrefix(); } public String classDefPrefix() { return classDefPrefix; } public String classDefPrefix; final public GazelleV_LeftArrowScriptParser setSourceInfo(Object sourceInfo) { return sourceInfo(sourceInfo); } public GazelleV_LeftArrowScriptParser sourceInfo(Object sourceInfo) { this.sourceInfo = sourceInfo; return this; } final public Object getSourceInfo() { return sourceInfo(); } public Object sourceInfo() { return sourceInfo; } public Object sourceInfo; final public GazelleV_LeftArrowScriptParser setOptimize(boolean optimize) { return optimize(optimize); } public GazelleV_LeftArrowScriptParser optimize(boolean optimize) { this.optimize = optimize; return this; } final public boolean getOptimize() { return optimize(); } public boolean optimize() { return optimize; } public boolean optimize = true; final public GazelleV_LeftArrowScriptParser setUseFixedVarContexts(boolean useFixedVarContexts) { return useFixedVarContexts(useFixedVarContexts); } public GazelleV_LeftArrowScriptParser useFixedVarContexts(boolean useFixedVarContexts) { this.useFixedVarContexts = useFixedVarContexts; return this; } final public boolean getUseFixedVarContexts() { return useFixedVarContexts(); } public boolean useFixedVarContexts() { return useFixedVarContexts; } public boolean useFixedVarContexts = false; public LASScope scope; public LinkedHashMap knownVars = new LinkedHashMap(); public List varAccessesToFix = new ArrayList(); public Set closerTokens = litset(";", "}", ")"); public BuildingScript currentReturnableScript; public BuildingScript currentLoop; public boolean inParens = false; public int idCounter; public Map classDefs = new HashMap(); final public Map getFunctionDefs() { return functionDefs(); } public Map functionDefs() { return functionDefs; } public Map functionDefs = new HashMap(); public Set flags = ciSet(); transient public Set>> onKnownVarsSnapshot; public GazelleV_LeftArrowScriptParser onKnownVarsSnapshot(IVF1> f) { onKnownVarsSnapshot = createOrAddToSyncLinkedHashSet(onKnownVarsSnapshot, f); return this; } public GazelleV_LeftArrowScriptParser removeKnownVarsSnapshotListener(IVF1> f) { loadableUtils.utils.remove(onKnownVarsSnapshot, f); return this; } public void knownVarsSnapshot(Map knownVars) { if (onKnownVarsSnapshot != null) for (var listener : onKnownVarsSnapshot) pcallF_typed(listener, knownVars); } transient public Set> onTypeHook; public GazelleV_LeftArrowScriptParser onTypeHook(IVF1 f) { onTypeHook = createOrAddToSyncLinkedHashSet(onTypeHook, f); return this; } public GazelleV_LeftArrowScriptParser removeTypeHookListener(IVF1 f) { loadableUtils.utils.remove(onTypeHook, f); return this; } public void typeHook(LASValueDescriptor type) { if (onTypeHook != null) for (var listener : onTypeHook) pcallF_typed(listener, type); } static public class EvaluableWrapper implements IFieldsToList { public GazelleV_LeftArrowScript.Evaluable expr; public EvaluableWrapper() { } public EvaluableWrapper(GazelleV_LeftArrowScript.Evaluable expr) { this.expr = expr; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + expr + ")"; } public boolean equals(Object o) { if (!(o instanceof EvaluableWrapper)) return false; EvaluableWrapper __20 = (EvaluableWrapper) o; return eq(expr, __20.expr); } public int hashCode() { int h = 700525824; h = boostHashCombine(h, _hashCode(expr)); return h; } public Object[] _fieldsToList() { return new Object[] { expr }; } } public class BuildingScript { public int id = ++idCounter; final public BuildingScript setReturnable(boolean returnable) { return returnable(returnable); } public BuildingScript returnable(boolean returnable) { this.returnable = returnable; return this; } final public boolean getReturnable() { return returnable(); } public boolean returnable() { return returnable; } public boolean returnable = false; final public BuildingScript setIsLoopBody(boolean isLoopBody) { return isLoopBody(isLoopBody); } public BuildingScript isLoopBody(boolean isLoopBody) { this.isLoopBody = isLoopBody; return this; } final public boolean getIsLoopBody() { return isLoopBody(); } public boolean isLoopBody() { return isLoopBody; } public boolean isLoopBody = false; public BuildingScript returnableParent, loopParent; final public BuildingScript setScope(LASScope scope) { return scope(scope); } public BuildingScript scope(LASScope scope) { this.scope = scope; return this; } final public LASScope getScope() { return scope(); } public LASScope scope() { return scope; } public LASScope scope; public GazelleV_LeftArrowScript.Script script = new GazelleV_LeftArrowScript.Script(); public List steps = new ArrayList(); public Map functionDefs = new HashMap(); public BuildingScript(boolean returnable) { this(); this.returnable = returnable; } public BuildingScript(boolean returnable, boolean isLoopBody) { this(); this.isLoopBody = isLoopBody; this.returnable = returnable; } public BuildingScript() { scope = currentScope(); } public void add(GazelleV_LeftArrowScript.Evaluable step) { if (step != null) steps.add(step); } public GazelleV_LeftArrowScript.Evaluable get() { script.scope = scope; var lastStep = last(steps); if (lastStep instanceof GazelleV_LeftArrowScript.ReturnFromScript) if (((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).script == script) replaceLast(steps, ((GazelleV_LeftArrowScript.ReturnFromScript) lastStep).value); if (!returnable && l(steps) == 1 && empty(functionDefs)) return first(steps); if (nempty(functionDefs)) script.functionDefs = functionDefs; script.steps = toTypedArray(GazelleV_LeftArrowScript.Evaluable.class, steps); return script; } public String toStringLong() { return pnlToLines(steps); } public String toString() { return formatRecordVars("BuildingScript", "id", id, "returnable", returnable, "returnableParent", returnableParent, "script", script); } } { tokenize = text -> { List tok = tokenize_base(text); preprocess(tok); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("=== PREPROCESSED\n" + indentx(join(tok)) + "\n==="); return tok; }; } public void preprocess(List tok) { tok_ifdef(tok, __19 -> getFlag(__19)); tok_pcall_script(tok); tok_script_settable(tok); } public GazelleV_LeftArrowScript.Script parse(String text) { setText(text); init(); return parse(); } public GazelleV_LeftArrowScript.Script parse() { GazelleV_LeftArrowScript.Script script = parseReturnableScript(); for (var varAccess : varAccessesToFix) varAccess.resolve(); if (optimize) script = script.optimizeScript(); return script; } public GazelleV_LeftArrowScript.Script parseReturnableScript() { return (GazelleV_LeftArrowScript.Script) parseScript(new BuildingScript().returnable(true)); } public GazelleV_LeftArrowScript.Evaluable parseScript(BuildingScript script) { return linkToSrc(() -> { script.returnableParent = currentReturnableScript; script.loopParent = currentLoop; if (script.returnable) currentReturnableScript = script; if (script.isLoopBody) currentLoop = script; return parseBuildingScript(script); }); } public GazelleV_LeftArrowScript.Evaluable parseBuildingScript(BuildingScript script) { try { parseScript_2(script); var builtScript = script.get(); currentReturnableScript = script.returnableParent; currentLoop = script.loopParent; return builtScript; } catch (Throwable e) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Parsed so far:\n" + script); throw rethrowAndAppendToMessage(e, squareBracketed(spaceCombine(sourceInfo, lineAndColumn(-1)))); } } public void parseScript_2(BuildingScript script) { AutoCloseable __9 = tempRestoreMap(knownVars); try { AssureAdvance assure = new AssureAdvance(); while (assure.get()) { knownVarsSnapshot(knownVars); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseScript_2: Next token is " + quote(token())); if (is(";")) { next(); continue; } if (isOneOf("}", ")")) break; GazelleV_LeftArrowScript.Evaluable instruction = linkToSrc(() -> parseInstruction(script)); if (instruction != null) script.add(instruction); } if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseScript_2 done"); knownVarsSnapshot(knownVars); } finally { _close(__9); } } public GazelleV_LeftArrowScript.Evaluable parseParamDecl(BuildingScript script) { String var = assertIdentifier(tpp()); LASValueDescriptor valueDescriptor = new LASValueDescriptor(); if (is(":")) { var type = parseColonType(); valueDescriptor = LASValueDescriptor.nonExactCanBeNull(type); } knownVars.put(var, valueDescriptor); script.script.params = putOrCreateLinkedHashMap(script.script.params, var, valueDescriptor); return null; } public GazelleV_LeftArrowScript.Evaluable parseInstruction(BuildingScript script) { if (consumeOpt("param")) return parseParamDecl(script); if (is("throw")) { consume(); return new GazelleV_LeftArrowScript.Throw(parseExpr()); } if (isOneOf("return", "ret")) { consume(); GazelleV_LeftArrowScript.Evaluable expr; if (atCmdEnd()) expr = _const(null); else expr = parseAssignmentOrExpr(); return new GazelleV_LeftArrowScript.ReturnFromScript(currentReturnableScript.script, expr); } if (consumeOpt("continue")) { assertCmdEnd(); if (currentLoop == null) throw fail("continue outside of loop"); return new GazelleV_LeftArrowScript.Continue(currentLoop.script); } if (is("temp")) { consume(); GazelleV_LeftArrowScript.Evaluable tempExpr = parseAssignmentOrExpr(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("tempExpr", tempExpr); GazelleV_LeftArrowScript.Evaluable body = parseScript(new BuildingScript()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("body", body); return new GazelleV_LeftArrowScript.TempBlock(tempExpr, body); } if (is("will") && is(1, "return")) { consume(2); GazelleV_LeftArrowScript.Evaluable exp = parseAssignmentOrExpr(); GazelleV_LeftArrowScript.Evaluable body = parseScript(new BuildingScript()); return new GazelleV_LeftArrowScript.WillReturn(exp, body); } return parseAssignmentOrExpr(); } public GazelleV_LeftArrowScript.Evaluable parseAssignmentOrExpr() { { var __3 = parseAssignmentOpt(); if (__3 != null) return __3; } return parseExpr(); } public GazelleV_LeftArrowScript.Evaluable parseAssignmentOpt() { String t = token(); if (isIdentifier(t)) { Type type = null; var ptr = ptr(); if (is(1, ":")) { next(); type = parseColonType(); unconsume(); } if (is(1, "<") && is(2, "-")) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Found assignment"); next(3); GazelleV_LeftArrowScript.Evaluable rhs = parseExpr(); assertNotNull("Expression expected", rhs); boolean newVar = !knownVars.containsKey(t); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("newVar", newVar, "t", t, "knownVars", knownVars); knownVars.put(t, type == null ? new LASValueDescriptor() : LASValueDescriptor.nonExactCanBeNull(type)); return newVar ? new GazelleV_LeftArrowScript.VarDeclaration(t, null, rhs) : new GazelleV_LeftArrowScript.Assignment(t, rhs); } ptr(ptr); } return null; } public GazelleV_LeftArrowScript.Evaluable parseOptionalInnerExpression() { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("parseOptionalInnerExpression", "token", token()); if (atCmdEnd() || isOneOf("{", ",", "then")) return null; return parseInnerExpr(); } public GazelleV_LeftArrowScript.Evaluable _const(Object o) { return new GazelleV_LeftArrowScript.Const(o); } public GazelleV_LeftArrowScript.Evaluable parseInnerExpr() { return parseExpr(true); } public GazelleV_LeftArrowScript.Evaluable parseExpr() { if (metaGet("scaffolding") != null) scaffoldCalled(this, "parseExpr"); return parseExpr(false); } public GazelleV_LeftArrowScript.Evaluable parseExpr(boolean inner) { GazelleV_LeftArrowScript.Evaluable e = linkToSrc(() -> inner ? parseExpr_impl(true) : parseFullExpr()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseExpr done:\n" + GazelleV_LeftArrowScript.indentedScriptStruct(e)); return e; } public GazelleV_LeftArrowScript.Evaluable parseFullExpr() { return linkToSrc(() -> parseExprPlusOptionalComma()); } public GazelleV_LeftArrowScript.CallOnTarget parseThenCall(GazelleV_LeftArrowScript.CallOnTarget expr) { consume("then"); GazelleV_LeftArrowScript.CallOnTarget secondCall = (GazelleV_LeftArrowScript.CallOnTarget) (parseCall(null)); return new GazelleV_LeftArrowScript.Then(expr, secondCall); } public GazelleV_LeftArrowScript.Evaluable parseExprPlusOptionalComma() { GazelleV_LeftArrowScript.Evaluable expr = parseExpr_impl(false); while (consumeOpt(",")) { expr = parseCall_noCmdEndCheck(expr); } return expr; } public GazelleV_LeftArrowScript.Evaluable parseExpr_impl(boolean inner) { if (atEnd()) return null; String t = token(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("parseExpr", "token", t); if (is(";")) return null; if (consumeOpt("try")) { GazelleV_LeftArrowScript.Evaluable body = parseCurlyBlock(); while (consumeOpt("catch")) { String var = consumeIdentifierOpt(); AutoCloseable __10 = tempAddKnownVars(var); try { GazelleV_LeftArrowScript.Evaluable catchBlock = parseCurlyBlock(); body = new GazelleV_LeftArrowScript.TryCatch(body, var, catchBlock); } finally { _close(__10); } } if (consumeOpt("finally")) { GazelleV_LeftArrowScript.Evaluable finallyBlock = parseCurlyBlock(); return new GazelleV_LeftArrowScript.TryFinally(body, finallyBlock); } return body; } if (is("def")) { var fd = parseFunctionDefinition(currentReturnableScript.functionDefs); return new GazelleV_LeftArrowScript.Const(fd); } if (is("{")) return parseCurlyBlock(); if (is("-") && empty(nextSpace()) && startsWithDigit(token(1)) || startsWithDigit(t)) { var e = parseNumberLiteral(); return parseCall(inner, e); } if (isQuoted(t)) { var e = parseStringLiteral(); return parseCall(inner, e); } if (startsWith(t, '\'')) { consume(); var e = _const(first(unquote(t))); return parseCall(inner, e); } if (isIdentifier(t)) { if (is("while")) return parseWhileLoop(); if (is("for")) return parseForEach(); if (is("if")) return parseIfStatement(); if (is("repeat")) return parseRepeatStatement(); if (is("outer")) { consume(); var a = parseAssignmentOpt(); if (!(a instanceof GazelleV_LeftArrowScript.Assignment)) throw fail("Assignment expected"); return new GazelleV_LeftArrowScript.AssignmentToOuterVar(((GazelleV_LeftArrowScript.Assignment) a).var, ((GazelleV_LeftArrowScript.Assignment) a).expression); } consume(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Consumed identifier " + t + ", next token: " + token() + ", inner: " + inner); var e = parseExprStartingWithIdentifier(t, inner); return inner ? parseCall(inner, e) : e; } if (eq(t, "(")) { consume(); GazelleV_LeftArrowScript.Evaluable e = parseExpr_inParens(); consume(")"); return parseCall(inner, e); } if (isOneOf("&", "|") && empty(nextSpace()) && is(1, token())) { return parseBinaryOperator(); } throw fail("Identifier, literal, operator or opening parentheses expected (got: " + quote(t)); } public GazelleV_LeftArrowScript.Evaluable parseExpr_inParens() { boolean inParensOld = inParens; inParens = true; try { return parseExpr(); } finally { inParens = inParensOld; } } public GazelleV_LeftArrowScript.Evaluable parseNumberLiteral() { String t = consumeMultiTokenLiteral(); if (swic(t, "0x")) return _const(parseHexInt(dropFirst(t, 2))); if (swic(t, "0b")) return _const(intFromBinary(dropFirst(t, 2))); if (isInteger(t)) return _const(parseIntOrLong(t)); if (ewic(t, "f")) return _const(parseFloat(t)); if (endsWith(t, "L")) return _const(parseLong(t)); return _const(parseDouble(t)); } public GazelleV_LeftArrowScript.Evaluable parseBinaryOperator() { boolean and = is("&"); next(2); GazelleV_LeftArrowScript.Evaluable a = parseInnerExpr(); GazelleV_LeftArrowScript.Evaluable b = parseInnerExpr(); return and ? new GazelleV_LeftArrowScript.BoolAnd(a, b) : new GazelleV_LeftArrowScript.BoolOr(a, b); } public boolean qualifiedNameContinues() { return empty(prevSpace()) && eq(token(), ".") && empty(nextSpace()) && isIdentifier(token(1)); } public GazelleV_LeftArrowScript.Evaluable parseNewExpr() { String className = assertIdentifier(tpp()); parseTypeArguments(null); LASClassDef cd = classDefs.get(className); if (cd != null) return new GazelleV_LeftArrowScript.NewObject_LASClass(cd.resolvable(lasClassLoader)); var type = knownVars.get(className); if (type != null) return new GazelleV_LeftArrowScript.NewObject_UnknownClass(new GazelleV_LeftArrowScript.GetVar(className), parseArguments()); Object o = findExternalObject(className); if (o instanceof Class) { Class c = (Class) o; if (c == List.class) c = ArrayList.class; else if (c == Map.class) c = HashMap.class; else if (c == Set.class) c = HashSet.class; return new GazelleV_LeftArrowScript.NewObject(c, parseArguments()); } throw new ClassNotFound(className); } public GazelleV_LeftArrowScript.Evaluable parseExprStartingWithIdentifier(String t, boolean inner) { if (eq(t, "true")) return _const(true); if (eq(t, "false")) return _const(false); if (eq(t, "null")) return _const(null); if (eq(t, "new")) return parseNewExpr(); if (eq(t, "class")) { unconsume(); return new GazelleV_LeftArrowScript.ClassDef(parseClassDef().resolvable(lasClassLoader)); } if (eq(t, "list") && is("{")) { GazelleV_LeftArrowScript.Script block = parseReturnableCurlyBlock(); GazelleV_LeftArrowScript.Evaluable e = new GazelleV_LeftArrowScript.ListFromScript(block); return parseCall(inner, e); } if (scope != null && scope.useFixedVars) { var type = scope.declaredVars.get(t); if (type != null) { var e = new GazelleV_LeftArrowScript.GetFixedVar(scope, t); e.scope(scope); e.returnType(type); varAccessesToFix.add(e); return parseCall(inner, e); } } var type = knownVars.get(t); if (type != null) { var e = new GazelleV_LeftArrowScript.GetVar(t).returnType(type); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Found var acccess: " + e + ", " + (!inner ? "Checking for call" : "Returning expression")); typeHook(type); return parseCall(inner, e); } if (!inner) { var fdef = lookupFunction(t); if (fdef != null) return new GazelleV_LeftArrowScript.CallFunction(fdef, parseArguments()); } if (eq(t, "_context")) return new GazelleV_LeftArrowScript.GetVarContext(); Object o = findExternalObject(t); if (o == null) { throw new UnknownObject(t); } else if (o instanceof EvaluableWrapper) { return parseCall(inner, ((EvaluableWrapper) o).expr); } else if (inner) return _const(o); else if (o instanceof Class) { return parseExprStartingWithClass((Class) o); } else if (o instanceof MethodOnObject) { if (inner) throw fail("Can't call methods in arguments"); return new GazelleV_LeftArrowScript.CallMethod(_const(((MethodOnObject) o).object), ((MethodOnObject) o).method, parseArguments()); } else return parseCall(_const(o)); } public GazelleV_LeftArrowScript.Evaluable parseExprStartingWithClass(Class c) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("parseExprStartingWithClass", "c", c); if (atCmdEnd()) return _const(c); if (is("(")) return new GazelleV_LeftArrowScript.NewObject(c, parseArguments()); { var __4 = parseLambdaOpt(c); if (__4 != null) return __4; } if (isIdentifier()) { String name = tpp(); if (hasStaticMethodNamed(c, name)) return new GazelleV_LeftArrowScript.CallMethod(_const(c), name, parseArguments()); if (isInterface(c)) return parseLambdaMethodRef(c, name); var field = getField(c, name); if (field != null) { if (!isStaticField(field)) throw fail(field + " is not a static field"); if (consumeLeftArrowOpt()) { GazelleV_LeftArrowScript.Evaluable rhs = parseExpr(); return new GazelleV_LeftArrowScript.SetStaticField(field, rhs); } assertCmdEnd(); return new GazelleV_LeftArrowScript.GetStaticField(field); } throw fail(name + " not found in " + c + " (looked for method or field)"); } else throw fail("Method name expected: " + token()); } public GazelleV_LeftArrowScript.Evaluable parseLambdaOpt(Class c) { if (!isInterface(c)) return null; var ptr = ptr(); var parameterized = parseTypeArgumentsOpt(c); if (is("{")) return finishLambdaDef(c, null); if (consumeOpt("_")) { String methodName = consumeIdentifier(); return new GazelleV_LeftArrowScript.LambdaMethodOnArgument(c, methodName, parseArguments()); } int nArgs = 0; while (isIdentifier(token(nArgs))) nArgs++; if (!(is(nArgs, "-") && is(nArgs + 1, ">"))) { ptr(ptr); return null; } String[] argNames = consumeArray(nArgs); skip(2); return finishLambdaDef(c, argNames); } public GazelleV_LeftArrowScript.Evaluable finishLambdaDef(Class c, String[] argNames) { AutoCloseable __11 = tempAddKnownVars(argNames); try { GazelleV_LeftArrowScript.Evaluable body; if (is("{")) body = parseReturnableCurlyBlock(); else body = parseExpr(); var lambda = new GazelleV_LeftArrowScript.LambdaDef(c, argNames, body); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("finishLambdaDef done:\n" + GazelleV_LeftArrowScript.indentedScriptStruct(lambda)); return lambda; } finally { _close(__11); } } public GazelleV_LeftArrowScript.Evaluable parseLambdaMethodRef(Class c, String name) { var fdef = lookupFunction(name); if (fdef != null) { GazelleV_LeftArrowScript.Evaluable[] curriedArguments = parseArguments(); return new GazelleV_LeftArrowScript.CurriedScriptFunctionLambda(c, fdef, curriedArguments); } Object function = findExternalObject(name); if (function == null) throw new UnknownObject(name); if (function instanceof MethodOnObject) { Object target = ((MethodOnObject) function).object; String targetMethod = ((MethodOnObject) function).method; GazelleV_LeftArrowScript.Evaluable[] curriedArguments = parseArguments(); return new GazelleV_LeftArrowScript.CurriedMethodLambda(c, target, targetMethod, curriedArguments); } else if (function instanceof Class) { Class c2 = (Class) function; assertCmdEnd(); var ctors = constructorsWithNumberOfArguments(c2, 1); if (empty(ctors)) throw fail("No single argument constructor found in " + c2); return new GazelleV_LeftArrowScript.CurriedConstructorLambda(c, toArray(Constructor.class, ctors), null); } else throw fail(function + " is not an instantiable class or callable method"); } public GazelleV_LeftArrowScript.FunctionDef lookupFunction(String name) { var script = currentReturnableScript; while (script != null) { var f = script.functionDefs.get(name); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("lookupFunction", "script", script, "name", name, "f", f); if (f != null) return f; script = script.returnableParent; } return functionDefs.get(name); } public GazelleV_LeftArrowScript.Evaluable[] parseArguments() { List l = new ArrayList(); try { while (true) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseArgumentsAsList: token is " + quote(t())); if (is("+") && empty(nextSpace()) && isIdentifier(token(1))) { consume(); l.add(_const(token())); continue; } if (consumeOpt("<")) { GazelleV_LeftArrowScript.Evaluable a = parseFullExpr(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseArgumentsAsList: token after expr is " + quote(t())); if (a == null) throw fail("expression expected"); l.add(a); break; } GazelleV_LeftArrowScript.Evaluable a = parseOptionalInnerExpression(); if (a == null) break; l.add(a); } return toArrayOrNull(GazelleV_LeftArrowScript.Evaluable.class, l); } catch (Throwable _e) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Arguments parsed so far: " + l); throw rethrow(_e); } } public String consumeMultiTokenLiteral() { return consumeUntilSpaceOr(() -> atCmdEnd() || is(",")); } public boolean atCmdEnd() { return !inParens && atEndOrLineBreak() || closerTokens.contains(token()); } public void assertCmdEnd() { if (!atCmdEnd()) throw fail("Expected end of command, token is: " + quote(token())); } public GazelleV_LeftArrowScript.Evaluable parseCall(GazelleV_LeftArrowScript.Evaluable target) { return parseCall(false, target); } public GazelleV_LeftArrowScript.Evaluable parseCall(boolean inner, GazelleV_LeftArrowScript.Evaluable target) { if (atCmdEnd()) return target; if (inner) { { var __5 = parseTildeCall(target); if (__5 != null) return __5; } return target; } return parseCall_noCmdEndCheck(target); } public GazelleV_LeftArrowScript.Evaluable parseCall_noCmdEndCheck(GazelleV_LeftArrowScript.Evaluable target) { var start = ptr(); if (isIdentifier()) { String name = tpp(); if (consumeLeftArrowOpt()) { GazelleV_LeftArrowScript.Evaluable rhs = parseExpr(); return new GazelleV_LeftArrowScript.SetField(target, name, rhs); } boolean allowNullReference = consumeOpt("?"); var args = parseArguments(); var call = finalizeCall(start, target, name, args); set(call, "allowNullReference", allowNullReference); return call; } { var __6 = parseTildeCall(target); if (__6 != null) return __6; } if (is("!") && is(1, "_getField_")) { next(2); String field = consumeIdentifier(); return new GazelleV_LeftArrowScript.GetField(target, field); } return target; } public boolean consumeLeftArrowOpt() { if (is("<") && eq(token(1), "-")) { next(2); return true; } return false; } public GazelleV_LeftArrowScript.Evaluable parseTildeCall(GazelleV_LeftArrowScript.Evaluable target) { var start = ptr(); if (consumeOpt("~")) { if (isIdentifier()) { String key = consumeIdentifier(); return parseCall(finalizeCall(start, target, "getOpt", _const(key))); } else { int idx = consumeInteger(); return parseCall(finalizeCall(start, target, "listGet", _const(idx))); } } return null; } public GazelleV_LeftArrowScript.Evaluable finalizeCall(ListAndIndex start, GazelleV_LeftArrowScript.Evaluable target, String name, GazelleV_LeftArrowScript.Evaluable... args) { return finalizeCall2(finalizeCall1(start, target, name, args)); } public GazelleV_LeftArrowScript.Evaluable finalizeCall2(GazelleV_LeftArrowScript.CallOnTarget call) { while (is("then")) call = parseThenCall(call); return call; } public GazelleV_LeftArrowScript.CallOnTarget finalizeCall1(ListAndIndex start, GazelleV_LeftArrowScript.Evaluable target, String name, GazelleV_LeftArrowScript.Evaluable... args) { if (magicSwitch) { Object ext = findExternalObject(name); if (ext instanceof MethodOnObject) { if (nempty(args)) return new GazelleV_LeftArrowScript.CallMethodOrGlobalFunction(target, name, ((MethodOnObject) ext), args); else return new GazelleV_LeftArrowScript.CallMethodOrGetFieldOrGlobalFunction(target, name, ((MethodOnObject) ext)); } } if (nempty(args)) return new GazelleV_LeftArrowScript.CallMethod(target, name, args); else return linkToSrc(start, new GazelleV_LeftArrowScript.CallMethodOrGetField(target, name)); } public A linkToSrc(ListAndIndex start, A a) { if (a instanceof IHasTokenRangeWithSrc) if (((IHasTokenRangeWithSrc) a).tokenRangeWithSrc() == null) ((IHasTokenRangeWithSrc) a).setTokenRangeWithSrc(new TokenRangeWithSrc(start, ptr().plus(-1)).sourceInfo(sourceInfo())); return a; } public A linkToSrc(IF0 a) { var start = ptr(); return linkToSrc(start, a.get()); } transient public IF1 findExternalObject; public Object findExternalObject(String name) { return findExternalObject != null ? findExternalObject.get(name) : findExternalObject_base(name); } final public Object findExternalObject_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : findExternalObject_base(name); } public Object findExternalObject_base(String name) { if (eq(name, "void")) return void.class; { var __7 = parsePrimitiveType(name); if (__7 != null) return __7; } if (qualifiedNameContinues()) { int idx = idx() - 2; do next(2); while (qualifiedNameContinues()); String fqn = joinSubList(tok, idx, idx() - 1); return classForName(fqn); } return findExternalObject2(name); } transient public IF1 findExternalObject2; public Object findExternalObject2(String name) { return findExternalObject2 != null ? findExternalObject2.get(name) : findExternalObject2_base(name); } final public Object findExternalObject2_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : findExternalObject2_base(name); } public Object findExternalObject2_base(String name) { String fullName = globalClassNames().get(name); if (fullName != null) return classForName(fullName); { var __8 = classForNameOpt_noCache(name); if (__8 != null) return __8; } for (var container : unnullForIteration(functionContainers)) { if (hasMethodNamed(container, name) && !isBlockedFunctionContainerMethod(container, name)) { var moo = new MethodOnObject(container, name); return moo; } var field = getField(container, name); if (field != null && isStaticField(field)) return new EvaluableWrapper(new GazelleV_LeftArrowScript.GetStaticField(field)); } return null; } transient public IF2 isBlockedFunctionContainerMethod; public boolean isBlockedFunctionContainerMethod(Object container, String name) { return isBlockedFunctionContainerMethod != null ? isBlockedFunctionContainerMethod.get(container, name) : isBlockedFunctionContainerMethod_base(container, name); } final public boolean isBlockedFunctionContainerMethod_fallback(IF2 _f, Object container, String name) { return _f != null ? _f.get(container, name) : isBlockedFunctionContainerMethod_base(container, name); } public boolean isBlockedFunctionContainerMethod_base(Object container, String name) { return false; } public GazelleV_LeftArrowScriptParser allowTheWorld() { return allowTheWorld(mc()); } public GazelleV_LeftArrowScriptParser allowTheWorld(Object... functionContainers) { for (Object o : unnullForIteration(reversed(functionContainers))) if (!contains(this.functionContainers, o)) { this.functionContainers.add(0, o); globalClassNames_cache = null; } return this; } public void printFunctionDefs(GazelleV_LeftArrowScript.Script script) { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print(values(script.functionDefs)); } public AutoCloseable tempAddKnownVars(String... vars) { return tempAddKnownVars(nonNulls(vars)); } public AutoCloseable tempAddKnownVars(Iterable vars) { var newVars = mapWithSingleValue(vars, new LASValueDescriptor()); return tempAddKnownVars(newVars); } public AutoCloseable tempAddKnownVars(Map newVars) { if (scope != null) for (var __1 : _entrySet(newVars)) { var name = __1.getKey(); var type = __1.getValue(); scope.addDeclaredVar(name, type); } return tempMapPutAll(knownVars, newVars); } public String parseFunctionDefArg(Map argsOut) { if (consumeOpt("(")) { String result = parseFunctionDefArg(argsOut); consume(")"); return result; } if (isIdentifier()) { String arg = tpp(); var type = typeToValueDescriptor(parseColonTypeOpt()); argsOut.put(arg, type); return arg; } return null; } public GazelleV_LeftArrowScript.FunctionDef parseFunctionDefinition(Map functionDefsToAddTo) { var start = ptr(); consume("def"); String functionName = assertIdentifier(tpp()); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("parseFunctionDefinition " + functionName); return parseFunctionDefinition_step2(functionDefsToAddTo, start, functionName); } public GazelleV_LeftArrowScript.FunctionDef parseFunctionDefinition_step2(Map functionDefsToAddTo, ListAndIndex start, String functionName) { LinkedHashMap args = new LinkedHashMap(); while (parseFunctionDefArg(args) != null) { } var returnType = parseColonTypeOpt(); var fd = new GazelleV_LeftArrowScript.FunctionDef(functionName, keysList(args), null); fd.argTypes(valuesArray(LASValueDescriptor.class, args)); { if (functionDefsToAddTo != null) functionDefsToAddTo.put(functionName, fd); } var scope = newScope(); scope.useFixedVars(useFixedVarContexts); AutoCloseable __12 = tempScope(scope); try { AutoCloseable __13 = tempAddKnownVars(args); try { if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Parsing function body"); fd.body = parseReturnableCurlyBlock(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("Defined function " + functionName + ", added to " + functionDefsToAddTo); fd.scope(scope); if (returnType != null) fd.returnType(returnType); return linkToSrc(start, fd); } finally { _close(__13); } } finally { _close(__12); } } public LASScope newScope() { return new LASScope(scope); } public LASScope currentScope() { return scope; } public AutoCloseable tempScope(LASScope scope) { var oldScope = currentScope(); this.scope = scope; return () -> { scope.resolve(); this.scope = oldScope; }; } public GazelleV_LeftArrowScript.Script parseReturnableCurlyBlock() { return (GazelleV_LeftArrowScript.Script) parseCurlyBlock(new BuildingScript().returnable(true)); } public GazelleV_LeftArrowScript.Evaluable parseCurlyBlock() { return parseCurlyBlock(new BuildingScript()); } public GazelleV_LeftArrowScript.Evaluable parseCurlyBlock(BuildingScript script) { consume("{"); boolean inParensOld = inParens; inParens = false; var body = parseScript(script); consume("}"); inParens = inParensOld; return body; } public GazelleV_LeftArrowScript.Evaluable parseWhileLoop() { consume("while"); var condition = parseExpr(); var body = parseCurlyBlock(new BuildingScript().isLoopBody(true)); return new GazelleV_LeftArrowScript.While(condition, body); } public GazelleV_LeftArrowScript.Evaluable parseForEach() { return new ParseForEach().get(); } public class ParseForEach { public GazelleV_LeftArrowScript.Evaluable collection, body; public IF0 finish; public Set vars = new HashSet(); public String addVar(String var) { return addAndReturn(vars, var); } public String consumeVar() { return addVar(consumeIdentifier()); } public void parseBody() { AutoCloseable __14 = tempAddKnownVars(vars); try { body = parseCurlyBlock(new BuildingScript().isLoopBody(true)); } finally { _close(__14); } } public GazelleV_LeftArrowScript.Evaluable get() { consume("for"); if (is(1, "to")) { String var = consumeVar(); consume("to"); GazelleV_LeftArrowScript.Evaluable endValue = parseExpr(); parseBody(); return new GazelleV_LeftArrowScript.ForIntTo(endValue, var, body); } int iIn = relativeIndexOf("in"); if (iIn < 0) throw fail("for without in"); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("iIn", iIn); if (iIn == 1) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForEach(collection, var, body); } else if (iIn == 2) { if (consumeOpt("iterator")) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForIterator(collection, var, body); } else if (consumeOpt("nested")) { String var = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForNested(collection, var, body); } else throw fail("Unknown pattern for 'for' loop"); } else if (iIn == 3) { if (isOneOf("pair", "Pair")) { consume(); String varA = consumeVar(); String varB = consumeVar(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("varA", varA, "varB", varB); finish = () -> new GazelleV_LeftArrowScript.ForPairs(collection, body, varA, varB); } else { String varA = consumeVar(); consume(","); String varB = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForKeyValue(collection, body, varA, varB); } } else if (iIn == 4) { consume("index"); String varIndex = consumeVar(); consume(","); String varElement = consumeVar(); finish = () -> new GazelleV_LeftArrowScript.ForIndex(collection, body, varIndex, varElement); } else throw fail("Unknown pattern for 'for' loop"); consume("in"); collection = parseExpr_inParens(); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) print("collection", collection); parseBody(); return finish.get(); } } public GazelleV_LeftArrowScript.Evaluable parseIfStatement() { consume("if"); GazelleV_LeftArrowScript.Evaluable condition, body, elseBranch = null; { AutoCloseable __15 = tempAdd(closerTokens, "then"); try { condition = parseExpr(); } finally { _close(__15); } } if (consumeOpt("then")) { AutoCloseable __16 = tempAdd(closerTokens, "else"); try { body = parseExpr(); if (consumeOpt("else")) elseBranch = parseExpr(); } finally { _close(__16); } } else { body = parseCurlyBlock(); if (consumeOpt("else")) { if (is("if")) elseBranch = parseIfStatement(); else elseBranch = parseCurlyBlock(); } } return new GazelleV_LeftArrowScript.IfThen(condition, body, elseBranch); } public GazelleV_LeftArrowScript.Evaluable parseRepeatStatement() { consume("repeat"); var n = parseExpr(); var body = parseCurlyBlock(); return new GazelleV_LeftArrowScript.RepeatN(n, body); } public void addVar(String var) { addVar(var, new LASValueDescriptor()); } public void addVar(String var, LASValueDescriptor type) { knownVars.put(var, type); } public void addVar(String var, Class type, boolean canBeNull) { addVar(var, typeToValueDescriptor(type, canBeNull)); } public LASValueDescriptor typeToValueDescriptor(Type type) { return typeToValueDescriptor(type, true); } public LASValueDescriptor typeToValueDescriptor(Type type, boolean canBeNull) { return type == null ? new LASValueDescriptor() : new LASValueDescriptor.NonExact(typeToClass(type), canBeNull); } public Map globalClassNames_cache; public Map globalClassNames() { if (globalClassNames_cache == null) globalClassNames_cache = globalClassNames_load(); return globalClassNames_cache; } public Map globalClassNames_load() { var packages = mapToTreeSet(importedPackages(), pkg -> pkg + "."); Map out = new HashMap(); for (var name : importedClasses()) out.put(shortenClassName(name), name); for (var fc : functionContainers) if (fc instanceof Class) { if (isAnonymousClass((Class) fc)) continue; out.put(shortClassName((Class) fc), className((Class) fc)); } var classContainers = classContainerPrefixes(); TreeSet classContainerSet = asTreeSet(classContainers); out.put("List", "java.util.List"); for (var className : classNameResolver().allFullyQualifiedClassNames()) { if (isAnonymousClassName(className)) continue; if (!contains(className, '$')) { String pkg = longestPrefixInTreeSet(className, packages); if (pkg != null) { String shortName = dropPrefix(pkg, className); if (!shortName.contains(".") && !out.containsKey(shortName)) out.put(shortName, className); } } String container = longestPrefixInTreeSet(className, classContainerSet); if (container != null) { String shortName = dropPrefix(container, className); String existing = out.get(shortName); if (existing != null) { int priority = indexOf(classContainers, container); String oldContainer = longestPrefixInTreeSet(existing, classContainerSet); int oldPriority = indexOf(classContainers, oldContainer); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("className", className, "shortName", shortName, "container", container, "priority", priority, "existing", existing, "oldPriority", oldPriority); if (priority > oldPriority) continue; } out.put(shortName, className); } } for (var __0 : _entrySet(javaxClassShortcuts())) { var key = __0.getKey(); var val = __0.getValue(); String fullName = out.get(val); if (fullName != null) out.put(key, fullName); } return out; } transient public IF0> importedPackages; public Collection importedPackages() { return importedPackages != null ? importedPackages.get() : importedPackages_base(); } final public Collection importedPackages_fallback(IF0> _f) { return _f != null ? _f.get() : importedPackages_base(); } public Collection importedPackages_base() { return itemPlus("java.lang", standardImports_fullyImportedPackages()); } transient public IF0> importedClasses; public Collection importedClasses() { return importedClasses != null ? importedClasses.get() : importedClasses_base(); } final public Collection importedClasses_fallback(IF0> _f) { return _f != null ? _f.get() : importedClasses_base(); } public Collection importedClasses_base() { return standardImports_singleClasses(); } public void addClassAlias(String alias, String longName) { String fullName = globalClassNames().get(longName); if (fullName != null) globalClassNames().put(alias, fullName); } public List classContainerPrefixes() { return map(functionContainers, fc -> className(fc) + "$"); } static public class UnknownObject extends RuntimeException implements IFieldsToList { public String name; public UnknownObject() { } public UnknownObject(String name) { this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ")"; } public Object[] _fieldsToList() { return new Object[] { name }; } public String getMessage() { return "Unknown object: " + name; } } static public class ClassNotFound extends UnknownObject { public ClassNotFound(String className) { super(className); } public String getMessage() { return "Class not found: " + name; } } public LASClassDef parseClassDef() { return linkToSrc(() -> { consume("class"); LASClassDef classDef = new LASClassDef(); classDef.verbose(scaffoldingEnabled()); if (nempty(classDefPrefix)) classDef.classDefPrefix(classDefPrefix); String name = consumeIdentifier(); classDef.userGivenName(name); classDefs.put(name, classDef); AutoCloseable __17 = tempMapPut(classDefs, "selfType", classDef); try { if (consumeOpt("extends")) { classDef.superClass(parseType()); } if (consumeOpt("is")) classDef.interfaces.add(parseType()); consume("{"); AutoCloseable __18 = tempAddKnownVars("this"); try { while (!is("}")) { if (is(";")) { next(); continue; } if (is("def")) { GazelleV_LeftArrowScript.FunctionDef fd = parseFunctionDefinition(null); if (GazelleV_LeftArrowScriptParser.this.scaffoldingEnabled()) printVars("knownVarsAfterFunctionDef", knownVars); classDef.methods.add(fd); continue; } var start = ptr(); if (consumeOpt("ctor")) { var fd = parseFunctionDefinition_step2(null, start, ""); fd.returnType(void.class); classDef.methods.add(fd); continue; } if (consumeOpt("initializer")) { classDef.initializers.add(parseCurlyBlock()); continue; } LASClassDef.FieldDef fd = new LASClassDef.FieldDef(); fd.name(consumeIdentifier()); var type = parseColonType(); fd.type(type); if (is(0, "<") && is(1, "-")) { next(2); fd.initializer(parseExpr()); } classDef.addField(fd); } consume("}"); return classDef; } finally { _close(__18); } } finally { _close(__17); } }); } public Type parseColonTypeOpt() { if (is(":")) return parseColonType(); return null; } public Type parseColonType() { consume(":"); return parseType(); } public Type findType(String typeName) { LASClassDef cd = classDefs.get(typeName); if (cd != null) return cd.resolvable(lasClassLoader); Object o = findExternalObject(typeName); if (o instanceof Class) return ((Class) o); throw new ClassNotFound(typeName); } public Type parseType() { String typeName = consumeIdentifier(); Type type = findType(typeName); return parseArrayType(parseTypeArguments(type)); } public Type parseArrayType(Type type) { while (is("[") && is(1, "]")) { consume(2); type = new GenericArrayTypeImpl(type); } return type; } final public Type parseTypeArgumentsOpt(Type type) { return parseTypeArguments(type); } public Type parseTypeArguments(Type type) { if (is("<") && empty(nextSpace()) && isIdentifier(token(1))) { next(); List args = new ArrayList(); while (true) { args.add(parseType()); if (is(">")) break; consume(","); } consume(">"); if (type != null) type = new ParameterizedTypeImpl(null, type, toTypedArray(Type.class, args)); } return type; } transient public IF1 classForName; public Class classForName(String name) { return classForName != null ? classForName.get(name) : classForName_base(name); } final public Class classForName_fallback(IF1 _f, String name) { return _f != null ? _f.get(name) : classForName_base(name); } public Class classForName_base(String name) { try { return Class.forName(name); } catch (Exception __e) { throw rethrow(__e); } } public void copyFunctionContainersFrom(GazelleV_LeftArrowScriptParser parser) { functionContainers = cloneList(parser.functionContainers); globalClassNames_cache = parser.globalClassNames(); isBlockedFunctionContainerMethod = parser.isBlockedFunctionContainerMethod; } public ClassNameResolver classNameResolver() { if (classNameResolver == null) classNameResolver = new ClassNameResolver().byteCodePath(assertNotNull(getBytecodePathForClass(this))).init(); return classNameResolver; } public GazelleV_LeftArrowScriptParser classNameResolver(ClassNameResolver classNameResolver) { this.classNameResolver = classNameResolver; return this; } public GazelleV_LeftArrowScript.Evaluable parseStringLiteral() { return _const(unquote_relaxedMLS(consume())); } public void addFunctionDefs(Map map) { putAll(functionDefs, map); } public GazelleV_LeftArrowScriptParser setFlag(String flag) { flags.add(flag); return this; } public boolean getFlag(String flag) { return flags.contains(flag); } } static public class G22LeftArrowScript extends ConceptWithChangeListeners { static final public String _fieldOrder = "description text clearedForAutoRun editingText importNote runOnProjectOpen runOrder runCount lastResultByMode supercededBy metaCode compileResultForAutoRun compileResultForSaved compileResultForEditing"; public transient FieldVar varDescription_cache; public FieldVar varDescription() { if (varDescription_cache == null) varDescription_cache = varDescription_load(); return varDescription_cache; } public FieldVar varDescription_load() { return new FieldVar(this, "description", () -> description(), description -> description(description)); } final public G22LeftArrowScript setDescription(String description) { return description(description); } public G22LeftArrowScript description(String description) { if (!eq(this.description, description)) { this.description = description; change(); } return this; } final public String getDescription() { return description(); } public String description() { return description; } public String description; public transient FieldVar varText_cache; public FieldVar varText() { if (varText_cache == null) varText_cache = varText_load(); return varText_cache; } public FieldVar varText_load() { return new FieldVar(this, "text", () -> text(), text -> text(text)); } final public G22LeftArrowScript setText(String text) { return text(text); } public G22LeftArrowScript text(String text) { if (!eq(this.text, text)) { this.text = text; change(); } return this; } final public String getText() { return text(); } public String text() { return text; } public String text; public transient FieldVar> varClearedForAutoRun_cache; public FieldVar> varClearedForAutoRun() { if (varClearedForAutoRun_cache == null) varClearedForAutoRun_cache = varClearedForAutoRun_load(); return varClearedForAutoRun_cache; } public FieldVar> varClearedForAutoRun_load() { return new FieldVar>(this, "clearedForAutoRun", () -> clearedForAutoRun(), clearedForAutoRun -> clearedForAutoRun(clearedForAutoRun)); } final public G22LeftArrowScript setClearedForAutoRun(ClearForAutoRun clearedForAutoRun) { return clearedForAutoRun(clearedForAutoRun); } public G22LeftArrowScript clearedForAutoRun(ClearForAutoRun clearedForAutoRun) { if (!eq(this.clearedForAutoRun, clearedForAutoRun)) { this.clearedForAutoRun = clearedForAutoRun; change(); } return this; } final public ClearForAutoRun getClearedForAutoRun() { return clearedForAutoRun(); } public ClearForAutoRun clearedForAutoRun() { return clearedForAutoRun; } public ClearForAutoRun clearedForAutoRun; public transient FieldVar varEditingText_cache; public FieldVar varEditingText() { if (varEditingText_cache == null) varEditingText_cache = varEditingText_load(); return varEditingText_cache; } public FieldVar varEditingText_load() { return new FieldVar(this, "editingText", () -> editingText(), editingText -> editingText(editingText)); } final public G22LeftArrowScript setEditingText(String editingText) { return editingText(editingText); } public G22LeftArrowScript editingText(String editingText) { if (!eq(this.editingText, editingText)) { this.editingText = editingText; change(); } return this; } final public String getEditingText() { return editingText(); } public String editingText() { return editingText; } public String editingText; public transient FieldVar varImportNote_cache; public FieldVar varImportNote() { if (varImportNote_cache == null) varImportNote_cache = varImportNote_load(); return varImportNote_cache; } public FieldVar varImportNote_load() { return new FieldVar(this, "importNote", () -> importNote(), importNote -> importNote(importNote)); } final public G22LeftArrowScript setImportNote(String importNote) { return importNote(importNote); } public G22LeftArrowScript importNote(String importNote) { if (!eq(this.importNote, importNote)) { this.importNote = importNote; change(); } return this; } final public String getImportNote() { return importNote(); } public String importNote() { return importNote; } public String importNote; public transient FieldVar varRunOnProjectOpen_cache; public FieldVar varRunOnProjectOpen() { if (varRunOnProjectOpen_cache == null) varRunOnProjectOpen_cache = varRunOnProjectOpen_load(); return varRunOnProjectOpen_cache; } public FieldVar varRunOnProjectOpen_load() { return new FieldVar(this, "runOnProjectOpen", () -> runOnProjectOpen(), runOnProjectOpen -> runOnProjectOpen(runOnProjectOpen)); } final public G22LeftArrowScript setRunOnProjectOpen(boolean runOnProjectOpen) { return runOnProjectOpen(runOnProjectOpen); } public G22LeftArrowScript runOnProjectOpen(boolean runOnProjectOpen) { if (!eq(this.runOnProjectOpen, runOnProjectOpen)) { this.runOnProjectOpen = runOnProjectOpen; change(); } return this; } final public boolean getRunOnProjectOpen() { return runOnProjectOpen(); } public boolean runOnProjectOpen() { return runOnProjectOpen; } public boolean runOnProjectOpen = false; public transient FieldVar varRunOrder_cache; public FieldVar varRunOrder() { if (varRunOrder_cache == null) varRunOrder_cache = varRunOrder_load(); return varRunOrder_cache; } public FieldVar varRunOrder_load() { return new FieldVar(this, "runOrder", () -> runOrder(), runOrder -> runOrder(runOrder)); } final public G22LeftArrowScript setRunOrder(String runOrder) { return runOrder(runOrder); } public G22LeftArrowScript runOrder(String runOrder) { if (!eq(this.runOrder, runOrder)) { this.runOrder = runOrder; change(); } return this; } final public String getRunOrder() { return runOrder(); } public String runOrder() { return runOrder; } public String runOrder; public long runCount; public Map>> lastResultByMode; public Ref supercededBy = new Ref(); public transient FieldVar varMetaCode_cache; public FieldVar varMetaCode() { if (varMetaCode_cache == null) varMetaCode_cache = varMetaCode_load(); return varMetaCode_cache; } public FieldVar varMetaCode_load() { return new FieldVar(this, "metaCode", () -> metaCode(), metaCode -> metaCode(metaCode)); } final public G22LeftArrowScript setMetaCode(String metaCode) { return metaCode(metaCode); } public G22LeftArrowScript metaCode(String metaCode) { if (!eq(this.metaCode, metaCode)) { this.metaCode = metaCode; change(); } return this; } final public String getMetaCode() { return metaCode(); } public String metaCode() { return metaCode; } public String metaCode; public void _doneLoading2() { super._doneLoading2(); cMigrateField(this, "code", "text"); } public String myType() { return dropPrefix("G22", shortClassName(this)); } public String toString() { if (empty(description)) return myType() + " " + id; else return "Script " + id + ": " + description; } public void initEditingText() { editingText(unnull(or(editingText, text))); } public void receiveEditingText(String text) { editingText(text); } public String stableText() { return text; } final public void save() { completeEdit(); } public void completeEdit() { String t = editingText; if (t != null) { setTextWithHistory(t); } } public void setTextWithHistory(String text) { if (eq(this.text, text)) return; text(text); saveTextToHistory(); } public void discardEdit() { String text = editedText(); if (text == null) return; saveFieldToHistory("discardingEdit", text); editingText(null); } public String textForEditing() { initEditingText(); return editingText; } public File historyFile() { return fileInConceptsDir("History/" + shortDynName(this) + id + ".history"); } public void saveTextToHistory() { saveFieldToHistory("text", text); } public void saveFieldToHistory(String field, String value) { File historyFile = historyFile(); if (historyFile == null) return; String contents = value == null ? " empty" : " (" + nLines(value) + ", " + nChars(value) + "):\n" + indentx(value) + "\n" + "\n"; appendToTextFile(historyFile, "\n===\n" + "Concept ID: " + id + "\n" + "Date: " + dateWithMSUTC() + "\n" + firstToUpper(field) + contents + "===" + "\n"); } public boolean isSaved() { return text != null; } public boolean isSavedDistinctFromAutoRunVersion() { return isSaved() && !eq(text, codeForAutoRun()); } public boolean isEditing() { return editedText() != null; } public boolean isClearForAutoRun() { return clearedForAutoRun != null; } public String editedText() { return eq(editingText, text) ? null : editingText; } public String codeForAutoRun() { return getVar(clearedForAutoRun()); } public String safestCode() { return or(codeForAutoRun(), stableText()); } public void clearForAutoRun() { if (!isSaved()) return; String text = text(); saveFieldToHistory("Auto-runnable code", text); clearedForAutoRun(new ClearForAutoRun(text)); } public void forgetAutoRunCode() { if (!isClearForAutoRun()) return; saveFieldToHistory("Auto-runnable code", null); clearedForAutoRun(null); compileResultForAutoRun = null; } public void forgetCompileResults() { compileResultForAutoRun = compileResultForSaved = null; } public G22Utils g22utils() { return assertNotNull("g22utils", main.g22utils(_concepts())); } public GazelleV_LeftArrowScriptParser makeParser() { return g22utils().leftArrowParser().sourceInfo(this); } public LASCompileResult newCompileResult() { return new LASCompileResult(); } public LASCompileResult returnOrCompile(LASCompileResult lastCompileResult, String code) { if (g22utils().compileResultValid(lastCompileResult, code)) return lastCompileResult; var cr = newCompileResult(); cr.script(code); var parser = makeParser(); cr.parser(parser); cr.compile(); return cr; } transient public LASCompileResult compileResultForAutoRun; public LASCompileResult compileForAutoRun() { String code = codeForAutoRun(); if (code == null) return null; var cr = returnOrCompile(compileResultForAutoRun, code); return compileResultForAutoRun = cr; } transient public LASCompileResult compileResultForSaved; public LASCompileResult compileSaved() { String code = stableText(); if (code == null) return null; var cr = returnOrCompile(compileResultForSaved, code); return compileResultForSaved = cr; } transient public LASCompileResult compileResultForEditing; public LASCompileResult compileEditing() { String code = editingText(); if (code == null) return null; var cr = returnOrCompile(compileResultForEditing, code); return compileResultForEditing = cr; } public LASCompileResult safestCompileResult() { { var __1 = compileForAutoRun(); if (__1 != null) return __1; } return compileSaved(); } public LASCompileResult latestCompileResult() { { var __2 = compileEditing(); if (__2 != null) return __2; } { var __3 = compileSaved(); if (__3 != null) return __3; } return compileForAutoRun(); } public LASCompileResult latestRunnableCompileResult() { var cr = compileEditing(); if (cr != null && cr.runnable()) return cr; cr = compileSaved(); if (cr != null && cr.runnable()) return cr; cr = compileForAutoRun(); if (cr != null && cr.runnable()) return cr; return null; } public Object evaluateWithoutTimeout() { var cr = safestCompileResult(); if (cr == null) throw fail("Not saved: " + this); AutoCloseable __4 = g22utils().enter(); try { return cr.parsedScriptMandatory().get(); } finally { _close(__4); } } public Object evaluateAutoRunWithoutTimeout() { var cr = compileForAutoRun(); if (cr == null) throw fail("Not cleared for auto-run: " + this); AutoCloseable __5 = g22utils().enter(); try { return cr.parsedScriptMandatory().get(); } finally { _close(__5); } } public String renderRunOnProjectOpenStatus() { return runOnProjectOpen ? "Yes" + appendBracketed(appendPrefixIfNempty("prio ", runOrder)) : null; } public Set allTexts() { return asSet(llNonNulls(text(), editedText(), codeForAutoRun())); } } static public class G22RegionThinner_v2 implements Steppable, IFieldsToList { public IImageRegion originalRegion; public G22RegionThinner_v2() { } public G22RegionThinner_v2(IImageRegion originalRegion) { this.originalRegion = originalRegion; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + originalRegion + ")"; } public Object[] _fieldsToList() { return new Object[] { originalRegion }; } public Rect bounds; public IImageRegion region; public boolean phase1done = false; final public G22RegionThinner_v2 setDebug(boolean debug) { return debug(debug); } public G22RegionThinner_v2 debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug() { return debug(); } public boolean debug() { return debug; } public boolean debug = false; final public G22RegionThinner_v2 setDoFinalStep(boolean doFinalStep) { return doFinalStep(doFinalStep); } public G22RegionThinner_v2 doFinalStep(boolean doFinalStep) { this.doFinalStep = doFinalStep; return this; } final public boolean getDoFinalStep() { return doFinalStep(); } public boolean doFinalStep() { return doFinalStep; } public boolean doFinalStep = true; final public G22RegionThinner_v2 setLastPhaseThreshold1(int lastPhaseThreshold1) { return lastPhaseThreshold1(lastPhaseThreshold1); } public G22RegionThinner_v2 lastPhaseThreshold1(int lastPhaseThreshold1) { this.lastPhaseThreshold1 = lastPhaseThreshold1; return this; } final public int getLastPhaseThreshold1() { return lastPhaseThreshold1(); } public int lastPhaseThreshold1() { return lastPhaseThreshold1; } public int lastPhaseThreshold1 = 2; final public G22RegionThinner_v2 setLastPhaseThreshold(int lastPhaseThreshold) { return lastPhaseThreshold(lastPhaseThreshold); } public G22RegionThinner_v2 lastPhaseThreshold(int lastPhaseThreshold) { this.lastPhaseThreshold = lastPhaseThreshold; return this; } final public int getLastPhaseThreshold() { return lastPhaseThreshold(); } public int lastPhaseThreshold() { return lastPhaseThreshold; } public int lastPhaseThreshold = 5; final public G22RegionThinner_v2 setLookupTable(byte[] lookupTable) { return lookupTable(lookupTable); } public G22RegionThinner_v2 lookupTable(byte[] lookupTable) { this.lookupTable = lookupTable; return this; } final public byte[] getLookupTable() { return lookupTable(); } public byte[] lookupTable() { return lookupTable; } public byte[] lookupTable; public byte[] pixels; public int idx(int x, int y) { return (y - bounds.y) * bounds.w + x - bounds.x; } public int idx(Pt p) { return idx(p.x, p.y); } public Pt idxToPt(int idx) { return pt(bounds.x + (idx % bounds.w), bounds.y + idx / bounds.w); } public byte getPixel(long p) { return getPixel(firstIntFromLong(p), secondIntFromLong(p)); } public byte getPixel(Pt p) { return !containsPt(bounds, p) ? 0 : pixels[idx(p)]; } public byte getPixel(int x, int y) { return !containsPt(bounds, x, y) ? 0 : pixels[idx(x, y)]; } public boolean contains(int x, int y) { return getPixel(x, y) != 0; } public boolean clearPixel(int x, int y) { if (!region.contains(x, y)) return false; pixels[idx(x, y)] = 0; return true; } public void init() { if (bounds != null) return; bounds = originalRegion.bounds(); pixels = new byte[area(bounds)]; for (Pt p : originalRegion.pixelIterator()) pixels[idx(p.x, p.y)] = 1; region = new ThinnedRegion(); } public class ThinnedRegion implements IImageRegion { public Img image() { return originalRegion.image(); } public Rect bounds() { return bounds; } public boolean contains(int x, int y) { return containsPt(bounds, x, y) && pixels[idx(x, y)] > 0; } public IterableIterator pixelIterator() { return iff_null(new IF0() { public int idx = 0; public Pt get() { for (; idx < pixels.length; idx++) if (pixels[idx] > 0) return idxToPt(idx++); return null; } }); } } public boolean step() { init(); if (phase1done) return finalStep(); List traces = g22_allBorderTraces_withDiagonals(region); for (var points : traces) for (var p : points) pixels[idx(p)] = 2; PtBuffer toDelete = new PtBuffer(); for (var points : traces) { int nPoints = l(points); BitSet deletable = emptyBitSet(nPoints); for (int i = 0; i < nPoints; i++) { boolean del = deletableBorderPoint(points, i); if (del) deletable.set(i); } for (int i = 0; i < nPoints; i++) if (cyclicGet(deletable, nPoints, i - 1) && !deletable.get(i) && cyclicGet(deletable, nPoints, i + 1)) { Pt p = points.get(i); Pt prev = ptMinus(cyclicGet(points, i - 1), p); Pt next = ptMinus(cyclicGet(points, i + 1), p); int dir1 = onePathLookupDirection(prev); int dir2 = onePathLookupDirection(next); int diff = mod(dir2 - dir1, 8); if (debug) printVars("special case", "p", p, "prev", prev, "next", next, "dir1", dir1, "dir2", dir2, "diff", diff); if (diff == 1 || diff == 7) deletable.set(i); } for (int i = 0; i < nPoints; i++) if (deletable.get(i)) toDelete.add(points.get(i)); } for (var p : toDelete) pixels[idx(p)] = 0; if (empty(toDelete)) phase1done = true; return true; } public boolean deletableBorderPoint(PtBuffer points, int i) { LongBuffer pointsBuf = points.buf; long p_long = pointsBuf.get(i); if (p_long == cyclicGet(pointsBuf, i - 2) || p_long == cyclicGet(pointsBuf, i + 2)) { return false; } int surroundingInnerPixels = 0; int foreignBorderPixels = 0; for (int dir = 1; dir <= 8; dir++) { long p2_long = onePathDirection_long(p_long, dir); byte value = getPixel(p2_long); if (value == 2 && !rangeContains(pointsBuf, i, p2_long)) { boolean fix = dir == 5 || dir == 7; if (!fix) return false; } else if (value == 1) { surroundingInnerPixels++; } } boolean deletable = surroundingInnerPixels > 0; int imgPattern = neighborhoodPattern(firstIntFromLong(p_long), secondIntFromLong(p_long)); if (imgPattern == 0b10011100 || imgPattern == 0b01000111 || imgPattern == 0b00111001 || imgPattern == 0b00111111 || imgPattern == 0b10111101) deletable = false; else if (imgPattern == 0b11010110) deletable = true; return deletable; } public boolean rangeContains(LongBuffer pointsBuf, int i, long p2_long) { for (int j = i - 3; j <= i + 3; j++) if (cyclicGet(pointsBuf, j) == p2_long) return true; return false; } public boolean deletableBorderPoint_old(PtBuffer points, int i) { List range = cyclicSubList_incl(points, i - 3, i + 3); Pt p = points.get(i); if (eq(range.get(1), p) || eq(range.get(5), p)) return false; int surroundingBorderPixels = 0, surroundingInnerPixels = 0; for (int dir = 1; dir <= 8; dir++) { Pt p2 = ptPlus(p, onePathDirection(dir)); byte value = getPixel(p2); if (value == 2 && !range.contains(p2)) surroundingBorderPixels++; else if (value == 1) surroundingInnerPixels++; } boolean deletable = surroundingInnerPixels > 0 && surroundingBorderPixels == 0; return deletable; } final public IImageRegion get() { return region(); } public IImageRegion region() { return or(region, originalRegion); } public boolean finalStep() { if (!doFinalStep) return false; if (lookupTable == null) lookupTable = new G22RegionThinner_LookupTable().lastPhaseThreshold(lastPhaseThreshold).lastPhaseThreshold1(lastPhaseThreshold1).get(); boolean change = false; int x1 = bounds.x, x2 = bounds.x2(); int y1 = bounds.y, y2 = bounds.y2(); var pingSource = pingSource(); for (int y = y1; y < y2; y++) { ping(pingSource); for (int x = x1; x < x2; x++) { if (!contains(x, y)) continue; int imgPattern = neighborhoodPattern(x, y); boolean delete = getBit(lookupTable, imgPattern); if (delete) change |= clearPixel(x, y); } } return change; } public int neighborhoodPattern(int x, int y) { return ubyteFromBits(contains(x - 1, y - 1), contains(x, y - 1), contains(x + 1, y - 1), contains(x - 1, y), contains(x + 1, y), contains(x - 1, y + 1), contains(x, y + 1), contains(x + 1, y + 1)); } } static public class PStack implements Steppable { public PStack() { } final public PStack setScheduler(ProbabilisticScheduler scheduler) { return scheduler(scheduler); } public PStack scheduler(ProbabilisticScheduler scheduler) { this.scheduler = scheduler; return this; } final public ProbabilisticScheduler getScheduler() { return scheduler(); } public ProbabilisticScheduler scheduler() { return scheduler; } public ProbabilisticScheduler scheduler = new ProbabilisticScheduler(); final public PStack setVerbose(boolean verbose) { return verbose(verbose); } public PStack verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; static public class NoOptionsException extends RuntimeException { } public PStack(VStack.Computable computable) { add(computable); } static public class ExecuteOption implements VStack.Computable, IFieldsToList { public IVF1 option; public ExecuteOption() { } public ExecuteOption(IVF1 option) { this.option = option; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + option + ")"; } public Object[] _fieldsToList() { return new Object[] { option }; } public void step(VStack stack, Object subComputationResult) { Object target = stack.caller(); stack._return(); option.get(target); } } public class SingleStack extends VStack implements IPStack, Runnable { public double probability = 1.0; public SingleStack() { } public SingleStack(VStack.Computable computable) { super(computable); } public void run() { try { if (verbose) print("Stepping " + last(stack)); if (step() && !isEmpty()) { if (verbose) print("Re-scheduling at " + probability + ": " + last(stack)); scheduler.add(probability, this); } } catch (Exception __e) { throw rethrow(__e); } } public void options(B function, Iterable> options) { List> optionsList = nonNulls(options); if (empty(optionsList)) throw new NoOptionsException(); probability = probability / l(optionsList); int n = l(optionsList) - 1; for (int i = 0; i < n; i++) { SingleStack s = new SingleStack(); s.stack = shallowCloneElements(stack); s.push(new ExecuteOption(optionsList.get(i))); s.probability = probability; scheduler.at(probability, s); } push(new ExecuteOption(last(optionsList))); } public void probabilisticOptions(B currentFrame, Iterable>> options) { List>> optionsList = nonNulls(options); if (empty(optionsList)) throw new NoOptionsException(); int n = l(optionsList) - 1; for (int i = 0; i < n; i++) { SingleStack s = new SingleStack(); s.stack = shallowCloneElements(stack); var option = optionsList.get(i); s.push(new ExecuteOption(option.get())); s.probability = probability * option.probability(); scheduler.at(s.probability, s); } var option = last(optionsList); probability *= option.probability(); push(new ExecuteOption(option.get())); } } static public class FollowUp extends PStackComputableWithStep implements IFieldsToList { public VStack.Computable computable; public IVF1 onCompletion; public FollowUp() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + computable + ", " + onCompletion + ")"; } public Object[] _fieldsToList() { return new Object[] { computable, onCompletion }; } public FollowUp(VStack.Computable computable, IVF1 onCompletion) { this.onCompletion = onCompletion; this.computable = computable; probability = getProbability(computable); } public void step(IPStack stack) { if (step == 0) { stack.push(computable); ++step; } else { onCompletion.get((A) stack.subResult()); stack._return(); } } } public void add(VStack.Computable computable) { scheduler.at(getProbability(computable), new SingleStack(computable)); } public void add(VStack.Computable computable, IVF1 onCompletion) { if (onCompletion != null) add(new FollowUp<>(computable, onCompletion)); else add(computable); } public boolean step() { return scheduler.step(); } public void run() { scheduler.run(); } public void run(VStack.Computable computable) { add(computable); run(); } public void runWithStats() { scheduler.runWithStats(); } public void runWithStats(VStack.Computable computable) { add(computable); runWithStats(); } static public double getProbability(VStack.Computable computable) { return computable instanceof PStackComputable ? ((PStackComputable) computable).probability : 1.0; } } static public class Chaser extends G22TradingStrategy { static final public String _fieldOrder = "maxPositionHours maxLoss pullback relativePullback minPullback maxPullback opener lastDirection rlc openSignal"; final public Chaser setMaxPositionHours(double maxPositionHours) { return maxPositionHours(maxPositionHours); } public Chaser maxPositionHours(double maxPositionHours) { this.maxPositionHours = maxPositionHours; return this; } final public double getMaxPositionHours() { return maxPositionHours(); } public double maxPositionHours() { return maxPositionHours; } public double maxPositionHours = 4; final public Chaser setMaxLoss(double maxLoss) { return maxLoss(maxLoss); } public Chaser maxLoss(double maxLoss) { this.maxLoss = maxLoss; return this; } final public double getMaxLoss() { return maxLoss(); } public double maxLoss() { return maxLoss; } public double maxLoss = 0.6; final public Chaser setPullback(double pullback) { return pullback(pullback); } public Chaser pullback(double pullback) { this.pullback = pullback; return this; } final public double getPullback() { return pullback(); } public double pullback() { return pullback; } public double pullback = 0.4; final public Chaser setRelativePullback(double relativePullback) { return relativePullback(relativePullback); } public Chaser relativePullback(double relativePullback) { this.relativePullback = relativePullback; return this; } final public double getRelativePullback() { return relativePullback(); } public double relativePullback() { return relativePullback; } public double relativePullback; final public Chaser setMinPullback(double minPullback) { return minPullback(minPullback); } public Chaser minPullback(double minPullback) { this.minPullback = minPullback; return this; } final public double getMinPullback() { return minPullback(); } public double minPullback() { return minPullback; } public double minPullback; final public Chaser setMaxPullback(double maxPullback) { return maxPullback(maxPullback); } public Chaser maxPullback(double maxPullback) { this.maxPullback = maxPullback; return this; } final public double getMaxPullback() { return maxPullback(); } public double maxPullback() { return maxPullback; } public double maxPullback; final public Chaser setOpener(Opener opener) { return opener(opener); } public Chaser opener(Opener opener) { this.opener = opener; return this; } final public Opener getOpener() { return opener(); } public Opener opener() { return opener; } public Opener opener; public transient FieldVar varLastDirection_cache; public FieldVar varLastDirection() { if (varLastDirection_cache == null) varLastDirection_cache = varLastDirection_load(); return varLastDirection_cache; } public FieldVar varLastDirection_load() { return new FieldVar(this, "lastDirection", () -> lastDirection(), lastDirection -> lastDirection(lastDirection)); } final public Chaser setLastDirection(int lastDirection) { return lastDirection(lastDirection); } public Chaser lastDirection(int lastDirection) { if (!eq(this.lastDirection, lastDirection)) { this.lastDirection = lastDirection; change(); } return this; } final public int getLastDirection() { return lastDirection(); } public int lastDirection() { return lastDirection; } public int lastDirection; public RunLengthCounter rlc = new RunLengthCounter(); public OpenSignal openSignal; public class CloseSignal implements IFieldsToList { public String reason; public double trigger; public CloseSignal() { } public CloseSignal(String reason, double trigger) { this.trigger = trigger; this.reason = reason; } public Object[] _fieldsToList() { return new Object[] { reason, trigger }; } public double trigger() { return trigger; } public String toString() { return "Close signal " + reason + " (" + iround(trigger * 100) + "%)"; } } public class OpenSignal implements IFieldsToList { public String reason; public double trigger; public int direction; public OpenSignal() { } public OpenSignal(String reason, double trigger, int direction) { this.direction = direction; this.trigger = trigger; this.reason = reason; } public Object[] _fieldsToList() { return new Object[] { reason, trigger, direction }; } public double trigger() { return trigger; } public String toString() { return "Open signal " + reason + " (" + iround(trigger * 100) + "%)"; } } public class BaseJuicer { public BaseJuicer() { } final public BaseJuicer setMaxLoss(double maxLoss) { return maxLoss(maxLoss); } public BaseJuicer maxLoss(double maxLoss) { this.maxLoss = maxLoss; return this; } final public double getMaxLoss() { return maxLoss(); } public double maxLoss() { return maxLoss; } public double maxLoss; public List closeSignals(Position p) { List signals = new ArrayList(); double profit = p.profitBeforeLeverage(); if (p.maxClosingTime() < infinity()) signals.add(new CloseSignal("Age", transformToZeroToOne(currentTime(), p.openingTime(), p.maxClosingTime()))); if (profit < 0) signals.add(new CloseSignal("Loss", doubleRatio(-profit, maxLoss))); return signals; } } public class Juicer extends BaseJuicer { public Juicer() { } final public Juicer setPullback(double pullback) { return pullback(pullback); } public Juicer pullback(double pullback) { this.pullback = pullback; return this; } final public double getPullback() { return pullback(); } public double pullback() { return pullback; } public double pullback; public Juicer(double maxLoss, double pullback) { this.pullback = pullback; this.maxLoss = maxLoss; } public String toString() { return renderRecord("Juicer", "maxLoss", maxLoss, "pullback", pullback); } public List closeSignals(Position p) { List signals = super.closeSignals(p); double profit = p.profitBeforeLeverage(); if (profit >= 0) signals.add(new CloseSignal("Profit", transformToZeroToOne(profit, p.crest, p.crest - pullback))); return signals; } } public class RelativePullbackJuicer extends BaseJuicer { public RelativePullbackJuicer() { } final public RelativePullbackJuicer setRelativePullback(double relativePullback) { return relativePullback(relativePullback); } public RelativePullbackJuicer relativePullback(double relativePullback) { this.relativePullback = relativePullback; return this; } final public double getRelativePullback() { return relativePullback(); } public double relativePullback() { return relativePullback; } public double relativePullback; final public RelativePullbackJuicer setMinPullback(double minPullback) { return minPullback(minPullback); } public RelativePullbackJuicer minPullback(double minPullback) { this.minPullback = minPullback; return this; } final public double getMinPullback() { return minPullback(); } public double minPullback() { return minPullback; } public double minPullback; final public RelativePullbackJuicer setMaxPullback(double maxPullback) { return maxPullback(maxPullback); } public RelativePullbackJuicer maxPullback(double maxPullback) { this.maxPullback = maxPullback; return this; } final public double getMaxPullback() { return maxPullback(); } public double maxPullback() { return maxPullback; } public double maxPullback; public String toString() { return renderRecord("RelativePullbackJuicer", "maxLoss", maxLoss, "relativePullback", relativePullback, "minPullback", minPullback, "maxPullback", maxPullback); } public List closeSignals(Position p) { List signals = super.closeSignals(p); double profit = p.profitBeforeLeverage(); if (profit >= 0) signals.add(new CloseSignal("Profit", transformToZeroToOne(profit, p.crest, p.crest - calculatePullback(p.crest)))); return signals; } public double calculatePullback(double crest) { return clamp(relativePullback / 100 * crest, minPullback, maxPullback); } } abstract static public class Opener { abstract public OpenSignal openSignal(); abstract public Opener cloneInto(Chaser strat); } public class PreRunOpener extends Opener implements IFieldsToList { public int minRunUp; public int minRunDown; public PreRunOpener() { } public PreRunOpener(int minRunUp, int minRunDown) { this.minRunDown = minRunDown; this.minRunUp = minRunUp; } public boolean equals(Object o) { if (!(o instanceof PreRunOpener)) return false; PreRunOpener __0 = (PreRunOpener) o; return minRunUp == __0.minRunUp && minRunDown == __0.minRunDown; } public int hashCode() { int h = 1447043999; h = boostHashCombine(h, _hashCode(minRunUp)); h = boostHashCombine(h, _hashCode(minRunDown)); return h; } public Object[] _fieldsToList() { return new Object[] { minRunUp, minRunDown }; } public Opener cloneInto(Chaser strat) { return strat.new PreRunOpener(minRunUp, minRunDown); } public OpenSignal openSignal() { int direction = Chaser.this.direction; if (direction == 0) return null; int preRun = direction > 1 ? minRunUp : minRunDown; int runLength = toInt(rlc.runLength()); return new OpenSignal("RunLength " + runLength, doubleRatio(runLength, preRun), direction); } public String toString() { return "PreRunOpener up " + minRunUp + ", down " + minRunDown; } } public class Position extends G22TradingStrategy.Position { public Position() { } final public Position setOpenSignal(OpenSignal openSignal) { return openSignal(openSignal); } public Position openSignal(OpenSignal openSignal) { this.openSignal = openSignal; return this; } final public OpenSignal getOpenSignal() { return openSignal(); } public OpenSignal openSignal() { return openSignal; } public OpenSignal openSignal; final public Position setJuicer(BaseJuicer juicer) { return juicer(juicer); } public Position juicer(BaseJuicer juicer) { this.juicer = juicer; return this; } final public BaseJuicer getJuicer() { return juicer(); } public BaseJuicer juicer() { return juicer; } public BaseJuicer juicer; final public Position setCrest(double crest) { return crest(crest); } public Position crest(double crest) { this.crest = crest; return this; } final public double getCrest() { return crest(); } public double crest() { return crest; } public double crest = -infinity(); public double maxClosingTime() { return usingLiveData ? infinity() : openingTime() + hoursToMS(maxPositionHours); } public List closeSignals() { return juicer == null ? null : juicer.closeSignals(this); } public double closeSignal() { CloseSignal strongestSignal = closeSignalWithDescription(); return strongestSignal == null ? 0 : strongestSignal.trigger; } public CloseSignal closeSignalWithDescription() { return highestBy(closeSignals(), signal -> signal.trigger); } public void update() { crest = max(crest, profitBeforeLeverage()); } public String toString() { var closeSignal = closed() ? null : closeSignalWithDescription(); return commaCombine(super.toString(), closeSignal); } } public List status() { return listCombine(commaCombine("Max loss: " + formatDouble3(maxLoss) + "%", relativePullback == 0 ? "pullback: " + formatDouble3(pullback) + "%" : commaCombine("relative pullback: " + formatDouble3(relativePullback) + "%", "min pullback: " + formatDouble3(minPullback) + "%", "max pullback: " + formatDouble3(maxPullback) + "%")), "Opener: " + opener, "Run length: " + signToUpDown(unnull(rlc.value())) + " " + rlc.runLength(), openSignal, super.status()); } public Position openPosition(OpenSignal openSignal) { int direction = openSignal.direction; if (l(positionsInDirection(direction)) > 0) { return null; } nextStep(); Position p = new Position(); p.openSignal(openSignal); p.juicer(makeJuicer()); return openPosition(p, direction); } public BaseJuicer makeJuicer() { if (relativePullback != 0) return new RelativePullbackJuicer().relativePullback(relativePullback).minPullback(minPullback).maxPullback(maxPullback).maxLoss(maxLoss); else return new Juicer(maxLoss, pullback); } public void start() { if (started()) throw fail("Already started"); if (currentPrice() == 0) { primed(true); return; } startingPrice = currentPrice(); var priceCells = makePriceCells(startingPrice); digitizer = new PriceDigitizer2(priceCells); digitizer.verbose(verbose); log("Starting CHASER at " + startingPrice + " +/- " + cellSize); } public void price(double price) { if (currentPrice == price) return; currentPrice = price; if (!started()) { if (primed) { primed(false); start(); nextStep(); beforeStep(); afterStep(); } return; } digitizer.digitize(price); direction = sign(digitizedPrice() - lastDigitizedPrice()); if (direction != 0) lastDirection = direction; if (started()) step(); } transient public Runnable step; public void step() { if (step != null) step.run(); else step_base(); } final public void step_fallback(Runnable _f) { if (_f != null) _f.run(); else step_base(); } public void step_base() { for (var p : openPositions()) { ((Position) p).update(); } List toClose = new ArrayList(); for (var p : openPositions()) { CloseSignal signal = ((Position) p).closeSignalWithDescription(); if (signal != null && signal.trigger() >= 1) { ((Position) p).closeReason(signal); log("Closing position because " + signal + ": " + ((Position) p)); toClose.add((Position) p); } } if (nempty(toClose)) { nextStep(); closePositions(toClose); afterStep(); } beforeStep(); double p1 = lastDigitizedPrice(); double p2 = digitizedPrice(); direction = sign(p2 - p1); if (direction != 0) rlc.add(direction); if (haveBackData()) { openSignal = makeOpenSignal(); if (openSignal != null && openSignal.trigger >= 1) openPosition(openSignal); afterStep(); } } transient public IF0 makeOpenSignal; public OpenSignal makeOpenSignal() { return makeOpenSignal != null ? makeOpenSignal.get() : makeOpenSignal_base(); } final public OpenSignal makeOpenSignal_fallback(IF0 _f) { return _f != null ? _f.get() : makeOpenSignal_base(); } public OpenSignal makeOpenSignal_base() { return opener == null ? null : opener.openSignal(); } transient public Runnable beforeStep; public void beforeStep() { if (beforeStep != null) beforeStep.run(); else beforeStep_base(); } final public void beforeStep_fallback(Runnable _f) { if (_f != null) _f.run(); else beforeStep_base(); } public void beforeStep_base() { } public String baseToString() { return colonCombine(_conceptID() == 0 ? "" : "Strategy " + _conceptID(), "Chaser profit " + formatMarginProfit(coinProfit())); } public String fieldsToReset() { return lines(ll(super.fieldsToReset(), "lastDirection rlc openSignal")); } public Chaser emptyClone() { Chaser strat = (Chaser) (super.emptyClone()); return strat.opener(opener == null ? null : opener.cloneInto(strat)); } public String toString() { return baseToString(); } public Chaser preRunOpener(int minRunUp, int minRunDown) { return opener(new PreRunOpener(minRunUp, minRunDown)); } } static public class G22ScreenPartsPanel extends G22CRUDAndDetailPanel { public G22ScreenPartsPanel() { } public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22ScreenPart.class); crud.entityName = () -> "Screen part"; crud.addButton("Add all screens", runnableThread(new Runnable() { public void run() { try { addAllScreens(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "addAllScreens();"; } })); return crud; } public void addAllScreens() { uniq(g22utils.concepts(), G22ScreenPart.class, "name", "All screens", "bounds", combinedScreenBounds()); } public JComponent makeDetailView(G22ScreenPart screenPart) { var maxSize = 100; var full = combinedScreenRect(); var rect = screenPart.bounds; var scale = min(doubleRatio(maxSize, full.w()), doubleRatio(maxSize, full.h())); var image = whiteImage(iround(scale * full.w()), iround(scale * full.h())); if (rect != null) { var scaled = scaleRect(rect, scale); fillRect(image, scaled, java.awt.Color.gray); } image = addBorderToImage(image, java.awt.Color.black, 1); return g22utils.stdImageSurface(image); } public G22ScreenPartsPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } } static public class TradingCandleMaker { public TradingCandleMaker() { } final public TradingCandleMaker setCandleLength(double candleLength) { return candleLength(candleLength); } public TradingCandleMaker candleLength(double candleLength) { this.candleLength = candleLength; return this; } final public double getCandleLength() { return candleLength(); } public double candleLength() { return candleLength; } public double candleLength = 1; final public TradingCandleMaker setMaxCandles(int maxCandles) { return maxCandles(maxCandles); } public TradingCandleMaker maxCandles(int maxCandles) { this.maxCandles = maxCandles; return this; } final public int getMaxCandles() { return maxCandles(); } public int maxCandles() { return maxCandles; } public int maxCandles = Integer.MAX_VALUE; final public TradingCandleMaker setAlignment(double alignment) { return alignment(alignment); } public TradingCandleMaker alignment(double alignment) { this.alignment = alignment; return this; } final public double getAlignment() { return alignment(); } public double alignment() { return alignment; } public double alignment; public TradingCandleMaker(double candleLength) { this.candleLength = candleLength; } public List candles = syncL(); public TradingCandle currentCandle() { return last(candles); } public TradingCandle completedCandle() { return nextToLast(candles); } public boolean isEmpty() { return loadableUtils.utils.isEmpty(candles); } public Timestamp endTime() { var candle = last(candles); return candle == null ? null : candle.endTime(); } public double lastPrice() { return currentCandle().end(); } public void add(double price, long timestamp) { var ts = new Timestamp(timestamp); int safety = 0; while (currentCandle() != null) { if (safety++ >= 1000) { warn("TradingCandleMaker safety warning"); break; } Timestamp maxEnd = maxEndOfCurrentCandle(); if (!greaterOrEq(ts, maxEnd)) break; currentCandle().endTime(maxEnd); double lastPrice = lastPrice(); newCandle(); currentCandle().addValue(lastPrice, maxEnd); } if (empty(candles)) newCandle(); currentCandle().addValue(price, ts); } public void newCandle() { var c = currentCandle(); { if (c != null) c.ongoing(false); } candles.add(new TradingCandle().ongoing(true)); dropOldCandles(); } final public int feed(TickerSequence ts) { return addTickerSequence(ts); } public int addTickerSequence(TickerSequence ts) { int entriesProcessed = 0; Timestamp endTime = endTime(); if (endTime != null) ts = ts.subSequenceFromTimestamp(endTime().unixDate() + 1); int n = l(ts); for (int i = 0; i < n; i++) { add(ts.prices.get(i), ts.timestamps.get(i)); ++entriesProcessed; } if (!isEmpty() && ts.lastTickerEvent > currentCandle().endTime().toLong()) { add(ts.lastPrice(), ts.lastTickerEvent); ++entriesProcessed; } return entriesProcessed; } public Timestamp maxEndOfCurrentCandle() { long time = currentCandle().startTime.toLong(); long align = secondsToMS(alignment); time = roundUpTo(secondsToMS(candleLength * 60), time + align + 1) - align; return new Timestamp(time); } public void dropOldCandles() { if (l(candles) > maxCandles) removeSubList(candles, 0, l(candles) - maxCandles); } final public List get() { return candles(); } public List candles() { return cloneList(candles); } public List liveCandles() { return candles; } public String toString() { return "Candle maker " + formatDouble(candleLength) + "m, " + nCandles(candles); } } static public class DynamicVStack extends DynamicStack { transient public IF0 _componentConstraints; public GridBagConstraints _componentConstraints() { return _componentConstraints != null ? _componentConstraints.get() : _componentConstraints_base(); } final public GridBagConstraints _componentConstraints_fallback(IF0 _f) { return _f != null ? _f.get() : _componentConstraints_base(); } public GridBagConstraints _componentConstraints_base() { return gridBagConstraints_vstack_1(spacing); } public GridBagConstraints _fillerConstraints() { return gridBagConstraints_vstack_rest(); } } static public class G22PointOfInterest extends ConceptWithChangeListeners { static final public String _fieldOrder = "imageMD5 pt bnpSettings source labelsText"; public String imageMD5; public Pt pt; public BlurAndPosterizeSettings bnpSettings; public String source; public String labelsText; public String toString() { return commaCombine("Point of interest " + id, labelsText); } public G22Utils g22utils() { return main.g22utils(this); } public BufferedImage image() { var img = galleryImage(); return img == null ? null : img.image(); } public G22GalleryImage galleryImage() { return g22utils().galleryImageForMD5(imageMD5); } public boolean sameImage(G22PointOfInterest otherPOI) { return otherPOI != null && eq(imageMD5, otherPOI.imageMD5); } public G22DataWrangler wrangler() { return wranglerStealingFrom(null, null); } public G22DataWrangler wranglerStealingFrom(G22PointOfInterest otherPOI, G22DataWrangler otherWrangler) { if (otherWrangler != null && !sameImage(otherPOI)) otherWrangler = null; G22DataWrangler wrangler = new G22DataWrangler(); wrangler.inputImage(otherWrangler != null ? otherWrangler.inputImage : image()); wrangler.stealingFrom(otherWrangler); wrangler.timings(g22utils().functionTimings()); wrangler.importSettings(bnpSettings); return wrangler; } public IImageRegion regionAroundPoint() { return regionAroundPoint(wrangler()); } public IImageRegion regionAroundPoint(G22DataWrangler wrangler) { var rm = wrangler.regionMaker(); return rm.getRegion(rm.regionAt(pt)); } } static public class G22MeshScrambler implements IFieldsToList { public G22Mesh mesh; public G22MeshScrambler() { } public G22MeshScrambler(G22Mesh mesh) { this.mesh = mesh; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + mesh + ")"; } public Object[] _fieldsToList() { return new Object[] { mesh }; } public G22Mesh scrambledMesh; public Map anchorMap = new HashMap(); public G22Mesh get() { scrambledMesh = new G22Mesh(); for (var a1 : shuffled(mesh.anchors())) { var a2 = scrambledMesh.newAnchor(a1.pt); anchorMap.put(a1, a2); } for (var c1 : shuffled(mesh.curves())) { boolean flip = flipCoin(); var path = flip ? c1.path.reversed() : c1.path; scrambledMesh.addCurve(new G22Mesh.Curve(anchorMap.get(c1.anchor(flip)), anchorMap.get(c1.anchor(!flip)), path)); } return scrambledMesh; } } static public class G22SelfTests implements IFieldsToList { public G22Utils g22utils; public G22SelfTests() { } public G22SelfTests(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } volatile public boolean started = false; volatile public OKOrError result; public void run() { try { started = true; result = okOrError(() -> runImpl()); String msg = "Self Tests " + status(); if (result.isOK()) print(msg); else infoBox(msg); } catch (Exception __e) { throw rethrow(__e); } } public void runImpl() { G22LAScriptIDE.selfTest(g22utils); } public String status() { return !started ? "Not started" : result == null ? "Running" : result.isOK() ? "OK" : "Failed"; } } static public class G22Analyzer extends G22LeftArrowScript { public Ref exampleImage = new Ref(); @Override public GazelleV_LeftArrowScriptParser makeParser() { var parser = super.makeParser(); parser.addVar("image", BufferedImage.class, false); parser.addVar("imageStream", SourceTriggeredStream.class, false); parser.addVar("context", G22AnalysisContext.class, false); return parser; } public class CompiledAnalyzer extends LASCompileResult { final public CompiledAnalyzer setTimeout(double timeout) { return timeout(timeout); } public CompiledAnalyzer timeout(double timeout) { this.timeout = timeout; return this; } final public double getTimeout() { return timeout(); } public double timeout() { return timeout; } public double timeout = 10; public G22AnalysisContext createAnalysisContext(BufferedImage image) { return new G22AnalysisContext(g22utils(), image); } public Object get_impl(G22AnalysisContext context) { FlexibleVarContext ctx = new FlexibleVarContext(); ctx.set("image", context.image); ctx.set("imageStream", context.imageStream); ctx.set("context", context); return parsedScript.get(ctx); } public Object get_impl(BufferedImage image) { return get_impl(createAnalysisContext(image)); } public Object get(BufferedImage image) { return get(createAnalysisContext(image)); } public Object get(G22AnalysisContext context) { if (context.analyzerResults.containsKey(analyzer())) { Object value = context.analyzerResults.get(analyzer()); if (value == G22AnalysisContext.calculating) throw fail("Recursive call to analyzer " + this); return ((OKOrError) value).getMandatory(); } context.analyzerResults.put(analyzer(), G22AnalysisContext.calculating); var result = okOrError(() -> { if (parsedScript == null) rethrow(compileError); if (context.image == null && context.imageStream == null) throw fail("Need image or imageStream"); return g22utils().evalRegisteredCode(timeout, str(G22Analyzer.this), () -> get_impl(context)); }); context.analyzerResults.put(analyzer(), result); return result.getMandatory(); } } public G22Analyzer analyzer() { return this; } public LASCompileResult newCompileResult() { return new CompiledAnalyzer(); } public CompiledAnalyzer compileForAutoRun() { return (CompiledAnalyzer) super.compileForAutoRun(); } } static public class FastDownscale4x4 { static final public int scaleX = 4, scaleY = scaleX; public int w, h, w2, h2; public int[] finalPixels; public void scaleDown(BufferedImage img) { scaleDown(loadableUtils.utils.grabbableIntPixels_fastOrSlow(img)); } public void scaleDown(GrabbableIntPixels gp) { w = gp.w; int h = this.h = gp.h; int w2 = this.w2 = w / scaleX, h2 = this.h2 = h / scaleY; int stride = gp.scanlineStride; int scaleArea = scaleX * scaleY; int[] newPixels = finalPixels = new int[w2 * h2]; int iRow = gp.offset, iOut = 0; int[] pixels = gp.data; for (int y = 0; y < h2; y++) { int iIn = iRow; for (int x = 0; x < w2; x++) { int r = 0, g = 0, b = 0; int iSub = iIn; for (int subY = 0; subY < scaleY; subY++) { for (int subX = 0; subX < scaleX; subX++) { int rgb = pixels[iSub + subX]; r += (rgb >> 16) & 0xFF; g += (rgb >> 8) & 0xFF; b += rgb & 0xFF; } iSub += stride; } iIn += scaleX; newPixels[iOut++] = rgbIntFullAlpha(r / scaleArea, g / scaleArea, b / scaleArea); } iRow += stride * scaleY; } } public BufferedImage get(BufferedImage img) { scaleDown(img); return get(); } public BufferedImage get() { return bufferedImage(w2, h2, finalPixels); } public GrabbableIntPixels grabbableIntPixels() { return new GrabbableIntPixels(finalPixels, w2, h2, 0, w2); } } static public class SetWithChangeListeners extends NotifyingSet implements IHasChangeListeners { transient public Set onChange; public SetWithChangeListeners onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public SetWithChangeListeners removeChangeListener(Runnable r) { loadableUtils.utils.remove(onChange, r); return this; } public void fireChange() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public void change() { fireChange(); } public SetWithChangeListeners() { super(new HashSet()); } public SetWithChangeListeners(Set set) { super(set); } } static public class G22DataWrangler extends Stages2 implements IHasChangeListeners { transient public Set onChange; public G22DataWrangler onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public G22DataWrangler removeChangeListener(Runnable r) { loadableUtils.utils.remove(onChange, r); return this; } public void change() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } final public G22DataWrangler setInputImage(BufferedImage inputImage) { return inputImage(inputImage); } public G22DataWrangler inputImage(BufferedImage inputImage) { this.inputImage = inputImage; return this; } final public BufferedImage getInputImage() { return inputImage(); } public BufferedImage inputImage() { return inputImage; } public BufferedImage inputImage; final public G22DataWrangler setStealingFrom(G22DataWrangler stealingFrom) { return stealingFrom(stealingFrom); } public G22DataWrangler stealingFrom(G22DataWrangler stealingFrom) { this.stealingFrom = stealingFrom; return this; } final public G22DataWrangler getStealingFrom() { return stealingFrom(); } public G22DataWrangler stealingFrom() { return stealingFrom; } public G22DataWrangler stealingFrom; final public G22DataWrangler setWithDiagonals(boolean withDiagonals) { return withDiagonals(withDiagonals); } public G22DataWrangler withDiagonals(boolean withDiagonals) { this.withDiagonals = withDiagonals; return this; } final public boolean getWithDiagonals() { return withDiagonals(); } public boolean withDiagonals() { return withDiagonals; } public boolean withDiagonals = true; public transient FieldVar varBlur_cache; public FieldVar varBlur() { if (varBlur_cache == null) varBlur_cache = varBlur_load(); return varBlur_cache; } public FieldVar varBlur_load() { return new FieldVar(this, "blur", () -> blur(), blur -> blur(blur)); } final public G22DataWrangler setBlur(int blur) { return blur(blur); } public G22DataWrangler blur(int blur) { if (!eq(this.blur, blur)) { this.blur = blur; change(); } return this; } final public int getBlur() { return blur(); } public int blur() { return blur; } public int blur = 1; public transient FieldVar varColorsPerChannel_cache; public FieldVar varColorsPerChannel() { if (varColorsPerChannel_cache == null) varColorsPerChannel_cache = varColorsPerChannel_load(); return varColorsPerChannel_cache; } public FieldVar varColorsPerChannel_load() { return new FieldVar(this, "colorsPerChannel", () -> colorsPerChannel(), colorsPerChannel -> colorsPerChannel(colorsPerChannel)); } final public G22DataWrangler setColorsPerChannel(int colorsPerChannel) { return colorsPerChannel(colorsPerChannel); } public G22DataWrangler colorsPerChannel(int colorsPerChannel) { if (!eq(this.colorsPerChannel, colorsPerChannel)) { this.colorsPerChannel = colorsPerChannel; change(); } return this; } final public int getColorsPerChannel() { return colorsPerChannel(); } public int colorsPerChannel() { return colorsPerChannel; } public int colorsPerChannel = 2; public transient FieldVar varDrift_cache; public FieldVar varDrift() { if (varDrift_cache == null) varDrift_cache = varDrift_load(); return varDrift_cache; } public FieldVar varDrift_load() { return new FieldVar(this, "drift", () -> drift(), drift -> drift(drift)); } final public G22DataWrangler setDrift(float drift) { return drift(drift); } public G22DataWrangler drift(float drift) { if (!eq(this.drift, drift)) { this.drift = drift; change(); } return this; } final public float getDrift() { return drift(); } public float drift() { return drift; } public float drift; public transient FieldVar varAntiDrift_cache; public FieldVar varAntiDrift() { if (varAntiDrift_cache == null) varAntiDrift_cache = varAntiDrift_load(); return varAntiDrift_cache; } public FieldVar varAntiDrift_load() { return new FieldVar(this, "antiDrift", () -> antiDrift(), antiDrift -> antiDrift(antiDrift)); } final public G22DataWrangler setAntiDrift(float antiDrift) { return antiDrift(antiDrift); } public G22DataWrangler antiDrift(float antiDrift) { if (!eq(this.antiDrift, antiDrift)) { this.antiDrift = antiDrift; change(); } return this; } final public float getAntiDrift() { return antiDrift(); } public float antiDrift() { return antiDrift; } public float antiDrift; final public G22DataWrangler setKilobytes(TargetAndActual kilobytes) { return kilobytes(kilobytes); } public G22DataWrangler kilobytes(TargetAndActual kilobytes) { this.kilobytes = kilobytes; return this; } final public TargetAndActual getKilobytes() { return kilobytes(); } public TargetAndActual kilobytes() { return kilobytes; } public TargetAndActual kilobytes = new TargetAndActual<>(250.0); final public G22DataWrangler setCoveredPixelsPercentage(TargetAndActual coveredPixelsPercentage) { return coveredPixelsPercentage(coveredPixelsPercentage); } public G22DataWrangler coveredPixelsPercentage(TargetAndActual coveredPixelsPercentage) { this.coveredPixelsPercentage = coveredPixelsPercentage; return this; } final public TargetAndActual getCoveredPixelsPercentage() { return coveredPixelsPercentage(); } public TargetAndActual coveredPixelsPercentage() { return coveredPixelsPercentage; } public TargetAndActual coveredPixelsPercentage = new TargetAndActual(); final public G22DataWrangler setDetailLevel(TargetAndActual detailLevel) { return detailLevel(detailLevel); } public G22DataWrangler detailLevel(TargetAndActual detailLevel) { this.detailLevel = detailLevel; return this; } final public TargetAndActual getDetailLevel() { return detailLevel(); } public TargetAndActual detailLevel() { return detailLevel; } public TargetAndActual detailLevel = new TargetAndActual(); final public G22DataWrangler setVectorize(boolean vectorize) { return vectorize(vectorize); } public G22DataWrangler vectorize(boolean vectorize) { this.vectorize = vectorize; return this; } final public boolean getVectorize() { return vectorize(); } public boolean vectorize() { return vectorize; } public boolean vectorize = true; final public G22DataWrangler setAllowPartialSSIs(boolean allowPartialSSIs) { return allowPartialSSIs(allowPartialSSIs); } public G22DataWrangler allowPartialSSIs(boolean allowPartialSSIs) { this.allowPartialSSIs = allowPartialSSIs; return this; } final public boolean getAllowPartialSSIs() { return allowPartialSSIs(); } public boolean allowPartialSSIs() { return allowPartialSSIs; } public boolean allowPartialSSIs = true; final public boolean getBlackAndWhiteMode() { return blackAndWhiteMode(); } public boolean blackAndWhiteMode() { return blackAndWhiteMode; } public boolean blackAndWhiteMode = false; final public G22DataWrangler setSortMode(SortMode sortMode) { return sortMode(sortMode); } public G22DataWrangler sortMode(SortMode sortMode) { this.sortMode = sortMode; return this; } final public SortMode getSortMode() { return sortMode(); } public SortMode sortMode() { return sortMode; } public SortMode sortMode = SortMode.compressibility; public enum SortMode { compressibility, pixels } public BufferedImage blurredImage; public int maxLines, maxInts; public List currentSSIs; public List initialSSIs; public AbstractSSIList sortedSSIs, cutSSIs, vectorizedSSIs, cutVectorizedSSIs; public CutListToBudget cutter; public Hi15Image posterizedImage; public FastRegions_Hi15Image regionMaker; public List> regions, regionsBySize; public G22DataWrangler() { } public G22DataWrangler(BufferedImage inputImage) { this.inputImage = inputImage; } public SinglePixelPosterizer posterizer() { return new SinglePixelPosterizer(colorsPerChannel()).drift(drift).antiDrift(antiDrift); } public G22DataWrangler kb(TargetAndActual kb) { return kilobytes(kb); } public TargetAndActual kb() { return kilobytes; } public WidthAndHeight resolution() { return imageSize(inputImage); } public double detailDivisor() { return areaRoot(inputImage); } public int colors() { return blackAndWhiteMode ? 2 : cubed(colorsPerChannel()); } transient public FieldVar varColors_cache; public FieldVar varColors() { if (varColors_cache == null) varColors_cache = varColors_load(); return varColors_cache; } public FieldVar varColors_load() { return new FieldVar(this, "colors", () -> colors(), __1 -> colors(__1)); } public G22DataWrangler colors(int colors) { int perChannel = iceil(cbrt(colors)); blackAndWhiteMode = colors == 2; return colorsPerChannel(perChannel); } { stage("Stop Stealing", new Runnable() { public void run() { try { if (stealingFrom != null) { if (stealingFrom.inputImage != inputImage) { stealingFrom = null; return; } stealingFrom.stealingFrom = null; } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (stealingFrom != null) {\r\n if (stealingFrom.inputImage != inputImage)..."; } }); } { stage("Blur", new Runnable() { public void run() { try { if (stealingFrom != null) if (stealingFrom.blur == blur) { blurredImage = stealingFrom.blurredImage; return; } else stealingFrom = null; blurredImage = blurBufferedImage(blur, inputImage); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (stealingFrom != null)\r\n if (stealingFrom.blur == blur)\r\n { bl..."; } }); } { stage("Posterize", new Runnable() { public void run() { try { if (stealingFrom != null) if (eq(stealingFrom.posterizer(), posterizer())) { posterizedImage = stealingFrom.posterizedImage; return; } else stealingFrom = null; var image = blurredImage; if (blackAndWhiteMode) image = new BWImage(image).getBufferedImage(); posterizedImage = posterizeBufferedImageToHi15(image, posterizer()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (stealingFrom != null)\r\n if (eq(stealingFrom.posterizer(), posterizer..."; } }); } public Stage regionsStage = stage("Regions", new Runnable() { public void run() { try { if (stealingFrom != null) if (stealingFrom.withDiagonals == withDiagonals) { regionMaker = stealingFrom.regionMaker; regions = stealingFrom.regions; return; } else stealingFrom = null; regionMaker = new FastRegions_Hi15Image(posterizedImage); regionMaker.withDiagonals(withDiagonals); regions = regionMaker.get(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (stealingFrom != null)\r\n if (stealingFrom.withDiagonals == withDiagon..."; } }); public Stage biggestRegionsStage = stage("Sort regions", new Runnable() { public void run() { try { regions = regionsBySize = biggestRegionsFirst(regions); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "regions = regionsBySize = biggestRegionsFirst(regions);"; } }); { stage("SSIs", new Runnable() { public void run() { try { initialSSIs = new ArrayList(); for (var region : regions) initialSSIs.addAll(new G22_RegionToSSIs_v2(region).withDiagonals(withDiagonals).get()); currentSSIs = initialSSIs; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "initialSSIs = new ArrayList();\r\n for (var region : regions)\r\n initial..."; } }); } public int initialSSILines() { return totalSSILines(initialSSIs); } { stage("Vector-Optimize", new Runnable() { public void run() { try { currentSSIs = vectorizedSSIs = vectorize ? new VectorOptimizedSSIList(currentSSIs) : new GeneralSSIList(currentSSIs); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "currentSSIs = vectorizedSSIs = vectorize\r\n ? new VectorOptimizedSSIList(..."; } }); } { stage("Sort SSIs", new Runnable() { public void run() { try { if (sortMode == SortMode.compressibility) sortedSSIs = new GeneralSSIList(sortedDesc(currentSSIs, (a, b) -> { int x = cmp(a.compressibility(), b.compressibility()); if (x != 0) return x; return cmp(a.numberOfPixels(), b.numberOfPixels()); })); else if (sortMode == SortMode.pixels) sortedSSIs = new GeneralSSIList(biggestSSIsFirst(currentSSIs)); else throw fail("Unknown sort mode"); currentSSIs = sortedSSIs; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (sortMode == SortMode.compressibility)\r\n sortedSSIs = new GeneralSSIL..."; } }); } { stage("Cut SSI List by detail level", new Runnable() { public void run() { try { maxLines = !detailLevel.hasTarget() ? Integer.MAX_VALUE : iround(detailDivisor() * detailLevel.target()); currentSSIs = cutSSIs = new GeneralSSIList(takeFirstNSSILines(maxLines, currentSSIs)); detailLevel.set(l(cutSSIs) / detailDivisor()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "maxLines = !detailLevel.hasTarget() ? Integer.MAX_VALUE\r\n : iround(detai..."; } }); } { stage("Cut Vector-Optimized SSIs by file size", new Runnable() { public void run() { try { maxInts = !kilobytes.hasTarget() ? Integer.MAX_VALUE : iround(kilobytes.target() * 512); cutter = new CutListToBudget(ssi -> (double) ssi.sizeInInts(), maxInts, (List) currentSSIs); if (allowPartialSSIs) cutter.allowPartial((ssi, budget) -> ssi.reduceToInts(iround(budget))); currentSSIs = cutVectorizedSSIs = new GeneralSSIList(cutter.get()); kilobytes.set(totalSizeInInts(cutVectorizedSSIs) / 512.0); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "maxInts = !kilobytes.hasTarget() ? Integer.MAX_VALUE\r\n : iround(kilobyte..."; } }); } public List> regions() { stepUntilStage(regionsStage); return regions; } public List> regionsBySize() { stepUntilStage(biggestRegionsStage); return regions; } public List regionsAsIBinaryImages() { return map(__59 -> regionToIBinaryImage(__59), regions()); } public BlurAndPosterizeSettings bnpSettings() { return new BlurAndPosterizeSettings().blur(blur).colors(colors()).colorDrift(new RGB(drift())).antiDrift(new RGB(antiDrift)); } public void importSettings(BlurAndPosterizeSettings bnp) { blur(bnp.blur); colors(bnp.colors); drift(bnp.colorDrift.brightness()); antiDrift(bnp.antiDrift.brightness()); } public FastRegions_Hi15Image regionMaker() { stepUntilStage(regionsStage); return regionMaker; } } static public class RunLengthCounter { final public A getValue() { return value(); } public A value() { return value; } public A value; final public long getRunLength() { return runLength(); } public long runLength() { return runLength; } public long runLength; public long add(A value) { if (eq(this.value, value)) ++runLength; else runLength = 1; this.value = value; return runLength; } } static public class VScrollingWrapLayout extends AbstractLayoutManager { final public VScrollingWrapLayout setCenteredHorizontally(boolean centeredHorizontally) { return centeredHorizontally(centeredHorizontally); } public VScrollingWrapLayout centeredHorizontally(boolean centeredHorizontally) { this.centeredHorizontally = centeredHorizontally; return this; } final public boolean getCenteredHorizontally() { return centeredHorizontally(); } public boolean centeredHorizontally() { return centeredHorizontally; } public boolean centeredHorizontally = false; public void layoutContainer(Container parent) { List components = getComponents(parent); class X { public int maxWidth = parent.getWidth(); public int x, y; public int lineHeight; public int componentsInLine, i; public void finishLine() { if (centeredHorizontally) { int x1 = (maxWidth - x) / 2; for (int j = i - componentsInLine; j < i; j++) { var c = components.get(j); Rectangle r = c.getBounds(); c.setBounds(r.x + x1, r.y, r.width, r.height); } } } public void run() { for (i = 0; i < l(components); i++) { var c = components.get(i); Dimension size = c.getPreferredSize(); boolean needNewLine = componentsInLine != 0 && x + size.width > maxWidth; if (needNewLine) { finishLine(); y += lineHeight; x = componentsInLine = lineHeight = 0; } c.setBounds(x, y, size.width, size.height); x += size.width; lineHeight = max(size.height, lineHeight); ++componentsInLine; } finishLine(); preferredSize(maxWidth, y + lineHeight); } } new X().run(); } } static public class MockJuiceable implements Juiceable { final public MockJuiceable setJuiceValue(double juiceValue) { return juiceValue(juiceValue); } public MockJuiceable juiceValue(double juiceValue) { this.juiceValue = juiceValue; return this; } final public double getJuiceValue() { return juiceValue(); } public double juiceValue() { return juiceValue; } public double juiceValue; } static public class G22MeshMapper_v2 implements IFieldsToList { public G22Mesh mesh1; public G22Mesh mesh2; public G22MeshMapper_v2() { } public G22MeshMapper_v2(G22Mesh mesh1, G22Mesh mesh2) { this.mesh2 = mesh2; this.mesh1 = mesh1; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + mesh1 + ", " + mesh2 + ")"; } public Object[] _fieldsToList() { return new Object[] { mesh1, mesh2 }; } final public G22MeshMapper_v2 setChooseAnchor1AtRandom(boolean chooseAnchor1AtRandom) { return chooseAnchor1AtRandom(chooseAnchor1AtRandom); } public G22MeshMapper_v2 chooseAnchor1AtRandom(boolean chooseAnchor1AtRandom) { this.chooseAnchor1AtRandom = chooseAnchor1AtRandom; return this; } final public boolean getChooseAnchor1AtRandom() { return chooseAnchor1AtRandom(); } public boolean chooseAnchor1AtRandom() { return chooseAnchor1AtRandom; } public boolean chooseAnchor1AtRandom = false; public G22MeshMapping mm; final public G22MeshMapper_v2 setDebugOutput(List debugOutput) { return debugOutput(debugOutput); } public G22MeshMapper_v2 debugOutput(List debugOutput) { this.debugOutput = debugOutput; return this; } final public List getDebugOutput() { return debugOutput(); } public List debugOutput() { return debugOutput; } public List debugOutput; final public G22MeshMapper_v2 setContrast(float contrast) { return contrast(contrast); } public G22MeshMapper_v2 contrast(float contrast) { this.contrast = contrast; return this; } final public float getContrast() { return contrast(); } public float contrast() { return contrast; } public float contrast = 0.25f; final public G22MeshMapper_v2 setBrightness(int brightness) { return brightness(brightness); } public G22MeshMapper_v2 brightness(int brightness) { this.brightness = brightness; return this; } final public int getBrightness() { return brightness(); } public int brightness() { return brightness; } public int brightness = 128; public MultiMap anchorsByArity2; final public G22MeshMapper_v2 setRejectedBecause(Object rejectedBecause) { return rejectedBecause(rejectedBecause); } public G22MeshMapper_v2 rejectedBecause(Object rejectedBecause) { this.rejectedBecause = rejectedBecause; return this; } final public Object getRejectedBecause() { return rejectedBecause(); } public Object rejectedBecause() { return rejectedBecause; } public Object rejectedBecause; public boolean rejected() { return rejectedBecause != null; } public boolean prechecksDone = false; public String sig1, sig2; public G22Mesh.Anchor anchor1; public G22MeshMapping get() { return mm; } public Search newSearch() { return new Search(); } public class Search extends VStackComputableWithStep implements IMakeEmptyClone { public G22Mesh.Anchor anchor2; public Search makeEmptyClone() { return new Search(); } public void step(VStack stack) { if (step == 0) { prechecks(); if (rejected()) ((BStack) stack)._return(); step = 1; } else if (step == 1) { mm = new G22MeshMapping(mesh1, mesh2); anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity()); anchor1 = chooseAnchor1AtRandom ? random(mesh1.anchors()) : first(mesh1.anchors()); List anchor2options = anchorsByArity2.get(anchor1.arity()); step = 2; ((BStack) stack).options(this, map(anchor2options, anchor2 -> instance -> instance.anchor2 = anchor2)); } else if (step == 2) { print("G22MeshMapper_v2 step1: Connecting " + anchor1 + " to " + anchor2); add(debugOutput, "Mapping anchor"); ((BStack) stack).temp(mm.tempMapAnchor(anchor1, anchor2)); ((BStack) stack).temp(() -> add(debugOutput, print("Unmapping anchor"))); addMappingToDebugOutput(); step = 3; } else if (step == 3) { ((BStack) stack).call(new Step2()); step = 4; } else { if (isTrue(((BStack) stack).subResult())) step = 3; else ((BStack) stack)._return(); } } } public class Step2 extends VStackComputableWithStep implements IMakeEmptyClone { public boolean change = false; public Iterator curve1iterator; public G22Mesh.Curve curve1; public G22MeshMapping.MappedCurve c2; public G22Mesh.Anchor a2; public Step2 makeEmptyClone() { return new Step2(); } public void step(VStack stack) { if (step == 0) { print(n2(mesh1.curves(), "curve") + " in mesh1, mapped: " + l(mm.curveMap)); print("mesh1.curves: " + map(__60 -> identityHashCode(__60), mesh1.curves())); print("mapped: " + map(__61 -> identityHashCode(__61), keys(mm.curveMap))); print("mapped (backward map): " + map(__62 -> identityHashCode(__62), keys(mm.curveBackwardMap))); curve1iterator = iterator(mesh1.curves()); step++; } else if (step == 1) { if (!curve1iterator.hasNext()) { ((BStack) stack)._return(change); return; } curve1 = curve1iterator.next(); print("Looking to match " + curve1); G22MeshMapping.MappedCurve curve1mapping = mm.get(curve1); if (curve1mapping != null) { print("Curve is mapped: " + curve1); assertTrue("mesh2 contains curve1mapping", mesh2.containsCurve(curve1mapping.get())); return; } G22Mesh.Anchor start2 = mm.get(curve1.start); G22Mesh.Anchor end2 = mm.get(curve1.end); if (start2 == null && end2 == null) { return; } List possibleCurves = new ArrayList(); if (start2 != null && end2 != null) { for (var curve2 : start2.curves()) if (curve2.connectedTo(end2)) { boolean flipped = curve2.end == start2; possibleCurves.add(new G22MeshMapping.MappedCurve(curve2, flipped)); } } else { boolean startAtEnd = end2 != null; G22Mesh.Anchor a1 = curve1.anchor(startAtEnd); G22Mesh.Anchor a1other = curve1.anchor(!startAtEnd); a2 = mm.get(curve1.anchor(startAtEnd)); print("a1", a1); print("a2", a2); print("a1other", a1other); for (var c2 : a2.curves()) { if (mm.isMapped(c2)) { continue; } G22Mesh.Anchor a3 = c2.anchorOpposite(a2); print("a3", a3); int arity1 = a3.arity(), arity2 = a1other.arity(); if (arity1 != arity2) { print("Arity mismatch (" + arity1 + "/" + arity2 + ") for curve " + c2); continue; } boolean flipped = c2.start() != a2; possibleCurves.add(new G22MeshMapping.MappedCurve(c2, flipped)); print("Possible curve!"); } } addPossibleCurvesToDebugOutput(curve1, possibleCurves); print(l(possibleCurves) + " possible curve(s) to map " + curve1 + " to: "); pnl(possibleCurves); if (empty(possibleCurves)) { ((BStack) stack).temp(tempRejectedBecause("Could not map curve " + curve1)); { ((BStack) stack)._return(false); return; } } step = 2; ((BStack) stack).options(this, map(possibleCurves, c2 -> instance -> instance.c2 = c2)); return; } else { print("Mapping curve " + curve1 + " to " + c2); add(debugOutput, print("Mapping curve")); ((BStack) stack).temp(mm.tempMapCurve(curve1, c2.get(), c2.flipped)); ((BStack) stack).temp(() -> add(debugOutput, "Unmapping curve")); addMappingToDebugOutput(); change = true; step = 1; } } } public void prechecks() { prechecksDone = true; sig1 = mesh1.signature(); sig2 = mesh1.signature(); if (!eq(sig1, sig2)) { rejectedBecause(new G22SignatureMismatch(mesh1, mesh2)); return; } } public AutoCloseable tempRejectedBecause(Object reason) { rejectedBecause(reason); return () -> rejectedBecause(null); } public void addMappingToDebugOutput() { if (debugOutput == null) return; Object error = mm.validityError(); addIfNotNull(debugOutput, error); var img1 = mesh1.getBufferedImage(); var img2 = mesh2.getBufferedImage(); for (var img : ll(img1, img2)) bufferedImageContrastAndBrightness(img, contrast, brightness); mm.drawMappedPartOfMesh1(createGraphics(img1)); mm.drawMappedPartOfMesh2(createGraphics(img2)); addPair(debugOutput, img1, img2); } public void addPossibleCurvesToDebugOutput(G22Mesh.Curve c1, Collection possibleCurves) { if (debugOutput == null) return; var img1 = mesh1.getBufferedImage(); var img2 = mesh2.getBufferedImage(); for (var img : ll(img1, img2)) bufferedImageContrastAndBrightness(img, contrast, brightness); new G22VisualizeMeshes().drawCurve(createGraphics(img1), c1); for (var curve : possibleCurves) { G22VisualizeMeshes vm = new G22VisualizeMeshes(); if (curve.flipped) vm.curveColor(Color.green); vm.drawCurve(createGraphics(img2), curve.get()); } add(debugOutput, n2(possibleCurves, "possible curve")); addPair(debugOutput, img1, img2); } } static public class G22JavaObjectVisualizer implements Swingable, IFieldsToList { public G22Utils g22utils; public G22JavaObjectVisualizer() { } public G22JavaObjectVisualizer(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } final public G22JavaObjectVisualizer setWithTypeAndTime(boolean withTypeAndTime) { return withTypeAndTime(withTypeAndTime); } public G22JavaObjectVisualizer withTypeAndTime(boolean withTypeAndTime) { this.withTypeAndTime = withTypeAndTime; return this; } final public boolean getWithTypeAndTime() { return withTypeAndTime(); } public boolean withTypeAndTime() { return withTypeAndTime; } public boolean withTypeAndTime = true; final public G22JavaObjectVisualizer setSingleLineLayout(boolean singleLineLayout) { return singleLineLayout(singleLineLayout); } public G22JavaObjectVisualizer singleLineLayout(boolean singleLineLayout) { this.singleLineLayout = singleLineLayout; return this; } final public boolean getSingleLineLayout() { return singleLineLayout(); } public boolean singleLineLayout() { return singleLineLayout; } public boolean singleLineLayout = false; final public G22JavaObjectVisualizer setMaxElements(int maxElements) { return maxElements(maxElements); } public G22JavaObjectVisualizer maxElements(int maxElements) { this.maxElements = maxElements; return this; } final public int getMaxElements() { return maxElements(); } public int maxElements() { return maxElements; } public int maxElements = 1000; final public G22JavaObjectVisualizer setHorizontal(boolean horizontal) { return horizontal(horizontal); } public G22JavaObjectVisualizer horizontal(boolean horizontal) { this.horizontal = horizontal; return this; } final public boolean getHorizontal() { return horizontal(); } public boolean horizontal() { return horizontal; } public boolean horizontal = false; final public G22JavaObjectVisualizer setFloatingPointDigits(int floatingPointDigits) { return floatingPointDigits(floatingPointDigits); } public G22JavaObjectVisualizer floatingPointDigits(int floatingPointDigits) { this.floatingPointDigits = floatingPointDigits; return this; } final public int getFloatingPointDigits() { return floatingPointDigits(); } public int floatingPointDigits() { return floatingPointDigits; } public int floatingPointDigits = 4; final public G22JavaObjectVisualizer setAllowDescendingIntoListElements(boolean allowDescendingIntoListElements) { return allowDescendingIntoListElements(allowDescendingIntoListElements); } public G22JavaObjectVisualizer allowDescendingIntoListElements(boolean allowDescendingIntoListElements) { this.allowDescendingIntoListElements = allowDescendingIntoListElements; return this; } final public boolean getAllowDescendingIntoListElements() { return allowDescendingIntoListElements(); } public boolean allowDescendingIntoListElements() { return allowDescendingIntoListElements; } public boolean allowDescendingIntoListElements = false; final public G22JavaObjectVisualizer setScriptTimeout(double scriptTimeout) { return scriptTimeout(scriptTimeout); } public G22JavaObjectVisualizer scriptTimeout(double scriptTimeout) { this.scriptTimeout = scriptTimeout; return this; } final public double getScriptTimeout() { return scriptTimeout(); } public double scriptTimeout() { return scriptTimeout; } public double scriptTimeout = 10.0; final public G22JavaObjectVisualizer setStringDisplayLength(int stringDisplayLength) { return stringDisplayLength(stringDisplayLength); } public G22JavaObjectVisualizer stringDisplayLength(int stringDisplayLength) { this.stringDisplayLength = stringDisplayLength; return this; } final public int getStringDisplayLength() { return stringDisplayLength(); } public int stringDisplayLength() { return stringDisplayLength; } public int stringDisplayLength = 80; public Set seen = identityHashSet(); final public G22JavaObjectVisualizer setObject(Object object) { return object(object); } public G22JavaObjectVisualizer object(Object object) { this.object = object; return this; } final public Object getObject() { return object(); } public Object object() { return object; } transient public Object object; final public G22JavaObjectVisualizer setNanos(long nanos) { return nanos(nanos); } public G22JavaObjectVisualizer nanos(long nanos) { this.nanos = nanos; return this; } final public long getNanos() { return nanos(); } public long nanos() { return nanos; } transient public long nanos = -1; transient public SingleComponentPanel scp = scp(); public G22JavaObjectVisualizer(G22Utils g22utils, Object object) { this.object = object; this.g22utils = g22utils; } public String objectInfos() { return objectInfos(this.object); } public String objectInfos(Object object) { List infos = new ArrayList(); infos.add(str(shortClassName2(object))); for (var __0 : _entrySet(mainVisualizer().properties)) { var key = __0.getKey(); var val = __0.getValue(); String s = n2OrStrOrNull(val); if (nempty(s)) infos.add(key + " " + s); } if (nanos >= 0) { String timeDesc = nanos < 0 ? "" : formatElapsedTimeWithAppropriateUnit(nanosToSeconds(nanos)); infos.add(timeDesc); } return joinNemptiesWithComma(infos); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { scp.set(visualizeObjectWithExtras(object)); return scp; } public JComponent visualizeObject(Object object) { return mainVisualizer().visualize(object); } public JComponent visualizeObjectWithExtras(Object object) { return visualizeObjectWithExtras(object, null); } public JComponent visualizeObjectWithExtras(Object object, Component back) { JComponent c = visualizeObject(object); JButton btnBack = back == null ? null : jimageButtonScaledToWidth(16, "#1103102", () -> scp.set(back)); JComponent lblType = null; if (withTypeAndTime) { String type = objectInfos(object); lblType = withLabel("Type:", jlabel(type)); } if (btnBack != null || lblType != null) { JComponent top = or(lblType, jpanel()); if (btnBack != null) top = westAndCenterWithMargin(btnBack, top); return northAndCenterWithMargins(top, c); } return c; } public ObjectVisualizer mainVisualizer_cache; public ObjectVisualizer mainVisualizer() { if (mainVisualizer_cache == null) mainVisualizer_cache = mainVisualizer_load(); return mainVisualizer_cache; } public ObjectVisualizer mainVisualizer_load() { return new ObjectVisualizer().recurse(true).bigFont(true).horizontal(horizontal); } public class ObjectVisualizer { final public ObjectVisualizer setRecurse(boolean recurse) { return recurse(recurse); } public ObjectVisualizer recurse(boolean recurse) { this.recurse = recurse; return this; } final public boolean getRecurse() { return recurse(); } public boolean recurse() { return recurse; } public boolean recurse = false; final public ObjectVisualizer setBigFont(boolean bigFont) { return bigFont(bigFont); } public ObjectVisualizer bigFont(boolean bigFont) { this.bigFont = bigFont; return this; } final public boolean getBigFont() { return bigFont(); } public boolean bigFont() { return bigFont; } public boolean bigFont = false; final public ObjectVisualizer setHorizontal(boolean horizontal) { return horizontal(horizontal); } public ObjectVisualizer horizontal(boolean horizontal) { this.horizontal = horizontal; return this; } final public boolean getHorizontal() { return horizontal(); } public boolean horizontal() { return horizontal; } public boolean horizontal = false; final public ObjectVisualizer setScrollable(boolean scrollable) { return scrollable(scrollable); } public ObjectVisualizer scrollable(boolean scrollable) { this.scrollable = scrollable; return this; } final public boolean getScrollable() { return scrollable(); } public boolean scrollable() { return scrollable; } public boolean scrollable = true; public LinkedHashMap properties = new LinkedHashMap(); public ObjectVisualizer subVisualizer() { return new ObjectVisualizer().horizontal(!horizontal); } public ObjectVisualizer subVisualizerOnSameLevel() { return new ObjectVisualizer().horizontal(horizontal).recurse(recurse).bigFont(bigFont).scrollable(false); } public JComponent makeBig(JComponent c) { if (bigFont) return fontSizePlus(10, c); return c; } public JComponent subVisualizeOnSameLevel(Object o) { return subVisualizerOnSameLevel().visualize(o); } public JComponent visualize(Object object) { try { return visualize2(object); } catch (Throwable e) { return g22utils.jErrorView(new RuntimeException("Visualization error", e)); } } public JComponent visualize2(Object object) { if (object instanceof Throwable) return g22utils.jErrorView((Throwable) object); if (object == null || eq(object, "")) return jpanel(); object = arrayToList(object); if (object instanceof Swingable) object = ((Swingable) object).visualize(); if (object instanceof JComponent && getParent((JComponent) object) == null) return ((JComponent) object); if (object instanceof Integer) object = toLong((Integer) object); if (object instanceof Long) return bigText(n2((Long) object)); if (object instanceof Double) return toolTip(str((Double) object), bigText(formatDouble(((Double) object), floatingPointDigits))); if (object instanceof Number) return bigText((Number) object); if (object instanceof Pair) { if (horizontal) return jcenteredline(jlabel("<"), visualize(((Pair) object).a), jlabel(","), visualize(((Pair) object).b), jlabel(">")); else return stackElements(listCombine(subVisualizeOnSameLevel(((Pair) object).a), subVisualizeOnSameLevel(((Pair) object).b))); } if (object instanceof MakesBufferedImage) object = toBufferedImage((MakesBufferedImage) object); if (object instanceof BufferedImage) { var is = g22utils.stdImageSurface((BufferedImage) object); if (!recurse) is.setAutoZoomToDisplay(false); return jscroll_centered_borderless(is); } if (object instanceof GazelleV_LeftArrowScript.FunctionDef) { var f = (GazelleV_LeftArrowScript.FunctionDef) object; if (empty(f.args)) return centerAndEastWithMargin(visualizeAsText(f), jverticalCenter(jThreadedButton("Call", () -> inspectElement(callFunctionDef(f))))); } if (recurse) { if (object instanceof MultiMap) { propertyLength(l((MultiMap) object)); propertyKeyCount(((MultiMap) object).keyCount()); object = multiMapToMapPairs((MultiMap) object); } if (object instanceof MultiSetMap) { propertyLength(l((MultiSetMap) object)); propertyKeyCount(((MultiSetMap) object).keyCount()); object = multiSetMapToMapPairs((MultiSetMap) object); } if (object instanceof Map) { propertyLength(l((Map) object)); object = mapToPairs((Map) object); } if (object instanceof Collection) { propertyLength(l((Collection) object)); var sub = subVisualizer(); var elements = map(cloneTakeFirst(maxElements, ((Collection) object)), element -> { var elementVis = sub.visualize(element); if (allowDescendingIntoListElements) elementVis = centerAndEastWithMargin(elementVis, new JPopDownButton().content("Inspect element", runnableThread(new Runnable() { public void run() { try { inspectElement(element); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "inspectElement(element)"; } }))); return elementVis; }); return stackElements(elements); } } return visualizeAsText(object); } public JComponent visualizeAsText(Object object) { if (object instanceof String) { propertyLength(l((String) object)); } String string = str(object); if (containsNewLine(string)) return jscroll_borderless(wordWrapTypeWriterTextArea(string)); if (recurse && l(string) > stringDisplayLength) return jText(string); var lbl = jcenterNarrowLabel(shorten(string)); if (l(string) <= 10) return makeBig(lbl); return lbl; } public void propertyLength(int l) { properties.put("size", l); } public void propertyKeyCount(int l) { properties.put("keys", l); } public JComponent bigText(Object o) { return makeBig(jcenteredLabel(str(o))); } public Object arrayToList(Object object) { if (isArray(object)) object = wrapArrayAsImmutableList(object); return object; } public JComponent stackElements(List elements) { var c = horizontal ? hstackWithSpacing(elements) : vstackWithSpacing(elements); return scrollable ? jscroll_centered_borderless(c) : c; } } public G22JavaObjectVisualizer withType(boolean b) { return withTypeAndTime(b); } public void inspectElement(Object element) { var back = scp.getComponent(); scp.set(visualizeObjectWithExtras(element, back)); } public Object callFunctionDef(GazelleV_LeftArrowScript.FunctionDef f) { return evalWithTimeoutOrFail(scriptTimeout, () -> f.call(new FlexibleVarContext())); } } static public class JGazelleVScriptRunner implements IFieldsToList { public SimpleLiveValue lvScript; public JGazelleVScriptRunner() { } public JGazelleVScriptRunner(SimpleLiveValue lvScript) { this.lvScript = lvScript; } public Object[] _fieldsToList() { return new Object[] { lvScript }; } public GazelleVScript parsedScript; public GazelleVScript.Run run; public Object result; public SingleComponentPanel scpScriptResult = singleComponentPanel(); public WeakVar isScriptResult = new WeakVar(); public WeakVar taResult = new WeakVar(); public JLabel lblScore = jlabel(); public JComponent scriptAndResultPanel() { return northAndCenter(scriptInputField(), scpScriptResult = singleComponentPanel()); } public JComponent scriptInputField() { return withMargin(centerAndEastWithMargin(withLabel("Gazelle \"Linear\" Script:", jLiveTextField(lvScript)), jPopDownButton_noText("Show Scripting Help", runnableThread(new Runnable() { public void run() { try { showText("Gazelle 'Linear Script' Help", GazelleVScript.helpText); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showText(\"Gazelle 'Linear Script' Help\", GazelleVScript.helpText)"; } })))); } public void showScriptOutput() { if (result instanceof BWImage) { showImageResult((BWImage) result); } else if (result instanceof BufferedImage) { showImageResult((BufferedImage) result); } else if (result instanceof Animation) { showImageResult(((Animation) result).toImage()); } else { showTextResult(str(result)); } } public void showTextResult(String text) { text = shorten(1000, text); if (isShowing(taResult.get())) { setTextKeepCaret(taResult.get(), text); } else { var ta = jTextArea_noUndo(text); scpScriptResult.set(jscroll(ta)); taResult.set(ta); } } public void showImageResult(MakesBufferedImage img) { showImageResult(toBufferedImage(img)); } public void showImageResult(BufferedImage img) { if (img == null) return; if (isShowing(isScriptResult.get())) { isScriptResult.get().setImage(img); } else { var is = stdImageSurface(); is.setImage(img); scpScriptResult.set(jscroll_centered(is)); isScriptResult.set(is); } if (isShowing(lblScore)) { String score = ""; if (sameSize(run.inputImage, img)) { double distance = bwDistance(toBWImage(run.inputImage), toBWImage(img)); score = "Score: " + formatDoubleX(100 * (1 - distance), 1); } setText(lblScore, score); } } public ImageSurface stdImageSurface() { return pixelatedImageSurface().setAutoZoomToDisplay(true).repaintInThread(false); } public void parse() { parsedScript = new GazelleVScript(lvScript.get()); } public void runOn(IBWIntegralImage ii) { run = parsedScript.new Run(); run.setInputImage(ii); run.setIntegralImage(ii); run.run(); result = run.result(); } public void parseAndRunOn(IBWIntegralImage ii) { try { parse(); runOn(ii); } catch (Throwable e) { result = exceptionToStringShort(e); printStackTrace(e); } showScriptOutput(); } } static public class PicturesByMD5 implements IFieldsToList { public File dir; public PicturesByMD5() { } public PicturesByMD5(File dir) { this.dir = dir; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + dir + ")"; } public Object[] _fieldsToList() { return new Object[] { dir }; } final public PicturesByMD5 setExtension(String extension) { return extension(extension); } public PicturesByMD5 extension(String extension) { this.extension = extension; return this; } final public String getExtension() { return extension(); } public String extension() { return extension; } public String extension = ".jpeg"; transient public Lock lock = lock(); transient public VarWithNotify imageCount = new VarWithNotify(); public File imageFile(String md5) { return newFile(dir, assertMD5(md5) + extension); } public boolean has(String md5) { return isFile(imageFile(md5)); } public BufferedImage get(String md5) { return decodeImage(imageFile(md5)); } transient public IF1 decodeImage; public BufferedImage decodeImage(File f) { return decodeImage != null ? decodeImage.get(f) : decodeImage_base(f); } final public BufferedImage decodeImage_fallback(IF1 _f, File f) { return _f != null ? _f.get(f) : decodeImage_base(f); } public BufferedImage decodeImage_base(File f) { return loadImage2(f); } public boolean put(String md5, byte[] imageData) { if (has(md5)) return false; Lock __0 = lock; lock(__0); try { if (has(md5)) return false; saveBinaryFile(imageFile(md5), imageData); if (imageCount.has()) imageCount.set(imageCount() + 1); return true; } finally { unlock(__0); } } public int freshImageCount() { Lock __1 = lock; lock(__1); try { return setAndReturn(imageCount, l(freshImageFiles())); } finally { unlock(__1); } } public List freshImageFiles() { return listFilesWithExtension(dir, extension); } public int imageCount() { Lock __2 = lock; lock(__2); try { if (!imageCount.has()) freshImageCount(); return imageCount.get(); } finally { unlock(__2); } } public IVarWithNotify varImageCount() { return imageCount; } } static public class BitGetCredentials { final public BitGetCredentials setName(String name) { return name(name); } public BitGetCredentials name(String name) { this.name = name; return this; } final public String getName() { return name(); } public String name() { return name; } public String name; final public BitGetCredentials setApiKey(String apiKey) { return apiKey(apiKey); } public BitGetCredentials apiKey(String apiKey) { this.apiKey = apiKey; return this; } final public String getApiKey() { return apiKey(); } public String apiKey() { return apiKey; } public String apiKey; final public BitGetCredentials setPassphrase(String passphrase) { return passphrase(passphrase); } public BitGetCredentials passphrase(String passphrase) { this.passphrase = passphrase; return this; } final public String getPassphrase() { return passphrase(); } public String passphrase() { return passphrase; } public String passphrase; final public BitGetCredentials setSecretKey(String secretKey) { return secretKey(secretKey); } public BitGetCredentials secretKey(String secretKey) { this.secretKey = secretKey; return this; } final public String getSecretKey() { return secretKey(); } public String secretKey() { return secretKey; } public String secretKey; public String toString() { return joinNempties(" with ", spaceCombine(shortClassName(this), quoteOrEmpty(name)), commaCombine(nempty(apiKey) ? "apiKey " + roundBracket(nCharacters(apiKey)) : null, nempty(passphrase) ? "passphrase " + roundBracket(nCharacters(passphrase)) : null, nempty(secretKey) ? "secretKey " + roundBracket(nCharacters(secretKey)) : null)); } static public BitGetCredentials fromFile(File f) { var credMap = mapValues(__63 -> toSecretValue(__63), parseColonPropertyCIMap(loadTextFile(f))); var cred = new BitGetCredentials(); cred.apiKey(getSecretValue(credMap.get("API-Key"))); cred.passphrase(getSecretValue(credMap.get("Passphrase"))); cred.secretKey(getSecretValue(credMap.get("SecretKey"))); cred.name(getSecretValue(credMap.get("Name"))); return cred; } public void save(File f) { saveTextFile(f, formatColonProperties(litorderedmap("API-Key", apiKey, "Passphrase", passphrase, "SecretKey", secretKey, "Name", name))); } } static public class JButtonWithInset extends JButton { public JButtonWithInset() { } public JButtonWithInset(String text) { super(text); } public JButtonWithInset(Action action) { super(action); } public int inset = 10; public Dimension getMinimumSize() { Dimension d = super.getMinimumSize(); return new Dimension(d.width + inset, d.height + inset); } public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); return new Dimension(d.width + inset, d.height + inset); } } static public class G22Label extends ConceptWithGlobalID { public String name; public String toString() { return name; } final public boolean textIs(String text) { return nameIs(text); } public boolean nameIs(String text) { return eqic(name, text); } } static public class G22Tiler_Hi15Image extends G22AbstractTiler { public int getColor(int pos) { return image.getHi15Pixel_noRangeCheck(pos); } public G22Tiler_Hi15Image(Hi15Image img) { super(img); } public G22Tiler_Hi15Image(BufferedImage img) { this(new Hi15Image(img)); } } static public class DifferentialRegionsMaker_RGBImage extends DifferentialRegionsMaker { public int getRGB(int pos) { return image.getIntPixel_noRangeCheck(pos); } public DifferentialRegionsMaker_RGBImage(BufferedImage img) { super(new RGBImage(img)); } public DifferentialRegionsMaker_RGBImage(RGBImage img) { super(img); } } static public class G22ScriptsPanel extends G22CRUDAndDetailPanel { final public G22ScriptsPanel setScriptIDE(G22LAScriptIDE scriptIDE) { return scriptIDE(scriptIDE); } public G22ScriptsPanel scriptIDE(G22LAScriptIDE scriptIDE) { this.scriptIDE = scriptIDE; return this; } final public G22LAScriptIDE getScriptIDE() { return scriptIDE(); } public G22LAScriptIDE scriptIDE() { return scriptIDE; } transient volatile public G22LAScriptIDE scriptIDE; public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22LeftArrowScript.class); crud.noSubclasses(true); crud.entityName = () -> "Script"; g22utils.setupScriptCRUD(crud, true); var ts = crud.tableSearcher(); var basicRowTester = ts.rowTester; ts.rowTester = if2ToF2((pat, map) -> { if (basicRowTester.get(pat, map)) return true; long id = toLong(map.get(crud.hID)); G22LeftArrowScript script = g22utils.getScript(id); if (anyContainsIgnoreCase(script.allTexts(), pat)) return true; return false; }); crud.addButton(new JPopDownButton().content("Show all scripts as one long text", runnableThread(new Runnable() { public void run() { try { showHugeText(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showHugeText();"; } }))); return crud; } public JComponent makeDetailView(G22LeftArrowScript script) { scriptIDE(new G22LAScriptIDE(g22utils)); scriptIDE.setScript(script); return scriptIDE.visualize(); } public SimpleCRUD_v2 scriptCRUD() { return crud(); } public G22ScriptsPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } public void showHugeText() { String text = new G22ScriptUtil(g22utils).makeHugeText(g22utils.list(G22LeftArrowScript.class)); showFrame("Scripts in project", g22utils.newSyntaxTextArea(text)); } public void edit(G22LeftArrowScript script, LineAndColumn lineAndCol) { edit(script); print("scriptIDE", scriptIDE); print("Waiting for script IDE to appear for " + script); var ide = pollWaitUntilNotNull(100, 5.0, () -> { if (scriptIDE == null) return null; if (scriptIDE.script() != script) return null; return scriptIDE; }); print("Going to position " + lineAndCol + " in " + ide); { if (ide != null) ide.goToPositionInAllModes(lineAndCol); } } } static public class G22_RegionToSSIs implements IFieldsToList { public IImageRegion region; public G22_RegionToSSIs() { } public G22_RegionToSSIs(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } public Color color; public List ssis; public List growingSSIs = new ArrayList(); public class GrowingSSI { final public GrowingSSI setY1(int y1) { return y1(y1); } public GrowingSSI y1(int y1) { this.y1 = y1; return this; } final public int getY1() { return y1(); } public int y1() { return y1; } public int y1; public ShortBuffer data = new ShortBuffer(); public int y2() { return y1 + l(data) / 2; } public SSI finish() { return new SSI(y1, y2()).data(data.toArray()).color(color); } } public List get() { if (region == null) return null; color = region.color(); ssis = new ArrayList(); Rect r = region.bounds(); int x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2 - y1, w = r.w; for (int y = y1; y < y2; y++) { var _y_2 = y; List streaks = genericStreaks(w, x -> region.contains(x1 + x, _y_2)); while (longerThan(growingSSIs, streaks)) ssis.add(popLast(growingSSIs).finish()); for (int i = l(growingSSIs); i < l(streaks); i++) growingSSIs.add(new GrowingSSI().y1(_y_2)); for (var __0 : zipTwoLists(growingSSIs, streaks)) { var ssi = pairA(__0); var range = pairB(__0); ssi.data.add(toShort_enforce(x1 + range.start)); ssi.data.add(toShort_enforce(x1 + range.end)); } } for (var ssi : cloneAndClear(growingSSIs)) ssis.add(ssi.finish()); return ssis; } } static public class G22RegionThinner implements Steppable, IFieldsToList { public IImageRegion originalRegion; public G22RegionThinner() { } public G22RegionThinner(IImageRegion originalRegion) { this.originalRegion = originalRegion; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + originalRegion + ")"; } public Object[] _fieldsToList() { return new Object[] { originalRegion }; } public Rect bounds; public boolean[] pixels; final public IImageRegion getRegion() { return region(); } public IImageRegion region() { return region; } public IImageRegion region = new IImageRegion() { public Rect bounds() { return bounds; } public boolean contains(int x, int y) { return containsPt(bounds, x, y) && pixels[idx(x, y)]; } public IterableIterator pixelIterator() { return iff_null(new IF0() { public int idx = 0; public Pt get() { for (; idx < pixels.length; idx++) if (pixels[idx]) return idxToPt(idx++); return null; } }); } }; public int idx(int x, int y) { return (y - bounds.y) * bounds.w + x - bounds.x; } public Pt idxToPt(int idx) { return pt(bounds.x + (idx % bounds.w), bounds.y + idx / bounds.w); } public void init() { if (bounds != null) return; bounds = originalRegion.bounds(); pixels = new boolean[area(bounds)]; for (Pt p : originalRegion.pixelIterator()) pixels[idx(p.x, p.y)] = true; } public boolean change = false; public boolean step() { init(); change = false; List traces = g22_allBorderTraces_withDiagonals(region); for (var points : traces) { if (eq(first(points), last(points))) removeLast(points); for (int i = 0; i < l(points); i++) { ping(); if (deletableBorderPoint(points, i)) { Pt p = points.get(i); pixels[idx(p.x, p.y)] = false; change = true; } } points.clear(); } return change; } public boolean deletableBorderPoint(PtBuffer points, int i) { List range = cyclicSubList(points, i - 1, i + 2); Pt lastPoint = cyclicGet(points, i - 1); Pt p = points.get(i); Pt diff = ptDiff(p, lastPoint); Pt l = ptPlus(p, rotatePtLeft(diff)); Pt r = ptPlus(p, rotatePtRight(diff)); boolean deletable = !range.contains(l) && region.contains(l) || !range.contains(r) && region.contains(r); return deletable; } public boolean deletableBorderPoint_v1(PtBuffer points, int i) { List range = cyclicSubList(points, i - 1, i + 2); Pt p = points.get(i); for (int dir = 1; dir <= 8; dir++) { Pt p2 = ptPlus(p, onePathDirection(dir)); if (region.contains(p2.x, p2.y) && !range.contains(p2)) { return true; } } return false; } public IImageRegion get() { return region; } } static public class BestWorstAndAverage { public IBest best = new Best(); public IBest worst = new Lowest(); public Average average = new Average(); public BestWorstAndAverage lowerIsBetter() { best = new Lowest(); worst = new Best(); return this; } public boolean put(A a, double score) { average.add(score); return best.put(a, score) | worst.put(a, score); } public String toString() { return renderVars("avg", average, "best", best, "worst", worst); } } static public class TickerSequence implements IntSize { public TickerSequence() { } final public TickerSequence setMarket(String market) { return market(market); } public TickerSequence market(String market) { this.market = market; return this; } final public String getMarket() { return market(); } public String market() { return market; } public String market; final public TickerSequence setPriceCells(PriceCells priceCells) { return priceCells(priceCells); } public TickerSequence priceCells(PriceCells priceCells) { this.priceCells = priceCells; return this; } final public PriceCells getPriceCells() { return priceCells(); } public PriceCells priceCells() { return priceCells; } public PriceCells priceCells; final public TickerSequence setLive(boolean live) { return live(live); } public TickerSequence live(boolean live) { this.live = live; return this; } final public boolean getLive() { return live(); } public boolean live() { return live; } public boolean live = false; final public TickerSequence setLoading(boolean loading) { return loading(loading); } public TickerSequence loading(boolean loading) { this.loading = loading; return this; } final public boolean getLoading() { return loading(); } public boolean loading() { return loading; } public boolean loading = false; public ILongBuffer timestamps = new SynchronizedLongBuffer(); public IDoubleBuffer prices = new SynchronizedFloatBufferPresentingAsDoubles(); final public TickerSequence setLastTickerEvent(long lastTickerEvent) { return lastTickerEvent(lastTickerEvent); } public TickerSequence lastTickerEvent(long lastTickerEvent) { this.lastTickerEvent = lastTickerEvent; return this; } final public long getLastTickerEvent() { return lastTickerEvent(); } public long lastTickerEvent() { return lastTickerEvent; } public long lastTickerEvent; final public TickerSequence setEpsilon(double epsilon) { return epsilon(epsilon); } public TickerSequence epsilon(double epsilon) { this.epsilon = epsilon; return this; } final public double getEpsilon() { return epsilon(); } public double epsilon() { return epsilon; } public double epsilon = 1e-6; transient public Set> onPricePointAdded; public TickerSequence onPricePointAdded(IVF1 f) { onPricePointAdded = createOrAddToSyncLinkedHashSet(onPricePointAdded, f); return this; } public TickerSequence removePricePointAddedListener(IVF1 f) { loadableUtils.utils.remove(onPricePointAdded, f); return this; } public void pricePointAdded(long timestamp) { if (onPricePointAdded != null) for (var listener : onPricePointAdded) pcallF_typed(listener, timestamp); } transient public Set onNewTickerEvent; public TickerSequence onNewTickerEvent(Runnable r) { onNewTickerEvent = createOrAddToSyncLinkedHashSet(onNewTickerEvent, r); return this; } public TickerSequence removeNewTickerEventListener(Runnable r) { loadableUtils.utils.remove(onNewTickerEvent, r); return this; } public void newTickerEvent() { if (onNewTickerEvent != null) for (var listener : onNewTickerEvent) pcallF_typed(listener); } public TickerSequence(String market) { this.market = market; } synchronized public void addIfPriceChanged(double price, long timestamp) { if (isEmpty() || differentByEpsilonRatio(prices.last(), price, epsilon)) add(price, timestamp); updateTickerEvent(timestamp); } public void updateTickerEvent(long timestamp) { if (timestamp > lastTickerEvent) { lastTickerEvent(timestamp); newTickerEvent(); } } final public void addPrice(double price, long timestamp) { add(price, timestamp); } synchronized public void add(double price, long timestamp) { timestamps.add(timestamp); prices.add(price); pricePointAdded(timestamp); updateTickerEvent(timestamp); } synchronized public void add(double[] prices, long[] timestamps) { assertEquals(l(prices), l(timestamps)); if (empty(prices)) return; this.prices.addAll(asList(prices)); this.timestamps.addAll(asList(timestamps)); lastTickerEvent = max(lastTickerEvent, endTime()); } synchronized public void add(TickerSequence ticker) { add(ticker.prices.toArray(), ticker.timestamps.toArray()); } synchronized public String toString() { return commaCombine(spaceCombine("Ticker", market, priceCells == null ? null : roundBracket(priceCells)), formatDays(duration()), n2(l(prices), "price point"), timeRange()); } public synchronized TickerSequence clone() { return subSequence(0, size()); } synchronized public TickerSequence subSequence(int start) { return subSequence(start, size()); } synchronized public TickerSequence subSequence(int start, int end) { TickerSequence s = new TickerSequence(); s.market(market); s.add(subDoubleArray(prices.toArray(), start, end), subArray(timestamps.toArray(), start, end)); return s; } synchronized public TickerSequence cutOffAfterSeconds(double seconds) { int idx = indexOfTimestamp(startTime() + secondsToMS(seconds)); return subSequence(0, idx); } public TickerSequence takeFirstDays(double days) { return cutOffAfterSeconds(daysToSeconds(days)); } public TickerSequence takeLastDays(double days) { int idx = indexOfTimestamp(endTime() - daysToMS(days)); return subSequence(idx); } synchronized public TickerSequence subSequenceByTimestamps(long from, long to) { int idx1 = indexOfTimestamp(from); int idx2 = indexOfTimestamp(to); return subSequence(idx1, idx2); } synchronized public TickerSequence subSequenceFromTimestamp(long from) { return subSequence(indexOfTimestamp(from)); } synchronized public int indexOfTimestamp(double ts) { return binarySearch_insertionPoint(timestamps.asVirtualList(), lround(ts)); } synchronized public long nextTimestamp(double ts) { return getTimestamp(indexOfTimestamp(ts) + 1); } synchronized public double priceAtTimestamp(double ts) { return getPrice(indexOfTimestamp(ts)); } public int size() { return l(prices); } public boolean isEmpty() { return size() == 0; } synchronized public TimestampRange timeRange() { return isEmpty() ? null : new TimestampRange(startTime(), endTime()); } public Duration duration() { return main.duration(timeRange()); } synchronized public long startTime() { return empty(timestamps) ? 0 : first(timestamps); } synchronized public long endTime() { return empty(timestamps) ? 0 : last(timestamps); } synchronized public double getPrice(int i) { return isEmpty() ? Double.NaN : prices.get(clampToLength(size(), i)); } synchronized public long getTimestamp(int i) { return isEmpty() ? 0 : timestamps.get(clampToLength(size(), i)); } synchronized public TickerSequence removePlateaus() { TickerSequence seq = new TickerSequence(); seq.market(market); int n = size(); for (int i = 0; i < n; i++) { var value = getPrice(i); seq.prices.add(value); seq.timestamps.add(getTimestamp(i)); while (i + 1 < n && getPrice(i + 1) == value) ++i; } return seq.trimToSize(); } synchronized public TickerSequence alignTimestamps(int interval) { TickerSequence seq = new TickerSequence(); seq.market(market); int n = size(); for (int i = 0; i < n; i++) { var value = getPrice(i); long time = roundDownTo(interval, getTimestamp(i)); if (time != seq.endTime()) seq.addIfPriceChanged(value, time); } return seq.trimToSize(); } public TickerSequence trimToSize() { prices.trimToSize(); timestamps.trimToSize(); return this; } public double minPrice() { return doubleMin(prices.toArray()); } public double maxPrice() { return doubleMax(prices.toArray()); } public DoubleRange priceRange() { return doubleRange(minPrice(), maxPrice()); } synchronized public double firstPrice() { return empty(prices) ? Double.NaN : prices.first(); } synchronized public double lastPrice() { return empty(prices) ? Double.NaN : prices.last(); } synchronized public TickerPoint lastPoint() { return new TickerPoint(this, endTime()); } static public Pattern reBestAsk = regexp("\"bestAsk\":([0-9\\.]+)"); static public Pattern reSystemTime = regexp("\"systemTime\":(\\d+)"); synchronized public void addJSONLine_fast(String line) { long time = toLong(regexpFirstGroup(reSystemTime, line)); if (time > lastTickerEvent) { double price = toDouble(regexpFirstGroup(reBestAsk, line)); addIfPriceChanged(price, time); } } transient public IVF1 addJSONLine; public void addJSONLine(String line) { if (addJSONLine != null) addJSONLine.get(line); else addJSONLine_base(line); } final public void addJSONLine_fallback(IVF1 _f, String line) { if (_f != null) _f.get(line); else addJSONLine_base(line); } public void addJSONLine_base(String line) { addJSONLine_fast(line); } synchronized public void addJSONLine_slow(String line) { Map data = parseJSONMap(line); double price = toDouble(data.get("bestAsk")); long time = toLong(data.get("systemTime")); if (time > lastTickerEvent) addIfPriceChanged(price, time); } final public UpDownSequence upDownSequence() { return toUpDownSequence(); } public UpDownSequence toUpDownSequence() { return toUpDownSequence(priceCells); } final public UpDownSequence upDownSequence(PriceCells cells) { return toUpDownSequence(cells); } public UpDownSequence toUpDownSequence(PriceCells cells) { if (cells == null) return null; var dig = digitize(new PriceDigitizer2(cells)); List cellNumbers = dig.roundedCellNumbers(); return UpDownSequence.fromInts(cellNumbers); } public TickerSequence digitizeToPercent(double cellSizeInPercent) { return digitizeToPercent(firstPrice(), cellSizeInPercent); } public TickerSequence digitizeToPercent(double basePrice, double cellSizeInPercent) { if (isEmpty()) return this; return digitize(geometricPriceDigitizer(basePrice, cellSizeInPercent)); } public TickerSequence digitize(PriceDigitizer2 digitizer) { TickerSequence seq = new TickerSequence(); seq.market(market); seq.priceCells(digitizer.priceCells()); int n = size(); for (int i = 0; i < n; i++) { seq.addIfPriceChanged(digitizer.digitize(getPrice(i)), getTimestamp(i)); } return seq.trimToSize(); } public List pricePoints() { return listFromFunction(__64 -> getPricePoint(__64), size()); } public PricePoint getPricePoint(int idx) { return new PricePoint(timestamps.get(idx), prices.get(idx)); } public List roundedCellNumbers() { return map(__65 -> iround(__65), cellNumbers()); } public List cellNumbers() { if (priceCells == null) return null; int n = size(); DoubleBuffer buf = new DoubleBuffer(n); for (int i = 0; i < n; i++) buf.add(priceCells.toCellNumber(getPrice(i))); return buf.asVirtualList(); } public TickerSequence toCellNumbers() { if (priceCells == null) return null; TickerSequence seq = new TickerSequence(); seq.market(market + " cell numbers " + roundBracket(priceCells)); int n = size(); for (int i = 0; i < n; i++) seq.add(priceCells.toCellNumber(getPrice(i)), getTimestamp(i)); return seq.trimToSize(); } public void dropLastPricePoint() { if (isEmpty()) return; prices.popLast(); timestamps.popLast(); lastTickerEvent = endTime(); newTickerEvent(); } public TickerSequence marketIfEmpty(String market) { if (empty(this.market)) market(market); return this; } public TickerSequence legacyCompact() { if (!(prices instanceof SynchronizedFloatBufferPresentingAsDoubles)) prices = new SynchronizedFloatBufferPresentingAsDoubles(prices.toArray()); return this; } public boolean compactTimestamps() { return compactTimestamps(20); } public boolean compactTimestamps(long msUnit) { if (!(timestamps instanceof SynchronizedLongBufferStoredAsLinearInts)) { timestamps = new SynchronizedLongBufferStoredAsLinearInts(roundDownTo(msUnit, startTime()), msUnit, timestamps); return true; } return false; } public double averageTimeStep() { return doubleRatio(endTime() - startTime(), size() - 1); } public void write(ByteHead head) { head.writeString(market); SynchronizedLongBufferStoredAsLinearInts timestamps = (SynchronizedLongBufferStoredAsLinearInts) (this.timestamps); head.writeLong(timestamps.base); head.writeLong(timestamps.factor); int n = size(); head.writeInt(n); for (int i = 0; i < n; i++) { head.writeInt(timestamps.getRaw(i)); head.writeFloat((float) prices.get(i)); } } static public TickerSequence read(ByteHead head) { TickerSequence t = new TickerSequence(); t.market = head.readString(); if (head.eof()) return null; long base = head.readLong(); long factor = head.readLong(); SynchronizedLongBufferStoredAsLinearInts timestamps = new SynchronizedLongBufferStoredAsLinearInts(base, factor); t.timestamps = timestamps; int n = head.readInt(); for (int i = 0; i < n; i++) { int time = head.readInt(); if (head.eof()) break; timestamps.addRaw(time); t.prices.add(head.readFloat()); } return t; } public TickerSequence loadJSONFile(File f) { var it = linesFromFile(f); try { for (var line : it) { try { addJSONLine(line); } catch (Throwable __e) { pcallFail(__e); } } return this; } finally { _close(it); } } } static public class RecursiveObjectSize { public long size; public SimpleStack stack = new SimpleStack(); public Set seen = new CompactIdentityHashSet(); public Set fieldsToIgnore; public Set realmsToIgnore; final public RecursiveObjectSize setSkipTransientFields(boolean skipTransientFields) { return skipTransientFields(skipTransientFields); } public RecursiveObjectSize skipTransientFields(boolean skipTransientFields) { this.skipTransientFields = skipTransientFields; return this; } final public boolean getSkipTransientFields() { return skipTransientFields(); } public boolean skipTransientFields() { return skipTransientFields; } public boolean skipTransientFields = false; transient public IVF1 onNewObject; public void onNewObject(Object o) { if (onNewObject != null) onNewObject.get(o); else onNewObject_base(o); } final public void onNewObject_fallback(IVF1 _f, Object o) { if (_f != null) _f.get(o); else onNewObject_base(o); } public void onNewObject_base(Object o) { } transient public Runnable onSizeChanged; public void onSizeChanged() { if (onSizeChanged != null) onSizeChanged.run(); else onSizeChanged_base(); } final public void onSizeChanged_fallback(Runnable _f) { if (_f != null) _f.run(); else onSizeChanged_base(); } public void onSizeChanged_base() { } transient public IF1 shouldIgnore; public boolean shouldIgnore(Object o) { return shouldIgnore != null ? shouldIgnore.get(o) : shouldIgnore_base(o); } final public boolean shouldIgnore_fallback(IF1 _f, Object o) { return _f != null ? _f.get(o) : shouldIgnore_base(o); } public boolean shouldIgnore_base(Object o) { return false; } public void resize(int expectedObjectCount) { seen = new CompactIdentityHashSet(expectedObjectCount); } public void incSize(long n) { size += n; onSizeChanged(); } public long recurse(Object o) { if (o == null) return 0; seen.add(o); stack.add(o); while (nempty(stack)) { ping(); step(popLast(stack)); } return size; } public void step(Object o) { if (guessDeepObjectSize_shouldIgnoreObject(o)) return; if (shouldIgnore(o)) return; onNewObject(o); if (realmsToIgnore != null && contains(realmsToIgnore, getRealm(o))) return; if (o instanceof Class) return; incSize(unsafe_sizeOf(o)); if (o instanceof Object[]) { for (Object x : ((Object[]) o)) if (x != null && seen.add(x)) stack.add(x); return; } if (sizeCalculation_shouldSkipObject(o)) return; for (Field f : nonStaticNonPrimitiveFieldObjects(o)) { if (contains(fieldsToIgnore, f)) continue; if (skipTransientFields && isTransient(f)) continue; Object x; try { x = f.get(o); } catch (Throwable e) { print("Error trying to access " + f + ": " + e); continue; } if (x != null && seen.add(x)) { stack.add(x); } } } public boolean hasSeen(Object o) { return seen.contains(o); } } static public class G22ProjectOverviewPanel implements IFieldsToList { public G22Utils g22utils; public G22ProjectOverviewPanel() { } public G22ProjectOverviewPanel(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public JSyntaxTextFileEditor storyView; public JLabel lblStats; transient public G22ShowCasePanel showCasePanel; public void updateStats() { setText(lblStats, "Database core size: " + str_toKB(fileSize(g22utils.concepts().conceptsFile()))); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { var conceptsFile = g22utils.concepts().conceptsFile(); lblStats = rightAlignedLabel(); IVF1 fileListener = file -> { if (sameFile(file, conceptsFile)) updateStats(); }; bindToComponent(lblStats, () -> { g22utils.onProjectFileChanged(fileListener); updateStats(); }, () -> g22utils.removeProjectFileChangedListener(fileListener)); storyView = new JSyntaxTextFileEditor(g22utils.projectStoryTextFile()).uneditable(true); storyView.adaptSyntaxTextArea = textArea -> g22_adaptSyntaxTextAreaForHashRefs(textArea, g22utils); addInFront(storyView.buttons(), jImageButtonScaledToWidth(16, "#1103068", "Edit", runnableThread(new Runnable() { public void run() { try { storyView.uneditable(false); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "//g22utils.projectActions.editProjectStory();\r\n storyView.uneditable(f..."; } }))); showCasePanel = new G22ShowCasePanel(g22utils); String title = "Project " + quote(g22utils.projectName()) + " Overview"; G22VariablesPanel variablesPanel = g22utils.makeVariablesPanel(); variablesPanel.crud().tableSearcher().scpRightOfSearchPanel.set(withLeftMargin(toolTip("Maximize variables panel", jimageButtonScaledToWidth(16, "#1103161", runnableThread(new Runnable() { public void run() { try { g22utils.showUIURL("Variables"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.showUIURL(\"Variables\")"; } }))))); return withTopAndBottomMargin(jRaisedCenteredSection(title, jvsplit_minZero(jhsplit(0.75, jCenteredSection("Project Story", centerAndSouthWithMargin(storyView, centerAndEastWithMargin(lblStats, jFilePathButton(conceptsFile)))), northAndCenterWithMargin(new G22AutoStartPanel(g22utils), variablesPanel.compactView(false))), jCenteredSection("Showcase", showCasePanel.visualize())))); } } static public class TradingSignal extends Meta { final public TradingSignal setCoin(String coin) { return coin(coin); } public TradingSignal coin(String coin) { this.coin = coin; return this; } final public String getCoin() { return coin(); } public String coin() { return coin; } public String coin; final public TradingSignal setIsLong(boolean isLong) { return isLong(isLong); } public TradingSignal isLong(boolean isLong) { this.isLong = isLong; return this; } final public boolean getIsLong() { return isLong(); } public boolean isLong() { return isLong; } public boolean isLong = false; final public TradingSignal setTimestamp(Timestamp timestamp) { return timestamp(timestamp); } public TradingSignal timestamp(Timestamp timestamp) { this.timestamp = timestamp; return this; } final public Timestamp getTimestamp() { return timestamp(); } public Timestamp timestamp() { return timestamp; } public Timestamp timestamp; final public TradingSignal setAfterRun(TradingRun afterRun) { return afterRun(afterRun); } public TradingSignal afterRun(TradingRun afterRun) { this.afterRun = afterRun; return this; } final public TradingRun getAfterRun() { return afterRun(); } public TradingRun afterRun() { return afterRun; } public TradingRun afterRun; public String toString() { String text = (isLong ? "Long" : "Short") + " signal " + (empty(coin) ? "" : "for " + coin + " ") + "at " + timestamp; if (afterRun != null) text += " after " + formatDouble2X(afterRun.changePercent()) + "% run"; return text; } public TradingCandle candle() { return afterRun == null ? null : last(afterRun.candles); } public double price() { var candle = candle(); return candle == null ? Double.NaN : candle.end(); } } static public class G22MasksPanel extends G22CRUDAndDetailPanel { public G22MasksPanel() { } public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22MaskConcept.class); crud.excludeFieldsFromEditing("maskImage"); crud.entityName = () -> "Mask"; return crud; } public JComponent makeDetailView(G22MaskConcept mask) { return g22utils.stdImageSurface(mask.maskImage); } public G22MasksPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } } static public class FloatBuffer implements Iterable, IntSize { public float[] data; public int size; public FloatBuffer() { } public FloatBuffer(int size) { if (size != 0) data = new float[size]; } public FloatBuffer(Iterable l) { addAll(l); } public FloatBuffer(Collection l) { this(l(l)); addAll(l); } public FloatBuffer(float... data) { this.data = data; size = l(data); } public void add(float i) { if (size >= lFloatArray(data)) { data = resizeFloatArray(data, Math.max(1, toInt(Math.min(maximumSafeArraySize(), lFloatArray(data) * 2L)))); if (size >= data.length) throw fail("FloatBuffer too large: " + size); } data[size++] = i; } public void addAll(Iterable l) { if (l != null) for (float i : l) add(i); } public float[] toArray() { return size == 0 ? null : resizeFloatArray(data, size); } public float[] toArrayNonNull() { return unnull(toArray()); } public List toList() { return floatArrayToList(data, 0, size); } public List asVirtualList() { return new RandomAccessAbstractList() { public int size() { return size; } public Float get(int i) { return FloatBuffer.this.get(i); } public Float set(int i, Float val) { Float a = get(i); data[i] = val; return a; } }; } public void reset() { size = 0; } public void clear() { reset(); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public float get(int idx) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); return data[idx]; } public void set(int idx, float value) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); data[idx] = value; } public float popLast() { if (size == 0) throw fail("empty buffer"); return data[--size]; } public float last() { return data[size - 1]; } public float nextToLast() { return data[size - 2]; } public String toString() { return squareBracket(joinWithSpace(toList())); } public Iterator iterator() { return new IterableIterator() { public int i = 0; public boolean hasNext() { return i < size; } public Float next() { return data[i++]; } }; } public void trimToSize() { data = resizeFloatArray(data, size); } public int indexOf(float b) { for (int i = 0; i < size; i++) if (data[i] == b) return i; return -1; } public float[] subArray(int start, int end) { return subFloatArray(data, start, min(end, size)); } } static public class G22_TestScreenPanel implements IHasChangeListeners { public G22_TestScreenPanel() { } final public G22_TestScreenPanel setScript(String script) { return script(script); } public G22_TestScreenPanel script(String script) { if (!eq(this.script, script)) { this.script = script; change(); } return this; } final public String getScript() { return script(); } public String script() { return script; } public String script = "rasters"; final public G22_TestScreenPanel setAnimate(boolean animate) { return animate(animate); } public G22_TestScreenPanel animate(boolean animate) { if (!eq(this.animate, animate)) { this.animate = animate; change(); } return this; } final public boolean getAnimate() { return animate(); } public boolean animate() { return animate; } public boolean animate = true; transient public Set onChange; public G22_TestScreenPanel onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public G22_TestScreenPanel removeChangeListener(Runnable r) { loadableUtils.utils.remove(onChange, r); return this; } public void change() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } transient public Animation animation; final public G22_TestScreenPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22_TestScreenPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; transient public ImageSurface isInput; transient public JGazelleVScriptRunner scriptRunner; public void start() { scriptRunner = new JGazelleVScriptRunner(liveValue_hasChangeListeners(this, String.class, () -> script, x -> script = x)); isInput = g22utils.stdImageSurface(); awtEvery(isInput, 1000 / 20, new Runnable() { public void run() { try { stepAnimation(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "stepAnimation();"; } }); } public void stepAnimation() { if (!animate) return; if (animation == null) { animation = new AnimatedLine(); animation.start(); } animation.nextFrame(); var img = whiteImage(animation.w, animation.h); animation.setGraphics(createGraphics(img)); animation.paint(); { if (isInput != null) isInput.setImage(img); } var ii = bwIntegralImage_withMeta(img); scriptRunner.parseAndRunOn(ii); } public JComponent visualize() { if (isInput == null) start(); return centerAndSouthWithMargin(hsplit(northAndCenterWithMargin(centerAndEastWithMargin(jlabel("Input"), liveValueCheckBox("Animate", liveValue_hasChangeListeners(this, boolean.class, () -> animate, x -> animate(x)))), jscroll_centered_borderless(isInput)), northAndCenterWithMargin(centerAndEastWithMargin(jlabel("Output"), scriptRunner.lblScore), scriptRunner.scpScriptResult)), scriptRunner.scriptInputField()); } } static public class G22Utils_Base { transient public Set> onProjectFileChanged; public G22Utils_Base onProjectFileChanged(IVF1 f) { onProjectFileChanged = createOrAddToSyncLinkedHashSet(onProjectFileChanged, f); return this; } public G22Utils_Base removeProjectFileChangedListener(IVF1 f) { loadableUtils.utils.remove(onProjectFileChanged, f); return this; } public void projectFileChanged(File file) { if (onProjectFileChanged != null) for (var listener : onProjectFileChanged) pcallF_typed(listener, file); } } static public class G22Utils extends G22Utils_Base implements AutoCloseable, TransientObject { final public G22Utils setBackgroundProcessesUI(IBackgroundProcesses backgroundProcessesUI) { return backgroundProcessesUI(backgroundProcessesUI); } public G22Utils backgroundProcessesUI(IBackgroundProcesses backgroundProcessesUI) { this.backgroundProcessesUI = backgroundProcessesUI; return this; } final public IBackgroundProcesses getBackgroundProcessesUI() { return backgroundProcessesUI(); } public IBackgroundProcesses backgroundProcessesUI() { return backgroundProcessesUI; } public IBackgroundProcesses backgroundProcessesUI; final public G22Utils setModule(Enterable module) { return module(module); } public G22Utils module(Enterable module) { this.module = module; return this; } final public Enterable getModule() { return module(); } public Enterable module() { return module; } public Enterable module; final public G22Utils setMasterStuff(G22MasterStuff masterStuff) { return masterStuff(masterStuff); } public G22Utils masterStuff(G22MasterStuff masterStuff) { this.masterStuff = masterStuff; return this; } final public G22MasterStuff getMasterStuff() { return masterStuff(); } public G22MasterStuff masterStuff() { return masterStuff; } public G22MasterStuff masterStuff; final public G22Utils setConcepts(Concepts concepts) { return concepts(concepts); } public G22Utils concepts(Concepts concepts) { this.concepts = concepts; return this; } final public Concepts getConcepts() { return concepts(); } public Concepts concepts() { return concepts; } public Concepts concepts; final public G22Utils setProjectActions(G22ProjectActions projectActions) { return projectActions(projectActions); } public G22Utils projectActions(G22ProjectActions projectActions) { this.projectActions = projectActions; return this; } final public G22ProjectActions getProjectActions() { return projectActions(); } public G22ProjectActions projectActions() { return projectActions; } public G22ProjectActions projectActions; final public G22AutoStarter getAutoStarter() { return autoStarter(); } public G22AutoStarter autoStarter() { return autoStarter; } public G22AutoStarter autoStarter = new G22AutoStarter(this); final public G22Utils setFunctionTimings(FunctionTimings functionTimings) { return functionTimings(functionTimings); } public G22Utils functionTimings(FunctionTimings functionTimings) { this.functionTimings = functionTimings; return this; } final public FunctionTimings getFunctionTimings() { return functionTimings(); } public FunctionTimings functionTimings() { return functionTimings; } public FunctionTimings functionTimings = new FunctionTimings(); final public Map getProjectWideFunctionDefs() { return projectWideFunctionDefs(); } public Map projectWideFunctionDefs() { return projectWideFunctionDefs; } public Map projectWideFunctionDefs = syncMap(); final public Map getProjectWideClassDefs() { return projectWideClassDefs(); } public Map projectWideClassDefs() { return projectWideClassDefs; } public Map projectWideClassDefs = syncMap(); public Timestamp recompileDate; final public Set getAutoClosingResources() { return autoClosingResources(); } public Set autoClosingResources() { return autoClosingResources; } public Set autoClosingResources = syncLinkedHashSet(); public FileWatchService fileWatcher; public boolean projectFileListenerInitiated = false; final public CombinedStringifier getStringifier() { return stringifier(); } public CombinedStringifier stringifier() { return stringifier; } public CombinedStringifier stringifier = new CombinedStringifier(o -> o instanceof BufferedImage ? "Image (" + ((BufferedImage) o).getWidth() + "*" + ((BufferedImage) o).getHeight() + " px)" : null); public ILASClassLoader lasClassLoader() { return masterStuff == null ? null : masterStuff.lasClassLoader(); } final public G22Utils setConfirmProjectReplacements(boolean confirmProjectReplacements) { return confirmProjectReplacements(confirmProjectReplacements); } public G22Utils confirmProjectReplacements(boolean confirmProjectReplacements) { this.confirmProjectReplacements = confirmProjectReplacements; return this; } final public boolean getConfirmProjectReplacements() { return confirmProjectReplacements(); } public boolean confirmProjectReplacements() { return confirmProjectReplacements; } public boolean confirmProjectReplacements = false; public ImageSurface stdImageSurface_noToolTip() { return stdImageSurface_noToolTip(imageSurface()); } public ImageSurface stdImageSurface_noToolTip(ImageSurface is) { imageSurface_pixelated(is); is.setAutoZoomToDisplay(true).repaintInThread(false); is.defaultImageDir = () -> dbDir(); is.specialPurposed = true; return is; } public ImageSurface stdImageSurface() { return stdImageSurface(imageSurface()); } public ImageSurface stdImageSurface(ImageSurface is) { stdImageSurface_noToolTip(is); new ImageSurface_PositionToolTip(is); return is; } public List stdImageSurfaces(Collection images) { return map(__66 -> stdImageSurface(__66), toBufferedImages(images)); } public ImageSurface stdImageSurface(MakesBufferedImage img) { return stdImageSurface(toBufferedImage(img)); } public ImageSurface stdImageSurface(BufferedImage img) { var is = stdImageSurface(); is.setImage(img); return is; } public ImageSurface stdImageSurface(File file) { var is = stdImageSurface(); is.setImage(file); return is; } public ImageSurface stdImageSurface(G22GalleryImage img) { return stdImageSurface(img == null ? null : img.path); } public ImageSurface stdImageSurfaceWithSelection(MakesBufferedImage img, Rect selection) { return stdImageSurfaceWithSelection(toBufferedImage(img), selection); } public ImageSurface stdImageSurfaceWithSelection(BufferedImage img, Rect selection) { var is = stdImageSurface(img); is.setSelection(selection); return is; } public String stringify(Object o) { return stringifier.toString(o); } transient public Set> onBigVariableLoaded; public G22Utils onBigVariableLoaded(IVF1 f) { onBigVariableLoaded = createOrAddToSyncLinkedHashSet(onBigVariableLoaded, f); return this; } public G22Utils removeBigVariableLoadedListener(IVF1 f) { loadableUtils.utils.remove(onBigVariableLoaded, f); return this; } public void bigVariableLoaded(G22Variable var) { if (onBigVariableLoaded != null) for (var listener : onBigVariableLoaded) pcallF_typed(listener, var); } transient public Set> onSettingUpParser; public G22Utils onSettingUpParser(IVF1 f) { onSettingUpParser = createOrAddToSyncLinkedHashSet(onSettingUpParser, f); return this; } public G22Utils removeSettingUpParserListener(IVF1 f) { loadableUtils.utils.remove(onSettingUpParser, f); return this; } public void settingUpParser(GazelleV_LeftArrowScriptParser parser) { if (onSettingUpParser != null) for (var listener : onSettingUpParser) pcallF_typed(listener, parser); } transient public Set> onSettingUpScriptIDE; public G22Utils onSettingUpScriptIDE(IVF1 f) { onSettingUpScriptIDE = createOrAddToSyncLinkedHashSet(onSettingUpScriptIDE, f); return this; } public G22Utils removeSettingUpScriptIDEListener(IVF1 f) { loadableUtils.utils.remove(onSettingUpScriptIDE, f); return this; } public void settingUpScriptIDE(JLeftArrowScriptIDE ide) { if (onSettingUpScriptIDE != null) for (var listener : onSettingUpScriptIDE) pcallF_typed(listener, ide); } public GazelleV_LeftArrowScriptParser leftArrowParser() { GazelleV_LeftArrowScriptParser parser = new GazelleV_LeftArrowScriptParser(); parser.classNameResolver(classNameResolver()); parser.lasClassLoader(lasClassLoader()); settingUpParser(parser); parser.addClassAlias("BollingerBands", "LiveBollingerBands"); parser.addClassAlias("Freq", "Frequency"); parser.addClassAlias("PriceDigitizer", "PriceDigitizer2"); parser.addClassAlias("MRUAndAllTimeTop", "MRUAndAllTimeTop_optimized"); parser.findExternalObject2 = name -> { { var __2 = projectWideClassDefs.get(name); if (__2 != null) return __2; } return parser.findExternalObject2_base(name); }; parser.addFunctionDefs(projectWideFunctionDefs); return parser; } public Object leftArrow(String script) { return leftArrowParse(script).get(); } public GazelleV_LeftArrowScript.Script leftArrowParse(String script) { return leftArrowParser().parse(script); } public Object leftArrowWithVars(String script, Object... vars) { var parser = leftArrowParser(); for (int i = 0; i < l(vars); i += 2) parser.addVar((String) vars[i], or(_getClass(vars[i + 1]), Object.class), true); var parsed = parser.parse(script); FlexibleVarContext varContext = new FlexibleVarContext(); for (int i = 0; i < l(vars); i += 2) varContext.set((String) vars[i], vars[i + 1]); return parsed.get(varContext); } public void basicParserTest() { var parser = leftArrowParser(); print("classContainerPrefixes", parser.classContainerPrefixes()); assertEquals(pair(1, 2), parser.parse("new Pair 1 2").get()); } final public JLeftArrowScriptIDE leftArrowScriptIDE() { return leftArrowIDE(); } public JLeftArrowScriptIDE leftArrowIDE() { JLeftArrowScriptIDE ide = new JLeftArrowScriptIDE(); ide.g22utils(this); ide.scriptTimeout(projectWideScriptTimeout()); settingUpScriptIDE(ide); return ide; } public File byteCodePath() { return assertNotNull(getBytecodePathForClass(this)); } public ClassNameResolver classNameResolver_cache; public ClassNameResolver classNameResolver() { if (classNameResolver_cache == null) classNameResolver_cache = classNameResolver_load(); return classNameResolver_cache; } public ClassNameResolver classNameResolver_load() { return new ClassNameResolver().byteCodePath(byteCodePath()).init(); } public File databasesMotherDir() { return masterStuff.databasesMotherDir(); } public File dirOfProjectNamed(String name) { assertNempty(name); return newFile(databasesMotherDir(), name); } public AutoCloseable enter() { return module == null ? null : module.enter(); } public String defaultDBName() { return "Default"; } public File lastOpenedDBsFile() { return newFile(databasesMotherDir(), "Last Opened"); } public File recentlyOpenedDBsFile() { return newFile(databasesMotherDir(), "Recently Opened"); } public File autoUpdateFile() { return newFile(databasesMotherDir(), "Auto-Update"); } public boolean autoUpdateEnabled() { return fileExists(autoUpdateFile()); } public void setAutoUpdate(boolean b) { createOrRemoveFile(autoUpdateFile(), b); } public List dbsToOpen() { return loadRecentProjectsFile(lastOpenedDBsFile()); } public List dbNamesRecentlyOpened() { return loadRecentProjectsFile(recentlyOpenedDBsFile()); } public void addToRecentDBNames(String dbName, boolean hidden) { List list = dbNamesRecentlyOpened(); List list2 = cloneList(list); removeAll(list2, dbName, "*" + dbName); list2.add(0, hidden ? "*" + dbName : dbName); truncateList(list2, 100); if (!eq(list, list2)) saveTextFile(recentlyOpenedDBsFile(), lines(list2)); } public List loadRecentProjectsFile(File file) { List dbNames = new ArrayList(); for (String name : tlft(loadTextFile(file))) { String name2 = dropPrefix("*", name); if (fileExists(newFile(databasesMotherDir(), name2))) dbNames.add(name); } if (empty(dbNames)) dbNames.add(defaultDBName()); return dbNames; } public void setOpenDBs(Collection dbs) { List dbNames = new ArrayList(); for (var db : dbs) { var dbDir = conceptsDir(db.concepts()); if (sameFile(databasesMotherDir(), dirOfFile(dbDir))) dbNames.add((db.hidden() ? "*" : "") + fileName(dbDir)); } saveTextFile(lastOpenedDBsFile(), lines(dbNames)); } public void setupScriptCRUD(SimpleCRUD_v2 crud) { setupScriptCRUD(crud, false); } public void setupScriptCRUD(SimpleCRUD_v2 crud, boolean allowRunOnProjectOpen) { crud.useNewChangeHandler(true); crud.editableFieldsForItem = x -> llNonNulls("description", allowRunOnProjectOpen ? "runOnProjectOpen" : null, allowRunOnProjectOpen ? "runOrder" : null); crud.multiLineField("text"); crud.multiLineField("editingText"); crud.makeTextArea = text -> jMinHeight(200, crud.makeTextArea_base(text)); crud.humanizeFieldNames = false; crud.iconButtons(true); crud.itemToMap_inner2 = c -> scriptToMap(c, allowRunOnProjectOpen); crud.dontDuplicateFields = litset("runOnProjectOpen", "runOrder", "runCount", "lastResultByMode"); } public Map scriptToMap(G22LeftArrowScript c) { return scriptToMap(c, false); } public Map scriptToMap(G22LeftArrowScript c, boolean allowRunOnProjectOpen) { return litorderedmap("Description", c.description(), "Status", renderScriptStatus(c), "LoC", renderScriptLoC(c), "Import note", c.importNote, "Run on project open", c.renderRunOnProjectOpenStatus()); } public String renderScriptStatus(G22LeftArrowScript c) { return or2_rev("Empty", joinNemptiesWithSpacedPlus(c.isClearForAutoRun() ? "Clear for auto-run" : null, c.isSavedDistinctFromAutoRunVersion() ? "Saved (not cleared)" : null, c.isEditing() ? "Editing" : null)); } public String renderScriptLoC(G22LeftArrowScript c) { return n2(intMax(mapLL(__67 -> linesOfCode_javaTok(__67), c.editingText, c.text, c.codeForAutoRun()))); } public List labelsForFile(File file) { if (file == null) return null; File labelsFile = appendToFileName(file, ".labels"); List labels = tlft(loadTextFile(labelsFile)); return map(__68 -> getLabel(__68), labels); } public File labelsFile(File file) { if (file == null) return null; return appendToFileName(file, ".labels"); } public void setLabelsForFile(File file, List labels) { List list = map(labels, label -> label.name); File f = labelsFile(file); saveTextFile(f, lines(list)); print("Saved " + nLabels(list) + " (" + joinWithComma(list) + ") to " + f); } public G22Label getLabel(String name) { if (empty(name)) return null; if (containsNewLine(name)) throw fail("No newlines in label names allowed: " + name); return uniqCI(concepts, G22Label.class, "name", name); } final public File projectDir() { return dbDir(); } public File dbDir() { return conceptsDir(concepts); } final public File projectFile(String name) { return fileInDbDir(name); } public File fileInDbDir(String name) { return newFile(dbDir(), name); } public class GazelleDB implements IFieldsToList { public String name; public File dir; public GazelleDB() { } public GazelleDB(String name, File dir) { this.dir = dir; this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + dir + ")"; } public boolean equals(Object o) { if (!(o instanceof GazelleDB)) return false; GazelleDB __0 = (GazelleDB) o; return eq(name, __0.name) && eq(dir, __0.dir); } public int hashCode() { int h = 1669530526; h = boostHashCombine(h, _hashCode(name)); h = boostHashCombine(h, _hashCode(dir)); return h; } public Object[] _fieldsToList() { return new Object[] { name, dir }; } public String name() { return name; } public File dir() { return dir; } public boolean loaded() { return loadedDB() != null; } public IG22LoadedDB loadedDB_cache; public IG22LoadedDB loadedDB() { if (loadedDB_cache == null) loadedDB_cache = loadedDB_load(); return loadedDB_cache; } public IG22LoadedDB loadedDB_load() { return masterStuff.getLoadedDBForConceptDir(dir); } public File conceptsFile() { return conceptsFileIn(dir); } } public List gazelleDBs() { List dbs = new ArrayList(); for (File dir : listDirsContainingFileNamed(databasesMotherDir(), "concepts.structure.gz")) dbs.add(new GazelleDB(fileName(dir), dir)); return dbs; } public IterableIterator peekAllProjectsConcepts() { var classFinder = masterStuff.makeClassFinder(); return mapI_pcall(gazelleDBs(), db -> { var cc = newConceptsWithClassFinder(db.conceptsFile(), classFinder); cc.loadFromDisk(); return cc; }); } public RSyntaxTextAreaWithSearch newSyntaxTextArea() { return newSyntaxTextArea((IF1) null); } public RSyntaxTextAreaWithSearch newSyntaxTextArea(IF1 wrapStatusLabel) { RSyntaxTextAreaWithSearch ta = new RSyntaxTextAreaWithSearch(wrapStatusLabel); ta.textArea().setHighlightCurrentLine(false); ta.menuLessOperation(); return ta; } public RSyntaxTextAreaWithSearch newSyntaxTextArea(String text) { var ta = newSyntaxTextArea(); ta.setText(text); return ta; } public File projectStoryTextFile() { return newFile(dbDir(), "story.txt"); } public String projectName() { return fileName(dbDir()); } public void close() { try { autoStarter.close(); closeAndClear(autoClosingResources); { cleanUp(fileWatcher); fileWatcher = null; } } catch (Exception __e) { throw rethrow(__e); } } public void close(AutoCloseable c) { loadableUtils.utils.close(c); } public G22Variable findProjectVar(String name) { return conceptWhereCI(concepts, G22Variable.class, "name", name); } public Collection projectVarNames() { return collect("name", list(concepts, G22Variable.class)); } public Object getProjectVar(String name) { G22Variable var = findProjectVar(name); return var == null ? null : var.value(); } public Object getBigProjectVarOnce(String name) { G22Variable var = findProjectVar(name); return var == null ? null : var.getOnce(); } public Object getMandatoryProjectVar(String name) { return assertNotNull(name, getProjectVar(name)); } public Object getOrSetTransientProjectVar(String name, IF0 f) { { var __3 = getProjectVar(name); if (__3 != null) return __3; } return setTransientProjectVarAndReturn(name, f.get()); } public Object getProjectVarOrCallScript(String name, long scriptID) { { var __4 = getProjectVar(name); if (__4 != null) return __4; } return callScript(scriptID); } public Object getProjectVarSetByScript(String name, long scriptID) { { var __5 = getProjectVar(name); if (__5 != null) return __5; } callScript(scriptID); return getProjectVar(name); } public Object getProjectVarFromAnyProject(String name) { for (var project : masterStuff().openProjects()) { var __6 = project.g22utils().getProjectVar(name); if (__6 != null) return __6; } return null; } final public List getVarFromAnyProject(String name) { return getProjectVarFromAllProjects(name); } public List getProjectVarFromAllProjects(String name) { return nonNulls(masterStuff().openProjects(), project -> project.g22utils().getProjectVar(name)); } public G22Variable projectVarConcept(String name) { return optimizedUniqCI(concepts, G22Variable.class, "name", name); } public Object waitForProjectVar(String name) { return waitForProjectVar(infinity(), name); } public Object waitForProjectVar(double timeoutSeconds, String name) { G22Variable var = projectVarConcept(name); return waitForCalculatedValueUsingChangeListener(timeoutSeconds, () -> var.value(), var); } public void setBigProjectVar(boolean persistent, String name, Object value) { if (persistent) setBigProjectVar(name, value); else setTransientProjectVar(name, value); } public G22Variable setProjectVar(boolean persistent, String name, Object value) { G22Variable var = projectVarConcept(name); if (!persistent) var.persistent(persistent); var.value(value); if (persistent) var.persistent(persistent); return var; } public void unloadProjectVar(String name) { var var = findProjectVar(name); { if (var != null) var.unload(); } } public A setBigProjectVar(String name, A value) { setPersistentProjectVar(name, value); G22Variable var = projectVarConcept(name); var.makeBig(); return value; } public Object getCachedProjectVar(String name) { var var = findProjectVar(name); return var == null ? null : var.cachedValue(); } public boolean isBigProjectVar(String name) { var v = findProjectVar(name); return v != null && v.big(); } public A setPersistentProjectVar(String name, A value) { setProjectVar(true, name, value); return value; } public G22Variable setTransientProjectVar(String name, Object value) { return setProjectVar(false, name, value); } public A setTransientProjectVarAndReturn(String name, A value) { setProjectVar(false, name, value); return value; } public void setAutoClosingProjectVar(String name, Object value) { setTransientProjectVar(name, value).autoClose(true); } public void deleteProjectVar(String name) { deleteConcept(findProjectVar(name)); } final public Object getOrCreateTransientProjectVar(String name, IF0 maker) { return getOrCreateProjectVar(name, maker); } public Object getOrCreateProjectVar(String name, IF0 maker) { return getOrCreateProjectVar(projectVarConcept(name), maker); } public Object getOrCreatePersistentProjectVar(String name, IF0 maker) { var var = projectVarConcept(name); Object value = getOrCreateProjectVar(var, maker); var.persistent(true); return value; } public Object getOrCreateBigProjectVar(String name, IF0 maker) { var var = projectVarConcept(name); Object value = getOrCreateProjectVar(var, maker); var.makeBig(); return value; } public Object getOrCreateAutoClosingProjectVar(String name, IF0 maker) { var var = projectVarConcept(name); Object value = getOrCreateProjectVar(var, maker); var.autoClose(true); return value; } public boolean projectVarIsNotNull(String name) { var var = findProjectVar(name); return var != null && var.has(); } public Object getOrCreateProjectVar(G22Variable var, IF0 maker) { if (!var.has()) { Object value = maker.get(); if (value != null) var.setValueIfNull(value); } return var.get(); } public IVarWithNotify liveProjectVar(String name) { return liveProjectVar(name, null); } public IVarWithNotify liveProjectVar(String name, Object defaultValue) { G22Variable var = projectVarConcept(name); var.persistent(true); var.setValueIfNull(defaultValue); return var.varValue(); } public IVarWithNotify liveTransientProjectVar(String name) { return liveTransientProjectVar(name, null); } public IVarWithNotify liveTransientProjectVar(String name, Object defaultValue) { G22Variable var = projectVarConcept(name); var.persistent(false); var.setValueIfNull(defaultValue); return var.varValue(); } public void replaceCloseableProjectVar(String name, IF0 calc) { Object value = getProjectVar(name); if (value instanceof AutoCloseable) { loadableUtils.utils.close((AutoCloseable) value); deleteProjectVar(name); } setTransientProjectVar(name, calc == null ? null : calc.get()); } public void projectVarChanged(String name) { var var = findProjectVar(name); { if (var != null) var.changeInsideOfValue(); } } public Collection projectVarChanged(Object value) { var vars = conceptsWhere(concepts, G22Variable.class, "value", value); for (var var : vars) var.change(); return vars; } public double defaultScriptTimeout() { return 10.0; } public double projectWideScriptTimeout() { return or(toDoubleOrNull(getProjectVar("!Script Timeout")), defaultScriptTimeout()); } public G22Analyzer getAnalyzer(long id) { var a = getConcept(concepts, G22Analyzer.class, id); if (a == null) throw fail("Analyzer not found: " + id); return a; } public G22LeftArrowScript getScript(long id) { var a = getConcept(concepts, G22LeftArrowScript.class, id); if (a == null) throw fail("Script not found: " + id); return a; } public Object callScript(long id) { var script = getScript(id); return script.evaluateWithoutTimeout(); } public Object callAutoRunnableScript(long id) { var script = getScript(id); return script.evaluateAutoRunWithoutTimeout(); } public double defaultTimeout() { return infinity(); } public A evalRegisteredCode(String processName, IF0 code) { return evalRegisteredCode(defaultTimeout(), processName, code); } public A evalRegisteredCode(double timeoutSeconds, String processName, IF0 code) { if (code == null) return null; return evalWithTimeoutOrTypedException(timeoutSeconds, () -> useThisThreadAsBackgroundProcess(processName, code)); } public Thread startAsRegisteredThread(String processName, Runnable r) { if (r == null) return null; return startThread(processName, () -> useThisThreadAsBackgroundProcess(processName, toIF0(r))); } public A useThisThreadAsBackgroundProcess(String processName, IF0 code) { AutoCloseable __8 = enter(); try { var process = backgroundProcessesUI.tempAdd(processName); try { Thread myThread = currentThread(); process.setInterruptAction(new Runnable() { public void run() { try { cancelThread(myThread); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "cancelThread(myThread)"; } }); return code.get(); } finally { _close(process); } } finally { _close(__8); } } public Object host() { AutoCloseable __9 = enter(); try { return dm_os(); } finally { _close(__9); } } public A timeFunction(String name, IF0 f) { return functionTimings.get(name, f); } public boolean isConceptsDir(File dir) { return isSameFile(conceptsDir(concepts), dir); } synchronized public FileWatchService fileWatcher() { { if (fileWatcher == null) fileWatcher = new FileWatchService(); return fileWatcher; } } synchronized public G22Utils onProjectFileChanged(IVF1 listener) { super.onProjectFileChanged(listener); if (!projectFileListenerInitiated) { projectFileListenerInitiated = true; fileWatcher().addRecursiveListener(dbDir(), __10 -> projectFileChanged(__10)); } return this; } public G22ProjectInfo projectInfo_cache; public G22ProjectInfo projectInfo() { if (projectInfo_cache == null) projectInfo_cache = projectInfo_load(); return projectInfo_cache; } public G22ProjectInfo projectInfo_load() { return optimizedUniq(concepts, G22ProjectInfo.class); } public RunnablesReferenceQueue runnablesReferenceQueue() { return masterStuff.runnablesReferenceQueue(); } public EphemeralObjectIDs ephemeralObjectIDs() { return masterStuff.ephemeralObjectIDs(); } public Object eph(long id) { return ephemeralObjectIDs().get(id); } public void openInBrowser(String url) { loadableUtils.utils.openPlatformBrowser(url); } public String compilationDate() { return or2(compilationDateFromClassPath(this), "unknown"); } public String projectID() { return projectInfo().projectID(); } public IG22LoadedDB getLoadedDB() { return masterStuff.getLoadedDB(concepts); } public ConceptsComboBox galleryImagesComboBox() { return swing(() -> new ConceptsComboBox(concepts, G22GalleryImage.class)); } public IBackgroundProcess tempAddBackgroundProcess(String name) { return backgroundProcessesUI == null ? null : backgroundProcessesUI.tempAdd(name); } public IF1 classFinder() { var master = masterStuff.makeClassFinder(); return name -> { { var __7 = projectWideClassDefs().get(dropPrefix("main$", name)); if (__7 != null) return __7; } return master.get(name); }; } public Object restructure(Object o) { return unstructure(structure(o), false, concepts.classFinder); } public G22ProjectActions project() { return projectActions(); } public boolean openPathInProject(String path) { return projectActions().openPathInProject(path); } final public void showUIURL(String url) { openUIURL(url); } final public void goToURIURL(String url) { openUIURL(url); } public void openUIURL(String url) { projectActions().openUIURL(url); } public BufferedImage loadProjectImage(String fileName) { return loadImage2(projectFile(fileName)); } public IG22LoadedDB openDB(String name) { return openDB(name, false); } public IG22LoadedDB openDB(String name, boolean hidden) { return masterStuff().openDB(name, hidden); } public G22Utils getProject(String name) { return openDB(name, true).g22utils(); } public G22Utils getProjectIfOpen(String name) { var db = first(openProjects(), p -> eqic(p.g22utils().projectName(), name)); return db == null ? null : db.g22utils(); } final public G22JavaObjectVisualizer visualizeJavaObject(Object o) { return visualizeObject(o); } public G22JavaObjectVisualizer visualizeObject(Object o) { return new G22JavaObjectVisualizer(this, o); } final public G22JavaObjectVisualizer visualizeJavaObjectWithoutType(Object o) { return visualizeObjectWithoutType(o); } public G22JavaObjectVisualizer visualizeObjectWithoutType(Object o) { return visualizeObject(o).withTypeAndTime(false); } transient public IF0 makeVariablesPanel; public G22VariablesPanel makeVariablesPanel() { return makeVariablesPanel != null ? makeVariablesPanel.get() : makeVariablesPanel_base(); } final public G22VariablesPanel makeVariablesPanel_fallback(IF0 _f) { return _f != null ? _f.get() : makeVariablesPanel_base(); } public G22VariablesPanel makeVariablesPanel_base() { return new G22VariablesPanel().g22utils(this); } transient public IF0 jGazelleLogo; public JComponent jGazelleLogo() { return jGazelleLogo != null ? jGazelleLogo.get() : jGazelleLogo_base(); } final public JComponent jGazelleLogo_fallback(IF0 _f) { return _f != null ? _f.get() : jGazelleLogo_base(); } public JComponent jGazelleLogo_base() { return loadableUtils.utils.jGazelleLogo(); } public boolean devMode() { return masterStuff().devMode(); } public List list(Class type) { return list(type, concepts()); } public List list(Class type, Concepts cc) { return loadableUtils.utils.list(cc, type); } public List list(Concepts concepts, Class type) { return loadableUtils.utils.list(type, concepts); } public G22GalleryImage galleryImageForMD5(String md5) { return firstThat(list(concepts, G22GalleryImage.class), img -> cic(fileName(img.path), md5)); } public JComponent wrapImageSurface(ImageSurface is) { return is == null ? null : jscroll_centered_borderless(is); } public JComponent wrap(Object o) { var c = loadableUtils.utils.wrap(o); if (c instanceof ImageSurface) return wrapImageSurface((ImageSurface) c); return c; } transient public IF0 byUser; public String byUser() { return byUser != null ? byUser.get() : byUser_base(); } final public String byUser_fallback(IF0 _f) { return _f != null ? _f.get() : byUser_base(); } public String byUser_base() { return ""; } final public Collection openProjects() { return getLoadedDBs(); } public Collection getLoadedDBs() { return masterStuff().openProjects(); } public List listInOpenProjects(Class type) { return concatMap(openProjects(), db -> db.g22utils().list(type)); } transient public PicturesByMD5 picturesByMD5_cache; public PicturesByMD5 picturesByMD5() { if (picturesByMD5_cache == null) picturesByMD5_cache = picturesByMD5_load(); return picturesByMD5_cache; } public PicturesByMD5 picturesByMD5_load() { return new PicturesByMD5(projectFile("Images")).extension(".qoi"); } public JButton reloadButton(String toolTip, Runnable action) { return jimageButton("#1101440", toolTip, action); } public void registerConcept(Concept c) { loadableUtils.utils.registerConcept(concepts, c); } public void registerConcept(Concepts cc, Concept c) { loadableUtils.utils.registerConcept(cc, c); } public void addingAdditionalAutoCompletes(LeftArrowScriptAutoCompleter autoCompleter) { String token = autoCompleter.prevToken(); if (isIdentifier(token) && contains(token, "ProjectVar")) autoCompleter.addToSearcher(quoteAll(projectVarNames())); autoCompleter.addToSearcher(keys(projectWideClassDefs())); } public boolean addLibrary(String library) { if (!loadableUtils.utils.addLibrary(library)) return false; print("Loaded library: " + library); masterStuff().newClassesDefined(); return true; } public boolean addLibrary(File library) { if (!loadableUtils.utils.addLibrary(library)) return false; print("Loaded library: " + library); masterStuff().newClassesDefined(); return true; } public WrappedCloseable addResource(A resource) { if (resource == null) return null; autoClosingResources.add(resource); return new WrappedCloseable<>(resource) { @Override public void beforeClose() { autoClosingResources.remove(resource); } }; } public Object callFunctionFromScript(int scriptID, String functionName, Object... args) { return callFunctionFromScript((long) scriptID, functionName, args); } public Object callLatestFunctionFromScript(int scriptID, String functionName, Object... args) { var function = getScript(scriptID).latestCompileResult().get().getFunction(functionName); return function.callFromOutside(args); } public Object callSavedFunctionFromScript(int scriptID, String functionName, Object... args) { var function = getScript(scriptID).compileSaved().get().getFunction(functionName); return function.callFromOutside(args); } public Object callFunctionFromScript(long scriptID, String functionName, Object... args) { var function = getScript(scriptID).safestCompileResult().get().getFunction(functionName); return function.callFromOutside(args); } public JComponent visualizeAutoRunnableScript(long scriptID) { return visualizeAutoRunnableScript(getScript(scriptID)); } public JComponent visualizeAutoRunnableScript(G22LeftArrowScript script) { if (script == null) return null; if (!script.isClearForAutoRun()) return jcenteredlabel("Script not clear for auto-run"); try { Object result = script.evaluateAutoRunWithoutTimeout(); var objVisualizer = new G22JavaObjectVisualizer(this, result).withType(false); return objVisualizer.visualize(); } catch (Throwable e) { printStackTrace(e); return jErrorView(e); } } public void importProjectFromZip(File zipFile, String baseDirInZip, String projectName) { File dir = dirOfProjectNamed(projectName); if (isConceptsDir(dir)) { if (eqic(projectName(), "Default")) { infoMessage("Sorry dude"); return; } IG22LoadedDB defaultDB = masterStuff().getLoadedDBForConceptDir(dirOfProjectNamed("Default")); IG22LoadedDB preloadedDefaultDB = defaultDB; if (defaultDB == null) defaultDB = openDB("Default"); project().closeProject(); defaultDB.g22utils().importProjectFromZip(zipFile, baseDirInZip, projectName); if (preloadedDefaultDB == null) defaultDB.projectActions().closeProject(); return; } if (!directoryIsEmpty(dir)) { if (confirmProjectReplacements && !swingConfirm("Archive and overwrite existing project " + projectName + "?")) return; File archiveDir = javaxBackupDir("Gazelle/" + projectName + "-" + computerID() + "-" + ymdMinusHMS()); moveFile(dir, archiveDir); infoMessage("Archived project to: " + archiveDir); } zip2dir(zipFile, empty(baseDirInZip) ? dir : dir.getParentFile()); infoBox("Imported project " + projectName); masterStuff().openDB(projectName); } public void importProjectFromZip(File zipFile) { String baseDir = baseDirInZip(zipFile); String projectName = takeFirst(baseDir, smartIndexOf(baseDir, '/')); if (empty(projectName)) { { inputText("Please enter name for imported project", name -> { if (!validFileName(name)) { infoBox("Invalid name, use simpler characters"); importProjectFromZip(zipFile); return; } importProjectFromZip(zipFile, "", name); }); return; } } assertValidFileName(projectName); importProjectFromZip(zipFile, baseDir, projectName); } public Class export(Class c) { if (c != null) { projectWideClassDefs.put(dropHashFromClassName(shortClassName(c)), c); newFunctionsDefined(); } return c; } final public GazelleV_LeftArrowScript.FunctionDef export(GazelleV_LeftArrowScript.FunctionDef def) { return exportFunction(def); } public GazelleV_LeftArrowScript.FunctionDef exportFunction(GazelleV_LeftArrowScript.FunctionDef def) { return def == null ? null : exportFunction(def.name, def); } final public GazelleV_LeftArrowScript.FunctionDef export(String name, GazelleV_LeftArrowScript.FunctionDef def) { return exportFunction(name, def); } public GazelleV_LeftArrowScript.FunctionDef exportFunction(String name, GazelleV_LeftArrowScript.FunctionDef def) { projectWideFunctionDefs.put(name, def); newFunctionsDefined(); return def; } final public GazelleV_LeftArrowScript.FunctionDef unexport(String name) { return unexportFunction(name); } public GazelleV_LeftArrowScript.FunctionDef unexportFunction(String name) { GazelleV_LeftArrowScript.FunctionDef f = projectWideFunctionDefs.remove(name); if (f != null) { print("Undefined function " + name); newFunctionsDefined(); } return f; } public void newFunctionsDefined() { masterStuff().newClassesDefined(); recompileDate = tsNow(); } public boolean shouldRecompile(LASCompileResult cr) { return recompileDate != null && cr.compilationStart() != null && cr.compilationStart().compareTo(recompileDate) < 0; } public boolean compileResultValid(LASCompileResult cr, String code) { return cr != null && eq(cr.script, code) && !shouldRecompile(cr); } public String toString() { return "G22Utils for " + projectName(); } public void editScript(G22LeftArrowScript script) { projectActions().editScript(script); } public JButton editButton(String toolTip, Runnable action) { return jimageButtonScaledToWidth(16, "#1103068", toolTip, action); } public JButton editScriptButton(G22LeftArrowScript script) { return editButton("Edit script", () -> projectActions().editScript(script)); } public G22ScriptView scriptView(long scriptID) { return new G22ScriptView(getScript(scriptID)); } public File gazelleJar() { return getBytecodePathForClass(this); } public List projectErrors() { return projectActions().projectErrors(); } public JComponent jErrorView(Throwable e) { var view = loadableUtils.utils.jErrorView(e); var scriptErrors = instancesOf(GazelleV_LeftArrowScript.ScriptError.class, allCausesIncludingSelf(e)); var sources = mapNotNulls(scriptErrors, __11 -> __11.tokenRangeWithSrc()); if (empty(sources)) return view; sources = uniquifySources(sources); return centerAndEastWithMargin(view, jline(map(sources, src -> jThreadedButton(str_shorten(src, 40), () -> projectActions().goToSource(src))))); } public List uniquifySources(List sources) { return uniquifyWith(sources, src -> pair(src.sourceInfo, src.renderRange())); } public structure_Data makeStructureData() { return concepts().makeStructureData(); } public String g22struct(Object o) { return struct(o, makeStructureData()); } public Object g22unstruct(String struct) { return unstructure(struct, classFinder()); } } static public class JG22ProjectSelector implements Swingable, IFieldsToList { public G22Utils g22utils; public JG22ProjectSelector() { } public JG22ProjectSelector(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } transient public JLabel lblDB; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { lblDB = toolTip("Currently selected project (" + f2s(g22utils.projectDir()) + ")", (jSimpleLabel(fileName(g22utils.projectDir())))); onClick(lblDB, evt -> new PopupMenuMaker(evt, menu -> { addMenuItem(menu, "New project...", runnableThread(new Runnable() { public void run() { try { g22utils.projectActions().databasesPanel().newDatabase(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.projectActions().databasesPanel().newDatabase()"; } })); addMenuItem(menu, "Projects...", runnableThread(new Runnable() { public void run() { try { g22utils.showUIURL("Projects"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.showUIURL(\"Projects\")"; } })); List recent = takeFirst(10, g22utils.dbNamesRecentlyOpened()); for (IG22LoadedDB otherDB : g22utils.masterStuff().openProjects()) { String name = otherDB.g22utils().projectName(); if (g22utils != otherDB.g22utils()) { String status = otherDB.hidden() ? "Hidden" : "Open"; addMenuItem(menu, name + " [" + status + "]", runnableThread(new Runnable() { public void run() { try { otherDB.activate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "otherDB.activate()"; } })); } removeAll(recent, name, "*" + name); } for (var name : recent) { String name2 = dropStarPrefix(name); File otherDB = newFile(g22utils.databasesMotherDir(), name2); if (isDirectory(otherDB)) addMenuItem(menu, name2, runnableThread(new Runnable() { public void run() { try { g22utils.masterStuff().openDatabase(otherDB, neq(name, name2)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.masterStuff().openDatabase(otherDB, neq(name, name2))"; } })); } }).run()); return lblDB; } } static public class G22_RegionToSSIs_v2 extends Meta implements IFieldsToList { public IImageRegion region; public G22_RegionToSSIs_v2() { } public G22_RegionToSSIs_v2(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } public Color color; public List ssis; public List growingSSIs = new ArrayList(); final public G22_RegionToSSIs_v2 setWithDiagonals(boolean withDiagonals) { return withDiagonals(withDiagonals); } public G22_RegionToSSIs_v2 withDiagonals(boolean withDiagonals) { this.withDiagonals = withDiagonals; return this; } final public boolean getWithDiagonals() { return withDiagonals(); } public boolean withDiagonals() { return withDiagonals; } public boolean withDiagonals = false; final public G22_RegionToSSIs_v2 setCheckCoherence(boolean checkCoherence) { return checkCoherence(checkCoherence); } public G22_RegionToSSIs_v2 checkCoherence(boolean checkCoherence) { this.checkCoherence = checkCoherence; return this; } final public boolean getCheckCoherence() { return checkCoherence(); } public boolean checkCoherence() { return checkCoherence; } public boolean checkCoherence = true; final public G22_RegionToSSIs_v2 setCheckStreaks(boolean checkStreaks) { return checkStreaks(checkStreaks); } public G22_RegionToSSIs_v2 checkStreaks(boolean checkStreaks) { this.checkStreaks = checkStreaks; return this; } final public boolean getCheckStreaks() { return checkStreaks(); } public boolean checkStreaks() { return checkStreaks; } public boolean checkStreaks = true; public int x1, y; public class GrowingSSI { final public GrowingSSI setY1(int y1) { return y1(y1); } public GrowingSSI y1(int y1) { this.y1 = y1; return this; } final public int getY1() { return y1(); } public int y1() { return y1; } public int y1; public ShortBuffer data = new ShortBuffer(); public int y2() { return y1 + l(data) / 2; } public SSI finish() { return addAndReturn(ssis, new SSI(y1, y2()).data(data.toArray()).color(color)); } public boolean isEmpty() { return data.isEmpty(); } public int lastx1() { return data.get(l(data) - 2); } public int lastx2() { return data.get(l(data) - 1); } public IntRange lastRange() { return isEmpty() ? null : intRange(lastx1(), lastx2()); } public boolean canAdd(IntRange r) { return isEmpty() || intRangesOverlapNempty(r.start, r.end, lastx1() - diag(), lastx2() + diag()); } public void add(IntRange r) { if (checkCoherence() && !canAdd(r)) throw fail("Coherence fail", "lastx1", lastx1(), "lastx2", lastx2(), "r", r); data.add(toShort_enforce(r.start)); data.add(toShort_enforce(r.end)); } } public void finishSSI(int iSSI) { growingSSIs.remove(iSSI).finish(); } private GrowingSSI startSSI(IntRange range) { return startSSI(l(growingSSIs), range); } private GrowingSSI startSSI(int iSSI, IntRange range) { if (scaffoldingEnabled()) printVars("startSSI", "iSSI", iSSI, "range", range); var ssi = new GrowingSSI().y1(y); ssi.add(range); return addAndReturn(growingSSIs, iSSI, ssi); } public List lastStreaks() { return reallyLazyMap(growingSSIs, __1 -> __1.lastRange()); } public int diag() { return withDiagonals ? 1 : 0; } public List get() { if (region == null) return null; color = region.color(); ssis = new ArrayList(); Rect r = region.bounds(); int x1 = this.x1 = r.x1(), y1 = r.y1(), y2 = r.y2(), h = y2 - y1, w = r.w; boolean scaff = scaffoldingEnabled(); for (y = y1; y < y2; y++) { var _y_2 = y; List streaks = shiftIntRanges(x1, genericStreaks(w, x -> region.contains(x1 + x, _y_2))); var lastStreaks = lastStreaks(); if (checkStreaks()) assertProperStreaks(lastStreaks); int iStreak = 0, iSSI = 0; int nStreaks = l(streaks); if (scaff) printVars("y", _y_2, "lastStreaks", lastStreaks, "streaks", streaks); while (iStreak < nStreaks) { ping(); var range = streaks.get(iStreak); var ssi = _get(growingSSIs, iSSI); if (scaff) printVars("y", _y_2, "iStreak", iStreak, "iSSI", iSSI, "range", range, "ssi", ssi == null ? null : ssi.lastRange()); if (ssi == null || range.end <= ssi.lastx1() - diag()) { startSSI(iSSI++, range); ++iStreak; continue; } if (range.start >= ssi.lastx2() + diag()) { finishSSI(iSSI); continue; } int jStreak = iStreak + 1; while (jStreak < nStreaks && ssi.canAdd(streaks.get(jStreak))) ++jStreak; int jSSI = iSSI + 1; while (jSSI < l(growingSSIs) && growingSSIs.get(jSSI).canAdd(range)) ++jSSI; int nSSI = jSSI - iSSI, nStreak = jStreak - iStreak; if (scaff) printVars("nSSI", nSSI, "nStreak", nStreak); Best best = new Best(); if (nSSI > 1) { if (nStreak > 1) throw fail("ANOMALY", "nSSI", nSSI, "nStreak", nStreak, "ssis", subList(lastStreaks(), iSSI, jSSI), "streaks", subList(streaks, iStreak, jStreak)); for (int idx = iSSI; idx < jSSI; idx++) best.put(idx, l(growingSSIs.get(idx).lastRange())); jSSI = best.get(); while (jSSI-- > iSSI) finishSSI(iSSI); } else if (nStreak > 1) { for (int idx = iStreak; idx < jStreak; idx++) best.put(idx, l(streaks.get(idx))); jStreak = best.get(); while (iStreak < jStreak) startSSI(iSSI++, streaks.get(iStreak++)); } growingSSIs.get(iSSI++).add(streaks.get(iStreak++)); } while (iSSI < l(growingSSIs)) finishSSI(iSSI); } for (var ssi : cloneAndClear(growingSSIs)) ssi.finish(); return ssis; } } static public class G22CandleBasedStrategyWithJuicer extends G22CandleBasedStrategy { public class Position extends G22TradingStrategy.Position { public Position() { } final public Position setJuicer(AbstractJuicer juicer) { return juicer(juicer); } public Position juicer(AbstractJuicer juicer) { this.juicer = juicer; return this; } final public AbstractJuicer getJuicer() { return juicer(); } public AbstractJuicer juicer() { return juicer; } public AbstractJuicer juicer; } static public class ProfitBeforeLeverageJuiceable implements Juiceable, IFieldsToList { public Position p; public ProfitBeforeLeverageJuiceable() { } public ProfitBeforeLeverageJuiceable(Position p) { this.p = p; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + p + ")"; } public boolean equals(Object o) { if (!(o instanceof ProfitBeforeLeverageJuiceable)) return false; ProfitBeforeLeverageJuiceable __98 = (ProfitBeforeLeverageJuiceable) o; return eq(p, __98.p); } public int hashCode() { int h = -1988713406; h = boostHashCombine(h, _hashCode(p)); return h; } public Object[] _fieldsToList() { return new Object[] { p }; } public double juiceValue() { return p.profitBeforeLeverage(); } } public void juiceStrategy_price(double price) { if (currentPrice == price) return; currentPrice = price; AutoCloseable __96 = tempAfterwards(new Runnable() { public void run() { try { change(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "change();"; } }); try { for (var p : openPositions()) { if (((Position) p).juicer != null) { var signals = ((Position) p).juicer.calculateCloseSignals(); var strongest = highestBy(signals, s -> s.strength()); if (strongest != null && strongest.isTrigger()) { ((Position) p).close(strongest); } } } } finally { _close(__96); } } public Position openShort() { return openPosition(-1); } public Position openLong() { return openPosition(1); } public Position openPosition(int direction) { return openPosition(direction, null); } public Position openPosition(int direction, Object openReason) { Position p = new Position(); p.marginToUse = marginPerPosition; addJuicer(p); return openPosition(p, direction, openReason); } public void addJuicer(Position p) { p.juicer(makeJuicer()); p.juicer.juiceable(new ProfitBeforeLeverageJuiceable(p)); } public void recreateJuicersForExistingPositions() { for (var p : openPositions()) { addJuicer((Position) p); } } public List openPositions() { return (List) super.openPositions(); } public List allJuicers() { return map(openPositions(), __97 -> __97.juicer()); } public transient FieldVar varProfitLevel1_cache; public FieldVar varProfitLevel1() { if (varProfitLevel1_cache == null) varProfitLevel1_cache = varProfitLevel1_load(); return varProfitLevel1_cache; } public FieldVar varProfitLevel1_load() { return new FieldVar(this, "profitLevel1", () -> profitLevel1(), profitLevel1 -> profitLevel1(profitLevel1)); } final public G22CandleBasedStrategyWithJuicer setProfitLevel1(double profitLevel1) { return profitLevel1(profitLevel1); } public G22CandleBasedStrategyWithJuicer profitLevel1(double profitLevel1) { if (!eq(this.profitLevel1, profitLevel1)) { this.profitLevel1 = profitLevel1; change(); } return this; } final public double getProfitLevel1() { return profitLevel1(); } public double profitLevel1() { return profitLevel1; } public double profitLevel1 = 0.1; public transient FieldVar varKeepPercentage1_cache; public FieldVar varKeepPercentage1() { if (varKeepPercentage1_cache == null) varKeepPercentage1_cache = varKeepPercentage1_load(); return varKeepPercentage1_cache; } public FieldVar varKeepPercentage1_load() { return new FieldVar(this, "keepPercentage1", () -> keepPercentage1(), keepPercentage1 -> keepPercentage1(keepPercentage1)); } final public G22CandleBasedStrategyWithJuicer setKeepPercentage1(double keepPercentage1) { return keepPercentage1(keepPercentage1); } public G22CandleBasedStrategyWithJuicer keepPercentage1(double keepPercentage1) { if (!eq(this.keepPercentage1, keepPercentage1)) { this.keepPercentage1 = keepPercentage1; change(); } return this; } final public double getKeepPercentage1() { return keepPercentage1(); } public double keepPercentage1() { return keepPercentage1; } public double keepPercentage1 = 50; public transient FieldVar varProfitLevel2_cache; public FieldVar varProfitLevel2() { if (varProfitLevel2_cache == null) varProfitLevel2_cache = varProfitLevel2_load(); return varProfitLevel2_cache; } public FieldVar varProfitLevel2_load() { return new FieldVar(this, "profitLevel2", () -> profitLevel2(), profitLevel2 -> profitLevel2(profitLevel2)); } final public G22CandleBasedStrategyWithJuicer setProfitLevel2(double profitLevel2) { return profitLevel2(profitLevel2); } public G22CandleBasedStrategyWithJuicer profitLevel2(double profitLevel2) { if (!eq(this.profitLevel2, profitLevel2)) { this.profitLevel2 = profitLevel2; change(); } return this; } final public double getProfitLevel2() { return profitLevel2(); } public double profitLevel2() { return profitLevel2; } public double profitLevel2; public transient FieldVar varKeepPercentage2_cache; public FieldVar varKeepPercentage2() { if (varKeepPercentage2_cache == null) varKeepPercentage2_cache = varKeepPercentage2_load(); return varKeepPercentage2_cache; } public FieldVar varKeepPercentage2_load() { return new FieldVar(this, "keepPercentage2", () -> keepPercentage2(), keepPercentage2 -> keepPercentage2(keepPercentage2)); } final public G22CandleBasedStrategyWithJuicer setKeepPercentage2(double keepPercentage2) { return keepPercentage2(keepPercentage2); } public G22CandleBasedStrategyWithJuicer keepPercentage2(double keepPercentage2) { if (!eq(this.keepPercentage2, keepPercentage2)) { this.keepPercentage2 = keepPercentage2; change(); } return this; } final public double getKeepPercentage2() { return keepPercentage2(); } public double keepPercentage2() { return keepPercentage2; } public double keepPercentage2; public transient FieldVar varProfitLevel3_cache; public FieldVar varProfitLevel3() { if (varProfitLevel3_cache == null) varProfitLevel3_cache = varProfitLevel3_load(); return varProfitLevel3_cache; } public FieldVar varProfitLevel3_load() { return new FieldVar(this, "profitLevel3", () -> profitLevel3(), profitLevel3 -> profitLevel3(profitLevel3)); } final public G22CandleBasedStrategyWithJuicer setProfitLevel3(double profitLevel3) { return profitLevel3(profitLevel3); } public G22CandleBasedStrategyWithJuicer profitLevel3(double profitLevel3) { if (!eq(this.profitLevel3, profitLevel3)) { this.profitLevel3 = profitLevel3; change(); } return this; } final public double getProfitLevel3() { return profitLevel3(); } public double profitLevel3() { return profitLevel3; } public double profitLevel3; public transient FieldVar varKeepPercentage3_cache; public FieldVar varKeepPercentage3() { if (varKeepPercentage3_cache == null) varKeepPercentage3_cache = varKeepPercentage3_load(); return varKeepPercentage3_cache; } public FieldVar varKeepPercentage3_load() { return new FieldVar(this, "keepPercentage3", () -> keepPercentage3(), keepPercentage3 -> keepPercentage3(keepPercentage3)); } final public G22CandleBasedStrategyWithJuicer setKeepPercentage3(double keepPercentage3) { return keepPercentage3(keepPercentage3); } public G22CandleBasedStrategyWithJuicer keepPercentage3(double keepPercentage3) { if (!eq(this.keepPercentage3, keepPercentage3)) { this.keepPercentage3 = keepPercentage3; change(); } return this; } final public double getKeepPercentage3() { return keepPercentage3(); } public double keepPercentage3() { return keepPercentage3; } public double keepPercentage3; public transient FieldVar varMaxLoss_cache; public FieldVar varMaxLoss() { if (varMaxLoss_cache == null) varMaxLoss_cache = varMaxLoss_load(); return varMaxLoss_cache; } public FieldVar varMaxLoss_load() { return new FieldVar(this, "maxLoss", () -> maxLoss(), maxLoss -> maxLoss(maxLoss)); } final public G22CandleBasedStrategyWithJuicer setMaxLoss(double maxLoss) { return maxLoss(maxLoss); } public G22CandleBasedStrategyWithJuicer maxLoss(double maxLoss) { if (!eq(this.maxLoss, maxLoss)) { this.maxLoss = maxLoss; change(); } return this; } final public double getMaxLoss() { return maxLoss(); } public double maxLoss() { return maxLoss; } public double maxLoss = 0.5; transient public IF0 makeJuicer; public MultiPullbackJuicer makeJuicer() { return makeJuicer != null ? makeJuicer.get() : makeJuicer_base(); } final public MultiPullbackJuicer makeJuicer_fallback(IF0 _f) { return _f != null ? _f.get() : makeJuicer_base(); } public MultiPullbackJuicer makeJuicer_base() { MultiPullbackJuicer j = new MultiPullbackJuicer(); j.stopLossLimit(-maxLoss); j.stopLossEnabled(true); for (int i = 1; i <= 3; i++) { double profitLevel = toDouble(get(this, "profitLevel" + i)); double keepPercentage = toDouble(get(this, "keepPercentage" + i)); if (profitLevel != 0 || keepPercentage != 0) j.addLevel(profitLevel, keepPercentage); } return j; } public void price(double price) { juiceStrategy_price(price); super.price(price); } } static public class JCalculatedComponent extends SingleComponentPanel implements ChangeTriggerable { final public JCalculatedComponent setMakeComponent(IF0 makeComponent) { return makeComponent(makeComponent); } public JCalculatedComponent makeComponent(IF0 makeComponent) { this.makeComponent = makeComponent; return this; } final public IF0 getMakeComponent() { return makeComponent(); } public IF0 makeComponent() { return makeComponent; } public IF0 makeComponent; public JCalculatedComponent(IF0 makeComponent) { this.makeComponent = makeComponent; } transient public ReliableSingleThread rstMakeComponent = new ReliableSingleThread(() -> { setComponent(makeComponent == null ? null : makeComponent.get()); }); { bindToComponent(this, () -> { rstMakeComponent.trigger(); }, null); } public void change() { rstMakeComponent.trigger(); } public void reactToChangesIn(IHasChangeListeners source) { bindHasChangeListenersToComponent(this, source, () -> change()); } } static public class G22AnalysisContext implements IFieldsToList { public G22Utils g22utils; public BufferedImage image; public G22AnalysisContext() { } public G22AnalysisContext(G22Utils g22utils, BufferedImage image) { this.image = image; this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ", " + image + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils, image }; } public SourceTriggeredStream imageStream; public Map analyzerResults = syncMap(); static public Object calculating; public G22AnalysisContext(G22Utils g22utils, SourceTriggeredStream imageStream) { this.imageStream = imageStream; this.g22utils = g22utils; } public Object callAnalyzer(long analyzerID) { var analyzer = getConcept(g22utils.concepts(), G22Analyzer.class, analyzerID); if (analyzer == null) throw fail("Analyzer with ID " + analyzerID + " not found"); return callAnalyzer(analyzer); } public Object callAnalyzer(G22Analyzer analyzer) { return analyzer.compileForAutoRun().get(this); } } static public class TradingCandlePainter extends AbstractTickerPainter implements IToolTipMaker { final public TradingCandlePainter setCandles(List candles) { return candles(candles); } public TradingCandlePainter candles(List candles) { this.candles = candles; return this; } final public List getCandles() { return candles(); } public List candles() { return candles; } public List candles; public int spikeWidth = 1; public Color shortColor = java.awt.Color.blue; public Color longColor = java.awt.Color.yellow; public void drawOn(Graphics2D g) { if (empty(candles)) return; var run = new TradingRun(candles); verticalRange(doubleRange(run.min(), run.max())); horizontalRange(doubleRange(run.startTime().unixDate(), run.endTime().unixDate())); drawPercentLines(g); drawAdditionalObjects(g); var nCandles = l(candles); for (int i = 0; i < nCandles; i++) { var candle = candles.get(i); var x1 = xRange().start() + doubleRatio(i, nCandles) * xRange().length(); var x2 = xRange().start() + doubleRatio(i + 1, nCandles) * xRange().length(); x2 = blend(x1, x2, 0.75); var xCenter = avg(x1, x2); var y1 = yToScreen(candle.max()); var y2 = yToScreen(candle.min()); var yStart = yToScreen(candle.start()); var yEnd = yToScreen(candle.end()); var r = doubleRectFromPoints(xCenter, y1, xCenter + spikeWidth, y2); fillRect(g, growRectBottom(1, toRect_round(r)), candle.color()); r = doubleRectFromPoints(x1, min(yStart, yEnd), x2, max(yStart, yEnd)); fillRect(g, growRectBottom(1, toRect_round(r)), candle.color()); } drawPositions(g); } public BufferedImage render() { var img = super.render(); var img2 = cloneBufferedImageWithMeta(img); metaSet(img2, IToolTipMaker.class, this); return img2; } public transient IF1 getToolTip; public String getToolTip(Pt p) { return getToolTip != null ? getToolTip.get(p) : getToolTip_base(p); } final public String getToolTip_fallback(IF1 _f, Pt p) { return _f != null ? _f.get(p) : getToolTip_base(p); } public String getToolTip_base(Pt p) { if (!hasScale()) return "No candles yet"; double time = xFromScreen(p.x); TradingCandle candle = firstThat(candles, c -> c.startTime().unixDate() >= time); if (candle == null) return formatLocalDateWithSeconds(lround(time)); return str(candle); } public TradingCandlePainter candles(TradingCandleMaker candleMaker) { return candles(candleMaker.get()); } } static public class MultiSleeper extends RestartableCountdown implements ISleeper_v2 { public MultiSetMap entries = treeMultiSetMap(); public void check() { var time = nextWakeUpTime(); var action = firstValue(entries); setTargetTime(time == null ? 0 : time.sysTime(), new Runnable() { public void run() { try { Set toCall; synchronized (MultiSleeper.this) { toCall = entries.get(time); entries.remove(time); check(); } pcallFAll(toCall); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Set toCall;\r\n synchronized(MultiSleeper.this) {\r\n toCal..."; } }); } synchronized public void removeEntry(Timestamp targetTime, Runnable action) { entries.remove(targetTime, action); } synchronized public Timestamp nextWakeUpTime() { return firstKey(entries); } public synchronized Sleeping doLater(Timestamp targetTime, Runnable r) { if (r == null || targetTime == null) return null; targetTime = max(targetTime, tsNow()); entries.put(targetTime, r); check(); return new Sleeping(targetTime, r) { public void close() { try { removeEntry(targetTime, r); } catch (Exception __e) { throw rethrow(__e); } } }; } } static public class G22DBFileBrowser { public G22Utils g22utils; public File dir; public JObjectTable table; public ReliableSingleThread rstUpdate = rstWithPreDelay(0.5, new Runnable() { public void run() { try { _updateTable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_updateTable();"; } }); public G22DBFileBrowser(G22Utils g22utils) { this.g22utils = g22utils; dir = g22utils.concepts.conceptsDir(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { table = swing(() -> new JObjectTable()); table.itemToMap = file -> litorderedmap("File / Directory", nameRelativeToPhysicalSubdirectory(file, dir), "Size", file.isDirectory() ? "Directory" : str_toK(fileSize(file))); var tbl = table.visualize(); IVF1 fileListener = file -> rstUpdate.get(); bindToComponent(tbl, () -> { g22utils.onProjectFileChanged(fileListener); rstUpdate.get(); }, () -> g22utils.removeProjectFileChangedListener(fileListener)); return withTopAndBottomMargin(jCenteredRaisedSection("Files in Project", northAndCenterWithMargins(withLabel("Project directory:", swing(() -> new JFilePathLabel(dir).visualize())), tbl))); } public void _updateTable() { table.setData_force(findAllFiles(dir)); } } static public class G22ShowCasePanel implements Swingable, IFieldsToList { public G22Utils g22utils; public G22ShowCasePanel() { } public G22ShowCasePanel(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } transient public SingleComponentPanel scpShowCase; transient public ReliableSingleThread rstUpdateShowCase = rst(() -> updateShowCase()); public void updateShowCase() { if (!isShowing(scpShowCase)) return; var autoStarter = g22utils.autoStarter(); if (autoStarter.cancelled()) { scpShowCase.set(jcenteredlabel("Auto-start cancelled")); return; } if (!autoStarter.waitedAndDone()) return; var script = varShowCasedScript().get(); if (script == null) { scpShowCase.set(g22utils.jGazelleLogo()); return; } scpShowCase.set(g22utils.visualizeAutoRunnableScript(script)); } public IVarWithNotify varShowCasedScript() { return g22utils.projectActions().varShowCasedScript(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { g22utils.autoStarter().onDone(rstUpdateShowCase); scpShowCase = singleComponentPanel(varShowCasedScript().get() == null ? null : jcenteredlabel("Waiting for auto-start to finish...")); onChange(varShowCasedScript(), rstUpdateShowCase); bindToComponent(scpShowCase, rstUpdateShowCase); return northAndCenterWithMargin(centerAndEastWithMargin(withSideMargins(withLabel("Script:", bindComboBoxToVar(varShowCasedScript(), swing(() -> centerComboBoxAndItems(new ConceptsComboBox<>(g22utils.concepts(), G22LeftArrowScript.class).allowNull(true).itemFilter(script -> classIs(G22LeftArrowScript.class, script) && script.isClearForAutoRun()).sorter(l -> sortedByFieldAlphanumIC("description", l))))))), jline(jimageButton("#1101440", "Re-run script", rstUpdateShowCase), jimageButtonScaledToWidth(16, "#1103068", "Edit script", () -> g22utils.projectActions().editScript(varShowCasedScript().get())))), scpShowCase); } } static public class G22HashedMasks implements IG22SimpleMasksHolder { public G22HashedMasks() { } public class Mask implements IG22Mask, IFieldsToList { public Image2B image; public Mask() { } public Mask(Image2B image) { this.image = image; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + image + ")"; } public Object[] _fieldsToList() { return new Object[] { image }; } final public Mask setLabel(A label) { return label(label); } public Mask label(A label) { this.label = label; return this; } final public A getLabel() { return label(); } public A label() { return label; } public A label; public int hash; public boolean equals(Object o) { if (o instanceof G22HashedMasks.Mask) return hashCode() == ((G22HashedMasks.Mask) o).hashCode() && binaryImagesIdentical(image, ((G22HashedMasks.Mask) o).image); return false; } public int hashCode() { if (hash == 0) hash = (int) hashImage2B(image); return hash; } public Image2B image() { return image; } } public CompactHashSet masks = new CompactHashSet(); public G22HashedMasks(List> masks) { assertNempty(masks); maskSize(imageSize(first(masks).image())); for (var mask : unnullForIteration(masks)) this.masks.add(mask); } public G22HashedMasks(List> masks, G22GhostImage ghost) { this(masks); ghost_cache = ghost; } public void addRegion(IImageRegion region, A label) { addMask(regionToMaskImage(region), label); } public void addMask(IBinaryImage maskImage) { addMask(maskImage, null); } public void addMask(IBinaryImage maskImage, A label) { var mask = new Mask(toImage2B(maskImage)); var existingMask = masks.find(mask); if (existingMask != null) { mask = existingMask; mask.label = combineLabels(mask.label, label); } else { mask.label = label; masks.add(mask); } ghost_cache = null; certainty_cache = null; } public List masks() { return asList(masks); } public A combineLabels(A label1, A label2) { if (eq(label1, label2)) return label1; if (label1 == null) return label2; if (label2 == null) return label1; return specialCombineLabels(label1, label2); } transient public IF2 specialCombineLabels; public A specialCombineLabels(A label1, A label2) { return specialCombineLabels != null ? specialCombineLabels.get(label1, label2) : specialCombineLabels_base(label1, label2); } final public A specialCombineLabels_fallback(IF2 _f, A label1, A label2) { return _f != null ? _f.get(label1, label2) : specialCombineLabels_base(label1, label2); } public A specialCombineLabels_base(A label1, A label2) { throw fail("Can't combine labels: " + label1 + " + " + label2); } public IG22MasksHolder cloneTreeWithLabelTransform(IF1 f) { G22HashedMasks clone = new G22HashedMasks(); for (var mask : masks) { G22HashedMasks.Mask clonedMask = clone.new Mask(); clonedMask.image = mask.image; clonedMask.hash = mask.hash; clonedMask.label = f.get(mask.label); clone.masks.add(clonedMask); } return clone; } final public G22HashedMasks setMaskSize(WidthAndHeight maskSize) { return maskSize(maskSize); } public G22HashedMasks maskSize(WidthAndHeight maskSize) { this.maskSize = maskSize; return this; } final public WidthAndHeight getMaskSize() { return maskSize(); } public WidthAndHeight maskSize() { return maskSize; } public WidthAndHeight maskSize; { maskSize(g22defaultMaskSideLength()); } public G22HashedMasks maskSize(int size) { return maskSize(widthAndHeight(size)); } public Image2B regionToMaskImage(IImageRegion region) { return g22standardRegionToMaskImage(region, maskSize()); } public List maskImages() { return map(masks(), mask -> mask.image()); } public BufferedImage masksSquare() { return mergeBufferedImagesAsSquare(allToBufferedImage(maskImages())); } public PatchworkImage masksPatchworkSquare() { return patchworkImagesAsSquare(map(masks(), mask -> pair(toBufferedImage(mask.image()), mask))); } public String toString() { return renderVars(shortClassName(this), "maskSize", maskSize, "masks", n2(masks())); } public G22GhostImage ghost_cache; public G22GhostImage ghost() { if (ghost_cache == null) ghost_cache = ghost_load(); return ghost_cache; } public G22GhostImage ghost_load() { return new G22GhostImage(maskImages()); } public Double certainty_cache; public double certainty() { if (certainty_cache == null) certainty_cache = certainty_load(); return certainty_cache; } public double certainty_load() { return ghost().certainty(); } } static public class SmoothedMovingAverage implements IFieldsToList { public double period; public SmoothedMovingAverage() { } public SmoothedMovingAverage(double period) { this.period = period; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + period + ")"; } public Object[] _fieldsToList() { return new Object[] { period }; } public SmoothedMovingAverage period(double period) { this.period = period; return this; } final public double getValue() { return value(); } public double value() { return value; } public double value = Double.NaN; final public long getSteps() { return steps(); } public long steps() { return steps; } public long steps; public double get() { return value; } public double add(double x) { ++steps; if (isNaN(value)) value = x; else value = blend(value, x, alpha()); return value; } public double alpha() { return reciprocal(period); } } static public class PatchworkImageSurface extends ImageSurface { public PatchworkImage patchworkImage; public PatchworkImageSurface() { } public PatchworkImageSurface(PatchworkImage patchworkImage) { this.patchworkImage = patchworkImage; setImage(patchworkImage); } } static public class G22CandleBasedStrategy extends G22TradingStrategy { public transient FieldVar varGranularity_cache; public FieldVar varGranularity() { if (varGranularity_cache == null) varGranularity_cache = varGranularity_load(); return varGranularity_cache; } public FieldVar varGranularity_load() { return new FieldVar(this, "granularity", () -> granularity(), granularity -> granularity(granularity)); } final public G22CandleBasedStrategy setGranularity(double granularity) { return granularity(granularity); } public G22CandleBasedStrategy granularity(double granularity) { if (!eq(this.granularity, granularity)) { this.granularity = granularity; change(); } return this; } final public double getGranularity() { return granularity(); } public double granularity() { return granularity; } public double granularity = 1; public transient FieldVar varCandleMaker_cache; public FieldVar varCandleMaker() { if (varCandleMaker_cache == null) varCandleMaker_cache = varCandleMaker_load(); return varCandleMaker_cache; } public FieldVar varCandleMaker_load() { return new FieldVar(this, "candleMaker", () -> candleMaker(), candleMaker -> candleMaker(candleMaker)); } final public G22CandleBasedStrategy setCandleMaker(TradingCandleMaker candleMaker) { return candleMaker(candleMaker); } public G22CandleBasedStrategy candleMaker(TradingCandleMaker candleMaker) { if (!eq(this.candleMaker, candleMaker)) { this.candleMaker = candleMaker; change(); } return this; } final public TradingCandleMaker getCandleMaker() { return candleMaker(); } public TradingCandleMaker candleMaker() { return candleMaker; } public TradingCandleMaker candleMaker; public transient FieldVar varFirstCandle_cache; public FieldVar varFirstCandle() { if (varFirstCandle_cache == null) varFirstCandle_cache = varFirstCandle_load(); return varFirstCandle_cache; } public FieldVar varFirstCandle_load() { return new FieldVar(this, "firstCandle", () -> firstCandle(), firstCandle -> firstCandle(firstCandle)); } final public G22CandleBasedStrategy setFirstCandle(TradingCandle firstCandle) { return firstCandle(firstCandle); } public G22CandleBasedStrategy firstCandle(TradingCandle firstCandle) { if (!eq(this.firstCandle, firstCandle)) { this.firstCandle = firstCandle; change(); } return this; } final public TradingCandle getFirstCandle() { return firstCandle(); } public TradingCandle firstCandle() { return firstCandle; } public TradingCandle firstCandle; public transient FieldVar varCompletedCandle_cache; public FieldVar varCompletedCandle() { if (varCompletedCandle_cache == null) varCompletedCandle_cache = varCompletedCandle_load(); return varCompletedCandle_cache; } public FieldVar varCompletedCandle_load() { return new FieldVar(this, "completedCandle", () -> completedCandle(), completedCandle -> completedCandle(completedCandle)); } final public G22CandleBasedStrategy setCompletedCandle(TradingCandle completedCandle) { return completedCandle(completedCandle); } public G22CandleBasedStrategy completedCandle(TradingCandle completedCandle) { if (!eq(this.completedCandle, completedCandle)) { this.completedCandle = completedCandle; change(); } return this; } final public TradingCandle getCompletedCandle() { return completedCandle(); } public TradingCandle completedCandle() { return completedCandle; } public TradingCandle completedCandle; transient public Set> onCandleCompleted; public G22CandleBasedStrategy onCandleCompleted(IVF1 f) { onCandleCompleted = createOrAddToSyncLinkedHashSet(onCandleCompleted, f); return this; } public G22CandleBasedStrategy removeCandleCompletedListener(IVF1 f) { loadableUtils.utils.remove(onCandleCompleted, f); return this; } public void candleCompleted(TradingCandle candle) { if (onCandleCompleted != null) for (var listener : onCandleCompleted) pcallF_typed(listener, candle); } public void feed(Iterable candles) { for (var candle : unnullForIteration(candles)) try { currentTime(candle.endTime.toLong()); completedCandle(candle); candleCompleted(candle); } finally { afterStep(); } } public void price(double price) { currentPrice = price; if (hasClosedItself()) return; try { if (candleMaker == null) candleMaker(new TradingCandleMaker().candleLength(granularity)); var completed = candleMaker.completedCandle(); candleMaker.add(price, currentTime()); var candle = candleMaker.currentCandle(); if (firstCandle == null) firstCandle(candle); else if (candle != firstCandle) { if (completed != completedCandle()) { completedCandle(completed); candleCompleted(completed); } } } finally { afterStep(); } } public void reset() { super.reset(); resetFields(this, "candleMaker firstCandle completedCandle"); } public List candles() { return candleMaker().candles(); } } static public class G22AnalysisPanel extends MetaWithChangeListeners implements Swingable, AutoCloseable { public transient FieldVar varAnalyzer_cache; public FieldVar varAnalyzer() { if (varAnalyzer_cache == null) varAnalyzer_cache = varAnalyzer_load(); return varAnalyzer_cache; } public FieldVar varAnalyzer_load() { return new FieldVar(this, "analyzer", () -> analyzer(), analyzer -> analyzer(analyzer)); } final public G22AnalysisPanel setAnalyzer(G22Analyzer analyzer) { return analyzer(analyzer); } public G22AnalysisPanel analyzer(G22Analyzer analyzer) { if (!eq(this.analyzer, analyzer)) { this.analyzer = analyzer; change(); } return this; } final public G22Analyzer getAnalyzer() { return analyzer(); } public G22Analyzer analyzer() { return analyzer; } public G22Analyzer analyzer; final public G22AnalysisPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22AnalysisPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; final public G22AnalysisPanel setImageSurface(ImageSurface imageSurface) { return imageSurface(imageSurface); } public G22AnalysisPanel imageSurface(ImageSurface imageSurface) { this.imageSurface = imageSurface; return this; } final public ImageSurface getImageSurface() { return imageSurface(); } public ImageSurface imageSurface() { return imageSurface; } transient public ImageSurface imageSurface; transient public SingleComponentPanel scp; transient public ReliableSingleThread rstStartAnalysis = new ReliableSingleThread(new Runnable() { public void run() { try { _startAnalysis(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_startAnalysis();"; } }); final public BufferedImage getImage() { return image(); } public BufferedImage image() { return image; } transient public BufferedImage image; transient public G22RunSingleAnalyzerPanel analyzerPanel; public void setImage(File image) { setImage(loadImage2(image)); } public void setImage(BufferedImage image) { this.image = image; { if (analyzerPanel != null) analyzerPanel.setImage(image); } } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { scp = singleComponentPanel(); varAnalyzer().onChangeAndNow(rstStartAnalysis); return northAndCenterWithMargins(centerAndEastWithMargin(withLabel("Analyzer", bindComboBoxToVar(varAnalyzer(), swing(() -> new ConceptsComboBox(g22utils.concepts(), G22Analyzer.class).allowNull(true)))), jline(jimageButton("#1101440", "Re-run analyzer", () -> remakeAnalyzerPanel()), jimageButtonScaledToWidth(16, "#1103068", "Edit analyzer", () -> editAnalyzer(analyzer)))), scp); } public void _startAnalysis() { var panel = optCast(G22RunSingleAnalyzerPanel.class, analyzerPanel); if (panel == null || panel.analyzer != analyzer) { analyzerPanel = new G22RunSingleAnalyzerPanel(g22utils, image, analyzer); if (imageSurface != null) { analyzerPanel.onAnalyzerResult((analyzer, result) -> { imageSurface.clearOverlays(); analyzerResultToOverlays(result); }); analyzerPanel.onAnalyzerError((analyzer, error) -> imageSurface.clearOverlays()); } scp.set(analyzerPanel); } } public void analyzerResultToOverlays(Object result) { if (result instanceof Rect) { imageSurface.addOverlay(new RenderRecognizedBox(new RectAsRecognizedBox((Rect) result))); } else if (result instanceof IImageRegion) { imageSurface.addOverlay(new RenderRecognizedBox(new RecognizedRegion((IImageRegion) result))); } } public void remakeAnalyzerPanel() { analyzerPanel = null; { startThread(new Runnable() { public void run() { try { _startAnalysis(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_startAnalysis();"; } }); } } public void close() { try { } catch (Exception __e) { throw rethrow(__e); } } transient public IVF1 editAnalyzer; public void editAnalyzer(G22Analyzer analyzer) { if (editAnalyzer != null) editAnalyzer.get(analyzer); else editAnalyzer_base(analyzer); } final public void editAnalyzer_fallback(IVF1 _f, G22Analyzer analyzer) { if (_f != null) _f.get(analyzer); else editAnalyzer_base(analyzer); } public void editAnalyzer_base(G22Analyzer analyzer) { } } static public class JuiceStrategy1 extends JuiceStrategy { public transient FieldVar varProfitLevel1_cache; public FieldVar varProfitLevel1() { if (varProfitLevel1_cache == null) varProfitLevel1_cache = varProfitLevel1_load(); return varProfitLevel1_cache; } public FieldVar varProfitLevel1_load() { return new FieldVar(this, "profitLevel1", () -> profitLevel1(), profitLevel1 -> profitLevel1(profitLevel1)); } final public JuiceStrategy1 setProfitLevel1(double profitLevel1) { return profitLevel1(profitLevel1); } public JuiceStrategy1 profitLevel1(double profitLevel1) { if (!eq(this.profitLevel1, profitLevel1)) { this.profitLevel1 = profitLevel1; change(); } return this; } final public double getProfitLevel1() { return profitLevel1(); } public double profitLevel1() { return profitLevel1; } public double profitLevel1 = 0.1; public transient FieldVar varKeepPercentage1_cache; public FieldVar varKeepPercentage1() { if (varKeepPercentage1_cache == null) varKeepPercentage1_cache = varKeepPercentage1_load(); return varKeepPercentage1_cache; } public FieldVar varKeepPercentage1_load() { return new FieldVar(this, "keepPercentage1", () -> keepPercentage1(), keepPercentage1 -> keepPercentage1(keepPercentage1)); } final public JuiceStrategy1 setKeepPercentage1(double keepPercentage1) { return keepPercentage1(keepPercentage1); } public JuiceStrategy1 keepPercentage1(double keepPercentage1) { if (!eq(this.keepPercentage1, keepPercentage1)) { this.keepPercentage1 = keepPercentage1; change(); } return this; } final public double getKeepPercentage1() { return keepPercentage1(); } public double keepPercentage1() { return keepPercentage1; } public double keepPercentage1 = 50; public transient FieldVar varProfitLevel2_cache; public FieldVar varProfitLevel2() { if (varProfitLevel2_cache == null) varProfitLevel2_cache = varProfitLevel2_load(); return varProfitLevel2_cache; } public FieldVar varProfitLevel2_load() { return new FieldVar(this, "profitLevel2", () -> profitLevel2(), profitLevel2 -> profitLevel2(profitLevel2)); } final public JuiceStrategy1 setProfitLevel2(double profitLevel2) { return profitLevel2(profitLevel2); } public JuiceStrategy1 profitLevel2(double profitLevel2) { if (!eq(this.profitLevel2, profitLevel2)) { this.profitLevel2 = profitLevel2; change(); } return this; } final public double getProfitLevel2() { return profitLevel2(); } public double profitLevel2() { return profitLevel2; } public double profitLevel2; public transient FieldVar varKeepPercentage2_cache; public FieldVar varKeepPercentage2() { if (varKeepPercentage2_cache == null) varKeepPercentage2_cache = varKeepPercentage2_load(); return varKeepPercentage2_cache; } public FieldVar varKeepPercentage2_load() { return new FieldVar(this, "keepPercentage2", () -> keepPercentage2(), keepPercentage2 -> keepPercentage2(keepPercentage2)); } final public JuiceStrategy1 setKeepPercentage2(double keepPercentage2) { return keepPercentage2(keepPercentage2); } public JuiceStrategy1 keepPercentage2(double keepPercentage2) { if (!eq(this.keepPercentage2, keepPercentage2)) { this.keepPercentage2 = keepPercentage2; change(); } return this; } final public double getKeepPercentage2() { return keepPercentage2(); } public double keepPercentage2() { return keepPercentage2; } public double keepPercentage2; public transient FieldVar varProfitLevel3_cache; public FieldVar varProfitLevel3() { if (varProfitLevel3_cache == null) varProfitLevel3_cache = varProfitLevel3_load(); return varProfitLevel3_cache; } public FieldVar varProfitLevel3_load() { return new FieldVar(this, "profitLevel3", () -> profitLevel3(), profitLevel3 -> profitLevel3(profitLevel3)); } final public JuiceStrategy1 setProfitLevel3(double profitLevel3) { return profitLevel3(profitLevel3); } public JuiceStrategy1 profitLevel3(double profitLevel3) { if (!eq(this.profitLevel3, profitLevel3)) { this.profitLevel3 = profitLevel3; change(); } return this; } final public double getProfitLevel3() { return profitLevel3(); } public double profitLevel3() { return profitLevel3; } public double profitLevel3; public transient FieldVar varKeepPercentage3_cache; public FieldVar varKeepPercentage3() { if (varKeepPercentage3_cache == null) varKeepPercentage3_cache = varKeepPercentage3_load(); return varKeepPercentage3_cache; } public FieldVar varKeepPercentage3_load() { return new FieldVar(this, "keepPercentage3", () -> keepPercentage3(), keepPercentage3 -> keepPercentage3(keepPercentage3)); } final public JuiceStrategy1 setKeepPercentage3(double keepPercentage3) { return keepPercentage3(keepPercentage3); } public JuiceStrategy1 keepPercentage3(double keepPercentage3) { if (!eq(this.keepPercentage3, keepPercentage3)) { this.keepPercentage3 = keepPercentage3; change(); } return this; } final public double getKeepPercentage3() { return keepPercentage3(); } public double keepPercentage3() { return keepPercentage3; } public double keepPercentage3; public transient FieldVar varMaxLoss_cache; public FieldVar varMaxLoss() { if (varMaxLoss_cache == null) varMaxLoss_cache = varMaxLoss_load(); return varMaxLoss_cache; } public FieldVar varMaxLoss_load() { return new FieldVar(this, "maxLoss", () -> maxLoss(), maxLoss -> maxLoss(maxLoss)); } final public JuiceStrategy1 setMaxLoss(double maxLoss) { return maxLoss(maxLoss); } public JuiceStrategy1 maxLoss(double maxLoss) { if (!eq(this.maxLoss, maxLoss)) { this.maxLoss = maxLoss; change(); } return this; } final public double getMaxLoss() { return maxLoss(); } public double maxLoss() { return maxLoss; } public double maxLoss = 0.5; transient public IF0 makeJuicer; public MultiPullbackJuicer makeJuicer() { return makeJuicer != null ? makeJuicer.get() : makeJuicer_base(); } final public MultiPullbackJuicer makeJuicer_fallback(IF0 _f) { return _f != null ? _f.get() : makeJuicer_base(); } public MultiPullbackJuicer makeJuicer_base() { MultiPullbackJuicer j = new MultiPullbackJuicer(); j.stopLossLimit(-maxLoss); j.stopLossEnabled(true); for (int i = 1; i <= 3; i++) { double profitLevel = toDouble(get(this, "profitLevel" + i)); double keepPercentage = toDouble(get(this, "keepPercentage" + i)); if (profitLevel != 0 || keepPercentage != 0) j.addLevel(profitLevel, keepPercentage); } return j; } } static public class TradingCandle { final public TradingCandle setMin(double min) { return min(min); } public TradingCandle min(double min) { this.min = min; return this; } final public double getMin() { return min(); } public double min() { return min; } public double min = infinity(); final public TradingCandle setMax(double max) { return max(max); } public TradingCandle max(double max) { this.max = max; return this; } final public double getMax() { return max(); } public double max() { return max; } public double max; final public TradingCandle setStart(double start) { return start(start); } public TradingCandle start(double start) { this.start = start; return this; } final public double getStart() { return start(); } public double start() { return start; } public double start; final public TradingCandle setEnd(double end) { return end(end); } public TradingCandle end(double end) { this.end = end; return this; } final public double getEnd() { return end(); } public double end() { return end; } public double end; final public TradingCandle setStartTime(Timestamp startTime) { return startTime(startTime); } public TradingCandle startTime(Timestamp startTime) { this.startTime = startTime; return this; } final public Timestamp getStartTime() { return startTime(); } public Timestamp startTime() { return startTime; } public Timestamp startTime; final public TradingCandle setEndTime(Timestamp endTime) { return endTime(endTime); } public TradingCandle endTime(Timestamp endTime) { this.endTime = endTime; return this; } final public Timestamp getEndTime() { return endTime(); } public Timestamp endTime() { return endTime; } public Timestamp endTime; final public TradingCandle setOngoing(boolean ongoing) { return ongoing(ongoing); } public TradingCandle ongoing(boolean ongoing) { this.ongoing = ongoing; return this; } final public boolean getOngoing() { return ongoing(); } public boolean ongoing() { return ongoing; } public boolean ongoing = false; final public TradingCandle setCoin(String coin) { return coin(coin); } public TradingCandle coin(String coin) { this.coin = coin; return this; } final public String getCoin() { return coin(); } public String coin() { return coin; } public String coin; final public double startingPrice() { return openingPrice(); } final public double open() { return openingPrice(); } public double openingPrice() { return end; } final public double endPrice() { return closingPrice(); } final public double close() { return closingPrice(); } public double closingPrice() { return end; } public boolean isGreen() { return end > start; } public boolean isRed() { return end < start; } public boolean isWhite() { return end == start; } public String colorText() { return isGreen() ? "green" : isRed() ? "red" : "white"; } public double durationInSeconds() { return toSeconds(endTime.minus(startTime)); } public void addValue(double price, Timestamp timestamp) { if (price < min) min = price; if (price > max) max = price; end = price; endTime = timestamp; if (startTime == null) { startTime = timestamp; start = price; } } public String myType() { return "candle"; } public String toString() { String text = firstToUpper(colorText()) + " " + myType(); if (startTime != null) { text += " starting " + startTime + ", duration " + iround(toSeconds(endTime.minus(startTime))) + "s"; text += ", starting price " + formatPrice(start) + ", end price " + formatPrice(end); text += ", min " + formatPrice(min) + ", max " + formatPrice(max); } return text; } public double changeRatio() { return doubleRatio(end, start); } public TradingCandle clone() { return shallowClone(this); } public Color color() { return directionToCandleColor(end - start); } final public double mid() { return hl2(); } public double hl2() { return avg(min, max); } final public double move() { return delta(); } public double delta() { return end - start; } public double high() { return max; } public double low() { return min; } } static public class Supertrend extends CandleBasedIndicator { final public ATR getAtr() { return atr(); } public ATR atr() { return atr; } public ATR atr; final public Supertrend setMultiplier(double multiplier) { return multiplier(multiplier); } public Supertrend multiplier(double multiplier) { this.multiplier = multiplier; return this; } final public double getMultiplier() { return multiplier(); } public double multiplier() { return multiplier; } public double multiplier = 3; final public Supertrend setBands(DoubleRange bands) { return bands(bands); } public Supertrend bands(DoubleRange bands) { this.bands = bands; return this; } final public DoubleRange getBands() { return bands(); } public DoubleRange bands() { return bands; } public DoubleRange bands; final public Supertrend setSupertrend(double supertrend) { return supertrend(supertrend); } public Supertrend supertrend(double supertrend) { this.supertrend = supertrend; return this; } final public double getSupertrend() { return supertrend(); } public double supertrend() { return supertrend; } public double supertrend = Double.NaN; final public Supertrend setSignal(int signal) { return signal(signal); } public Supertrend signal(int signal) { this.signal = signal; return this; } final public int getSignal() { return signal(); } public int signal() { return signal; } public int signal; final public TickerSequence getUpperBandHistory() { return upperBandHistory(); } public TickerSequence upperBandHistory() { return upperBandHistory; } public TickerSequence upperBandHistory = new TickerSequence("Final upper band"); final public TickerSequence getLowerBandHistory() { return lowerBandHistory(); } public TickerSequence lowerBandHistory() { return lowerBandHistory; } public TickerSequence lowerBandHistory = new TickerSequence("Final lower band"); final public TickerSequence getBasicUpperBandHistory() { return basicUpperBandHistory(); } public TickerSequence basicUpperBandHistory() { return basicUpperBandHistory; } public TickerSequence basicUpperBandHistory = new TickerSequence("Basic upper band"); final public TickerSequence getBasicLowerBandHistory() { return basicLowerBandHistory(); } public TickerSequence basicLowerBandHistory() { return basicLowerBandHistory; } public TickerSequence basicLowerBandHistory = new TickerSequence("Basic lower band"); final public TickerSequence getSupertrendHistory() { return supertrendHistory(); } public TickerSequence supertrendHistory() { return supertrendHistory; } public TickerSequence supertrendHistory = new TickerSequence("Supertrend"); final public TickerSequence getSignalHistory() { return signalHistory(); } public TickerSequence signalHistory() { return signalHistory; } public TickerSequence signalHistory = new TickerSequence("Signal"); public int candlesNeeded() { return 2; } { length = 10; onCandleAdded(candle -> { if (atr == null) atr = new ATR(length); atr().add(candle); var atrValue = atr.get(); if (isNaN(atrValue)) return; TradingCandle prev = candles().nextToLast(); double hl2 = candle.hl2(); double basicUpperBand = hl2 + multiplier * atrValue; double basicLowerBand = hl2 - multiplier * atrValue; var previousBands = bands; double finalUpperBand = previousBands == null || basicUpperBand < previousBands.end || prev.close() > previousBands.end ? basicUpperBand : previousBands.end; double finalLowerBand = previousBands == null || basicLowerBand > previousBands.start || prev.close() < previousBands.start ? basicLowerBand : previousBands.start; if (previousBands == null || supertrend == previousBands.end) supertrend(candle.close() < finalUpperBand ? finalUpperBand : finalLowerBand); else supertrend(candle.close() > finalLowerBand ? finalLowerBand : finalUpperBand); signal(sign(hl2 - supertrend)); bands(doubleRange(finalLowerBand, finalUpperBand)); { if (upperBandHistory != null) upperBandHistory.addIfPriceChanged(finalUpperBand, candle.endTime().toLong()); } { if (lowerBandHistory != null) lowerBandHistory.addIfPriceChanged(finalLowerBand, candle.endTime().toLong()); } { if (basicUpperBandHistory != null) basicUpperBandHistory.addIfPriceChanged(basicUpperBand, candle.endTime().toLong()); } { if (basicLowerBandHistory != null) basicLowerBandHistory.addIfPriceChanged(basicLowerBand, candle.endTime().toLong()); } { if (supertrendHistory != null) supertrendHistory.add(supertrend, candle.endTime().toLong()); } { if (signalHistory != null) signalHistory.add(signal, candle.endTime().toLong()); } change(); }); } public List bandsAsTickers(List candles) { feed(candles); return ll(upperBandHistory, lowerBandHistory); } public Double value() { return supertrend(); } public void reset() { super.reset(); resetFields(this, "previousBands bands upperBandHistory lowerBandHistory basicUpperBandHistory basicLowerBandHistory supertrendHistory supertrend atr signal"); } } public interface IG22Mask extends MakesBufferedImage { public Image2B image(); public A label(); default public BufferedImage getBufferedImage() { return toBufferedImage(image()); } } static public class RunnerTradingAlgorithm extends G22TradingStrategy { static final public String _fieldOrder = "minRun bet lastDirection move run longestRunSeen"; public transient FieldVar varMinRun_cache; public FieldVar varMinRun() { if (varMinRun_cache == null) varMinRun_cache = varMinRun_load(); return varMinRun_cache; } public FieldVar varMinRun_load() { return new FieldVar(this, "minRun", () -> minRun(), minRun -> minRun(minRun)); } final public RunnerTradingAlgorithm setMinRun(int minRun) { return minRun(minRun); } public RunnerTradingAlgorithm minRun(int minRun) { if (!eq(this.minRun, minRun)) { this.minRun = minRun; change(); } return this; } final public int getMinRun() { return minRun(); } public int minRun() { return minRun; } public int minRun = 5; public transient FieldVar varBet_cache; public FieldVar varBet() { if (varBet_cache == null) varBet_cache = varBet_load(); return varBet_cache; } public FieldVar varBet_load() { return new FieldVar(this, "bet", () -> bet(), bet -> bet(bet)); } final public RunnerTradingAlgorithm setBet(int bet) { return bet(bet); } public RunnerTradingAlgorithm bet(int bet) { if (!eq(this.bet, bet)) { this.bet = bet; change(); } return this; } final public int getBet() { return bet(); } public int bet() { return bet; } public int bet; public Position openPosition(int direction) { if (direction == 0) return null; Position p = new Position(); p.marginToUse = marginPerPosition * abs(direction); return openPosition(p, direction); } public void start() { if (started()) throw fail("Already started"); if (currentPrice() == 0) { primed(true); return; } startingPrice = currentPrice(); startTime = currentTime(); var priceCells = makePriceCells(startingPrice); print("Made price cells: " + priceCells); digitizer = new PriceDigitizer2(priceCells); digitizer.verbose(verbose); log("Starting RUNNER at " + startingPrice + " +/- " + cellSize + ", min run: " + minRun); } public void price(double price) { if (currentPrice == price) return; currentPrice = price; if (hasClosedItself()) return; if (!started()) { if (primed) { primed(false); start(); } else return; } digitizer.digitize(price); direction = sign(digitizedPrice() - lastDigitizedPrice()); if (direction == 0) { afterStep(); return; } nextStep(); if (started()) step(); print(this); } transient public Runnable step; public void step() { if (step != null) step.run(); else step_base(); } final public void step_fallback(Runnable _f) { if (_f != null) _f.run(); else step_base(); } public void step_base() { double p1 = lastDigitizedPrice(); double p2 = digitizedPrice(); direction = sign(p2 - p1); if (direction == 0) return; bet = makeBet(); applyBet(); } transient public Runnable applyBet; public void applyBet() { if (applyBet != null) applyBet.run(); else applyBet_base(); } final public void applyBet_fallback(Runnable _f) { if (_f != null) _f.run(); else applyBet_base(); } public void applyBet_base() { double drift = drift(); if (sign(drift) != sign(bet)) { closeAllPositions(); openPosition(bet); } log(renderVars("stepCount", stepCount, "drift", drift, "bet", bet, "lastDirection", lastDirection, "direction", direction, "run", run, "minRun", minRun, "longestRunSeen", longestRunSeen)); afterStep(); } public double currentCellNumber() { return toCellNumber(currentPrice()); } public int currentDigitizedCell() { return iround(toCellNumber(digitizedPrice())); } public int priceDirection() { return sign(currentCellNumber() - currentDigitizedCell()); } public int targetCell() { return currentDigitizedCell() + priceDirection(); } public double targetPrice() { return fromCellNumber(targetCell()); } public double targetProfit() { return coinProfitAtPrice(targetPrice()); } public int profitDirection() { return sign(targetProfit() - coinProfit()); } public double progressInProfitDirection() { return absDiff(currentCellNumber(), currentDigitizedCell()) * 100; } public transient FieldVar varLastDirection_cache; public FieldVar varLastDirection() { if (varLastDirection_cache == null) varLastDirection_cache = varLastDirection_load(); return varLastDirection_cache; } public FieldVar varLastDirection_load() { return new FieldVar(this, "lastDirection", () -> lastDirection(), lastDirection -> lastDirection(lastDirection)); } final public RunnerTradingAlgorithm setLastDirection(int lastDirection) { return lastDirection(lastDirection); } public RunnerTradingAlgorithm lastDirection(int lastDirection) { if (!eq(this.lastDirection, lastDirection)) { this.lastDirection = lastDirection; change(); } return this; } final public int getLastDirection() { return lastDirection(); } public int lastDirection() { return lastDirection; } public int lastDirection; public transient FieldVar varMove_cache; public FieldVar varMove() { if (varMove_cache == null) varMove_cache = varMove_load(); return varMove_cache; } public FieldVar varMove_load() { return new FieldVar(this, "move", () -> move(), move -> move(move)); } final public RunnerTradingAlgorithm setMove(int move) { return move(move); } public RunnerTradingAlgorithm move(int move) { if (!eq(this.move, move)) { this.move = move; change(); } return this; } final public int getMove() { return move(); } public int move() { return move; } public int move; public transient FieldVar varRun_cache; public FieldVar varRun() { if (varRun_cache == null) varRun_cache = varRun_load(); return varRun_cache; } public FieldVar varRun_load() { return new FieldVar(this, "run", () -> run(), run -> run(run)); } final public RunnerTradingAlgorithm setRun(int run) { return run(run); } public RunnerTradingAlgorithm run(int run) { if (!eq(this.run, run)) { this.run = run; change(); } return this; } final public int getRun() { return run(); } public int run() { return run; } public int run; public transient FieldVar varLongestRunSeen_cache; public FieldVar varLongestRunSeen() { if (varLongestRunSeen_cache == null) varLongestRunSeen_cache = varLongestRunSeen_load(); return varLongestRunSeen_cache; } public FieldVar varLongestRunSeen_load() { return new FieldVar(this, "longestRunSeen", () -> longestRunSeen(), longestRunSeen -> longestRunSeen(longestRunSeen)); } final public RunnerTradingAlgorithm setLongestRunSeen(int longestRunSeen) { return longestRunSeen(longestRunSeen); } public RunnerTradingAlgorithm longestRunSeen(int longestRunSeen) { if (!eq(this.longestRunSeen, longestRunSeen)) { this.longestRunSeen = longestRunSeen; change(); } return this; } final public int getLongestRunSeen() { return longestRunSeen(); } public int longestRunSeen() { return longestRunSeen; } public int longestRunSeen; public String fieldsToReset() { return lines(ll(super.fieldsToReset(), "lastDirection run bet longestRunSeen move")); } transient public IF0 makeBet; public int makeBet() { return makeBet != null ? makeBet.get() : makeBet_base(); } final public int makeBet_fallback(IF0 _f) { return _f != null ? _f.get() : makeBet_base(); } public int makeBet_base() { move(direction); if (direction == lastDirection) ++run; else run = 1; longestRunSeen(max(longestRunSeen, run)); if (run >= minRun) bet = direction; if (bet != 0 && direction != bet) bet = 0; lastDirection = direction; return bet; } } static public class G22NetworksFromAllDBsPanel { public G22Utils g22utils; public JObjectTable table; public ReliableSingleThread rstUpdate = new ReliableSingleThread(new Runnable() { public void run() { try { _updateTable(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_updateTable();"; } }); transient public SingleComponentPanel scpDetail = singleComponentPanel(); public G22NetworksFromAllDBsPanel(G22Utils g22utils) { this.g22utils = g22utils; } public JComponent visualize() { table = new JObjectTable(); table.itemToMap = script -> litorderedmap("Network", script.description, "Project", fileName(networkToDBDir(script)), "ID in original project", str(script.id)); var tbl = table.visualize(); rstUpdate.get(); tablePopupMenuItem_top(table.table, "Open project", runnableThread(new Runnable() { public void run() { try { g22utils.masterStuff.openDatabase(table.selected()._concepts.conceptsDir()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.masterStuff.openDatabase(table.selected()._concepts.conceptsDir());"; } })); tablePopupMenuItem_top(table.table, "Import network", runnableThread(new Runnable() { public void run() { try { var network = table.selected(); var clonedNetwork = (G22Network) g22utils.restructure(network); registerConcept(g22utils.concepts(), clonedNetwork); g22utils.projectActions().openObjectInProject(clonedNetwork.id); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "var network = table.selected();\r\n var clonedNetwork = (G22Network) g22ut..."; } })); table.onSelect(network -> { if (network == null) scpDetail.clear(); else { scpDetail.set(makeDetailView(network)); } }); return withTopAndBottomMargin(jCenteredRaisedSection("Networks from all projects", jvsplit(tbl, scpDetail))); } public JComponent makeDetailView(G22Network network) { return new JG22Network(g22utils, network).visualize(); } public File networkToDBDir(G22Network network) { return network == null ? null : network._concepts.conceptsDir(); } public void _updateTable() { table.setData_force(concatLists(map_pcall(g22utils.gazelleDBs(), db -> { var classFinder = g22utils.masterStuff.makeClassFinder(); var cc = newConceptsWithClassFinder(db.conceptsFile(), classFinder); cc.loadFromDisk(); return list(cc, G22Network.class); }))); } } static public class G22POIsPanel extends G22CRUDAndDetailPanel { public G22POIsPanel() { } public SimpleCRUD_v2 makeCRUD() { var crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22PointOfInterest.class); crud.excludeFieldsFromEditing("bnpSettings"); crud.entityName = () -> "Point of interest"; crud.entityNamePlural = () -> "Points of interest"; crud.itemToMap_inner2 = poi -> { var map = crud.itemToMap_inner2_base(poi); changeKeyAndModifyValue(map, "bnpSettings", "Blur & Posterize", bnp -> tok_extractRoundBracketBody(str(bnp))); changeKey(map, "imageMD5", "Image ID"); return map; }; return crud; } @Override public String detailTitle(G22PointOfInterest poi) { return str(poi); } public JComponent makeDetailView(G22PointOfInterest poi) { return new G22POIPanel(poi).visualize(); } public G22POIsPanel g22utils(G22Utils g22utils) { super.g22utils(g22utils); return this; } } static public class Gazelle22_ImageToRegions { public BufferedImage inputImage; public BWIntegralImage ii; public SnPSettings snpSettings; public BWImage posterized; public FastRegions_BWImage regions; public Map, Double> scoredRegions; public boolean wasRun = false; final public Gazelle22_ImageToRegions setWithDiagonals(boolean withDiagonals) { return withDiagonals(withDiagonals); } public Gazelle22_ImageToRegions withDiagonals(boolean withDiagonals) { this.withDiagonals = withDiagonals; return this; } final public boolean getWithDiagonals() { return withDiagonals(); } public boolean withDiagonals() { return withDiagonals; } public boolean withDiagonals = false; public FunctionTimings timings; public Gazelle22_ImageToRegions(FunctionTimings timings, BufferedImage inputImage, SnPSettings snpSettings) { this.snpSettings = snpSettings; this.inputImage = inputImage; this.timings = timings; } public Decolorizer decolorizer() { return snpSettings.decolorizer; } public void run() { try { wasRun = true; var decolorizer = decolorizer(); timings.dO(decolorizer != null ? "bwIntegralImage w/decolorizer" : "bwIntegralImage", () -> ii = bwIntegralImage_withMeta(inputImage, decolorizer)); timings.dO("scaleAndPosterize", () -> posterized = scaleAndPosterize(ii, snpSettings)); regions = new FastRegions_BWImage(posterized); regions.collectBounds(); regions.withDiagonals(withDiagonals); timings.dO("Regions", regions); } catch (Exception __e) { throw rethrow(__e); } } public ScreenShotMeta screenShotMeta() { return optCast(ScreenShotMeta.class, getMetaSrc(inputImage)); } public Pt coordinatesFromScreen(Pt p) { var meta = screenShotMeta(); if (meta == null) return null; var r = meta.bounds; if (!r.contains(p)) return null; p = translatePt(p, -r.x, -r.y); return scalePt(p, doubleRatio(snpSettings.pixelRows, r.h)); } public Pt coordinatesToScreen(Pt p) { var meta = screenShotMeta(); if (meta == null) return null; var r = meta.bounds; return translatePt(r.x, r.y, scalePt(p, doubleRatio(r.h, snpSettings.pixelRows))); } final public FastRegions_BWImage get() { return regions(); } public FastRegions_BWImage regions() { if (!wasRun) run(); return regions; } public int nRegions() { return regions().nRegions(); } } static public class G22ShapeCollectorPanel extends MetaWithChangeListeners implements Swingable { final public G22ShapeCollectorPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22ShapeCollectorPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; final public G22ShapeCollectorPanel setQoiAlways(boolean qoiAlways) { return qoiAlways(qoiAlways); } public G22ShapeCollectorPanel qoiAlways(boolean qoiAlways) { this.qoiAlways = qoiAlways; return this; } final public boolean getQoiAlways() { return qoiAlways(); } public boolean qoiAlways() { return qoiAlways; } public boolean qoiAlways = false; public transient FieldVar varImageSourceDesc_cache; public FieldVar varImageSourceDesc() { if (varImageSourceDesc_cache == null) varImageSourceDesc_cache = varImageSourceDesc_load(); return varImageSourceDesc_cache; } public FieldVar varImageSourceDesc_load() { return new FieldVar(this, "imageSourceDesc", () -> imageSourceDesc(), imageSourceDesc -> imageSourceDesc(imageSourceDesc)); } final public G22ShapeCollectorPanel setImageSourceDesc(String imageSourceDesc) { return imageSourceDesc(imageSourceDesc); } public G22ShapeCollectorPanel imageSourceDesc(String imageSourceDesc) { if (!eq(this.imageSourceDesc, imageSourceDesc)) { this.imageSourceDesc = imageSourceDesc; change(); } return this; } final public String getImageSourceDesc() { return imageSourceDesc(); } public String imageSourceDesc() { return imageSourceDesc; } public String imageSourceDesc = "Left screen half"; public AnalyzedImage completedImage; final public G22ShapeCollectorPanel setGradientCycleTime(double gradientCycleTime) { return gradientCycleTime(gradientCycleTime); } public G22ShapeCollectorPanel gradientCycleTime(double gradientCycleTime) { this.gradientCycleTime = gradientCycleTime; return this; } final public double getGradientCycleTime() { return gradientCycleTime(); } public double gradientCycleTime() { return gradientCycleTime; } public double gradientCycleTime = 2.0; final public G22ShapeCollectorPanel setMaxDrift(int maxDrift) { return maxDrift(maxDrift); } public G22ShapeCollectorPanel maxDrift(int maxDrift) { this.maxDrift = maxDrift; return this; } final public int getMaxDrift() { return maxDrift(); } public int maxDrift() { return maxDrift; } public int maxDrift = 100; public MouseInComponentMonitor mouseMonitor = new MouseInComponentMonitor(); public PicturesByMD5 pics; public JMaxSpeedAnimation anim = new JMaxSpeedAnimation(); public JCheckBox cbOn = jcheckbox("On", true); public JCheckBox cbAnimateGradients = jcheckbox("Animate gradients", false); public JSpinner colorsSpinner = jListSpinner(itemPlus(2, dropFirst(firstNCubes(16)))); public JSpinner blurSpinner = jSpinner(0, 0, 99); public JLabel lblStats = rightAlignedLabel(); public JSlider driftSlider; public JCheckBox cbAntiDrift = jcheckbox("Antidrift", true); public class AnalyzedImage extends G22DataWrangler { public G22DataWrangler wrangler() { return this; } public byte[] qoiData_cache; public byte[] qoiData() { if (qoiData_cache == null) qoiData_cache = qoiData_load(); return qoiData_cache; } public byte[] qoiData_load() { return g22utils.timeFunction("QOI compress", () -> toQOI(inputImage())); } public String qoiMD5_cache; public String qoiMD5() { if (qoiMD5_cache == null) qoiMD5_cache = qoiMD5_load(); return qoiMD5_cache; } public String qoiMD5_load() { return md5(qoiData()); } public String saveImage() { pics.put(qoiMD5(), qoiData()); return qoiMD5(); } } public void init() { if (pics != null) return; pics = g22utils.picturesByMD5(); driftSlider = jSlider(-maxDrift, maxDrift, 0); componentPopupMenuItem(driftSlider, "Reset", new Runnable() { public void run() { try { driftSlider.setValue(0); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "driftSlider.setValue(0)"; } }); looselyBindLiveValueToCheckBox(g22utils.liveProjectVar("Animate gradients"), cbAnimateGradients); looselyBindLiveValueToSpinner(g22utils.liveProjectVar("colors"), colorsSpinner); looselyBindLiveValueToSpinner(g22utils.liveProjectVar("blur"), blurSpinner); looselyBindLiveValueToSlider(g22utils.liveProjectVar("brightnessDrift"), driftSlider); looselyBindLiveValueToCheckBox(g22utils.liveProjectVar("Antidrift"), cbAntiDrift); } transient public IF0 nextInputImage; public BufferedImage nextInputImage() { return nextInputImage != null ? nextInputImage.get() : nextInputImage_base(); } final public BufferedImage nextInputImage_fallback(IF0 _f) { return _f != null ? _f.get() : nextInputImage_base(); } public BufferedImage nextInputImage_base() { return shootLeftScreenHalf(); } public G22ShapeCollectorPanel imageSource(IF0 imageSource) { return imageSource(imageSource, str(imageSource)); } public G22ShapeCollectorPanel imageSource(IF0 imageSource, String imageSourceDesc) { nextInputImage = imageSource; imageSourceDesc = imageSourceDesc; return this; } public boolean running() { return isChecked(cbOn); } public BufferedImage nextFrame() { if (!running()) { sleepSeconds(0.1); return null; } var inputImage = nextInputImage(); AnalyzedImage ai = new AnalyzedImage(); var wrangler = ai.wrangler(); wrangler.timings(g22utils.functionTimings()); wrangler.inputImage(inputImage); wrangler.colors(intFromSpinner(colorsSpinner)); wrangler.blur(intFromSpinner(blurSpinner)); var drift = (float) (intFromSlider(driftSlider) / 100.0); if (isChecked(cbAnimateGradients)) drift = (float) transformFromZeroToOne(-1, 1, frac(sysSeconds() / gradientCycleTime)); wrangler.drift(drift); wrangler.antiDrift(isChecked(cbAntiDrift) || isChecked(cbAnimateGradients) ? -drift : 0); wrangler.stepUntilStage(wrangler.regionsStage); g22utils.setTransientProjectVar("Last wrangler", wrangler); List qoiInfo = !qoiAlways ? null : ll("QOI: " + str_toK(l(ai.qoiData())), "Hash: " + takeFirst(3, ai.qoiMD5()), "Saved: " + yesNo_short(pics.has(ai.qoiMD5()))); setText(lblStats, commaCombine(anim.fps(), nRegions(wrangler.regions), qoiInfo, nImages(pics.imageCount()) + " saved", n2(countConcepts(g22utils.concepts(), G22PointOfInterest.class), "POI"))); completedImage = ai; g22utils.setTransientProjectVar("Last analyzed image", ai); return toBufferedImage(wrangler.posterizedImage); } transient public IF0 watchingUI; public JComponent watchingUI() { return watchingUI != null ? watchingUI.get() : watchingUI_base(); } final public JComponent watchingUI_fallback(IF0 _f) { return _f != null ? _f.get() : watchingUI_base(); } public JComponent watchingUI_base() { return liveValueLabel(varImageSourceDesc()); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { init(); anim.renderFrame(() -> nextFrame()); mouseMonitor.init(anim.imageSurface()); return northAndCenterWithMargins(northAndCenterWithMargin(jcenteredline(withLabel("Watching:", watchingUI())), jCenteredSection(" Visual Controls ", jHigherScrollPane_borderless_center(withSideMargin(jcenteredline(cbOn, jCenteredSection("Colors", colorsSpinner), jCenteredSection("Blur", blurSpinner), cbAnimateGradients, jCenteredSection("Drift", driftSlider), cbAntiDrift))))), centerAndSouthWithMargin(jCenteredSection(" What I See ", anim), centerAndEastWithMargin(lblStats, jThreadedButton("Save image", () -> { { if (completedImage != null) completedImage.saveImage(); } })))); } public ImageSurface imageSurface() { return anim.imageSurface(); } static public G22ShapeCollectorPanel fullyConfigured(G22Utils g22utils) { return fullyConfigured(g22utils, new G22ShapeCollectorPanel()); } static public G22ShapeCollectorPanel fullyConfigured(G22Utils g22utils, G22ShapeCollectorPanel collector) { return (G22ShapeCollectorPanel) g22utils.leftArrowWithVars("\r\n collector g22utils < g22utils\r\n collector visualize\r\n is <- collector imageSurface\r\n hoveringOverRegion <- new Var\r\n is addOverlay < G2Drawable g -> {\r\n region <- hoveringOverRegion get\r\n if notNull region {\r\n //zoomGraphics g (is zoomY) (is zoomY)\r\n for outline in g22_allBorderTraces_autoDiagonals region {\r\n for p in outline {\r\n p <- scalePt p (is zoomY) (is zoomY)\r\n //drawPixel g p < Color green\r\n fillRect g (Color green) (p x) (p y) (iceil < is zoomX) (iceil < is zoomY)\r\n }\r\n }\r\n }\r\n }\r\n \r\n collector anim, displayNewImage <- IVF1 image -> {\r\n pt <- is mousePosition\r\n if isNull pt {\r\n hoveringOverRegion clear\r\n } else {\r\n ai <- collector completedImage\r\n regionMaker <- ai wrangler, regionMaker\r\n hoveringOverRegion set <\r\n regionMaker getRegion < regionMaker regionAt pt\r\n // TODO: doesn't work like this\r\n // if not < collector running { is repaint }\r\n }\r\n //toolTip is hoveringOverRegion\r\n collector anim, displayNewImage_base image\r\n }\r\n \r\n is imageSurfaceOnLeftClick < IVF1 pt -> {\r\n region <- hoveringOverRegion get\r\n if isNull region { ret }\r\n ai <- collector completedImage\r\n md5 <- ai saveImage\r\n poi <- new G22PointOfInterest\r\n poi imageMD5 <- md5\r\n poi pt <- pt\r\n poi bnpSettings <- ai wrangler, bnpSettings\r\n poi source <- spaceCombine \"Clicked\" (byUser) \"on\" ( ymdWithSlashes)\r\n registerConcept (concepts) poi\r\n }\r\n \r\n collector\r\n ", "collector", collector); } } static public class G22Network extends ConceptWithChangeListeners { static final public String _fieldOrder = "description elements magneticDistance autoCalculate"; public transient FieldVar varDescription_cache; public FieldVar varDescription() { if (varDescription_cache == null) varDescription_cache = varDescription_load(); return varDescription_cache; } public FieldVar varDescription_load() { return new FieldVar(this, "description", () -> description(), description -> description(description)); } final public G22Network setDescription(String description) { return description(description); } public G22Network description(String description) { if (!eq(this.description, description)) { this.description = description; change(); } return this; } final public String getDescription() { return description(); } public String description() { return description; } public String description; public Collection elements = syncL(); public transient FieldVar varMagneticDistance_cache; public FieldVar varMagneticDistance() { if (varMagneticDistance_cache == null) varMagneticDistance_cache = varMagneticDistance_load(); return varMagneticDistance_cache; } public FieldVar varMagneticDistance_load() { return new FieldVar(this, "magneticDistance", () -> magneticDistance(), magneticDistance -> magneticDistance(magneticDistance)); } final public G22Network setMagneticDistance(int magneticDistance) { return magneticDistance(magneticDistance); } public G22Network magneticDistance(int magneticDistance) { if (!eq(this.magneticDistance, magneticDistance)) { this.magneticDistance = magneticDistance; change(); } return this; } final public int getMagneticDistance() { return magneticDistance(); } public int magneticDistance() { return magneticDistance; } public int magneticDistance = 100; public transient FieldVar varAutoCalculate_cache; public FieldVar varAutoCalculate() { if (varAutoCalculate_cache == null) varAutoCalculate_cache = varAutoCalculate_load(); return varAutoCalculate_cache; } public FieldVar varAutoCalculate_load() { return new FieldVar(this, "autoCalculate", () -> autoCalculate(), autoCalculate -> autoCalculate(autoCalculate)); } final public G22Network setAutoCalculate(boolean autoCalculate) { return autoCalculate(autoCalculate); } public G22Network autoCalculate(boolean autoCalculate) { if (!eq(this.autoCalculate, autoCalculate)) { this.autoCalculate = autoCalculate; change(); } return this; } final public boolean getAutoCalculate() { return autoCalculate(); } public boolean autoCalculate() { return autoCalculate; } public boolean autoCalculate = true; public String toString() { return or2(description, super.toString()); } public Collection doMagneticConnections() { List newCables = new ArrayList(); List inputPorts = new ArrayList(); List outputPorts = new ArrayList(); for (var element : elements) for (var port : element.ports()) (port.isOutput() ? outputPorts : inputPorts).add(port); for (var port1 : inputPorts) { if (port1.isConnected()) continue; Rect bounds1 = port1.bounds(); Lowest best = new Lowest(); for (var port2 : outputPorts) { double distance = rectDistance(bounds1, port2.bounds()); if (distance >= magneticDistance) continue; if (!isSubclassOf(port2.dataType(), port1.dataType())) continue; best.put(port2, distance); } var port2 = best.get(); if (port2 != null) { var cable = new G22NetworkCable().from(port2).to(port1); newCables.add(cable); cable.connect(); print("Made cable: " + cable); } } return newCables; } public void deleteMagneticConnections() { for (var cable : allCables()) if (cable.isAutomatic()) cable.remove(); } public Set allCables() { Set set = new HashSet(); for (var element : elements) for (var port : element.ports()) addIfNotNull(set, port.cable); return set; } } static public class G22SkeletonWalker implements Steppable, IFieldsToList { public IImageRegion region; public G22SkeletonWalker() { } public G22SkeletonWalker(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } transient public Set> onFoundLink; public G22SkeletonWalker onFoundLink(IVF2 f) { onFoundLink = createOrAddToSyncLinkedHashSet(onFoundLink, f); return this; } public G22SkeletonWalker removeFoundLinkListener(IVF2 f) { loadableUtils.utils.remove(onFoundLink, f); return this; } public void foundLink(Pt a, Pt b) { if (onFoundLink != null) for (var listener : onFoundLink) pcallF_typed(listener, a, b); } final public G22SkeletonWalker setMinDist(int minDist) { return minDist(minDist); } public G22SkeletonWalker minDist(int minDist) { this.minDist = minDist; return this; } final public int getMinDist() { return minDist(); } public int minDist() { return minDist; } public int minDist = 3; public Map ptMap = new HashMap(); public boolean initialized = false; public LinkedList> queue = new LinkedList(); public boolean step() { if (!initialized) { initialized = true; Pt p = region.firstPixel(); if (p == null) return false; queue.add(pair(null, p)); } if (empty(queue)) return false; Pair pair = popFirst(queue); Pt prev = pair.a, p = pair.b; Pt mapped = lookupOrKeep(ptMap, p); boolean seen = ptMap.containsKey(p); Pt mapTo = p; if (prev != null) { if (distantEnough(prev, mapped)) foundLink(prev, mapped); else mapTo = prev; } if (!seen) { ptMap.put(p, mapTo); Pt linkFrom = mapTo; for (int dir = 1; dir <= 8; dir++) { Pt p2 = ptPlus(p, onePathDirection(dir)); if (region.contains(p2)) queue.add(pair(linkFrom, p2)); } } return true; } public boolean distantEnough(Pt a, Pt b) { return a != null && b != null && (absDiff(a.x, b.x) >= minDist || absDiff(a.y, b.y) >= minDist); } } static public class JContentAndControls implements Swingable, Updateable { final public JContentAndControls setMakeContent(IF0 makeContent) { return makeContent(makeContent); } public JContentAndControls makeContent(IF0 makeContent) { this.makeContent = makeContent; return this; } final public IF0 getMakeContent() { return makeContent(); } public IF0 makeContent() { return makeContent; } public IF0 makeContent; public SingleComponentPanel scpContent = singleComponentPanel(); public ReliableSingleThread rstReloadContent = rst(() -> reloadImpl()); final public JContentAndControls setBtnReload(JButton btnReload) { return btnReload(btnReload); } public JContentAndControls btnReload(JButton btnReload) { this.btnReload = btnReload; return this; } final public JButton getBtnReload() { return btnReload(); } public JButton btnReload() { return btnReload; } public JButton btnReload; final public DynamicHStack getControls() { return controls(); } public DynamicHStack controls() { return controls; } public DynamicHStack controls = dynamicHStack(); public SingleComponentPanel scpControls = singleComponentPanel(jfullcenter(controls)); final public JContentAndControls setLoadingScreenWhenReloading(boolean loadingScreenWhenReloading) { return loadingScreenWhenReloading(loadingScreenWhenReloading); } public JContentAndControls loadingScreenWhenReloading(boolean loadingScreenWhenReloading) { this.loadingScreenWhenReloading = loadingScreenWhenReloading; return this; } final public boolean getLoadingScreenWhenReloading() { return loadingScreenWhenReloading(); } public boolean loadingScreenWhenReloading() { return loadingScreenWhenReloading; } public boolean loadingScreenWhenReloading = false; final public JContentAndControls setShowControls(boolean showControls) { return showControls(showControls); } public JContentAndControls showControls(boolean showControls) { this.showControls = showControls; return this; } final public boolean getShowControls() { return showControls(); } public boolean showControls() { return showControls; } public boolean showControls = true; final public JContentAndControls setShowReloadButton(boolean showReloadButton) { return showReloadButton(showReloadButton); } public JContentAndControls showReloadButton(boolean showReloadButton) { this.showReloadButton = showReloadButton; return this; } final public boolean getShowReloadButton() { return showReloadButton(); } public boolean showReloadButton() { return showReloadButton; } public boolean showReloadButton = true; final public void update() { reload(); } public void reload() { rstReloadContent.trigger(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { onComponentShown(scpContent, () -> { if (scpContent.isEmpty()) reload(); }); if (!showControls) return scpContent; if (showReloadButton) btnReload = jReloadButton(() -> reload()); return northAndCenter(withMargin(showReloadButton ? centerAndEastWithMargin(scpControls, vstackWithSpacing(btnReload)) : scpControls), scpContent); } transient public IF0 makeLoadingScreen; public JComponent makeLoadingScreen() { return makeLoadingScreen != null ? makeLoadingScreen.get() : makeLoadingScreen_base(); } final public JComponent makeLoadingScreen_fallback(IF0 _f) { return _f != null ? _f.get() : makeLoadingScreen_base(); } public JComponent makeLoadingScreen_base() { return jCenteredLabel("Loading..."); } public void reloadImpl() { AutoCloseable __1 = tempDisableButton(btnReload); try { if (loadingScreenWhenReloading() || !scpContent.hasComponent()) scpContent.set(makeLoadingScreen()); try { scpContent.set(wrap(makeContent == null ? null : makeContent.get())); } catch (Throwable e) { printStackTrace(e); scpContent.set(jErrorView(e)); } } finally { _close(__1); } } public JContentAndControls addControl(String label, Swingable control) { return addControl(label, toJComponent(control)); } public JContentAndControls addControl(String label, JComponent control) { return addControl(withLabel(label, control)); } public JContentAndControls addControl(Swingable control) { return addControl(toJComponent(control)); } public JContentAndControls addControl(JComponent control) { controls.addComponent(control); return this; } public JContentAndControls content(IF0 makeContent) { return makeContent(makeContent); } public JContentAndControls addControlLine(JComponent newControls) { scpControls.set(centerAndSouthWithMargin(scpControls.get(), newControls)); return this; } } static public class ROCIndicator extends CandleBasedIndicator { public ROCIndicator() { } final public TickerSequence getRocHistory() { return rocHistory(); } public TickerSequence rocHistory() { return rocHistory; } public TickerSequence rocHistory = new TickerSequence("ROC"); final public ROCIndicator setRoc(double roc) { return roc(roc); } public ROCIndicator roc(double roc) { this.roc = roc; return this; } final public double getRoc() { return roc(); } public double roc() { return roc; } public double roc = Double.NaN; public Double value() { return roc(); } public ROCIndicator(int length) { this.length = length; } { length = 10; onCandleAdded((IVF1) candle -> { if (l(candles()) >= length) { roc(asPercentIncrease(candle.close(), candles().first().close())); long time = candle.endTime().toLong(); { if (rocHistory != null) rocHistory.addIfPriceChanged(roc, time); } } }); } public TickerSequence asTicker(List candles) { feed(candles); return rocHistory; } public void reset() { super.reset(); resetFields(this, "roc rocHistory"); } } static public class JG22Labels extends MetaWithChangeListeners { public transient FieldVar varShowCount_cache; public FieldVar varShowCount() { if (varShowCount_cache == null) varShowCount_cache = varShowCount_load(); return varShowCount_cache; } public FieldVar varShowCount_load() { return new FieldVar(this, "showCount", () -> showCount(), showCount -> showCount(showCount)); } final public JG22Labels setShowCount(boolean showCount) { return showCount(showCount); } public JG22Labels showCount(boolean showCount) { if (!eq(this.showCount, showCount)) { this.showCount = showCount; change(); } return this; } final public boolean getShowCount() { return showCount(); } public boolean showCount() { return showCount; } public boolean showCount = true; public transient FieldVar varAllowCreation_cache; public FieldVar varAllowCreation() { if (varAllowCreation_cache == null) varAllowCreation_cache = varAllowCreation_load(); return varAllowCreation_cache; } public FieldVar varAllowCreation_load() { return new FieldVar(this, "allowCreation", () -> allowCreation(), allowCreation -> allowCreation(allowCreation)); } final public JG22Labels setAllowCreation(boolean allowCreation) { return allowCreation(allowCreation); } public JG22Labels allowCreation(boolean allowCreation) { if (!eq(this.allowCreation, allowCreation)) { this.allowCreation = allowCreation; change(); } return this; } final public boolean getAllowCreation() { return allowCreation(); } public boolean allowCreation() { return allowCreation; } public boolean allowCreation = true; public transient FieldVar> varLabels_cache; public FieldVar> varLabels() { if (varLabels_cache == null) varLabels_cache = varLabels_load(); return varLabels_cache; } public FieldVar> varLabels_load() { return new FieldVar>(this, "labels", () -> labels(), labels -> labels(labels)); } final public JG22Labels setLabels(List labels) { return labels(labels); } public JG22Labels labels(List labels) { if (!eq(this.labels, labels)) { this.labels = labels; change(); } return this; } final public List getLabels() { return labels(); } public List labels() { return labels; } public List labels; transient public JLabel lblInfo = jlabel(); transient public JPanel line = jline(); transient public ReliableSingleThread rstUpdate = new ReliableSingleThread(new Runnable() { public void run() { try { _update(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_update();"; } }); public transient FieldVar varCreating_cache; public FieldVar varCreating() { if (varCreating_cache == null) varCreating_cache = varCreating_load(); return varCreating_cache; } public FieldVar varCreating_load() { return new FieldVar(this, "creating", () -> creating(), creating -> creating(creating)); } final public JG22Labels setCreating(JG22Label creating) { return creating(creating); } public JG22Labels creating(JG22Label creating) { if (!eq(this.creating, creating)) { this.creating = creating; change(); } return this; } final public JG22Label getCreating() { return creating(); } public JG22Label creating() { return creating; } transient public JG22Label creating; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { varLabels().onChangeAndNow(rstUpdate); varCreating().onChangeAndNow(rstUpdate); return borderless(jscrollHorizontal(line)); } public void _update() { var labels = labels(); removeAllComponents(line); if (showCount) { setText(lblInfo, nLabels(labels) + (empty(labels) ? "" : ":")); line.add(lblInfo); } for (var label : unnullForIteration(labels)) line.add(makeLabelComponent(label)); if (creating != null) line.add(creating); else if (allowCreation) line.add(jimageButtonScaledToWidth(16, "#1103069", "Add a label", new Runnable() { public void run() { try { _addALabel(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_addALabel();"; } })); revalidate(line); } public JG22Label makeLabelComponent(G22Label label) { var lbl = new JG22Label(label); componentPopupMenuItem(lbl.jLabel, "Remove label", runnableThread(new Runnable() { public void run() { try { removeLabel(label); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "removeLabel(label)"; } })); return lbl; } public boolean containsLabel(String text) { return containsPred(labels, lbl -> lbl.textIs(text)); } transient public IVF1 addLabel; public void addLabel(String text) { if (addLabel != null) addLabel.get(text); else addLabel_base(text); } final public void addLabel_fallback(IVF1 _f, String text) { if (_f != null) _f.get(text); else addLabel_base(text); } public void addLabel_base(String text) { } transient public IVF1 removeLabel; public void removeLabel(G22Label label) { if (removeLabel != null) removeLabel.get(label); else removeLabel_base(label); } final public void removeLabel_fallback(IVF1 _f, G22Label label) { if (_f != null) _f.get(label); else removeLabel_base(label); } public void removeLabel_base(G22Label label) { } public void _addALabel() { JG22Label lbl = new JG22Label(); lbl.onDoneEditing(text -> { if (!containsLabel(text)) { print("Adding label: " + text); addLabel(text); } else infoBox("Label already contained"); creating(null); }); focusOnFirstShowVerbose(lbl.focusablePart()); creating(lbl); } } static public class LineBuffer { public VF1 onLine; public StringBuilder currentLine = new StringBuilder(); public LineBuffer() { } public LineBuffer(VF1 onLine) { this.onLine = onLine; } public void append(String s) { append(s, onLine); } public void append(String s, VF1 onLine) { currentLine.append(s); if (contains(s, '\n')) { int i = 0, j; s = str(currentLine); while ((j = indexOf(s, i, '\n')) >= 0) { String line = dropTrailingBackslashR(substring(s, i, j)); callF(onLine, line); i = j + 1; } currentLine = new StringBuilder(substring(s, i)); } } public int size() { return l(currentLine); } } static public class G22AllConceptsPanel implements IFieldsToList { public G22Utils g22utils; public G22AllConceptsPanel() { } public G22AllConceptsPanel(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public JConceptsTable table; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { table = new JConceptsTable(g22utils.concepts, Concept.class); table.itemToMap_inner2 = c -> litorderedmap("description", cget(c, "description"), "path", f2s_opt(cget(c, "path"))); return withTopAndBottomMargin(jRaisedCenteredSection("All objects by ID", table.visualize())); } } static public class BollingerBands extends CandleBasedIndicator { public Welford welford = new Welford(); final public BollingerBands setDeviation(double deviation) { return deviation(deviation); } public BollingerBands deviation(double deviation) { this.deviation = deviation; return this; } final public double getDeviation() { return deviation(); } public double deviation() { return deviation; } public double deviation = 2; final public BollingerBands setRange(DoubleRange range) { return range(range); } public BollingerBands range(DoubleRange range) { this.range = range; return this; } final public DoubleRange getRange() { return range(); } public DoubleRange range() { return range; } public DoubleRange range; final public TickerSequence getUpperBand() { return upperBand(); } public TickerSequence upperBand() { return upperBand; } public TickerSequence upperBand = new TickerSequence("Upper Bollinger Band"); final public TickerSequence getLowerBand() { return lowerBand(); } public TickerSequence lowerBand() { return lowerBand; } public TickerSequence lowerBand = new TickerSequence("Lower Bollinger Band"); final public AverageAndStandardDeviation getAs() { return as(); } public AverageAndStandardDeviation as() { return as; } public AverageAndStandardDeviation as; { onCandleRemoved(candle -> welford.remove(candle.endPrice())); onCandleAdded(candle -> { welford.add(candle.endPrice()); if (l(candles()) >= length) { var bCandles = candles().asList(); as = welford.get(); range(bollingerRange(as, deviation)); { if (upperBand != null) upperBand.addIfPriceChanged(range.end(), candle.endTime().toLong()); } { if (lowerBand != null) lowerBand.addIfPriceChanged(range.start(), candle.endTime().toLong()); } change(); } }); } public List bandsAsTickers(List candles) { feed(candles); return ll(upperBand, lowerBand); } public DoubleRange value() { return range(); } public void reset() { super.reset(); resetFields(this, "welford range upperBand lowerBand as"); } } static public class G22ForegroundFinder { final public G22ForegroundFinder setAllRegions(List allRegions) { return allRegions(allRegions); } public G22ForegroundFinder allRegions(List allRegions) { this.allRegions = allRegions; return this; } final public List getAllRegions() { return allRegions(); } public List allRegions() { return allRegions; } public List allRegions; final public Rect getBorderRect() { return borderRect(); } public Rect borderRect() { return borderRect; } public Rect borderRect; public Set foregroundRegions; public G22ForegroundFinder() { } public G22ForegroundFinder(List allRegions) { this.allRegions = allRegions; } final public Set get() { return foregroundRegions(); } public Set foregroundRegions() { run(); return foregroundRegions; } public List backgroundRegions() { return listMinusSet(allRegions, foregroundRegions()); } public void run() { try { if (foregroundRegions != null) return; borderRect = mergeRects(map(allRegions, r -> r.bounds())); foregroundRegions = new LinkedHashSet(); for (var r : allRegions) if (isForegroundRegion(r)) foregroundRegions.add(r); } catch (Exception __e) { throw rethrow(__e); } } transient public IF1 isForegroundRegion; public boolean isForegroundRegion(IImageRegion region) { return isForegroundRegion != null ? isForegroundRegion.get(region) : isForegroundRegion_base(region); } final public boolean isForegroundRegion_fallback(IF1 _f, IImageRegion region) { return _f != null ? _f.get(region) : isForegroundRegion_base(region); } public boolean isForegroundRegion_base(IImageRegion region) { return defaultDecolorizer().toGrayScale(region.color()) < 128; } } static public class G22Tiler_BWImage extends G22AbstractTiler { public int getColor(int pos) { return image.getInt_noRangeCheck(pos); } public G22Tiler_BWImage(BWImage img) { super(img); } public G22Tiler_BWImage(BufferedImage img) { this(toBWImage(img)); } } static public class UpdateTrigger implements Runnable, IFieldsToList { public Updateable target; public UpdateTrigger() { } public UpdateTrigger(Updateable target) { this.target = target; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + target + ")"; } public boolean equals(Object o) { if (!(o instanceof UpdateTrigger)) return false; UpdateTrigger __1 = (UpdateTrigger) o; return eq(target, __1.target); } public int hashCode() { int h = -1756880753; h = boostHashCombine(h, _hashCode(target)); return h; } public Object[] _fieldsToList() { return new Object[] { target }; } public void run() { try { { if (target != null) target.update(); } } catch (Exception __e) { throw rethrow(__e); } } } static public class Corridor extends G22TradingStrategy { static final public String _fieldOrder = "capacity maxPositionsPerDirection instantRestart openTwoPositionsAtStart openRandomPositionAtStart openFixedDirectionAtStart alwaysOpenTwoPositions endStrategyWhenCapacityExceeded useStrategyJuicer closeSignal"; public transient FieldVar varCapacity_cache; public FieldVar varCapacity() { if (varCapacity_cache == null) varCapacity_cache = varCapacity_load(); return varCapacity_cache; } public FieldVar varCapacity_load() { return new FieldVar(this, "capacity", () -> capacity(), capacity -> capacity(capacity)); } final public Corridor setCapacity(int capacity) { return capacity(capacity); } public Corridor capacity(int capacity) { if (!eq(this.capacity, capacity)) { this.capacity = capacity; change(); } return this; } final public int getCapacity() { return capacity(); } public int capacity() { return capacity; } public int capacity = 3; public transient FieldVar varMaxPositionsPerDirection_cache; public FieldVar varMaxPositionsPerDirection() { if (varMaxPositionsPerDirection_cache == null) varMaxPositionsPerDirection_cache = varMaxPositionsPerDirection_load(); return varMaxPositionsPerDirection_cache; } public FieldVar varMaxPositionsPerDirection_load() { return new FieldVar(this, "maxPositionsPerDirection", () -> maxPositionsPerDirection(), maxPositionsPerDirection -> maxPositionsPerDirection(maxPositionsPerDirection)); } final public Corridor setMaxPositionsPerDirection(int maxPositionsPerDirection) { return maxPositionsPerDirection(maxPositionsPerDirection); } public Corridor maxPositionsPerDirection(int maxPositionsPerDirection) { if (!eq(this.maxPositionsPerDirection, maxPositionsPerDirection)) { this.maxPositionsPerDirection = maxPositionsPerDirection; change(); } return this; } final public int getMaxPositionsPerDirection() { return maxPositionsPerDirection(); } public int maxPositionsPerDirection() { return maxPositionsPerDirection; } public int maxPositionsPerDirection = 100; public transient FieldVar varInstantRestart_cache; public FieldVar varInstantRestart() { if (varInstantRestart_cache == null) varInstantRestart_cache = varInstantRestart_load(); return varInstantRestart_cache; } public FieldVar varInstantRestart_load() { return new FieldVar(this, "instantRestart", () -> instantRestart(), instantRestart -> instantRestart(instantRestart)); } final public Corridor setInstantRestart(boolean instantRestart) { return instantRestart(instantRestart); } public Corridor instantRestart(boolean instantRestart) { if (!eq(this.instantRestart, instantRestart)) { this.instantRestart = instantRestart; change(); } return this; } final public boolean getInstantRestart() { return instantRestart(); } public boolean instantRestart() { return instantRestart; } public boolean instantRestart = true; public transient FieldVar varOpenTwoPositionsAtStart_cache; public FieldVar varOpenTwoPositionsAtStart() { if (varOpenTwoPositionsAtStart_cache == null) varOpenTwoPositionsAtStart_cache = varOpenTwoPositionsAtStart_load(); return varOpenTwoPositionsAtStart_cache; } public FieldVar varOpenTwoPositionsAtStart_load() { return new FieldVar(this, "openTwoPositionsAtStart", () -> openTwoPositionsAtStart(), openTwoPositionsAtStart -> openTwoPositionsAtStart(openTwoPositionsAtStart)); } final public Corridor setOpenTwoPositionsAtStart(boolean openTwoPositionsAtStart) { return openTwoPositionsAtStart(openTwoPositionsAtStart); } public Corridor openTwoPositionsAtStart(boolean openTwoPositionsAtStart) { if (!eq(this.openTwoPositionsAtStart, openTwoPositionsAtStart)) { this.openTwoPositionsAtStart = openTwoPositionsAtStart; change(); } return this; } final public boolean getOpenTwoPositionsAtStart() { return openTwoPositionsAtStart(); } public boolean openTwoPositionsAtStart() { return openTwoPositionsAtStart; } public boolean openTwoPositionsAtStart = false; public transient FieldVar varOpenRandomPositionAtStart_cache; public FieldVar varOpenRandomPositionAtStart() { if (varOpenRandomPositionAtStart_cache == null) varOpenRandomPositionAtStart_cache = varOpenRandomPositionAtStart_load(); return varOpenRandomPositionAtStart_cache; } public FieldVar varOpenRandomPositionAtStart_load() { return new FieldVar(this, "openRandomPositionAtStart", () -> openRandomPositionAtStart(), openRandomPositionAtStart -> openRandomPositionAtStart(openRandomPositionAtStart)); } final public Corridor setOpenRandomPositionAtStart(boolean openRandomPositionAtStart) { return openRandomPositionAtStart(openRandomPositionAtStart); } public Corridor openRandomPositionAtStart(boolean openRandomPositionAtStart) { if (!eq(this.openRandomPositionAtStart, openRandomPositionAtStart)) { this.openRandomPositionAtStart = openRandomPositionAtStart; change(); } return this; } final public boolean getOpenRandomPositionAtStart() { return openRandomPositionAtStart(); } public boolean openRandomPositionAtStart() { return openRandomPositionAtStart; } public boolean openRandomPositionAtStart = true; public transient FieldVar varOpenFixedDirectionAtStart_cache; public FieldVar varOpenFixedDirectionAtStart() { if (varOpenFixedDirectionAtStart_cache == null) varOpenFixedDirectionAtStart_cache = varOpenFixedDirectionAtStart_load(); return varOpenFixedDirectionAtStart_cache; } public FieldVar varOpenFixedDirectionAtStart_load() { return new FieldVar(this, "openFixedDirectionAtStart", () -> openFixedDirectionAtStart(), openFixedDirectionAtStart -> openFixedDirectionAtStart(openFixedDirectionAtStart)); } final public Corridor setOpenFixedDirectionAtStart(int openFixedDirectionAtStart) { return openFixedDirectionAtStart(openFixedDirectionAtStart); } public Corridor openFixedDirectionAtStart(int openFixedDirectionAtStart) { if (!eq(this.openFixedDirectionAtStart, openFixedDirectionAtStart)) { this.openFixedDirectionAtStart = openFixedDirectionAtStart; change(); } return this; } final public int getOpenFixedDirectionAtStart() { return openFixedDirectionAtStart(); } public int openFixedDirectionAtStart() { return openFixedDirectionAtStart; } public int openFixedDirectionAtStart; public transient FieldVar varAlwaysOpenTwoPositions_cache; public FieldVar varAlwaysOpenTwoPositions() { if (varAlwaysOpenTwoPositions_cache == null) varAlwaysOpenTwoPositions_cache = varAlwaysOpenTwoPositions_load(); return varAlwaysOpenTwoPositions_cache; } public FieldVar varAlwaysOpenTwoPositions_load() { return new FieldVar(this, "alwaysOpenTwoPositions", () -> alwaysOpenTwoPositions(), alwaysOpenTwoPositions -> alwaysOpenTwoPositions(alwaysOpenTwoPositions)); } final public Corridor setAlwaysOpenTwoPositions(boolean alwaysOpenTwoPositions) { return alwaysOpenTwoPositions(alwaysOpenTwoPositions); } public Corridor alwaysOpenTwoPositions(boolean alwaysOpenTwoPositions) { if (!eq(this.alwaysOpenTwoPositions, alwaysOpenTwoPositions)) { this.alwaysOpenTwoPositions = alwaysOpenTwoPositions; change(); } return this; } final public boolean getAlwaysOpenTwoPositions() { return alwaysOpenTwoPositions(); } public boolean alwaysOpenTwoPositions() { return alwaysOpenTwoPositions; } public boolean alwaysOpenTwoPositions = false; public transient FieldVar varEndStrategyWhenCapacityExceeded_cache; public FieldVar varEndStrategyWhenCapacityExceeded() { if (varEndStrategyWhenCapacityExceeded_cache == null) varEndStrategyWhenCapacityExceeded_cache = varEndStrategyWhenCapacityExceeded_load(); return varEndStrategyWhenCapacityExceeded_cache; } public FieldVar varEndStrategyWhenCapacityExceeded_load() { return new FieldVar(this, "endStrategyWhenCapacityExceeded", () -> endStrategyWhenCapacityExceeded(), endStrategyWhenCapacityExceeded -> endStrategyWhenCapacityExceeded(endStrategyWhenCapacityExceeded)); } final public Corridor setEndStrategyWhenCapacityExceeded(boolean endStrategyWhenCapacityExceeded) { return endStrategyWhenCapacityExceeded(endStrategyWhenCapacityExceeded); } public Corridor endStrategyWhenCapacityExceeded(boolean endStrategyWhenCapacityExceeded) { if (!eq(this.endStrategyWhenCapacityExceeded, endStrategyWhenCapacityExceeded)) { this.endStrategyWhenCapacityExceeded = endStrategyWhenCapacityExceeded; change(); } return this; } final public boolean getEndStrategyWhenCapacityExceeded() { return endStrategyWhenCapacityExceeded(); } public boolean endStrategyWhenCapacityExceeded() { return endStrategyWhenCapacityExceeded; } public boolean endStrategyWhenCapacityExceeded = true; public transient FieldVar varUseStrategyJuicer_cache; public FieldVar varUseStrategyJuicer() { if (varUseStrategyJuicer_cache == null) varUseStrategyJuicer_cache = varUseStrategyJuicer_load(); return varUseStrategyJuicer_cache; } public FieldVar varUseStrategyJuicer_load() { return new FieldVar(this, "useStrategyJuicer", () -> useStrategyJuicer(), useStrategyJuicer -> useStrategyJuicer(useStrategyJuicer)); } final public Corridor setUseStrategyJuicer(boolean useStrategyJuicer) { return useStrategyJuicer(useStrategyJuicer); } public Corridor useStrategyJuicer(boolean useStrategyJuicer) { if (!eq(this.useStrategyJuicer, useStrategyJuicer)) { this.useStrategyJuicer = useStrategyJuicer; change(); } return this; } final public boolean getUseStrategyJuicer() { return useStrategyJuicer(); } public boolean useStrategyJuicer() { return useStrategyJuicer; } public boolean useStrategyJuicer = false; public transient FieldVar varProfitLevel1_cache; public FieldVar varProfitLevel1() { if (varProfitLevel1_cache == null) varProfitLevel1_cache = varProfitLevel1_load(); return varProfitLevel1_cache; } public FieldVar varProfitLevel1_load() { return new FieldVar(this, "profitLevel1", () -> profitLevel1(), profitLevel1 -> profitLevel1(profitLevel1)); } final public Corridor setProfitLevel1(double profitLevel1) { return profitLevel1(profitLevel1); } public Corridor profitLevel1(double profitLevel1) { if (!eq(this.profitLevel1, profitLevel1)) { this.profitLevel1 = profitLevel1; change(); } return this; } final public double getProfitLevel1() { return profitLevel1(); } public double profitLevel1() { return profitLevel1; } public double profitLevel1 = 0.1; public transient FieldVar varKeepPercentage1_cache; public FieldVar varKeepPercentage1() { if (varKeepPercentage1_cache == null) varKeepPercentage1_cache = varKeepPercentage1_load(); return varKeepPercentage1_cache; } public FieldVar varKeepPercentage1_load() { return new FieldVar(this, "keepPercentage1", () -> keepPercentage1(), keepPercentage1 -> keepPercentage1(keepPercentage1)); } final public Corridor setKeepPercentage1(double keepPercentage1) { return keepPercentage1(keepPercentage1); } public Corridor keepPercentage1(double keepPercentage1) { if (!eq(this.keepPercentage1, keepPercentage1)) { this.keepPercentage1 = keepPercentage1; change(); } return this; } final public double getKeepPercentage1() { return keepPercentage1(); } public double keepPercentage1() { return keepPercentage1; } public double keepPercentage1 = 50; public transient FieldVar varProfitLevel2_cache; public FieldVar varProfitLevel2() { if (varProfitLevel2_cache == null) varProfitLevel2_cache = varProfitLevel2_load(); return varProfitLevel2_cache; } public FieldVar varProfitLevel2_load() { return new FieldVar(this, "profitLevel2", () -> profitLevel2(), profitLevel2 -> profitLevel2(profitLevel2)); } final public Corridor setProfitLevel2(double profitLevel2) { return profitLevel2(profitLevel2); } public Corridor profitLevel2(double profitLevel2) { if (!eq(this.profitLevel2, profitLevel2)) { this.profitLevel2 = profitLevel2; change(); } return this; } final public double getProfitLevel2() { return profitLevel2(); } public double profitLevel2() { return profitLevel2; } public double profitLevel2; public transient FieldVar varKeepPercentage2_cache; public FieldVar varKeepPercentage2() { if (varKeepPercentage2_cache == null) varKeepPercentage2_cache = varKeepPercentage2_load(); return varKeepPercentage2_cache; } public FieldVar varKeepPercentage2_load() { return new FieldVar(this, "keepPercentage2", () -> keepPercentage2(), keepPercentage2 -> keepPercentage2(keepPercentage2)); } final public Corridor setKeepPercentage2(double keepPercentage2) { return keepPercentage2(keepPercentage2); } public Corridor keepPercentage2(double keepPercentage2) { if (!eq(this.keepPercentage2, keepPercentage2)) { this.keepPercentage2 = keepPercentage2; change(); } return this; } final public double getKeepPercentage2() { return keepPercentage2(); } public double keepPercentage2() { return keepPercentage2; } public double keepPercentage2; public transient FieldVar varProfitLevel3_cache; public FieldVar varProfitLevel3() { if (varProfitLevel3_cache == null) varProfitLevel3_cache = varProfitLevel3_load(); return varProfitLevel3_cache; } public FieldVar varProfitLevel3_load() { return new FieldVar(this, "profitLevel3", () -> profitLevel3(), profitLevel3 -> profitLevel3(profitLevel3)); } final public Corridor setProfitLevel3(double profitLevel3) { return profitLevel3(profitLevel3); } public Corridor profitLevel3(double profitLevel3) { if (!eq(this.profitLevel3, profitLevel3)) { this.profitLevel3 = profitLevel3; change(); } return this; } final public double getProfitLevel3() { return profitLevel3(); } public double profitLevel3() { return profitLevel3; } public double profitLevel3; public transient FieldVar varKeepPercentage3_cache; public FieldVar varKeepPercentage3() { if (varKeepPercentage3_cache == null) varKeepPercentage3_cache = varKeepPercentage3_load(); return varKeepPercentage3_cache; } public FieldVar varKeepPercentage3_load() { return new FieldVar(this, "keepPercentage3", () -> keepPercentage3(), keepPercentage3 -> keepPercentage3(keepPercentage3)); } final public Corridor setKeepPercentage3(double keepPercentage3) { return keepPercentage3(keepPercentage3); } public Corridor keepPercentage3(double keepPercentage3) { if (!eq(this.keepPercentage3, keepPercentage3)) { this.keepPercentage3 = keepPercentage3; change(); } return this; } final public double getKeepPercentage3() { return keepPercentage3(); } public double keepPercentage3() { return keepPercentage3; } public double keepPercentage3; public transient FieldVar varMaxLoss_cache; public FieldVar varMaxLoss() { if (varMaxLoss_cache == null) varMaxLoss_cache = varMaxLoss_load(); return varMaxLoss_cache; } public FieldVar varMaxLoss_load() { return new FieldVar(this, "maxLoss", () -> maxLoss(), maxLoss -> maxLoss(maxLoss)); } final public Corridor setMaxLoss(double maxLoss) { return maxLoss(maxLoss); } public Corridor maxLoss(double maxLoss) { if (!eq(this.maxLoss, maxLoss)) { this.maxLoss = maxLoss; change(); } return this; } final public double getMaxLoss() { return maxLoss(); } public double maxLoss() { return maxLoss; } public double maxLoss = 0.5; transient public IF0 makeJuicer; public MultiPullbackJuicer makeJuicer() { return makeJuicer != null ? makeJuicer.get() : makeJuicer_base(); } final public MultiPullbackJuicer makeJuicer_fallback(IF0 _f) { return _f != null ? _f.get() : makeJuicer_base(); } public MultiPullbackJuicer makeJuicer_base() { MultiPullbackJuicer j = new MultiPullbackJuicer(); j.stopLossLimit(-maxLoss); j.stopLossEnabled(true); for (int i = 1; i <= 3; i++) { double profitLevel = toDouble(get(this, "profitLevel" + i)); double keepPercentage = toDouble(get(this, "keepPercentage" + i)); if (profitLevel != 0 || keepPercentage != 0) j.addLevel(profitLevel, keepPercentage); } return j; } public transient FieldVar varCloseSignal_cache; public FieldVar varCloseSignal() { if (varCloseSignal_cache == null) varCloseSignal_cache = varCloseSignal_load(); return varCloseSignal_cache; } public FieldVar varCloseSignal_load() { return new FieldVar(this, "closeSignal", () -> closeSignal(), closeSignal -> closeSignal(closeSignal)); } final public Corridor setCloseSignal(SignalWithStrength closeSignal) { return closeSignal(closeSignal); } public Corridor closeSignal(SignalWithStrength closeSignal) { if (!eq(this.closeSignal, closeSignal)) { this.closeSignal = closeSignal; change(); } return this; } final public SignalWithStrength getCloseSignal() { return closeSignal(); } public SignalWithStrength closeSignal() { return closeSignal; } public SignalWithStrength closeSignal; public class Position extends G22TradingStrategy.Position { public Position() { } } public Position openPosition(int direction) { if (l(positionsInDirection(direction)) >= maxPositionsPerDirection) { log("Not opening new position in direction " + direction + ", max reached"); return null; } Position p = new Position(); p.marginToUse = marginPerPosition * abs(direction); return openPosition(p, direction); } public void start() { if (started()) throw fail("Already started"); if (currentPrice() == 0) { primed(true); return; } startingPrice = currentPrice(); startTime = currentTime(); var priceCells = makePriceCells(startingPrice); print("Made price cells: " + priceCells); digitizer = new PriceDigitizer2(priceCells); digitizer.verbose(verbose); makeStrategyJuicer(); log("Starting CORRIDOR at " + startingPrice + " +/- " + cellSize); startAction(); } transient public Runnable startAction; public void startAction() { if (startAction != null) startAction.run(); else startAction_base(); } final public void startAction_fallback(Runnable _f) { if (_f != null) _f.run(); else startAction_base(); } public void startAction_base() { if (openTwoPositionsAtStart) { nextStep(); openPosition(1); openPosition(-1); afterStep(); } else if (openRandomPositionAtStart) { nextStep(); log("Opening random initial position."); openPosition(securelyTossCoin() ? 1 : -1); afterStep(); } else if (openFixedDirectionAtStart != 0) { nextStep(); log("Opening fixed initial position."); openPosition(sign(openFixedDirectionAtStart)); afterStep(); } } public void price(double price) { if (currentPrice == price) return; currentPrice = price; if (hasClosedItself()) return; if (!started()) { if (primed) { primed(false); start(); } else return; } digitizer.digitize(price); direction = sign(digitizedPrice() - lastDigitizedPrice()); if (applyStrategyJuicer()) return; if (direction == 0) { afterStep(); return; } nextStep(); if (started()) step(); print(this); } public boolean applyStrategyJuicer() { closeSignal(strongestSignal(strategyJuicer == null ? null : strategyJuicer.calculateCloseSignals())); if (closeSignal != null && closeSignal.isTrigger()) { log("Juicer close signal! " + closeSignal); closeOrRestart(); afterStep(); return true; } return false; } transient public Runnable step; public void step() { if (step != null) step.run(); else step_base(); } final public void step_fallback(Runnable _f) { if (_f != null) _f.run(); else step_base(); } public void step_base() { double p1 = lastDigitizedPrice(); double p2 = digitizedPrice(); direction = sign(p2 - p1); if (direction == 0) return; List toClose = new ArrayList(); for (var p : direction > 0 ? longPositionsAtOrBelowDigitizedPrice(p1) : shortPositionsAtOrAboveDigitizedPrice(p1)) { ((Position) p).closeReason("WIN"); log("Closing winner position at " + formatPriceX(currentPrice) + " (" + p1 + " -> " + p2 + "): " + ((Position) p)); toClose.add((Position) p); } double limit = fromCellNumber(toCellNumber(digitizedPrice()) - capacity * direction); var toDismantle = direction > 0 ? shortPositionsAtOrBelowDigitizedPrice(limit) : longPositionsAtOrAboveDigitizedPrice(limit); if (logToPrint) printVars("dismantleLimit", formatPriceX(limit), "direction", direction, "capacity", capacity, "digitizedPrice", digitizedPrice(), "toDismantle", toDismantle); if (nempty(toDismantle)) { if (endStrategyWhenCapacityExceeded) { log("Capacity exceeded!"); closeOrRestart(); afterStep(); return; } else { for (var p : toDismantle) { ((Position) p).closeReason("DISMANTLE"); toClose.add((Position) p); } } } if (nempty(toClose)) closePositions(toClose); afterStep(); openNewPositionAfterMove(); afterStep(); } public void closeOrRestart() { if (instantRestart) restart(); else closeMyself(); } public void restart() { closeMyself(); active(true); closedItself(0); startAction(); } transient public Runnable openNewPositionAfterMove; public void openNewPositionAfterMove() { if (openNewPositionAfterMove != null) openNewPositionAfterMove.run(); else openNewPositionAfterMove_base(); } final public void openNewPositionAfterMove_fallback(Runnable _f) { if (_f != null) _f.run(); else openNewPositionAfterMove_base(); } public void openNewPositionAfterMove_base() { openPositionIfNotThere(-direction); if (alwaysOpenTwoPositions) openPositionIfNotThere(direction); } public Position openPositionIfNotThere(int direction) { if (!hasPosition(digitizedPrice(), direction)) return openPosition(direction); else return null; } transient public IF0 mainDesc; public String mainDesc() { return mainDesc != null ? mainDesc.get() : mainDesc_base(); } final public String mainDesc_fallback(IF0 _f) { return _f != null ? _f.get() : mainDesc_base(); } public String mainDesc_base() { String __1 = renderCustomName(); if (!empty(__1)) return __1; return capacity + "x" + formatCellSize(cellSize) + " Corridor"; } public String baseToString() { return colonCombine(_conceptID() == 0 ? "" : "Strategy " + _conceptID(), spaceCombine(squareBracketUnlessEmpty(areaDesc()), mainDesc(), nempty(cryptoCoin) ? "on " + cryptoCoin : "")); } public List status() { var r = currentCorridorPriceRange(); return listCombine(super.status(), "Max capacity: " + capacity, !started() ? null : "Current corridor: " + (r == null ? "-" : formatPrice(r.start) + " to " + formatPrice(r.end) + " (" + formatPercentage(currentCorridorSizeInPercent(), 3) + ")"), "Profit unit: " + formatMarginPrice(profitUnitBeforeAdversity()) + "/" + marginCoin + " " + formatMarginPrice(profitUnitAfterAdversity()) + ", loss unit: " + marginCoin + " " + formatMarginPrice(lossUnit()), closeSignal == null ? null : "Close signal: " + closeSignal); } public String toString() { return baseToString(); } public String renderCustomName() { return empty(customName) ? null : simpleQuoteOpt(trim(customName)); } public double maxCorridorPercentSize() { return capacity * cellSize; } public DoubleRange currentCorridorPriceRange() { double[] openingPrices = mapToDoubleArray(openPositions, __2 -> __2.openingPrice); return doubleRange(doubleMin(openingPrices), doubleMax(openingPrices)); } public double currentCorridorSizeInPercent() { DoubleRange r = currentCorridorPriceRange(); return r == null ? 0 : asPercentIncrease(r.end, r.start); } public Position openShort() { return openPosition(-1); } public Position openLong() { return openPosition(1); } { cellSize(3.0); } public double positionSize() { return marginPerPosition * leverage; } public double profitUnitBeforeAdversity() { return cellSize / 100 * positionSize(); } public double profitUnitAfterAdversity() { return (cellSize - adversity) / 100 * positionSize(); } public double lossUnit() { return (cellSize + adversity) / 100 * positionSize(); } public class ProfitUnitsJuiceable implements Juiceable { public double juiceValue() { return coinProfit() / profitUnitBeforeAdversity(); } } public void updateStrategyJuicer() { if (strategyJuicer != null) { makeStrategyJuicer(); applyStrategyJuicer(); } } public void makeStrategyJuicer() { if (!useStrategyJuicer) { strategyJuicer(null); return; } var j = makeJuicer(); j.copyTransientValuesFrom(strategyJuicer); j.juiceable(new ProfitUnitsJuiceable()); strategyJuicer(j); } public String fieldsToReset() { return lines(ll(super.fieldsToReset(), "closeSignal strategyJuicer")); } public double currentCellNumber() { return toCellNumber(currentPrice()); } public int currentDigitizedCell() { return iround(toCellNumber(digitizedPrice())); } public int priceDirection() { return sign(currentCellNumber() - currentDigitizedCell()); } public int targetCell() { return currentDigitizedCell() + priceDirection(); } public double targetPrice() { return fromCellNumber(targetCell()); } public double targetProfit() { return coinProfitAtPrice(targetPrice()); } public int profitDirection() { return sign(targetProfit() - coinProfit()); } public double progressInProfitDirection() { return absDiff(currentCellNumber(), currentDigitizedCell()) * 100; } } static public class G22BurnIn { final public G22BurnIn setAlphaStep(double alphaStep) { return alphaStep(alphaStep); } public G22BurnIn alphaStep(double alphaStep) { this.alphaStep = alphaStep; return this; } final public double getAlphaStep() { return alphaStep(); } public double alphaStep() { return alphaStep; } public double alphaStep = 0.1; final public G22BurnIn setTolerance(double tolerance) { return tolerance(tolerance); } public G22BurnIn tolerance(double tolerance) { this.tolerance = tolerance; return this; } final public double getTolerance() { return tolerance(); } public double tolerance() { return tolerance; } public double tolerance = 0.1; final public G22BurnIn setColorMorph(double colorMorph) { return colorMorph(colorMorph); } public G22BurnIn colorMorph(double colorMorph) { this.colorMorph = colorMorph; return this; } final public double getColorMorph() { return colorMorph(); } public double colorMorph() { return colorMorph; } public double colorMorph = 0.1; final public G22BurnIn setBackgroundColor(Color backgroundColor) { return backgroundColor(backgroundColor); } public G22BurnIn backgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; return this; } final public Color getBackgroundColor() { return backgroundColor(); } public Color backgroundColor() { return backgroundColor; } public Color backgroundColor = Color.black; public int toleranceSquaredInt; public int w, h; public int[] mask; public double motionFactor = Double.NaN; public void processFrame(BufferedImage frame) { toleranceSquaredInt = iround(sqr(tolerance * 255) * 3); int w = frame.getWidth(), h = frame.getHeight(); if (mask == null || this.w != w || this.h != h) { this.w = w; this.h = h; this.mask = new int[w * h]; } var gp = grabbableIntPixels_fastOrSlow(frame); int n = w * h, iMask = 0, iFrame = gp.offset; int[] pixels = gp.data; int[] mask = this.mask; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int mpix = mask[iMask]; int fcol = pixels[iFrame++] & 0xFFFFFF; if (mpix == 0) mpix = differentColor(mpix, fcol); else { int mcol = mpix & 0xFFFFFF; int diff = rgbDistanceSquaredInt(mcol, fcol); if (diff <= toleranceSquaredInt) mpix = sameColor(mpix, fcol); else mpix = differentColor(mpix, fcol); } mask[iMask++] = mpix; } iFrame += gp.scanlineStride - w; } motionFactor = Double.NaN; } public boolean isSameColor(int col1, int col2) { return toleranceSquaredInt == 0 ? col1 == col2 : rgbDistanceSquaredInt(col1, col2) <= tolerance; } public int sameColor(int mpix, int fcol) { double newAlpha = rgbAlphaZeroToOne(mpix) + alphaStep; int newColor = blendRGBInts(mpix, fcol, colorMorph); return withAlpha(newAlpha, newColor); } public int differentColor(int mpix, int fcol) { return withAlpha(alphaStep, fcol); } final public BufferedImage image() { return stillImage(); } public BufferedImage stillImage() { if (mask == null) return null; var img = bufferedImage(w, h, mask); return renderImageOnBackground(backgroundColor, img); } public BufferedImage motionImage() { if (mask == null) return null; int[] mask2 = pixelsWithInvertedAlpha(mask); var img = bufferedImage(w, h, mask2); return renderImageOnBackground(backgroundColor, img); } public BWImage motionDetectionImage() { return new BWImage(w, h, alphaChannelFromPixels(mask)); } public double motionFactor() { if (isNaN(motionFactor) && mask != null) motionFactor = 1 - alphaChannelAverage(mask) / 255.0; return motionFactor; } } static public class ListWithChangeListeners extends NotifyingList implements IHasChangeListeners { transient public Set onChange; public ListWithChangeListeners onChange(Runnable r) { onChange = createOrAddToSyncLinkedHashSet(onChange, r); return this; } public ListWithChangeListeners removeChangeListener(Runnable r) { loadableUtils.utils.remove(onChange, r); return this; } public void fireChange() { if (onChange != null) for (var listener : onChange) pcallF_typed(listener); } public void change() { fireChange(); } public ListWithChangeListeners() { super(new ArrayList()); } } static public class G22SnPSelector extends MetaWithChangeListeners implements Swingable { final public G22SnPSelector setSettings(SnPSettings settings) { return settings(settings); } public G22SnPSelector settings(SnPSettings settings) { this.settings = settings; return this; } final public SnPSettings getSettings() { return settings(); } public SnPSettings settings() { return settings; } public SnPSettings settings = new SnPSettings(); public transient FieldVar varPowerOfTwoColors_cache; public FieldVar varPowerOfTwoColors() { if (varPowerOfTwoColors_cache == null) varPowerOfTwoColors_cache = varPowerOfTwoColors_load(); return varPowerOfTwoColors_cache; } public FieldVar varPowerOfTwoColors_load() { return new FieldVar(this, "powerOfTwoColors", () -> powerOfTwoColors(), powerOfTwoColors -> powerOfTwoColors(powerOfTwoColors)); } final public G22SnPSelector setPowerOfTwoColors(boolean powerOfTwoColors) { return powerOfTwoColors(powerOfTwoColors); } public G22SnPSelector powerOfTwoColors(boolean powerOfTwoColors) { if (!eq(this.powerOfTwoColors, powerOfTwoColors)) { this.powerOfTwoColors = powerOfTwoColors; change(); } return this; } final public boolean getPowerOfTwoColors() { return powerOfTwoColors(); } public boolean powerOfTwoColors() { return powerOfTwoColors; } public boolean powerOfTwoColors = false; public transient FieldVar varPowerOfTwoPixelRows_cache; public FieldVar varPowerOfTwoPixelRows() { if (varPowerOfTwoPixelRows_cache == null) varPowerOfTwoPixelRows_cache = varPowerOfTwoPixelRows_load(); return varPowerOfTwoPixelRows_cache; } public FieldVar varPowerOfTwoPixelRows_load() { return new FieldVar(this, "powerOfTwoPixelRows", () -> powerOfTwoPixelRows(), powerOfTwoPixelRows -> powerOfTwoPixelRows(powerOfTwoPixelRows)); } final public G22SnPSelector setPowerOfTwoPixelRows(boolean powerOfTwoPixelRows) { return powerOfTwoPixelRows(powerOfTwoPixelRows); } public G22SnPSelector powerOfTwoPixelRows(boolean powerOfTwoPixelRows) { if (!eq(this.powerOfTwoPixelRows, powerOfTwoPixelRows)) { this.powerOfTwoPixelRows = powerOfTwoPixelRows; change(); } return this; } final public boolean getPowerOfTwoPixelRows() { return powerOfTwoPixelRows(); } public boolean powerOfTwoPixelRows() { return powerOfTwoPixelRows; } public boolean powerOfTwoPixelRows = true; final public G22SnPSelector setMaxPixelRows(int maxPixelRows) { return maxPixelRows(maxPixelRows); } public G22SnPSelector maxPixelRows(int maxPixelRows) { this.maxPixelRows = maxPixelRows; return this; } final public int getMaxPixelRows() { return maxPixelRows(); } public int maxPixelRows() { return maxPixelRows; } public int maxPixelRows = 512; public transient FieldVar varAllowDecolorizerSelection_cache; public FieldVar varAllowDecolorizerSelection() { if (varAllowDecolorizerSelection_cache == null) varAllowDecolorizerSelection_cache = varAllowDecolorizerSelection_load(); return varAllowDecolorizerSelection_cache; } public FieldVar varAllowDecolorizerSelection_load() { return new FieldVar(this, "allowDecolorizerSelection", () -> allowDecolorizerSelection(), allowDecolorizerSelection -> allowDecolorizerSelection(allowDecolorizerSelection)); } final public G22SnPSelector setAllowDecolorizerSelection(boolean allowDecolorizerSelection) { return allowDecolorizerSelection(allowDecolorizerSelection); } public G22SnPSelector allowDecolorizerSelection(boolean allowDecolorizerSelection) { if (!eq(this.allowDecolorizerSelection, allowDecolorizerSelection)) { this.allowDecolorizerSelection = allowDecolorizerSelection; change(); } return this; } final public boolean getAllowDecolorizerSelection() { return allowDecolorizerSelection(); } public boolean allowDecolorizerSelection() { return allowDecolorizerSelection; } public boolean allowDecolorizerSelection = false; public transient FieldVar varShowDecolorizerSelection_cache; public FieldVar varShowDecolorizerSelection() { if (varShowDecolorizerSelection_cache == null) varShowDecolorizerSelection_cache = varShowDecolorizerSelection_load(); return varShowDecolorizerSelection_cache; } public FieldVar varShowDecolorizerSelection_load() { return new FieldVar(this, "showDecolorizerSelection", () -> showDecolorizerSelection(), showDecolorizerSelection -> showDecolorizerSelection(showDecolorizerSelection)); } final public G22SnPSelector setShowDecolorizerSelection(boolean showDecolorizerSelection) { return showDecolorizerSelection(showDecolorizerSelection); } public G22SnPSelector showDecolorizerSelection(boolean showDecolorizerSelection) { if (!eq(this.showDecolorizerSelection, showDecolorizerSelection)) { this.showDecolorizerSelection = showDecolorizerSelection; change(); } return this; } final public boolean getShowDecolorizerSelection() { return showDecolorizerSelection(); } public boolean showDecolorizerSelection() { return showDecolorizerSelection; } public boolean showDecolorizerSelection = false; public JLabel lblColors; public SingleComponentPanel scpDecolorizer = scp(); public G22SnPSelector() { } public G22SnPSelector(SnPSettings settings) { this.settings = settings; } public SnPSettings get() { return settings; } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { var colors = jListSpinner(colorsList(), settings.colors); loadableUtils.utils.onChange(colors, () -> { settings.colors = intFromSpinner(colors); change(); }); varPowerOfTwoColors().onChange(() -> spinnerSetNumberList(colors, colorsList())); { swing(() -> { var menuItem = jLiveValueCheckBoxMenuItem("Only show powers of two", varPowerOfTwoColors()); JPopupMenu menu = new JPopupMenu(); menu.add(menuItem); colors.setComponentPopupMenu(menu); }); } var pixelRows = jListSpinner(pixelRowsList(), settings.pixelRows); loadableUtils.utils.onChange(pixelRows, () -> { settings.pixelRows = intFromSpinner(pixelRows); change(); }); varPowerOfTwoPixelRows().onChange(() -> spinnerSetNumberList(pixelRows, pixelRowsList())); { swing(() -> { var menuItem = jLiveValueCheckBoxMenuItem("Only show powers of two", varPowerOfTwoPixelRows()); JPopupMenu menu = new JPopupMenu(); menu.add(menuItem); pixelRows.setComponentPopupMenu(menu); }); } lblColors = jSimpleLabel(" colors "); bindChangeListenerToComponent(this, lblColors, () -> toolTip(lblColors, makeToolTip())); List controls = ll(colors, lblColors, scpDecolorizer, jSimpleLabel("@ "), pixelRows, jlabel(" p")); if (allowDecolorizerSelection) { varShowDecolorizerSelection().onChangeAndNow(() -> updateDecolorizerView()); controls.add(horizontalStrut(3)); controls.add(jPopDownButton_noText(jLiveValueCheckBoxMenuItem("Select channel", varShowDecolorizerSelection()))); } var vis = hstack(controls); bindChangeListenerToComponent(settings, vis, () -> change()); return vis; } public List colorsList() { return powerOfTwoColors ? powersOfTwoUpTo(2, 256) : virtualCountList_incl(2, 256); } public List pixelRowsList() { return powerOfTwoPixelRows ? powersOfTwoUpTo(maxPixelRows) : virtualCountList_incl(1, maxPixelRows); } public String makeToolTip() { long pixels = area(sixteenToNine_p(settings.pixelRows)); int colorBits = numberOfBitsNeededToRepresentNOptions(settings.colors); int bytes = iceil_div(pixels * colorBits, 8); return "Information per frame: " + nBytes(bytes) + " (assuming a 16:9 aspect ratio)"; } public List decolorizerList() { return ll(new Decolorizer.Simple(), new Decolorizer.Red(), new Decolorizer.Green(), new Decolorizer.Blue()); } public void updateDecolorizerView() { if (!showDecolorizerSelection) { scpDecolorizer.clear(); settings.decolorizer(null); } else { if (settings.decolorizer == null) settings.decolorizer(new Decolorizer.Simple()); scpDecolorizer.set(hstack(jlabel("from channel "), bindComboBoxToVar(settings.varDecolorizer(), jTypedComboBox(decolorizerList())), horizontalStrut(3))); } } } static public class Image2BAsLongs implements IBinaryImage { public Image2BAsLongs() { } public int w, h; final public long[] getPixels() { return pixels(); } public long[] pixels() { return pixels; } public long[] pixels; public Image2BAsLongs(int w, int h, long[] pixels) { this.pixels = pixels; this.h = h; this.w = w; cleanPixelArray(); } public Image2BAsLongs(Image2B img) { w = img.getWidth(); h = img.getHeight(); pixels = longArrayFromBytes_littleEndian_flexLength(img.pixels); } public Image2BAsLongs(Image2BAsLongs img) { w = img.getWidth(); h = img.getHeight(); pixels = cloneLongArray(img.pixels); } public Image2BAsLongs(RGBImage img) { w = img.getWidth(); h = img.getHeight(); pixels = new long[(w * h + 63) / 64]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) if (img.getPixel(x, y).getBrightness() >= 0.5f) { int i = y * w + x; pixels[i / 64] |= 1L << (i & 63); } } public Image2BAsLongs(BWImage img) { this(img, 128); } public Image2BAsLongs(BWImage img, int threshold) { w = img.w(); h = img.h(); int n = w * h; int nOut = (n + 63) / 64; long[] pixels = this.pixels = new long[nOut]; byte[] bwPixels = img.pixels; int iIn = 0; for (int iOut = 0; iOut < nOut - 1; iOut++) { long value = 0; for (int bit = 0; bit < 64; bit++) { value >>>= 1; if (ubyteToInt(bwPixels[iIn++]) >= threshold) value |= 0x80000000; } pixels[iOut] = value; } for (; iIn < n; iIn++) if (ubyteToInt(bwPixels[iIn]) >= threshold) pixels[nOut - 1] |= 1L << (iIn & 63); } public Image2BAsLongs(BufferedImage img) { this(img, 128); } public Image2BAsLongs(BufferedImage img, int threshold) { this(new BWImage(img), threshold); } public Image2BAsLongs(int w, int h) { this.h = h; this.w = w; pixels = new long[(w * h + 63) / 64]; } public RGBImage toRGB() { RGBImage img = new RGBImage(w, h, Color.black); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 64] & (1L << (i & 63))) != 0) img.setPixel(x, y, Color.white); } return img; } public BWImage toBW() { BWImage img = new BWImage(w, h, 0f); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 64] & (1L << (i & 63))) != 0) img.setPixel(x, y, 1f); } return img; } public BufferedImage getBufferedImage() { return toBW().getBufferedImage(); } final public boolean getBoolPixel(int x, int y) { return getPixel(x, y); } public boolean getPixel(int x, int y) { int i = y * w + x; return (pixels[i / 64] & (1L << (i & 63))) != 0; } final public boolean getBoolPixel(int x, int y, boolean defaultColor) { return getPixel(x, y, defaultColor); } public boolean getPixel(int x, int y, boolean defaultColor) { if (x < 0 || y < 0 || x >= w || y >= h) return defaultColor; return getPixel(x, y); } public void setPixel(int x, int y, boolean b) { int i = y * w + x; long val = pixels[i / 64], shifted = 1L << (i & 63); val = b ? val | shifted : val & ~shifted; pixels[i / 64] = val; } public void setPixel(int x, int y) { int i = y * w + x; pixels[i / 64] |= 1L << (i & 63); } public int getWidth() { return w; } public int getHeight() { return h; } public String toString() { return "Image2B " + str_px(w, h); } public void cleanPixelArray() { int n = w * h; if ((n & 63) != 0) pixels[n / 64] &= (1L << (n & 63)) - 1; } } static public class G22SkeletonToMesh_v2 implements Steppable, IFieldsToList { public IImageRegion region; public G22SkeletonToMesh_v2() { } public G22SkeletonToMesh_v2(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public G22SkeletonToMesh_v2 setDebug(boolean debug) { return debug(debug); } public G22SkeletonToMesh_v2 debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug() { return debug(); } public boolean debug() { return debug; } public boolean debug = false; final public G22SkeletonToMesh_v2 setDebugDroppingUnnecessaryAnchors(boolean debugDroppingUnnecessaryAnchors) { return debugDroppingUnnecessaryAnchors(debugDroppingUnnecessaryAnchors); } public G22SkeletonToMesh_v2 debugDroppingUnnecessaryAnchors(boolean debugDroppingUnnecessaryAnchors) { this.debugDroppingUnnecessaryAnchors = debugDroppingUnnecessaryAnchors; return this; } final public boolean getDebugDroppingUnnecessaryAnchors() { return debugDroppingUnnecessaryAnchors(); } public boolean debugDroppingUnnecessaryAnchors() { return debugDroppingUnnecessaryAnchors; } public boolean debugDroppingUnnecessaryAnchors = false; final public G22SkeletonToMesh_v2 setAutoSimplify(boolean autoSimplify) { return autoSimplify(autoSimplify); } public G22SkeletonToMesh_v2 autoSimplify(boolean autoSimplify) { this.autoSimplify = autoSimplify; return this; } final public boolean getAutoSimplify() { return autoSimplify(); } public boolean autoSimplify() { return autoSimplify; } public boolean autoSimplify = true; final public G22Mesh getMesh() { return mesh(); } public G22Mesh mesh() { return mesh; } public G22Mesh mesh; public IterableIterator regionIterator; public List queue = new ArrayList(); public PtSet pointsSeen = new PtSet(); static public class WorkItem implements IFieldsToList { public G22Mesh.Anchor anchor; public Pt p; public WorkItem() { } public WorkItem(G22Mesh.Anchor anchor, Pt p) { this.p = p; this.anchor = anchor; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + anchor + ", " + p + ")"; } public Object[] _fieldsToList() { return new Object[] { anchor, p }; } } public G22Mesh get() { if (mesh == null) run(); return mesh; } public void run() { stepAll(this); } public boolean step() { if (mesh == null) { regionIterator = region.pixelIterator(); mesh = new G22Mesh(); setMetaSrc(mesh, this); } if (nempty(queue)) { WorkItem work = popLast(queue); Pt p = work.p; PtBuffer curvePoints = new PtBuffer(); curvePoints.add(work.anchor.pt); G22Mesh.Anchor endAnchor = null; if (debug) print("Exploring from " + work.anchor.pt + " / " + p); while (true) { ping(); if (debug) print("Curve point " + p); curvePoints.add(p); endAnchor = mesh.getAnchor(p); if (endAnchor != null) { if (debug) print("Hit anchor " + endAnchor); break; } if (!pointsSeen.add(p)) { if (l(curvePoints) == 2) return true; else warn("Surprising seen point (" + curvePoints + "). Adding as anchor"); break; } PtBuffer branches = unexploredPointsAround(p); if (l(branches) != 1) { if (debug) print("Branch count: " + l(branches)); break; } else p = first(branches); } if (endAnchor == null) endAnchor = newAnchor(p); mesh.addCurve(new G22Mesh.Curve(work.anchor, endAnchor, curvePoints)); return true; } if (regionIterator.hasNext()) { Pt p = regionIterator.next(); if (!pointsSeen.add(p)) return true; newAnchor(p); return true; } if (autoSimplify) simplify(); return false; } public G22Mesh.Anchor newAnchor(Pt p) { G22Mesh.Anchor anchor = mesh.newAnchor(p); for (Pt p2 : unexploredPointsAround(p)) queue.add(new WorkItem(anchor, p2)); return anchor; } public PtBuffer unexploredPointsAround(Pt p) { PtBuffer out = new PtBuffer(); for (int dir = 1; dir <= 8; dir++) { Pt p2 = onePathDirection(p, dir); if (region.contains(p2) && !pointsSeen.contains(p2)) out.add(p2); } return out; } public boolean simplify() { return 0 != stepAll(combineSteppables_dontDropEnded(() -> dropLengthOneCurves(), () -> dropShortLoops(), () -> dropUnnecessaryAnchors())); } public boolean dropShortLoops() { int n = l(mesh.curves()); for (G22Mesh.Curve curve : cloneList(mesh.curves())) { if (curve.start != curve.end) continue; if (curve.length() > 3) continue; if (debug) print("Removing short loop: " + curve); mesh.removeCurve(curve); } return l(mesh.curves()) < n; } public boolean dropLengthOneCurves() { int n = l(mesh.anchors()); for (G22Mesh.Curve curve : cloneList(mesh.curves())) { if (curve.length() != 1) continue; boolean keepStartAnchor = curve.start.arity() >= curve.end.arity(); mesh.removeCurve(curve); if (keepStartAnchor) mesh.mergeAnchorInto(curve.end, curve.start); else mesh.mergeAnchorInto(curve.start, curve.end); } return l(mesh.anchors()) < n; } public boolean dropUnnecessaryAnchors() { int n = l(mesh.anchors()); for (G22Mesh.Anchor anchor : cloneList(mesh.anchors())) { if (anchor.arity() != 2) continue; if (anchor.isRingAnchor()) continue; if (debugDroppingUnnecessaryAnchors) print("Dropping " + anchor); List curves = concatLists(anchor.incomingCurves, anchor.outgoingCurves); if (debugDroppingUnnecessaryAnchors) printVars("curves", curves); G22Mesh.Curve curve1 = first(curves); mesh.removeCurve(curve1); List points1 = curve1.path.pointList(); if (eq(first(points1), anchor.pt)) reverseInPlace(points1); G22Mesh.Curve curve2 = second(curves); mesh.removeCurve(curve2); List points2 = curve2.path.pointList(); if (!eq(first(points2), anchor.pt)) reverseInPlace(points2); assertEquals(anchor.pt, popLast(points1)); List points = points1; addAll(points, points2); G22Mesh.Anchor anchor1 = assertNotNull(mesh.getAnchor(first(points))); G22Mesh.Anchor anchor2 = assertNotNull(mesh.getAnchor(last(points))); if (debugDroppingUnnecessaryAnchors) printVarsInMultipleLines("anchor", anchor, "anchor1", anchor1, "anchor2", anchor2); mesh.removeAnchor(anchor); mesh.addCurve(new G22Mesh.Curve(anchor1, anchor2, points)); } return l(mesh.anchors()) < n; } } static public class G22GalleryPanel implements Swingable { final public G22GalleryPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22GalleryPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; transient public JGallery_v2 gallery = new JGallery_v2(); transient public ImageSurface selectedImageSurface; transient public G22AnalysisPanel analysisPanel = new G22AnalysisPanel(); transient public ReliableSingleThread rstUpdateGallery = new ReliableSingleThread(() -> updateGalleryImpl()); public void selectImage(G22GalleryImage img) { if (img != null) gallery.selectFile(img.path); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { var selectedImageSurface = g22utils.stdImageSurface(); gallery.onAdaptingButton(button -> { if (!g22utils.devMode()) return; componentPopupMenuItem(button, "Upload image...", runnableThread(new Runnable() { public void run() { try { uploadImageFileDialog(button.imageFile()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "uploadImageFileDialog(button.imageFile())"; } })); }); new AWTOnConceptChangesByClass(g22utils.concepts(), G22GalleryImage.class, gallery.visualize(), rstUpdateGallery).install(); analysisPanel.g22utils(g22utils).imageSurface(selectedImageSurface); gallery.onFileClicked(imageFile -> { var img = loadImage2(imageFile); selectedImageSurface.setImage(img); { if (analysisPanel != null) analysisPanel.setImage(img); } }); return withBottomMargin(jhsplit(0.25, northAndCenter(withMargin(rightAlignedLine(g22utils.reloadButton("Update gallery", rstUpdateGallery))), jCenteredSection("All Images", gallery.visualize())), jRaisedCenteredSection("Selected Image", withRightAlignedButtons(selectedImageSurface.visualize(), "Gallery CRUD", new Runnable() { public void run() { try { g22utils.showUIURL("Gallery CRUD"); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.showUIURL(\"Gallery CRUD\")"; } })))); } public void updateGalleryImpl() { print("Updating gallery"); var files = sortFilesAlphaNumIC(map(list(g22utils.concepts(), G22GalleryImage.class), i -> i.path)); gallery.setImageFiles(files); updateEnclosingTabTitleWithCount(gallery.visualize(), l(files)); } } abstract static public class G22TradingStrategy extends ConceptWithChangeListeners implements Comparable, Juiceable { static final public String _fieldOrder = "verbose globalID customName comment q market mergePositionsForMarket cryptoCoin marginCoin primed usingLiveData doingRealTrades demoCoin active closedItself deactivated archived area adversity log epsilon cryptoStep minCrypto maxInvestment cellSize leverage marginPerPosition showClosedPositionsBackwards takeCoinProfit takeCoinProfitEnabled backDataHoursWanted backDataFed strategyJuicer logToPrint feedNote useDriftSystem driftSystem digitizer direction maxDebt currentPrice oldPrice startingPrice startTime realizedProfit realizedCoinProfit realizedWins realizedCoinWins realizedLosses realizedCoinLosses stepCount stepSince openPositions closedPositions positionsThatFailedToOpen"; final public String fieldsToReset_G22TradingStrategy() { return fieldsToReset(); } public String fieldsToReset() { return "\r\n globalID active\r\n q\r\n archived primed usingLiveData \r\n backDataFed startTime deactivated closedItself\r\n log currentTime currentPrice feedNote\r\n direction\r\n digitizer maxDebt direction oldPrice startingPrice\r\n maxInvestment\r\n realizedProfit realizedCoinProfit\r\n realizedWins realizedCoinWins\r\n realizedLosses realizedCoinLosses\r\n stepCount stepSince\r\n openPositions closedPositions positionsThatFailedToOpen\r\n drift driftSystem\r\n "; } final public G22TradingStrategy setVerbose(boolean verbose) { return verbose(verbose); } public G22TradingStrategy verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; final public String getGlobalID() { return globalID(); } public String globalID() { return globalID; } public String globalID = aGlobalID(); final public G22TradingStrategy setCustomName(String customName) { return customName(customName); } public G22TradingStrategy customName(String customName) { this.customName = customName; return this; } final public String getCustomName() { return customName(); } public String customName() { return customName; } public String customName; final public G22TradingStrategy setComment(String comment) { return comment(comment); } public G22TradingStrategy comment(String comment) { this.comment = comment; return this; } final public String getComment() { return comment(); } public String comment() { return comment; } public String comment; final public Q getQ() { return q(); } public Q q() { return q; } transient public Q q = startQ(); final public G22TradingStrategy setMarket(IFuturesMarket market) { return market(market); } public G22TradingStrategy market(IFuturesMarket market) { this.market = market; return this; } final public IFuturesMarket getMarket() { return market(); } public IFuturesMarket market() { return market; } transient public IFuturesMarket market; final public G22TradingStrategy setMergePositionsForMarket(boolean mergePositionsForMarket) { return mergePositionsForMarket(mergePositionsForMarket); } public G22TradingStrategy mergePositionsForMarket(boolean mergePositionsForMarket) { this.mergePositionsForMarket = mergePositionsForMarket; return this; } final public boolean getMergePositionsForMarket() { return mergePositionsForMarket(); } public boolean mergePositionsForMarket() { return mergePositionsForMarket; } public boolean mergePositionsForMarket = false; public transient FieldVar varCryptoCoin_cache; public FieldVar varCryptoCoin() { if (varCryptoCoin_cache == null) varCryptoCoin_cache = varCryptoCoin_load(); return varCryptoCoin_cache; } public FieldVar varCryptoCoin_load() { return new FieldVar(this, "cryptoCoin", () -> cryptoCoin(), cryptoCoin -> cryptoCoin(cryptoCoin)); } final public G22TradingStrategy setCryptoCoin(String cryptoCoin) { return cryptoCoin(cryptoCoin); } public G22TradingStrategy cryptoCoin(String cryptoCoin) { if (!eq(this.cryptoCoin, cryptoCoin)) { this.cryptoCoin = cryptoCoin; change(); } return this; } final public String getCryptoCoin() { return cryptoCoin(); } public String cryptoCoin() { return cryptoCoin; } public String cryptoCoin; public transient FieldVar varMarginCoin_cache; public FieldVar varMarginCoin() { if (varMarginCoin_cache == null) varMarginCoin_cache = varMarginCoin_load(); return varMarginCoin_cache; } public FieldVar varMarginCoin_load() { return new FieldVar(this, "marginCoin", () -> marginCoin(), marginCoin -> marginCoin(marginCoin)); } final public G22TradingStrategy setMarginCoin(String marginCoin) { return marginCoin(marginCoin); } public G22TradingStrategy marginCoin(String marginCoin) { if (!eq(this.marginCoin, marginCoin)) { this.marginCoin = marginCoin; change(); } return this; } final public String getMarginCoin() { return marginCoin(); } public String marginCoin() { return marginCoin; } public String marginCoin = "USDT"; public transient FieldVar varPrimed_cache; public FieldVar varPrimed() { if (varPrimed_cache == null) varPrimed_cache = varPrimed_load(); return varPrimed_cache; } public FieldVar varPrimed_load() { return new FieldVar(this, "primed", () -> primed(), primed -> primed(primed)); } final public G22TradingStrategy setPrimed(boolean primed) { return primed(primed); } public G22TradingStrategy primed(boolean primed) { if (!eq(this.primed, primed)) { this.primed = primed; change(); } return this; } final public boolean getPrimed() { return primed(); } public boolean primed() { return primed; } public boolean primed = false; public transient FieldVar varUsingLiveData_cache; public FieldVar varUsingLiveData() { if (varUsingLiveData_cache == null) varUsingLiveData_cache = varUsingLiveData_load(); return varUsingLiveData_cache; } public FieldVar varUsingLiveData_load() { return new FieldVar(this, "usingLiveData", () -> usingLiveData(), usingLiveData -> usingLiveData(usingLiveData)); } final public G22TradingStrategy setUsingLiveData(boolean usingLiveData) { return usingLiveData(usingLiveData); } public G22TradingStrategy usingLiveData(boolean usingLiveData) { if (!eq(this.usingLiveData, usingLiveData)) { this.usingLiveData = usingLiveData; change(); } return this; } final public boolean getUsingLiveData() { return usingLiveData(); } public boolean usingLiveData() { return usingLiveData; } public boolean usingLiveData = false; public transient FieldVar varDoingRealTrades_cache; public FieldVar varDoingRealTrades() { if (varDoingRealTrades_cache == null) varDoingRealTrades_cache = varDoingRealTrades_load(); return varDoingRealTrades_cache; } public FieldVar varDoingRealTrades_load() { return new FieldVar(this, "doingRealTrades", () -> doingRealTrades(), doingRealTrades -> doingRealTrades(doingRealTrades)); } final public G22TradingStrategy setDoingRealTrades(boolean doingRealTrades) { return doingRealTrades(doingRealTrades); } public G22TradingStrategy doingRealTrades(boolean doingRealTrades) { if (!eq(this.doingRealTrades, doingRealTrades)) { this.doingRealTrades = doingRealTrades; change(); } return this; } final public boolean getDoingRealTrades() { return doingRealTrades(); } public boolean doingRealTrades() { return doingRealTrades; } public boolean doingRealTrades = false; public transient FieldVar varDemoCoin_cache; public FieldVar varDemoCoin() { if (varDemoCoin_cache == null) varDemoCoin_cache = varDemoCoin_load(); return varDemoCoin_cache; } public FieldVar varDemoCoin_load() { return new FieldVar(this, "demoCoin", () -> demoCoin(), demoCoin -> demoCoin(demoCoin)); } final public G22TradingStrategy setDemoCoin(boolean demoCoin) { return demoCoin(demoCoin); } public G22TradingStrategy demoCoin(boolean demoCoin) { if (!eq(this.demoCoin, demoCoin)) { this.demoCoin = demoCoin; change(); } return this; } final public boolean getDemoCoin() { return demoCoin(); } public boolean demoCoin() { return demoCoin; } public boolean demoCoin = false; public transient FieldVar varActive_cache; public FieldVar varActive() { if (varActive_cache == null) varActive_cache = varActive_load(); return varActive_cache; } public FieldVar varActive_load() { return new FieldVar(this, "active", () -> active(), active -> active(active)); } final public G22TradingStrategy setActive(boolean active) { return active(active); } public G22TradingStrategy active(boolean active) { if (!eq(this.active, active)) { this.active = active; change(); } return this; } final public boolean getActive() { return active(); } public boolean active() { return active; } public boolean active = false; public transient FieldVar varClosedItself_cache; public FieldVar varClosedItself() { if (varClosedItself_cache == null) varClosedItself_cache = varClosedItself_load(); return varClosedItself_cache; } public FieldVar varClosedItself_load() { return new FieldVar(this, "closedItself", () -> closedItself(), closedItself -> closedItself(closedItself)); } final public G22TradingStrategy setClosedItself(long closedItself) { return closedItself(closedItself); } public G22TradingStrategy closedItself(long closedItself) { if (!eq(this.closedItself, closedItself)) { this.closedItself = closedItself; change(); } return this; } final public long getClosedItself() { return closedItself(); } public long closedItself() { return closedItself; } public long closedItself; public transient FieldVar varDeactivated_cache; public FieldVar varDeactivated() { if (varDeactivated_cache == null) varDeactivated_cache = varDeactivated_load(); return varDeactivated_cache; } public FieldVar varDeactivated_load() { return new FieldVar(this, "deactivated", () -> deactivated(), deactivated -> deactivated(deactivated)); } final public G22TradingStrategy setDeactivated(long deactivated) { return deactivated(deactivated); } public G22TradingStrategy deactivated(long deactivated) { if (!eq(this.deactivated, deactivated)) { this.deactivated = deactivated; change(); } return this; } final public long getDeactivated() { return deactivated(); } public long deactivated() { return deactivated; } public long deactivated; public transient FieldVar varArchived_cache; public FieldVar varArchived() { if (varArchived_cache == null) varArchived_cache = varArchived_load(); return varArchived_cache; } public FieldVar varArchived_load() { return new FieldVar(this, "archived", () -> archived(), archived -> archived(archived)); } final public G22TradingStrategy setArchived(boolean archived) { return archived(archived); } public G22TradingStrategy archived(boolean archived) { if (!eq(this.archived, archived)) { this.archived = archived; change(); } return this; } final public boolean getArchived() { return archived(); } public boolean archived() { return archived; } public boolean archived = false; public transient FieldVar varArea_cache; public FieldVar varArea() { if (varArea_cache == null) varArea_cache = varArea_load(); return varArea_cache; } public FieldVar varArea_load() { return new FieldVar(this, "area", () -> area(), area -> area(area)); } final public G22TradingStrategy setArea(String area) { return area(area); } public G22TradingStrategy area(String area) { if (!eq(this.area, area)) { this.area = area; change(); } return this; } final public String getArea() { return area(); } public String area() { return area; } public String area; public transient FieldVar varAdversity_cache; public FieldVar varAdversity() { if (varAdversity_cache == null) varAdversity_cache = varAdversity_load(); return varAdversity_cache; } public FieldVar varAdversity_load() { return new FieldVar(this, "adversity", () -> adversity(), adversity -> adversity(adversity)); } final public G22TradingStrategy setAdversity(double adversity) { return adversity(adversity); } public G22TradingStrategy adversity(double adversity) { if (!eq(this.adversity, adversity)) { this.adversity = adversity; change(); } return this; } final public double getAdversity() { return adversity(); } public double adversity() { return adversity; } public double adversity = 0.2; public transient FieldVar> varLog_cache; public FieldVar> varLog() { if (varLog_cache == null) varLog_cache = varLog_load(); return varLog_cache; } public FieldVar> varLog_load() { return new FieldVar>(this, "log", () -> log(), log -> log(log)); } final public G22TradingStrategy setLog(List log) { return log(log); } public G22TradingStrategy log(List log) { if (!eq(this.log, log)) { this.log = log; change(); } return this; } final public List getLog() { return log(); } public List log() { return log; } public List log = new ArrayList(); public transient FieldVar varEpsilon_cache; public FieldVar varEpsilon() { if (varEpsilon_cache == null) varEpsilon_cache = varEpsilon_load(); return varEpsilon_cache; } public FieldVar varEpsilon_load() { return new FieldVar(this, "epsilon", () -> epsilon(), epsilon -> epsilon(epsilon)); } final public G22TradingStrategy setEpsilon(double epsilon) { return epsilon(epsilon); } public G22TradingStrategy epsilon(double epsilon) { if (!eq(this.epsilon, epsilon)) { this.epsilon = epsilon; change(); } return this; } final public double getEpsilon() { return epsilon(); } public double epsilon() { return epsilon; } public double epsilon = 1e-6; public transient FieldVar varCryptoStep_cache; public FieldVar varCryptoStep() { if (varCryptoStep_cache == null) varCryptoStep_cache = varCryptoStep_load(); return varCryptoStep_cache; } public FieldVar varCryptoStep_load() { return new FieldVar(this, "cryptoStep", () -> cryptoStep(), cryptoStep -> cryptoStep(cryptoStep)); } final public G22TradingStrategy setCryptoStep(double cryptoStep) { return cryptoStep(cryptoStep); } public G22TradingStrategy cryptoStep(double cryptoStep) { if (!eq(this.cryptoStep, cryptoStep)) { this.cryptoStep = cryptoStep; change(); } return this; } final public double getCryptoStep() { return cryptoStep(); } public double cryptoStep() { return cryptoStep; } public double cryptoStep = 0.0001; public transient FieldVar varMinCrypto_cache; public FieldVar varMinCrypto() { if (varMinCrypto_cache == null) varMinCrypto_cache = varMinCrypto_load(); return varMinCrypto_cache; } public FieldVar varMinCrypto_load() { return new FieldVar(this, "minCrypto", () -> minCrypto(), minCrypto -> minCrypto(minCrypto)); } final public G22TradingStrategy setMinCrypto(double minCrypto) { return minCrypto(minCrypto); } public G22TradingStrategy minCrypto(double minCrypto) { if (!eq(this.minCrypto, minCrypto)) { this.minCrypto = minCrypto; change(); } return this; } final public double getMinCrypto() { return minCrypto(); } public double minCrypto() { return minCrypto; } public double minCrypto = 0.0001; public transient FieldVar varMaxInvestment_cache; public FieldVar varMaxInvestment() { if (varMaxInvestment_cache == null) varMaxInvestment_cache = varMaxInvestment_load(); return varMaxInvestment_cache; } public FieldVar varMaxInvestment_load() { return new FieldVar(this, "maxInvestment", () -> maxInvestment(), maxInvestment -> maxInvestment(maxInvestment)); } final public G22TradingStrategy setMaxInvestment(double maxInvestment) { return maxInvestment(maxInvestment); } public G22TradingStrategy maxInvestment(double maxInvestment) { if (!eq(this.maxInvestment, maxInvestment)) { this.maxInvestment = maxInvestment; change(); } return this; } final public double getMaxInvestment() { return maxInvestment(); } public double maxInvestment() { return maxInvestment; } public double maxInvestment; public transient FieldVar varCellSize_cache; public FieldVar varCellSize() { if (varCellSize_cache == null) varCellSize_cache = varCellSize_load(); return varCellSize_cache; } public FieldVar varCellSize_load() { return new FieldVar(this, "cellSize", () -> cellSize(), cellSize -> cellSize(cellSize)); } final public G22TradingStrategy setCellSize(double cellSize) { return cellSize(cellSize); } public G22TradingStrategy cellSize(double cellSize) { if (!eq(this.cellSize, cellSize)) { this.cellSize = cellSize; change(); } return this; } final public double getCellSize() { return cellSize(); } public double cellSize() { return cellSize; } public double cellSize = 1; public transient FieldVar varLeverage_cache; public FieldVar varLeverage() { if (varLeverage_cache == null) varLeverage_cache = varLeverage_load(); return varLeverage_cache; } public FieldVar varLeverage_load() { return new FieldVar(this, "leverage", () -> leverage(), leverage -> leverage(leverage)); } final public G22TradingStrategy setLeverage(double leverage) { return leverage(leverage); } public G22TradingStrategy leverage(double leverage) { if (!eq(this.leverage, leverage)) { this.leverage = leverage; change(); } return this; } final public double getLeverage() { return leverage(); } public double leverage() { return leverage; } public double leverage = 1; public transient FieldVar varMarginPerPosition_cache; public FieldVar varMarginPerPosition() { if (varMarginPerPosition_cache == null) varMarginPerPosition_cache = varMarginPerPosition_load(); return varMarginPerPosition_cache; } public FieldVar varMarginPerPosition_load() { return new FieldVar(this, "marginPerPosition", () -> marginPerPosition(), marginPerPosition -> marginPerPosition(marginPerPosition)); } final public G22TradingStrategy setMarginPerPosition(double marginPerPosition) { return marginPerPosition(marginPerPosition); } public G22TradingStrategy marginPerPosition(double marginPerPosition) { if (!eq(this.marginPerPosition, marginPerPosition)) { this.marginPerPosition = marginPerPosition; change(); } return this; } final public double getMarginPerPosition() { return marginPerPosition(); } public double marginPerPosition() { return marginPerPosition; } public double marginPerPosition = 1; public transient FieldVar varShowClosedPositionsBackwards_cache; public FieldVar varShowClosedPositionsBackwards() { if (varShowClosedPositionsBackwards_cache == null) varShowClosedPositionsBackwards_cache = varShowClosedPositionsBackwards_load(); return varShowClosedPositionsBackwards_cache; } public FieldVar varShowClosedPositionsBackwards_load() { return new FieldVar(this, "showClosedPositionsBackwards", () -> showClosedPositionsBackwards(), showClosedPositionsBackwards -> showClosedPositionsBackwards(showClosedPositionsBackwards)); } final public G22TradingStrategy setShowClosedPositionsBackwards(boolean showClosedPositionsBackwards) { return showClosedPositionsBackwards(showClosedPositionsBackwards); } public G22TradingStrategy showClosedPositionsBackwards(boolean showClosedPositionsBackwards) { if (!eq(this.showClosedPositionsBackwards, showClosedPositionsBackwards)) { this.showClosedPositionsBackwards = showClosedPositionsBackwards; change(); } return this; } final public boolean getShowClosedPositionsBackwards() { return showClosedPositionsBackwards(); } public boolean showClosedPositionsBackwards() { return showClosedPositionsBackwards; } public boolean showClosedPositionsBackwards = true; public transient FieldVar varTakeCoinProfit_cache; public FieldVar varTakeCoinProfit() { if (varTakeCoinProfit_cache == null) varTakeCoinProfit_cache = varTakeCoinProfit_load(); return varTakeCoinProfit_cache; } public FieldVar varTakeCoinProfit_load() { return new FieldVar(this, "takeCoinProfit", () -> takeCoinProfit(), takeCoinProfit -> takeCoinProfit(takeCoinProfit)); } final public G22TradingStrategy setTakeCoinProfit(double takeCoinProfit) { return takeCoinProfit(takeCoinProfit); } public G22TradingStrategy takeCoinProfit(double takeCoinProfit) { if (!eq(this.takeCoinProfit, takeCoinProfit)) { this.takeCoinProfit = takeCoinProfit; change(); } return this; } final public double getTakeCoinProfit() { return takeCoinProfit(); } public double takeCoinProfit() { return takeCoinProfit; } public double takeCoinProfit = infinity(); public transient FieldVar varTakeCoinProfitEnabled_cache; public FieldVar varTakeCoinProfitEnabled() { if (varTakeCoinProfitEnabled_cache == null) varTakeCoinProfitEnabled_cache = varTakeCoinProfitEnabled_load(); return varTakeCoinProfitEnabled_cache; } public FieldVar varTakeCoinProfitEnabled_load() { return new FieldVar(this, "takeCoinProfitEnabled", () -> takeCoinProfitEnabled(), takeCoinProfitEnabled -> takeCoinProfitEnabled(takeCoinProfitEnabled)); } final public G22TradingStrategy setTakeCoinProfitEnabled(boolean takeCoinProfitEnabled) { return takeCoinProfitEnabled(takeCoinProfitEnabled); } public G22TradingStrategy takeCoinProfitEnabled(boolean takeCoinProfitEnabled) { if (!eq(this.takeCoinProfitEnabled, takeCoinProfitEnabled)) { this.takeCoinProfitEnabled = takeCoinProfitEnabled; change(); } return this; } final public boolean getTakeCoinProfitEnabled() { return takeCoinProfitEnabled(); } public boolean takeCoinProfitEnabled() { return takeCoinProfitEnabled; } public boolean takeCoinProfitEnabled = false; public transient FieldVar varBackDataHoursWanted_cache; public FieldVar varBackDataHoursWanted() { if (varBackDataHoursWanted_cache == null) varBackDataHoursWanted_cache = varBackDataHoursWanted_load(); return varBackDataHoursWanted_cache; } public FieldVar varBackDataHoursWanted_load() { return new FieldVar(this, "backDataHoursWanted", () -> backDataHoursWanted(), backDataHoursWanted -> backDataHoursWanted(backDataHoursWanted)); } final public G22TradingStrategy setBackDataHoursWanted(double backDataHoursWanted) { return backDataHoursWanted(backDataHoursWanted); } public G22TradingStrategy backDataHoursWanted(double backDataHoursWanted) { if (!eq(this.backDataHoursWanted, backDataHoursWanted)) { this.backDataHoursWanted = backDataHoursWanted; change(); } return this; } final public double getBackDataHoursWanted() { return backDataHoursWanted(); } public double backDataHoursWanted() { return backDataHoursWanted; } public double backDataHoursWanted; public transient FieldVar varBackDataFed_cache; public FieldVar varBackDataFed() { if (varBackDataFed_cache == null) varBackDataFed_cache = varBackDataFed_load(); return varBackDataFed_cache; } public FieldVar varBackDataFed_load() { return new FieldVar(this, "backDataFed", () -> backDataFed(), backDataFed -> backDataFed(backDataFed)); } final public G22TradingStrategy setBackDataFed(boolean backDataFed) { return backDataFed(backDataFed); } public G22TradingStrategy backDataFed(boolean backDataFed) { if (!eq(this.backDataFed, backDataFed)) { this.backDataFed = backDataFed; change(); } return this; } final public boolean getBackDataFed() { return backDataFed(); } public boolean backDataFed() { return backDataFed; } public boolean backDataFed = false; public transient FieldVar varStrategyJuicer_cache; public FieldVar varStrategyJuicer() { if (varStrategyJuicer_cache == null) varStrategyJuicer_cache = varStrategyJuicer_load(); return varStrategyJuicer_cache; } public FieldVar varStrategyJuicer_load() { return new FieldVar(this, "strategyJuicer", () -> strategyJuicer(), strategyJuicer -> strategyJuicer(strategyJuicer)); } final public G22TradingStrategy setStrategyJuicer(AbstractJuicer strategyJuicer) { return strategyJuicer(strategyJuicer); } public G22TradingStrategy strategyJuicer(AbstractJuicer strategyJuicer) { if (!eq(this.strategyJuicer, strategyJuicer)) { this.strategyJuicer = strategyJuicer; change(); } return this; } final public AbstractJuicer getStrategyJuicer() { return strategyJuicer(); } public AbstractJuicer strategyJuicer() { return strategyJuicer; } public AbstractJuicer strategyJuicer; transient public IF0 currentTime; public long currentTime() { return currentTime != null ? currentTime.get() : currentTime_base(); } final public long currentTime_fallback(IF0 _f) { return _f != null ? _f.get() : currentTime_base(); } public long currentTime_base() { return now(); } final public G22TradingStrategy setLogToPrint(boolean logToPrint) { return logToPrint(logToPrint); } public G22TradingStrategy logToPrint(boolean logToPrint) { this.logToPrint = logToPrint; return this; } final public boolean getLogToPrint() { return logToPrint(); } public boolean logToPrint() { return logToPrint; } transient public boolean logToPrint = true; public transient FieldVar varFeedNote_cache; public FieldVar varFeedNote() { if (varFeedNote_cache == null) varFeedNote_cache = varFeedNote_load(); return varFeedNote_cache; } public FieldVar varFeedNote_load() { return new FieldVar(this, "feedNote", () -> feedNote(), feedNote -> feedNote(feedNote)); } final public G22TradingStrategy setFeedNote(String feedNote) { return feedNote(feedNote); } public G22TradingStrategy feedNote(String feedNote) { if (!eq(this.feedNote, feedNote)) { this.feedNote = feedNote; change(); } return this; } final public String getFeedNote() { return feedNote(); } public String feedNote() { return feedNote; } public String feedNote; public transient FieldVar varUseDriftSystem_cache; public FieldVar varUseDriftSystem() { if (varUseDriftSystem_cache == null) varUseDriftSystem_cache = varUseDriftSystem_load(); return varUseDriftSystem_cache; } public FieldVar varUseDriftSystem_load() { return new FieldVar(this, "useDriftSystem", () -> useDriftSystem(), useDriftSystem -> useDriftSystem(useDriftSystem)); } final public G22TradingStrategy setUseDriftSystem(boolean useDriftSystem) { return useDriftSystem(useDriftSystem); } public G22TradingStrategy useDriftSystem(boolean useDriftSystem) { if (!eq(this.useDriftSystem, useDriftSystem)) { this.useDriftSystem = useDriftSystem; change(); } return this; } final public boolean getUseDriftSystem() { return useDriftSystem(); } public boolean useDriftSystem() { return useDriftSystem; } public boolean useDriftSystem = false; public transient FieldVar varDriftSystem_cache; public FieldVar varDriftSystem() { if (varDriftSystem_cache == null) varDriftSystem_cache = varDriftSystem_load(); return varDriftSystem_cache; } public FieldVar varDriftSystem_load() { return new FieldVar(this, "driftSystem", () -> driftSystem(), driftSystem -> driftSystem(driftSystem)); } final public G22TradingStrategy setDriftSystem(G22DriftSystem driftSystem) { return driftSystem(driftSystem); } public G22TradingStrategy driftSystem(G22DriftSystem driftSystem) { if (!eq(this.driftSystem, driftSystem)) { this.driftSystem = driftSystem; change(); } return this; } final public G22DriftSystem getDriftSystem() { return driftSystem(); } public G22DriftSystem driftSystem() { return driftSystem; } public G22DriftSystem driftSystem; public A log(A o) { if (o != null) { log.add(printIf(logToPrint, "[" + formatLocalDateWithSeconds(currentTime()) + "] " + str(o))); change(); } return o; } public void logVars(Object... o) { log(renderVars(o)); } public List activationStatus() { return llNempties(active ? "Active" : "Inactive", empty(cryptoCoin) ? null : "coin: " + cryptoCoin + " over " + marginCoin + stringIf(demoCoin, " (demo coin)"), stringIf(market != null, "connected to market"), stringIf(usingLiveData, "using live data"), stringIf(doingRealTrades, "real trades")); } public double unrealizedProfit() { double sum = 0; for (var p : openPositions()) sum += p.profit(); return sum; } public double openMargins() { double sum = 0; for (var p : openPositions()) sum += p.margin(); return sum; } public double unrealizedCoinProfit() { return unrealizedCoinProfitAtPrice(currentPrice); } public double unrealizedCoinProfitAtPrice(double price) { double sum = 0; for (var p : openPositions) sum += p.coinProfitAtPrice(price); return sum; } public List positionsInDirection(int direction) { return filter(openPositions, p -> sign(p.direction) == sign(direction)); } public List longPositions() { return positionsInDirection(1); } public List shortPositions() { return positionsInDirection(-1); } public List shortPositionsAtOrBelowPrice(double openingPrice) { return filter(openPositions, p -> p.isShort() && p.openingPrice <= openingPrice); } public List longPositionsAtOrAbovePrice(double openingPrice) { return filter(openPositions, p -> p.isLong() && p.openingPrice >= openingPrice); } public List negativePositions() { return filter(openPositions, p -> p.profit() < 0); } public double debt() { return max(0, -unrealizedCoinProfit()); } public double profit() { return realizedProfit + unrealizedProfit(); } public double coinProfit() { return realizedCoinProfit + unrealizedCoinProfit(); } public double coinProfitAtPrice(double price) { return realizedCoinProfit + unrealizedCoinProfitAtPrice(price); } public String formatProfit(double x) { return plusMinusFix(formatDouble1(x)); } public transient FieldVar varDigitizer_cache; public FieldVar varDigitizer() { if (varDigitizer_cache == null) varDigitizer_cache = varDigitizer_load(); return varDigitizer_cache; } public FieldVar varDigitizer_load() { return new FieldVar(this, "digitizer", () -> digitizer(), digitizer -> digitizer(digitizer)); } final public G22TradingStrategy setDigitizer(PriceDigitizer2 digitizer) { return digitizer(digitizer); } public G22TradingStrategy digitizer(PriceDigitizer2 digitizer) { if (!eq(this.digitizer, digitizer)) { this.digitizer = digitizer; change(); } return this; } final public PriceDigitizer2 getDigitizer() { return digitizer(); } public PriceDigitizer2 digitizer() { return digitizer; } public PriceDigitizer2 digitizer; public transient FieldVar varDirection_cache; public FieldVar varDirection() { if (varDirection_cache == null) varDirection_cache = varDirection_load(); return varDirection_cache; } public FieldVar varDirection_load() { return new FieldVar(this, "direction", () -> direction(), direction -> direction(direction)); } final public G22TradingStrategy setDirection(int direction) { return direction(direction); } public G22TradingStrategy direction(int direction) { if (!eq(this.direction, direction)) { this.direction = direction; change(); } return this; } final public int getDirection() { return direction(); } public int direction() { return direction; } public int direction; public transient FieldVar varMaxDebt_cache; public FieldVar varMaxDebt() { if (varMaxDebt_cache == null) varMaxDebt_cache = varMaxDebt_load(); return varMaxDebt_cache; } public FieldVar varMaxDebt_load() { return new FieldVar(this, "maxDebt", () -> maxDebt(), maxDebt -> maxDebt(maxDebt)); } final public G22TradingStrategy setMaxDebt(double maxDebt) { return maxDebt(maxDebt); } public G22TradingStrategy maxDebt(double maxDebt) { if (!eq(this.maxDebt, maxDebt)) { this.maxDebt = maxDebt; change(); } return this; } final public double getMaxDebt() { return maxDebt(); } public double maxDebt() { return maxDebt; } public double maxDebt; public class Position { final public Position setMarginToUse(double marginToUse) { return marginToUse(marginToUse); } public Position marginToUse(double marginToUse) { this.marginToUse = marginToUse; return this; } final public double getMarginToUse() { return marginToUse(); } public double marginToUse() { return marginToUse; } public double marginToUse; final public Position setOpeningPrice(double openingPrice) { return openingPrice(openingPrice); } public Position openingPrice(double openingPrice) { this.openingPrice = openingPrice; return this; } final public double getOpeningPrice() { return openingPrice(); } public double openingPrice() { return openingPrice; } public double openingPrice; final public Position setDirection(double direction) { return direction(direction); } public Position direction(double direction) { this.direction = direction; return this; } final public double getDirection() { return direction(); } public double direction() { return direction; } public double direction; final public Position setDigitizedOpeningPrice(double digitizedOpeningPrice) { return digitizedOpeningPrice(digitizedOpeningPrice); } public Position digitizedOpeningPrice(double digitizedOpeningPrice) { this.digitizedOpeningPrice = digitizedOpeningPrice; return this; } final public double getDigitizedOpeningPrice() { return digitizedOpeningPrice(); } public double digitizedOpeningPrice() { return digitizedOpeningPrice; } public double digitizedOpeningPrice; final public double getClosingPrice() { return closingPrice(); } public double closingPrice() { return closingPrice; } public double closingPrice = Double.NaN; public long openingStep, closingStep; final public long getOpeningTime() { return openingTime(); } public long openingTime() { return openingTime; } public long openingTime; final public long getClosingTime() { return closingTime(); } public long closingTime() { return closingTime; } public long closingTime; public double leverage; final public Position setCryptoAmount(double cryptoAmount) { return cryptoAmount(cryptoAmount); } public Position cryptoAmount(double cryptoAmount) { this.cryptoAmount = cryptoAmount; return this; } final public double getCryptoAmount() { return cryptoAmount(); } public double cryptoAmount() { return cryptoAmount; } public double cryptoAmount; final public Position setOpenReason(Object openReason) { return openReason(openReason); } public Position openReason(Object openReason) { this.openReason = openReason; return this; } final public Object getOpenReason() { return openReason(); } public Object openReason() { return openReason; } public Object openReason; final public Position setOpenError(Object openError) { return openError(openError); } public Position openError(Object openError) { this.openError = openError; return this; } final public Object getOpenError() { return openError(); } public Object openError() { return openError; } public Object openError; final public Position setCloseReason(Object closeReason) { return closeReason(closeReason); } public Position closeReason(Object closeReason) { this.closeReason = closeReason; return this; } final public Object getCloseReason() { return closeReason(); } public Object closeReason() { return closeReason; } public Object closeReason; final public Position setCloseError(Object closeError) { return closeError(closeError); } public Position closeError(Object closeError) { this.closeError = closeError; return this; } final public Object getCloseError() { return closeError(); } public Object closeError() { return closeError; } public Object closeError; final public double getMargin() { return margin(); } public double margin() { return margin; } public double margin; final public Position setOpenedOnMarket(boolean openedOnMarket) { return openedOnMarket(openedOnMarket); } public Position openedOnMarket(boolean openedOnMarket) { this.openedOnMarket = openedOnMarket; return this; } final public boolean getOpenedOnMarket() { return openedOnMarket(); } public boolean openedOnMarket() { return openedOnMarket; } public boolean openedOnMarket = false; final public Position setClosedOnMarket(boolean closedOnMarket) { return closedOnMarket(closedOnMarket); } public Position closedOnMarket(boolean closedOnMarket) { this.closedOnMarket = closedOnMarket; return this; } final public boolean getClosedOnMarket() { return closedOnMarket(); } public boolean closedOnMarket() { return closedOnMarket; } public boolean closedOnMarket = false; final public Position setDontCloseOnMarket(boolean dontCloseOnMarket) { return dontCloseOnMarket(dontCloseOnMarket); } public Position dontCloseOnMarket(boolean dontCloseOnMarket) { this.dontCloseOnMarket = dontCloseOnMarket; return this; } final public boolean getDontCloseOnMarket() { return dontCloseOnMarket(); } public boolean dontCloseOnMarket() { return dontCloseOnMarket; } public boolean dontCloseOnMarket = false; public G22TradingStrategy strategy() { return G22TradingStrategy.this; } { if (!dynamicObjectIsLoading()) { marginToUse = marginPerPosition; openingStep = stepCount; leverage = G22TradingStrategy.this.leverage; openingTime = currentTime(); } } public boolean isLong() { return direction > 0; } public boolean isShort() { return direction < 0; } public boolean closed() { return !isNaN(closingPrice); } public String type() { return trading_directionToPositionType(direction); } public long closingOrCurrentTime() { return closed() ? closingTime() : currentTime(); } public long duration() { return closingOrCurrentTime() - openingTime(); } public double profitAtPrice(double price) { return profitAtPriceBeforeLeverage(price) * leverage; } public double profitAtPriceBeforeLeverage(double price) { return ((price - openingPrice) / openingPrice * direction * 100 - adversity); } public double workingPrice() { return closed() ? closingPrice : currentPrice(); } public double profit() { return profitAtPrice(workingPrice()); } public double profitBeforeLeverage() { return profitAtPriceBeforeLeverage(workingPrice()); } public double coinProfit() { return coinProfitAtPrice(workingPrice()); } public double coinProfitAtPrice(double price) { return profitAtPrice(price) / 100 * margin(); } public void close(Object closeReason) { if (closed()) throw fail("Can't close again"); if (closeReason != null) closeReason(closeReason); openPositions.remove(this); closingPrice = currentPrice(); closingTime = currentTime(); closingStep = stepCount; closedPositions.add(this); double cp = coinProfit(); realizedProfit += profit(); realizedCoinProfit += cp; if (cp > 0) { realizedWins++; realizedCoinWins += cp; } else { realizedLosses++; realizedCoinLosses += cp; } change(); closeOnMarket(); log(this); } public String winnerOrLoser() { var profit = coinProfit(); if (profit == 0) return "NEUTRAL"; if (profit > 0) return "WINNER"; return "LOSS"; } public String toString() { return commaCombine(spaceCombine(!closed() ? null : winnerOrLoser() + " " + formatLocalDateWithSeconds(closingTime()) + ", duration " + formatHoursMinutesColonSeconds(duration()), formatDouble1(leverage) + "X " + upper(type())), "opened " + formatLocalDateWithSeconds(openingTime()) + (openReason == null ? "" : " " + roundBracket(str(openReason))), !closed() ? null : "closed because: " + or(closeReason, "Unknown reason"), "profit: " + formatProfit(profit()) + "% (" + marginCoin + " " + formatMarginProfit(coinProfit()) + ")", "before leverage: " + formatProfit(profitBeforeLeverage()) + "%", "margin: " + marginCoin + " " + formatMarginPrice(margin()), "crypto: " + formatPrice(cryptoAmount), "opening price: " + formatPriceX(openingPrice) + " (digitized: " + formatPrice(digitizedOpeningPrice()) + ") @ step " + openingStep, !closed() ? null : "closing price: " + formatPriceX(closingPrice) + " @ step " + closingStep); } public void closeOnMarket() { if (dontCloseOnMarket) return; if (openError != null) { log("Not closing because open error: " + this); return; } try { if (market != null) { log("Closing on market: " + this); market.closePosition(new IFuturesMarket.CloseOrder().holdSide(HoldSide.fromInt(direction)).cryptoAmount(cryptoAmount)); closedOnMarket(true); change(); } } catch (Throwable e) { closeError = toPersistableThrowable(e); } } public void open() { margin = cryptoAmount * openingPrice / leverage; log("Opening: " + this); openPositions.add(this); change(); } public void openOnMarket() { try { if (market != null) { log("Opening on market: " + this); market.openPosition(new IFuturesMarket.OpenOrder().holdSide(HoldSide.fromInt(direction)).cryptoAmount(cryptoAmount).leverage(leverage).isCross(true)); openedOnMarket(true); change(); } } catch (Throwable e) { openError(toPersistableThrowable(e)); log("Open error:" + e); positionsThatFailedToOpen.add(this); close("Open error"); } } } final public double getCurrentPrice() { return currentPrice(); } public double currentPrice() { return currentPrice; } public double currentPrice = 0; final public double getOldPrice() { return oldPrice(); } public double oldPrice() { return oldPrice; } public double oldPrice = Double.NaN; final public double getStartingPrice() { return startingPrice(); } public double startingPrice() { return startingPrice; } public double startingPrice = Double.NaN; final public G22TradingStrategy setStartTime(long startTime) { return startTime(startTime); } public G22TradingStrategy startTime(long startTime) { this.startTime = startTime; return this; } final public long getStartTime() { return startTime(); } public long startTime() { return startTime; } public long startTime; final public double getRealizedProfit() { return realizedProfit(); } public double realizedProfit() { return realizedProfit; } public double realizedProfit; final public double getRealizedCoinProfit() { return realizedCoinProfit(); } public double realizedCoinProfit() { return realizedCoinProfit; } public double realizedCoinProfit; final public int getRealizedWins() { return realizedWins(); } public int realizedWins() { return realizedWins; } public int realizedWins; final public double getRealizedCoinWins() { return realizedCoinWins(); } public double realizedCoinWins() { return realizedCoinWins; } public double realizedCoinWins; final public int getRealizedLosses() { return realizedLosses(); } public int realizedLosses() { return realizedLosses; } public int realizedLosses; final public double getRealizedCoinLosses() { return realizedCoinLosses(); } public double realizedCoinLosses() { return realizedCoinLosses; } public double realizedCoinLosses; public transient FieldVar varStepCount_cache; public FieldVar varStepCount() { if (varStepCount_cache == null) varStepCount_cache = varStepCount_load(); return varStepCount_cache; } public FieldVar varStepCount_load() { return new FieldVar(this, "stepCount", () -> stepCount(), stepCount -> stepCount(stepCount)); } final public G22TradingStrategy setStepCount(long stepCount) { return stepCount(stepCount); } public G22TradingStrategy stepCount(long stepCount) { if (!eq(this.stepCount, stepCount)) { this.stepCount = stepCount; change(); } return this; } final public long getStepCount() { return stepCount(); } public long stepCount() { return stepCount; } public long stepCount; public transient FieldVar varStepSince_cache; public FieldVar varStepSince() { if (varStepSince_cache == null) varStepSince_cache = varStepSince_load(); return varStepSince_cache; } public FieldVar varStepSince_load() { return new FieldVar(this, "stepSince", () -> stepSince(), stepSince -> stepSince(stepSince)); } final public G22TradingStrategy setStepSince(long stepSince) { return stepSince(stepSince); } public G22TradingStrategy stepSince(long stepSince) { if (!eq(this.stepSince, stepSince)) { this.stepSince = stepSince; change(); } return this; } final public long getStepSince() { return stepSince(); } public long stepSince() { return stepSince; } public long stepSince; public LinkedHashSet openPositions = new LinkedHashSet(); final public List getClosedPositions() { return closedPositions(); } public List closedPositions() { return closedPositions; } public List closedPositions = new ArrayList(); final public List getPositionsThatFailedToOpen() { return positionsThatFailedToOpen(); } public List positionsThatFailedToOpen() { return positionsThatFailedToOpen; } public List positionsThatFailedToOpen = new ArrayList(); public void closeOnMarketMerged(Collection positions) { if (market == null) return; closeOnMarketMerged_oneDirection(filter(positions, __2 -> __2.isShort())); closeOnMarketMerged_oneDirection(filter(positions, __3 -> __3.isLong())); } public void closeOnMarketMerged_oneDirection(List positions) { if (empty(positions)) return; double direction = first(positions).direction; double cryptoAmount = doubleSum(positions, __4 -> __4.cryptoAmount); log("Closing on market: " + positions); try { market.closePosition(new IFuturesMarket.CloseOrder().holdSide(HoldSide.fromInt(direction)).cryptoAmount(cryptoAmount)); for (var p : positions) p.closedOnMarket(true); change(); } catch (Throwable e) { var e2 = toPersistableThrowable(e); for (var p : positions) p.closeError(e2); } } public boolean hasPosition(double price, double direction) { return findPosition(price, direction) != null; } public Position closePosition(double price, double direction, Object closeReason) { var p = findPosition(price, direction); { if (p != null) p.close(closeReason); } return p; } public void closePositions(Collection positions) { closePositions(positions, null); } public void closePositions(Collection positions, Object closeReason) { if (mergePositionsForMarket) { for (var p : positions) p.dontCloseOnMarket(true).close(closeReason); closeOnMarketMerged(positions); } else forEach(positions, __5 -> __5.close(closeReason)); } public Position findPosition(double digitizedPrice, double direction) { return firstThat(openPositions(), p -> diffRatio(p.digitizedOpeningPrice(), digitizedPrice) <= epsilon() && sign(p.direction) == sign(direction)); } public void printPositions() { print(colonCombine(n2(openPositions, "open position"), joinWithComma(openPositions))); } public boolean started() { return !isNaN(startingPrice); } public void prices(double... prices) { for (var price : unnullForIteration(prices)) { if (!active()) return; price(price); } } transient public IF1 makePriceCells; public PriceCells makePriceCells(double basePrice) { return makePriceCells != null ? makePriceCells.get(basePrice) : makePriceCells_base(basePrice); } final public PriceCells makePriceCells_fallback(IF1 _f, double basePrice) { return _f != null ? _f.get(basePrice) : makePriceCells_base(basePrice); } public PriceCells makePriceCells_base(double basePrice) { return new GeometricPriceCells(basePrice, cellSize); } public double digitizedPrice() { return digitizer == null ? Double.NaN : digitizer.digitizedPrice(); } public double lastDigitizedPrice() { return digitizer == null ? Double.NaN : digitizer.lastDigitizedPrice(); } public int digitizedCellNumber() { return digitizer == null ? 0 : digitizer.cellNumber(); } public void handleNewPriceInQ(double price) { q.add(() -> price(price)); } public void nextStep() { ++stepCount; stepSince(currentTime()); } public void afterStep() { maxDebt(max(maxDebt, debt())); maxInvestment(max(maxInvestment, investment())); if (takeCoinProfitEnabled() && coinProfit() >= takeCoinProfit) { log("Taking coin profit."); closeMyself(); } } public double investment() { return boundCoin() - realizedCoinProfit; } public double boundCoin() { return max(openMargins(), max(0, -coinProfit())); } public double fromCellNumber(double cellNumber) { return cells().fromCellNumber(cellNumber); } public double toCellNumber(double price) { return cells().toCellNumber(price); } public List shortPositionsAtOrBelowDigitizedPrice(double openingPrice) { return filter(openPositions, p -> p.isShort() && p.digitizedOpeningPrice() <= openingPrice); } public List shortPositionsAtOrAboveDigitizedPrice(double openingPrice) { return filter(openPositions, p -> p.isShort() && p.digitizedOpeningPrice() >= openingPrice); } public List longPositionsAtOrAboveDigitizedPrice(double openingPrice) { return filter(openPositions, p -> p.isLong() && p.digitizedOpeningPrice() >= openingPrice); } public List longPositionsAtOrBelowDigitizedPrice(double openingPrice) { return filter(openPositions, p -> p.isLong() && p.digitizedOpeningPrice() <= openingPrice); } final public PriceCells priceCells() { return cells(); } public PriceCells cells() { return digitizer == null ? null : digitizer.cells; } public String formatPriceX(double price) { if (isNaN(price)) return "-"; String s = formatPrice(price); if (cells() == null) return s; double num = cells().priceToCellNumber(price); return s + " (C" + formatDouble2(num) + ")"; } final public void currentPrice(double price) { price(price); } abstract public void price(double price); public

P openPosition(P p, int direction) { return openPosition(p, direction, null); } public

P openPosition(P p, int direction, Object openReason) { p.openReason(openReason); var price = digitizedPrice(); var realPrice = currentPrice(); logVars("openPosition", "realPrice", realPrice, "price", price, "digitizer", digitizer); if ((isNaN(price) || price == 0) && digitizer != null) { price = digitizer.digitizeIndividually(currentPrice()); print("digitized individually: " + price); } p.openingPrice(realPrice); p.direction(direction); p.digitizedOpeningPrice(price); double cryptoAmount = p.marginToUse / realPrice * leverage; cryptoAmount = roundTo(cryptoStep, cryptoAmount); log(renderVars("openPosition", "marginPerPosition", marginPerPosition, "realPrice", realPrice, "leverage", leverage, "cryptoAmount", cryptoAmount, "cryptoStep", cryptoStep)); p.cryptoAmount = max(minCrypto, cryptoAmount); p.open(); p.openOnMarket(); return p; } public List status() { double mulProf = multiplicativeProfit(); return llNonNulls(empty(comment) ? null : "Comment: " + comment, "Profit: " + marginCoin + " " + plusMinusFix(formatMarginPrice(coinProfit())), "Realized profit: " + marginCoin + " " + formatMarginProfit(realizedCoinProfit) + " from " + n2(closedPositions, "closed position") + " (" + formatMarginProfit(realizedCoinWins) + " from " + n2(realizedWins, "win") + ", " + formatMarginProfit(realizedCoinLosses) + " from " + n2(realizedLosses, "loss", "losses") + ")", "Unrealized profit: " + marginCoin + " " + formatMarginProfit(unrealizedCoinProfit()) + " in " + n2(openPositions, "open position"), isNaN(mulProf) ? null : "Multiplicative profit: " + formatProfit(mulProf) + "%", !primed() ? null : "Primed", !started() ? null : "Started. current price: " + formatPriceX(currentPrice) + (isNaN(digitizedPrice()) ? "" : ", digitized: " + formatPriceX(digitizedPrice())), "Leverage: " + leverage + ", margin per position: " + marginCoin + " " + formatPrice(marginPerPosition), "Cell size: " + formatCellSize(cellSize), spaceCombine("Step " + n2(stepCount), renderStepSince()), "Investment used: " + marginCoin + " " + formatMarginPrice(maxInvestment()), strategyJuicer == null ? null : "Strategy juicer: " + strategyJuicer, "Drift: " + cryptoCoin + " " + plusMinusFix(formatCryptoAmount(drift()))); } public String renderStepSince() { if (stepSince == 0) return ""; return "since " + (active() ? formatHoursMinutesColonSeconds(currentTime() - stepSince) : formatLocalDateWithSeconds(stepSince)); } public List fullStatus() { return listCombine(status(), "", n2(openPositions, "open position") + ":", reversed(openPositions), "", n2(closedPositions, "closed position") + " (" + (showClosedPositionsBackwards ? "latest first" : "oldest first") + "):", showClosedPositionsBackwards ? reversed(closedPositions) : closedPositions); } public void feed(PricePoint pricePoint) { if (!active()) return; setTime(pricePoint.timestamp); price(pricePoint.price); } public void feed(TickerSequence ts) { if (!active()) return; if (ts == null) return; for (var pricePoint : ts.pricePoints()) feed(pricePoint); } public int compareTo(G22TradingStrategy s) { return s == null ? 1 : cmp(coinProfit(), s.coinProfit()); } public void closeAllPositions() { closeAllPositions("User close"); } public void closeAllPositions(Object reason) { closePositions(openPositions(), reason); } public void closeMyself() { closedItself(currentTime()); closeAllPositionsAndDeactivate(); } public void closeAllPositionsAndDeactivate() { deactivate(); closeAllPositions(); } public void deactivate() { if (!active) return; active(false); deactivated(currentTime()); log("Strategy deactivated."); } final public void reset_G22TradingStrategy() { reset(); } public void reset() { resetFields(this, fieldsToReset()); change(); } final public G22TradingStrategy emptyClone_G22TradingStrategy() { return emptyClone(); } public G22TradingStrategy emptyClone() { var clone = shallowCloneToUnlistedConcept(this); clone.reset(); return clone; } public List allPositions() { return concatLists(openPositions, closedPositions); } public List sortedPositions() { var allPositions = allPositions(); return sortedByCalculatedField(allPositions, __6 -> __6.openingTime()); } public boolean positionsAreNonOverlapping() { for (var __0 : overlappingPairs(sortedPositions())) { var a = pairA(__0); var b = pairB(__0); if (b.openingTime() < a.closingTime()) return false; } return true; } public double multiplicativeProfit() { if (!positionsAreNonOverlapping()) return Double.NaN; double profit = 1; for (var p : sortedPositions()) profit *= 1 + p.profit() / 100; return (profit - 1) * 100; } public boolean haveBackData() { return backDataHoursWanted == 0 | backDataFed; } public boolean didRealTrades() { return any(allPositions(), p -> p.openedOnMarket() || p.closedOnMarket()); } public String formatCellSize(double cellSize) { return formatPercentage(cellSize, 3); } public String areaDesc() { if (eq(area, "Candidates")) return "Candidate"; return nempty(area) ? area : archived ? "Archived" : ""; } final public G22TradingStrategy currentTime(long time) { return setTime(time); } public G22TradingStrategy setTime(long time) { int age = ifloor(ageInHours()); long lastMod = mod(currentTime() - startTime, hoursToMS(1)); currentTime = () -> time; if (ifloor(ageInHours()) > age) log("Hourly profit log: " + formatMarginProfit(coinProfit())); return this; } public double ageInHours() { return startTime == 0 ? 0 : msToHours(currentTime() - startTime); } public G22TradingStrategy changeCellSize(double newCellSize) { double oldCellSize = cellSize(); if (oldCellSize == newCellSize) return this; cellSize(newCellSize); if (digitizer != null) digitizer.swapPriceCells(makePriceCells(priceCells().basePrice())); log("Changed cell size from " + oldCellSize + " to " + newCellSize); return this; } public boolean hasClosedItself() { return closedItself != 0; } public double juiceValue() { return coinProfit(); } public double drift() { double drift = 0; for (var p : openPositions()) drift += p.cryptoAmount() * p.direction(); return drift; } public String formatCryptoAmount(double amount) { return formatDouble3(amount); } public Position openShort() { return openPosition(-1); } public Position openLong() { return openPosition(1); } public Position openPosition(int direction) { return openPosition(direction, null); } public Position openPosition(int direction, Object openReason) { Position p = new Position(); p.marginToUse = marginPerPosition; return openPosition(p, direction, openReason); } public List winners() { return filter(closedPositions(), p -> p.coinProfit() > 0); } public List losers() { return filter(closedPositions(), p -> p.coinProfit() < 0); } public List openPositions() { return cloneList(openPositions); } } static public class G22ConnectivityPanel implements Swingable { final public G22ConnectivityPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22ConnectivityPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return jCenteredSection("Gazelle Users Online", fontSize(30, centerLabel(transformedLiveValueLabel(__69 -> n2(__69), g22utils.masterStuff().lvGazelleUserCount())))); } } static public class GeometricPriceCells implements PriceCells { public GeometricPriceCells() { } final public GeometricPriceCells setCellSizeInPercent(double cellSizeInPercent) { return cellSizeInPercent(cellSizeInPercent); } public GeometricPriceCells cellSizeInPercent(double cellSizeInPercent) { this.cellSizeInPercent = cellSizeInPercent; return this; } final public double getCellSizeInPercent() { return cellSizeInPercent(); } public double cellSizeInPercent() { return cellSizeInPercent; } public double cellSizeInPercent; final public GeometricPriceCells setBasePrice(double basePrice) { return basePrice(basePrice); } public GeometricPriceCells basePrice(double basePrice) { this.basePrice = basePrice; return this; } final public double getBasePrice() { return basePrice(); } public double basePrice() { return basePrice; } public double basePrice = 1000; public GeometricPriceCells(double cellSizeInPercent) { this.cellSizeInPercent = cellSizeInPercent; } public GeometricPriceCells(double basePrice, double cellSizeInPercent) { this.cellSizeInPercent = cellSizeInPercent; this.basePrice = basePrice; } public double ratio() { return 1 + cellSizeInPercent / 100; } public double toLogScale(double price) { return log(price, ratio()); } public double fromLogScale(double logPrice) { return pow(ratio(), logPrice); } public double logBasePrice() { return toLogScale(basePrice); } public double remainder(double price) { return remainder(toLogScale(price)); } public double remainderLog(double logPrice) { return frac(logPrice - logBasePrice()); } public boolean isCellLimit(double price) { return remainder(price) == 0; } public double nextCellLimitLog(double logPrice) { double r = remainderLog(logPrice); return logPrice + 1 - r; } public double nextCellLimit(double price) { return fromLogScale(nextCellLimitLog(toLogScale(price))); } public double previousCellLimitLog(double logPrice) { double r = remainderLog(logPrice); return logPrice - (r == 0 ? 1 : r); } public double previousCellLimit(double price) { return fromLogScale(previousCellLimitLog(toLogScale(price))); } public double nCellLimitsDown(double price, int n) { double logPrice = toLogScale(price); logPrice = previousCellLimitLog(logPrice) - (n - 1); return fromLogScale(logPrice); } public double nCellLimitsUp(double price, int n) { double logPrice = toLogScale(price); logPrice = nextCellLimitLog(logPrice) + n; return fromLogScale(logPrice); } public double priceToCellNumber(double price) { return toLogScale(price) - logBasePrice(); } public double cellNumberToPrice(double cellNumber) { return fromLogScale(cellNumber + logBasePrice()); } public String toString() { return formatDouble2(cellSizeInPercent) + "% cells with C0=" + formatPrice(basePrice); } } static public class G22RegionsToMeshes implements IFieldsToList { static final public String _fieldOrder = "regions keepMetaSrc thinnedRegion"; public Collection regions; public G22RegionsToMeshes() { } public G22RegionsToMeshes(Collection regions) { this.regions = regions; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + regions + ")"; } public boolean equals(Object o) { if (!(o instanceof G22RegionsToMeshes)) return false; G22RegionsToMeshes __1 = (G22RegionsToMeshes) o; return eq(regions, __1.regions); } public int hashCode() { int h = 131341070; h = boostHashCombine(h, _hashCode(regions)); return h; } public Object[] _fieldsToList() { return new Object[] { regions }; } final public G22RegionsToMeshes setKeepMetaSrc(boolean keepMetaSrc) { return keepMetaSrc(keepMetaSrc); } public G22RegionsToMeshes keepMetaSrc(boolean keepMetaSrc) { this.keepMetaSrc = keepMetaSrc; return this; } final public boolean getKeepMetaSrc() { return keepMetaSrc(); } public boolean keepMetaSrc() { return keepMetaSrc; } public boolean keepMetaSrc = true; public IImageRegion thinnedRegion; public List get() { return map(regions, region -> { var thinner = new G22RegionThinner_v2(region); stepAll(thinner); thinnedRegion = thinner.region(); var meshMaker = new G22SkeletonToMesh_v2(thinnedRegion); var mesh = meshMaker.get(); if (!keepMetaSrc) clearMetaSrc(mesh); return mesh; }); } } static public class JG22Network implements Swingable { public G22Utils g22utils; public MainPanel mainPanel = new MainPanel(); public G22Network network = new G22Network(); public Map elementToComponent = syncMap(); public ReliableSingleThread rstUpdate = rstWithPreDelay(0.25, () -> updateImpl()); public JCheckBox cbAutoCalculate; final public JG22Network setMaxMagneticDistance(int maxMagneticDistance) { return maxMagneticDistance(maxMagneticDistance); } public JG22Network maxMagneticDistance(int maxMagneticDistance) { this.maxMagneticDistance = maxMagneticDistance; return this; } final public int getMaxMagneticDistance() { return maxMagneticDistance(); } public int maxMagneticDistance() { return maxMagneticDistance; } public int maxMagneticDistance = 100; final public JG22Network setAutoCalcInterval(double autoCalcInterval) { return autoCalcInterval(autoCalcInterval); } public JG22Network autoCalcInterval(double autoCalcInterval) { this.autoCalcInterval = autoCalcInterval; return this; } final public double getAutoCalcInterval() { return autoCalcInterval(); } public double autoCalcInterval() { return autoCalcInterval; } public double autoCalcInterval = 0.1; final public JG22Network setNetworkInstance(G22NetworkInstance networkInstance) { return networkInstance(networkInstance); } public JG22Network networkInstance(G22NetworkInstance networkInstance) { this.networkInstance = networkInstance; return this; } final public G22NetworkInstance getNetworkInstance() { return networkInstance(); } public G22NetworkInstance networkInstance() { return networkInstance; } volatile public G22NetworkInstance networkInstance; transient public int margin = 50; public class MainPanel extends JPanel { public MainPanel() { super(null); } public boolean isOptimizedDrawingEnabled() { return false; } public Dimension getPreferredSize() { Rect r = combinedChildBounds(this); if (r == null) r = rect(0, 0, 0, 0); return new Dimension(r.x2() + margin, r.y2() + margin); } public void revalidateMe() { revalidateIncludingFullCenterContainer(this); repaint(); } public void paintComponent(Graphics g) { fillRect(((Graphics2D) g), 0, 0, getWidth(), getHeight(), Color.white); for (var cable : network.allCables()) { Rect r1 = cable.from.bounds(); Rect r2 = cable.to.bounds(); drawLine(((Graphics2D) g), center(r1), center(r2), Color.black); } } } public JG22Network(G22Utils g22utils, G22Network network) { this.network = network; this.g22utils = g22utils; network.onChangeAndNow(() -> networkChanged()); for (var element : network.elements) visualizeElement(element); } public void networkChanged() { rstUpdate.trigger(); } public void updateImpl() { if (networkInstance == null) makeInstance(); visualizePorts(); } public void visualizePorts() { swingLater(new Runnable() { public void run() { try { Map visualizations = new HashMap(); for (var port : directChildrenOfType(mainPanel, JG22NetworkPort.class)) visualizations.put(port.port, port); for (var e : network.elements) { var c = elementToComponent.get(e); if (c == null) print("No component for " + e); else for (var port : e.ports) { var p = visualizations.get(port); if (p != null) { p.update(); visualizations.remove(port); } else { p = new JG22NetworkPort(g22utils, c, port); p.init(); mainPanel.add(p); } } } for (var port : values(visualizations)) removeFromParent(port); mainPanel.repaint(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Map visualizations = new Map;\r\n f..."; } }); } public void makeInstance() { var networkInstance = new G22NetworkInstance(network); networkInstance.onDirtyStatesChanged(() -> dirtyStatesChanged()); networkInstance.init(g22utils); networkInstance(networkInstance); dirtyStatesChanged(); print("Network instance made"); } public void dirtyStatesChanged() { for (var component : values(elementToComponent)) component.updateDirtyFlag(); } public void visualizeElement(G22NetworkElement element) { swing(() -> { var c = new JG22NetworkElement(g22utils, this, element); elementToComponent.put(element, c); var component = c.visualize(); mainPanel.add(component); mainPanel.revalidateMe(); componentToFront(component); }); } public void newInstance() { networkInstance = null; rstUpdate.trigger(); } public void newElement() { G22NetworkElement element = new G22NetworkElement(); element.network(network); network.elements.add(element); network.change(); visualizeElement(element); } public void deleteElement(JG22NetworkElement element) { network.elements.remove(element.element); network.change(); mainPanel.remove(element.visualize()); mainPanel.repaint(); } public void doMagneticConnections() { var newCables = network.doMagneticConnections(); for (var cable : unnullForIteration(newCables)) networkInstance.invalidateNode(cable.to().element()); mainPanel.repaint(); } public void configureNodes() { for (var element : network.elements) element.configureBlueprint(g22utils); } public void calculationStep() { var node = networkInstance == null ? null : networkInstance.calculateOneNode(g22utils); if (node == null) return; elementToComponent.get(node).visualizeNode(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { cbAutoCalculate = jVarCheckBox("Auto-calculate", network.varAutoCalculate()); awtCalcEvery(mainPanel, autoCalcInterval, () -> { if (isChecked(cbAutoCalculate)) calculationStep(); }); var magneticDistanceSlider = jLiveValueSlider_int_bothWays(0, maxMagneticDistance, network.varMagneticDistance()); return withRightAlignedButtons(jscroll(mainPanel), cbAutoCalculate, withLabel("Magnetic auto-connect distance:", jMinWidth(maxMagneticDistance, magneticDistanceSlider)), "Do magnetic connections", runnableThread(new Runnable() { public void run() { try { doMagneticConnections(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "doMagneticConnections();"; } }), "Configure nodes", runnableThread(new Runnable() { public void run() { try { configureNodes(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "configureNodes();"; } }), "New instance", runnableThread(new Runnable() { public void run() { try { newInstance(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newInstance();"; } }), "New node", runnableThread(new Runnable() { public void run() { try { newElement(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newElement();"; } })); } } static public class G22Variable extends ConceptWithChangeListeners implements IPersistenceInfo, AutoCloseable { static final public String _fieldOrder = "name value persistent autoClose big loadLock"; public transient FieldVar varName_cache; public FieldVar varName() { if (varName_cache == null) varName_cache = varName_load(); return varName_cache; } public FieldVar varName_load() { return new FieldVar(this, "name", () -> name(), name -> name(name)); } final public G22Variable setName(String name) { return name(name); } public G22Variable name(String name) { if (!eq(this.name, name)) { this.name = name; change(); } return this; } final public String getName() { return name(); } public String name() { return name; } public String name; volatile public Object value; public transient FieldVar varPersistent_cache; public FieldVar varPersistent() { if (varPersistent_cache == null) varPersistent_cache = varPersistent_load(); return varPersistent_cache; } public FieldVar varPersistent_load() { return new FieldVar(this, "persistent", () -> persistent(), persistent -> persistent(persistent)); } final public G22Variable setPersistent(boolean persistent) { return persistent(persistent); } public G22Variable persistent(boolean persistent) { if (!eq(this.persistent, persistent)) { this.persistent = persistent; change(); } return this; } final public boolean getPersistent() { return persistent(); } public boolean persistent() { return persistent; } public boolean persistent = false; final public G22Variable setAutoClose(boolean autoClose) { return autoClose(autoClose); } public G22Variable autoClose(boolean autoClose) { this.autoClose = autoClose; return this; } final public boolean getAutoClose() { return autoClose(); } public boolean autoClose() { return autoClose; } public boolean autoClose = false; public transient FieldVar varBig_cache; public FieldVar varBig() { if (varBig_cache == null) varBig_cache = varBig_load(); return varBig_cache; } public FieldVar varBig_load() { return new FieldVar(this, "big", () -> big(), big -> big(big)); } final public G22Variable setBig(boolean big) { return big(big); } public G22Variable big(boolean big) { if (!eq(this.big, big)) { this.big = big; change(); } return this; } final public boolean getBig() { return big(); } public boolean big() { return big; } public boolean big = false; transient public Lock loadLock = lock(); public Map _persistenceInfo() { return litmap("value", persistent && !big); } public transient FieldVar varValue_cache; public FieldVar varValue() { if (varValue_cache == null) varValue_cache = varValue_load(); return varValue_cache; } public FieldVar varValue_load() { return new FieldVar(this, "value", () -> value(), value -> value(value)); } public void setValueIfNull(Object defaultValue) { if (defaultValue != null && value == null) value(defaultValue); } public Object cachedValue() { return value; } final public Object value() { return get(); } public Object get() { if (value != null) return value; if (big) return getBigValue(); return value; } public Object getOnce() { if (value != null) return value; if (big) return loadBigValueImpl(); return value; } public G22Utils g22utils() { return main.g22utils(this); } public File bigFile() { return newFile(assertNotNull(g22utils().projectDir()), id + "-" + sanitizeFileName(name) + ".structgz"); } public Object getBigValue() { Object o; { Lock __0 = loadLock; lock(__0); try { o = loadBigValueImpl(); setValueField(o); } finally { unlock(__0); } } g22utils().bigVariableLoaded(this); return o; } public Object loadBigValueImpl() { return unstructureGZFile(bigFile(), g22utils().classFinder()); } public void setBigValue(Object value) { if (value == null) { if (hasBigValue()) { deleteBigValue(); change(); } } else { File f = bigFile(); saveGZStructureToFile(f, value); change(); } } public void deleteBigValue() { deleteFile(bigFile()); } public boolean hasBigValue() { return fileExists(bigFile()); } public void makeBig() { if (big) return; setBigValue(value); big(true); persistent(true); } public void makeSmall() { if (!big) return; get(); big(false); deleteBigValue(); } final public G22Variable setValue(Object o) { return value(o); } public G22Variable value(Object o) { if (big) setBigValue(o); else if (!eq(value, o)) { setValueField(o); change(); } return this; } final public boolean has() { return notNull(); } public boolean notNull() { return big ? hasBigValue() : value != null; } public void unload() { if (big) setValueField(null); } public Object setValueField(Object o) { if (autoClose && o != value) { cleanUp(value); value = null; } return value = o; } public void close() { try { if (autoClose) { cleanUp(value); value = null; } } catch (Exception __e) { throw rethrow(__e); } } public void delete() { close(); super.delete(); } public void changeInsideOfValue() { if (big) value(value); change(); } } static public class G22ProjectStoryEditor implements IFieldsToList { public G22Utils g22utils; public G22ProjectStoryEditor() { } public G22ProjectStoryEditor(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public JSyntaxTextFileEditor editor; public File textFile() { return g22utils.projectStoryTextFile(); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { editor = new JSyntaxTextFileEditor(textFile()).autoSave(true); editor.adaptSyntaxTextArea = textArea -> g22_adaptSyntaxTextAreaForHashRefs(textArea, g22utils); return withTopAndBottomMargin(jRaisedCenteredSection("Project Story " + quote(g22utils.projectName()), editor.visualize())); } } static public class JTickerView implements Swingable { final public JTickerView setCoin(String coin) { return coin(coin); } public JTickerView coin(String coin) { this.coin = coin; return this; } final public String getCoin() { return coin(); } public String coin() { return coin; } public String coin; final public JTickerView setH(int h) { return h(h); } public JTickerView h(int h) { this.h = h; return this; } final public int getH() { return h(); } public int h() { return h; } public int h = 200; final public JTickerView setTicker(TickerSequence ticker) { return ticker(ticker); } public JTickerView ticker(TickerSequence ticker) { this.ticker = ticker; return this; } final public TickerSequence getTicker() { return ticker(); } public TickerSequence ticker() { return ticker; } public TickerSequence ticker; final public JTickerView setPainter(AbstractTickerPainter painter) { return painter(painter); } public JTickerView painter(AbstractTickerPainter painter) { this.painter = painter; return this; } final public AbstractTickerPainter getPainter() { return painter(); } public AbstractTickerPainter painter() { return painter; } public AbstractTickerPainter painter; final public JTickerView setImageSurfaceMaker(IImageSurfaceMaker imageSurfaceMaker) { return imageSurfaceMaker(imageSurfaceMaker); } public JTickerView imageSurfaceMaker(IImageSurfaceMaker imageSurfaceMaker) { this.imageSurfaceMaker = imageSurfaceMaker; return this; } final public IImageSurfaceMaker getImageSurfaceMaker() { return imageSurfaceMaker(); } public IImageSurfaceMaker imageSurfaceMaker() { return imageSurfaceMaker; } public IImageSurfaceMaker imageSurfaceMaker = () -> imageSurfaceWithToolTip(); final public JTickerView setIsTicker(ImageSurface isTicker) { return isTicker(isTicker); } public JTickerView isTicker(ImageSurface isTicker) { this.isTicker = isTicker; return this; } final public ImageSurface getIsTicker() { return isTicker(); } public ImageSurface isTicker() { return isTicker; } public ImageSurface isTicker; final public JTickerView setStrategy(G22TradingStrategy strategy) { return strategy(strategy); } public JTickerView strategy(G22TradingStrategy strategy) { this.strategy = strategy; return this; } final public G22TradingStrategy getStrategy() { return strategy(); } public G22TradingStrategy strategy() { return strategy; } public G22TradingStrategy strategy; public JSlider timeZoomSlider = jSlider(1, 10, 1); public ReliableSingleThread rstPaint = rst(() -> repaintImpl()); transient public Set> onSettingUpPainter; public JTickerView onSettingUpPainter(IVF1 f) { onSettingUpPainter = createOrAddToSyncLinkedHashSet(onSettingUpPainter, f); return this; } public JTickerView removeSettingUpPainterListener(IVF1 f) { loadableUtils.utils.remove(onSettingUpPainter, f); return this; } public void settingUpPainter(AbstractTickerPainter painter) { if (onSettingUpPainter != null) for (var listener : onSettingUpPainter) pcallF_typed(listener, painter); } public JTickerView() { } public JTickerView(TickerSequence ticker) { this.ticker = ticker; } transient public Runnable makePainter; public void makePainter() { if (makePainter != null) makePainter.run(); else makePainter_base(); } final public void makePainter_fallback(Runnable _f) { if (_f != null) _f.run(); else makePainter_base(); } public void makePainter_base() { painter = new TickerGraphPainter(); painter.w(300 * intFromSlider(timeZoomSlider)).h(h); painter.ticker(ticker); painter.drawPercentLines(false); if (strategy != null) for (var p : strategy.closedPositions()) { painter.positions.add(new TradingPosition().profit(p.profit()).openingTime(p.openingTime()).closingTime(p.closingTime()).openingPrice(p.openingPrice()).closingPrice(p.closingPrice()).isLong(p.direction > 0).leverage(iround(p.leverage))); } settingUpPainter(painter); } public void repaintImpl() { makePainter(); isTicker.setImage(painter.render()); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { if (isTicker == null) isTicker = imageSurfaceMaker.newImageSurface(); onChange(timeZoomSlider, rstPaint); rstPaint.trigger(); return jCenteredSection(str(ticker), centerAndSouthWithMargin(jMinHeight(h, jscroll_horizontal_borderless(isTicker)), withLabel("Time zoom:", timeZoomSlider))); } } static public class G22LocalFontsPanel implements Swingable, IFieldsToList { public G22Utils g22utils; public G22LocalFontsPanel() { } public G22LocalFontsPanel(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } transient public SingleComponentPanel scpFontDemo = singleComponentPanel(); transient public JList fontsList; transient public String demoText = mlsUnindent("\r\n Gazelle\r\n is a new\r\n image recognizer\r\n "); public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { var fontNames = localFontFamilies(); fontsList = jlist(fontNames); onSelect(fontsList, fontName -> { if (fontName == null) { scpFontDemo.clear(); return; } var font = localFont(fontName); var renderText = new RenderText(font).fontSize(50).alignment("center"); scpFontDemo.set(jCenteredSection("Font Demo: " + fontName, jscroll_center(g22utils.stdImageSurface(renderText.get(demoText))))); }); return jCenteredRaisedSection("Local Fonts", jhsplit(0.3, jCenteredSection(n2(fontNames, "Font"), fontsList), scpFontDemo)); } } static public class JMaxSpeedAnimation implements Swingable { final public JMaxSpeedAnimation setRenderFrame(IF0 renderFrame) { return renderFrame(renderFrame); } public JMaxSpeedAnimation renderFrame(IF0 renderFrame) { this.renderFrame = renderFrame; return this; } final public IF0 getRenderFrame() { return renderFrame(); } public IF0 renderFrame() { return renderFrame; } public IF0 renderFrame; final public ImageSurface getImageSurface() { return imageSurface(); } public ImageSurface imageSurface() { return imageSurface; } public ImageSurface imageSurface = new ImageSurface(); final public DoubleFPSCounter getFps() { return fps(); } public DoubleFPSCounter fps() { return fps; } public DoubleFPSCounter fps = new DoubleFPSCounter(); public JMaxSpeedAnimation() { } public JMaxSpeedAnimation(IF0 renderFrame) { this.renderFrame = renderFrame; } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { imageSurface.pixelate(true); imageSurface.autoZoomToDisplay(true); awtCalcContinuously(imageSurface, () -> { var img = renderFrame.get(); fps.inc(); displayNewImage(img); }); return jscroll_center_borderless(imageSurface); } transient public IVF1 displayNewImage; public void displayNewImage(BufferedImage image) { if (displayNewImage != null) displayNewImage.get(image); else displayNewImage_base(image); } final public void displayNewImage_fallback(IVF1 _f, BufferedImage image) { if (_f != null) _f.get(image); else displayNewImage_base(image); } public void displayNewImage_base(BufferedImage image) { if (image != null) imageSurface.setImage(image); } } static public class SimpleCircularBuffer implements Iterable, IntSize { public SimpleCircularBuffer() { } public A[] buffer; public long base; public int size; public SimpleCircularBuffer(int capacity) { buffer = (A[]) new Object[capacity]; } synchronized public void add(A a) { if (size == buffer.length) { --size; ++base; } buffer[(int) ((base + size) % buffer.length)] = a; ++size; } synchronized public A get(long pos) { if (pos < base || pos >= base + size) return null; return buffer[(int) (pos % buffer.length)]; } synchronized public A getFromBase(long pos) { return get(pos + base); } public synchronized int size() { return size; } public Iterator iterator() { return new IterableIterator() { public long i; public boolean hasNext() { return i < size(); } public A next() { return get(i++); } }; } synchronized public int capacity() { return buffer.length; } synchronized public boolean isFull() { return size() == capacity(); } public boolean isEmpty() { return size() == 0; } final public long base() { return getBase(); } synchronized public long getBase() { return base; } final public A remove() { return popFirst(); } synchronized public A popFirst() { if (isEmpty()) return null; A a = get(base); --size; ++base; return a; } synchronized public A nextToLast() { return get(base + size - 2); } synchronized public A last() { return get(base + size - 1); } synchronized public A first() { return get(base); } public List asList() { return loadableUtils.utils.asList(this); } } static public class TradingRun extends TradingCandle implements IntSize { public TradingRun() { } final public TradingRun setCandles(List candles) { return candles(candles); } public TradingRun candles(List candles) { this.candles = candles; return this; } final public List getCandles() { return candles(); } public List candles() { return candles; } public List candles = new ArrayList(); public TradingRun(Iterable candles) { for (var c : unnullForIteration(candles)) add(c); } final public void addCandle(TradingCandle candle) { add(candle); } public void add(TradingCandle candle) { candles.add(candle); addValue(candle.start, candle.startTime); addValue(candle.end, candle.endTime); if (candle.min < min) min = candle.min; if (candle.max > max) max = candle.max; } public int size() { return l(candles); } public double changePercent() { return asPercentIncrease(changeRatio()); } public String myType() { return "run length " + n2(candles) + ", change " + formatDouble2X(changePercent()) + "%"; } public boolean isCompatibleCandle(TradingCandle candle) { return candle.isWhite() || eq(candle.colorText(), colorText()); } public TradingRun clone() { return shallowClone(this).candles(map(candles, __1 -> __1.clone())); } } static public class TickerGraphPainter extends AbstractTickerPainter implements IToolTipMaker, MakesBufferedImage { final public TickerGraphPainter setPricePrefix(String pricePrefix) { return pricePrefix(pricePrefix); } public TickerGraphPainter pricePrefix(String pricePrefix) { this.pricePrefix = pricePrefix; return this; } final public String getPricePrefix() { return pricePrefix(); } public String pricePrefix() { return pricePrefix; } public String pricePrefix = "Price="; public TickerGraphPainter() { } public TickerGraphPainter(TickerSequence ticker) { ticker(ticker); } public void drawOn(Graphics2D g) { if (verticalRange == null) verticalRange(verticalRangeForTicker(ticker)); if (horizontalRange == null) horizontalRange(horizontalRangeForTicker(ticker)); if (horizontalRange == null) return; drawPercentLines(g); drawAdditionalObjects(g); var xRange = roundToIntRange(xRange()); int idx1 = ticker.indexOfTimestamp(xFromScreen(xRange.start)); int x = xRange.start; if (idx1 == 0) x = max(x, ifloor(xToScreen(ticker.startTime()))); int idx2 = idx1; for (; x < xRange.end; x++) { idx1 = idx2; idx2 = ticker.indexOfTimestamp(xFromScreen(x + 1)); var seq = ticker.subSequence(idx1, idx2 + 1); int y1 = iround(yToScreen(seq.maxPrice())); int y2 = iround(yToScreen(seq.minPrice())); drawLine(g, x, y1, x, y2, Color.white); } drawPositions(g); } public BufferedImage render() { var img = super.render(); var img2 = cloneBufferedImageWithMeta(img); metaSet(img2, IToolTipMaker.class, this); return img2; } public String getToolTip(Pt p) { double time = xFromScreen(p.x); double price = ticker.priceAtTimestamp(time); return spaceCombine(ticker.market, formatPrice(price), "at", formatLocalDateWithSeconds(lround(time))); } transient public IF1 formatPrice; public String formatPrice(double price) { return formatPrice != null ? formatPrice.get(price) : formatPrice_base(price); } final public String formatPrice_fallback(IF1 _f, double price) { return _f != null ? _f.get(price) : formatPrice_base(price); } public String formatPrice_base(double price) { return pricePrefix() + formatDouble3X(price); } } static public class AverageAndStandardDeviation implements IFieldsToList { public double avg; public double standardDeviation; public AverageAndStandardDeviation() { } public AverageAndStandardDeviation(double avg, double standardDeviation) { this.standardDeviation = standardDeviation; this.avg = avg; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + avg + ", " + standardDeviation + ")"; } public boolean equals(Object o) { if (!(o instanceof AverageAndStandardDeviation)) return false; AverageAndStandardDeviation __1 = (AverageAndStandardDeviation) o; return avg == __1.avg && standardDeviation == __1.standardDeviation; } public int hashCode() { int h = -1271115062; h = boostHashCombine(h, _hashCode(avg)); h = boostHashCombine(h, _hashCode(standardDeviation)); return h; } public Object[] _fieldsToList() { return new Object[] { avg, standardDeviation }; } } static public class PercentIncrease { public PercentIncrease() { } final public PercentIncrease setPercentIncrease(double percentIncrease) { return percentIncrease(percentIncrease); } public PercentIncrease percentIncrease(double percentIncrease) { this.percentIncrease = percentIncrease; return this; } final public double getPercentIncrease() { return percentIncrease(); } public double percentIncrease() { return percentIncrease; } public double percentIncrease; public PercentIncrease(double percentIncrease) { this.percentIncrease = percentIncrease; } public double get() { return percentIncrease; } final public double factor() { return asFactor(); } final public double getFactor() { return asFactor(); } public double asFactor() { return 1 + percentIncrease / 100; } static public PercentIncrease of(double percentIncrease) { return new PercentIncrease(percentIncrease); } static public PercentIncrease fromFactor(double factor) { return new PercentIncrease((factor - 1) * 100); } public String toString() { return plusMinusFix(formatDouble_significant(percentIncrease, 4)) + "%"; } final public PercentIncrease mul(PercentIncrease i) { return combineWith(i); } public PercentIncrease combineWith(PercentIncrease i) { return fromFactor(asFactor() * i.asFactor()); } final public double mul(double x) { return applyTo(x); } public double applyTo(double x) { return asFactor() * x; } final public PercentIncrease nthRoot(double n) { return root(n); } public PercentIncrease root(double n) { return fromFactor(Math.pow(asFactor(), 1 / n)); } final public PercentIncrease repeat(double n) { return pow(n); } public PercentIncrease pow(double n) { return fromFactor(Math.pow(asFactor(), n)); } } static public class G22ChallengesPanel { final public G22ChallengesPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22ChallengesPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; transient public SimpleCRUD_v2 challengeCRUD; transient public SingleComponentPanel scpChallengePanel; transient public SimpleCRUD_v2 recognizerCRUD; transient public G22ChallengePanel challengePanel; transient public G22ChallengeIDE challengeIDE; public JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { challengeCRUD = new SimpleCRUD_v2<>(g22utils.concepts(), G22Challenge.class); g22utils.setupScriptCRUD(challengeCRUD); challengeCRUD.addCountToEnclosingTab(true); challengeCRUD.entityName = () -> "Challenge"; challengeIDE = new G22ChallengeIDE(g22utils); challengeIDE.noScriptSelectedMsg("Please select a challenge above to start"); challengeIDE.modifyIDE = ide -> { }; recognizerCRUD = new SimpleCRUD_v2<>(g22utils.concepts(), G22Analyzer.class); recognizerCRUD.entityName = () -> "Recognizer"; g22utils.setupScriptCRUD(recognizerCRUD); var recognizerCRUDVis = recognizerCRUD.visualize(); recognizerCRUD.onSelectionChanged(() -> recognizerIDE().setScript(recognizerCRUD.selected())); scpChallengePanel = singleComponentPanel(); challengeCRUD.onSelectionChangedAndNow(r_dm_q(() -> makeChallengePanel())); return jhsplit(withTopRightAndBottomMargin(jCenteredRaisedSection("Challenges", withSideAndBottomMargin(jvsplit(jvsplit(withBottomMargin(challengeCRUD.visualize()), challengeIDE.visualize()), jCenteredRaisedSection("Recognizers", recognizerCRUDVis))))), withSideMargins(scpChallengePanel)); } public G22LAScriptIDE recognizerIDE() { return challengePanel.recognizerIDE; } public void makeChallengePanel() { var challenge = challengeCRUD.selected(); challengeIDE.setScript(challenge); if (challenge == null) return; var panel = challengePanel = new G22ChallengePanel(challenge); panel.g22utils(g22utils); panel.init(); scpChallengePanel.set(withTopAndBottomMargin(12, 6, panel.visualize())); } public void updateCount() { challengeCRUD.update(); } } static public class UpDownSequence extends RandomAccessAbstractList { public UpDownSequence() { } public BitBuffer moves = new BitBuffer(); public UpDownSequence(String s) { for (var c : characters(upper(s))) if (c == 'U') add(UpDown.up); else if (c == 'D') add(UpDown.down); } public UpDown get(int i) { return UpDown.fromBool(moves.get(i)); } public boolean add(UpDown move) { moves.add(move.bit); return true; } public String toString() { return join(countIterator(__70 -> moveChar(__70), size())); } public String moveChar(int i) { return moves.get(i) ? "U" : "D"; } public int size() { return moves.size(); } public void addUp() { add(UpDown.up); } public void addDown() { add(UpDown.down); } final static public UpDownSequence fromInts(List cellNumbers) { return fromCellNumbers(cellNumbers); } static public UpDownSequence fromCellNumbers(List cellNumbers) { UpDownSequence seq = new UpDownSequence(); if (nempty(cellNumbers)) { int cn = first(cellNumbers); for (int i = 1; i < l(cellNumbers); i++) { int cn2 = cellNumbers.get(i); int cn3 = clamp(cn2, cn - 10, cn + 10); while (cn3 > cn) { ping(); ++cn; seq.addUp(); } while (cn3 < cn) { ping(); --cn; seq.addDown(); } cn = cn2; } } return seq; } } static public class G22TravelLogEntry extends Concept { static final public String _fieldOrder = "computerID computerDescription timestamp gazelleCompilationDate projectID projectDir projectSize fileCount conceptCount conceptIDCounter lastConceptChange lastFileChange action importedFromURL importedFromFile backedUpToURL backedUpToFile comment"; final public G22TravelLogEntry setComputerID(String computerID) { return computerID(computerID); } public G22TravelLogEntry computerID(String computerID) { this.computerID = computerID; return this; } final public String getComputerID() { return computerID(); } public String computerID() { return computerID; } public String computerID; final public G22TravelLogEntry setComputerDescription(String computerDescription) { return computerDescription(computerDescription); } public G22TravelLogEntry computerDescription(String computerDescription) { this.computerDescription = computerDescription; return this; } final public String getComputerDescription() { return computerDescription(); } public String computerDescription() { return computerDescription; } public String computerDescription; final public G22TravelLogEntry setTimestamp(Timestamp timestamp) { return timestamp(timestamp); } public G22TravelLogEntry timestamp(Timestamp timestamp) { this.timestamp = timestamp; return this; } final public Timestamp getTimestamp() { return timestamp(); } public Timestamp timestamp() { return timestamp; } public Timestamp timestamp; final public G22TravelLogEntry setGazelleCompilationDate(String gazelleCompilationDate) { return gazelleCompilationDate(gazelleCompilationDate); } public G22TravelLogEntry gazelleCompilationDate(String gazelleCompilationDate) { this.gazelleCompilationDate = gazelleCompilationDate; return this; } final public String getGazelleCompilationDate() { return gazelleCompilationDate(); } public String gazelleCompilationDate() { return gazelleCompilationDate; } public String gazelleCompilationDate; final public G22TravelLogEntry setProjectID(String projectID) { return projectID(projectID); } public G22TravelLogEntry projectID(String projectID) { this.projectID = projectID; return this; } final public String getProjectID() { return projectID(); } public String projectID() { return projectID; } public String projectID; final public G22TravelLogEntry setProjectDir(File projectDir) { return projectDir(projectDir); } public G22TravelLogEntry projectDir(File projectDir) { this.projectDir = projectDir; return this; } final public File getProjectDir() { return projectDir(); } public File projectDir() { return projectDir; } public File projectDir; final public G22TravelLogEntry setProjectSize(long projectSize) { return projectSize(projectSize); } public G22TravelLogEntry projectSize(long projectSize) { this.projectSize = projectSize; return this; } final public long getProjectSize() { return projectSize(); } public long projectSize() { return projectSize; } public long projectSize; final public G22TravelLogEntry setFileCount(int fileCount) { return fileCount(fileCount); } public G22TravelLogEntry fileCount(int fileCount) { this.fileCount = fileCount; return this; } final public int getFileCount() { return fileCount(); } public int fileCount() { return fileCount; } public int fileCount; final public G22TravelLogEntry setConceptCount(int conceptCount) { return conceptCount(conceptCount); } public G22TravelLogEntry conceptCount(int conceptCount) { this.conceptCount = conceptCount; return this; } final public int getConceptCount() { return conceptCount(); } public int conceptCount() { return conceptCount; } public int conceptCount; final public G22TravelLogEntry setConceptIDCounter(long conceptIDCounter) { return conceptIDCounter(conceptIDCounter); } public G22TravelLogEntry conceptIDCounter(long conceptIDCounter) { this.conceptIDCounter = conceptIDCounter; return this; } final public long getConceptIDCounter() { return conceptIDCounter(); } public long conceptIDCounter() { return conceptIDCounter; } public long conceptIDCounter; final public G22TravelLogEntry setLastConceptChange(Timestamp lastConceptChange) { return lastConceptChange(lastConceptChange); } public G22TravelLogEntry lastConceptChange(Timestamp lastConceptChange) { this.lastConceptChange = lastConceptChange; return this; } final public Timestamp getLastConceptChange() { return lastConceptChange(); } public Timestamp lastConceptChange() { return lastConceptChange; } public Timestamp lastConceptChange; final public G22TravelLogEntry setLastFileChange(Timestamp lastFileChange) { return lastFileChange(lastFileChange); } public G22TravelLogEntry lastFileChange(Timestamp lastFileChange) { this.lastFileChange = lastFileChange; return this; } final public Timestamp getLastFileChange() { return lastFileChange(); } public Timestamp lastFileChange() { return lastFileChange; } public Timestamp lastFileChange; final public G22TravelLogEntry setAction(String action) { return action(action); } public G22TravelLogEntry action(String action) { this.action = action; return this; } final public String getAction() { return action(); } public String action() { return action; } public String action; final public G22TravelLogEntry setImportedFromURL(String importedFromURL) { return importedFromURL(importedFromURL); } public G22TravelLogEntry importedFromURL(String importedFromURL) { this.importedFromURL = importedFromURL; return this; } final public String getImportedFromURL() { return importedFromURL(); } public String importedFromURL() { return importedFromURL; } public String importedFromURL; final public G22TravelLogEntry setImportedFromFile(File importedFromFile) { return importedFromFile(importedFromFile); } public G22TravelLogEntry importedFromFile(File importedFromFile) { this.importedFromFile = importedFromFile; return this; } final public File getImportedFromFile() { return importedFromFile(); } public File importedFromFile() { return importedFromFile; } public File importedFromFile; final public G22TravelLogEntry setBackedUpToURL(String backedUpToURL) { return backedUpToURL(backedUpToURL); } public G22TravelLogEntry backedUpToURL(String backedUpToURL) { this.backedUpToURL = backedUpToURL; return this; } final public String getBackedUpToURL() { return backedUpToURL(); } public String backedUpToURL() { return backedUpToURL; } public String backedUpToURL; final public G22TravelLogEntry setBackedUpToFile(File backedUpToFile) { return backedUpToFile(backedUpToFile); } public G22TravelLogEntry backedUpToFile(File backedUpToFile) { this.backedUpToFile = backedUpToFile; return this; } final public File getBackedUpToFile() { return backedUpToFile(); } public File backedUpToFile() { return backedUpToFile; } public File backedUpToFile; final public G22TravelLogEntry setComment(String comment) { return comment(comment); } public G22TravelLogEntry comment(String comment) { this.comment = comment; return this; } final public String getComment() { return comment(); } public String comment() { return comment; } public String comment; static public G22TravelLogEntry create(G22Utils g22utils) { var cc = g22utils.concepts(); return new G22TravelLogEntry().computerID(loadableUtils.utils.computerID()).timestamp(tsNow()).gazelleCompilationDate(g22utils.compilationDate()).projectID(g22utils.projectID()).projectDir(g22utils.projectDir()).conceptCount(countConcepts(cc)).conceptIDCounter(cc.idCounter).lastConceptChange(loadableUtils.utils.lastConceptChange(cc)); } public G22TravelLogEntry scanProject(G22Utils g22utils) { List files = findAllFiles_noDirs(g22utils.projectDir()); return lastFileChange(toTimestamp(max(map(__71 -> modificationTime(__71), files)))).projectSize(longSum(__72 -> fileSize(__72), files)).fileCount(l(files)); } static public boolean shouldCreateEntry(G22Utils g22utils) { var entries = list(g22utils.concepts(), G22TravelLogEntry.class); if (empty(entries)) return true; var last = highestByField(entries, "timestamp"); if (!eq(last.computerID(), loadableUtils.utils.computerID())) return true; return false; } } static public class SNIKeyManager implements X509KeyManager { public Map> keyManagersByDomain; public boolean verbose = false; public SNIKeyManager(Map> keyManagersByDomain) { this.keyManagersByDomain = keyManagersByDomain; } @Override public String[] getClientAliases(String keyType, Principal[] issuers) { throw printStackTrace(new UnsupportedOperationException()); } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { throw printStackTrace(new UnsupportedOperationException()); } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { return toStringArray(keys(keyManagersByDomain)); } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { ExtendedSSLSession session = (ExtendedSSLSession) (((SSLSocket) socket).getHandshakeSession()); if (verbose) print("chooseServerAlias session type: " + className(session)); List names = session.getRequestedServerNames(); if (verbose) print("Requested server names: " + names); String requestedName = str(first(names)); requestedName = substring(requestedName, lastIndexOf(requestedName, "=") + 1); for (String knownName : keys(keyManagersByDomain)) if (domainIsUnder(requestedName, knownName)) { if (verbose) print("Matched server name: " + knownName); return knownName; } if (verbose) print("Reverting to default server name"); return first(keys(keyManagersByDomain)); } @Override public X509Certificate[] getCertificateChain(String alias) { X509KeyManager man; String alias2; Pair __1 = keyManagersByDomain.get(alias); man = __1.a; alias2 = __1.b; if (verbose) print("getCertificateChain " + alias + " => " + alias2); return man.getCertificateChain(alias2); } @Override public PrivateKey getPrivateKey(String alias) { X509KeyManager man; String alias2; Pair __2 = keyManagersByDomain.get(alias); man = __2.a; alias2 = __2.b; if (verbose) print("getPrivateKey " + alias + " => " + alias2); return man.getPrivateKey(alias2); } } static public class Hi15ScanlineIndex { public Hi15Image image; public int w, h; public int[] indexed; public IntBuffer scanlines; public Hi15ScanlineIndex() { } public Hi15ScanlineIndex(Hi15Image image) { this.image = image; } public void run() { try { int w = this.w = image.getWidth(); int h = this.h = image.getHeight(); short[] pixels = image.pixels; int lineStart = 0; var indexed = this.indexed = new int[w * h]; int guess = 128 * 1024; var scanlines = this.scanlines = new IntBuffer(guess); for (int y = 0; y < h; y++) { int i = lineStart; int lineEnd = lineStart + w; while (i < lineEnd) { short color = pixels[i]; int j = i + 1; if (j < lineEnd && pixels[j] == color) { do ++j; while (j < lineEnd && pixels[j] == color); scanlines.add(i); scanlines.add(j); } int iScanline = scanlines.size(); while (i < j) indexed[i++] = iScanline; } lineStart = lineEnd; } } catch (Exception __e) { throw rethrow(__e); } } public int nScanlines() { return scanlines.size() / 2; } public BufferedImage scanlinesAsImage() { int[] pixels = new int[w * h]; int n = nScanlines(); for (int i = 0; i < n; i++) { int from = scanlines.get(i * 2); int to = scanlines.get(i * 2 + 1); int color = withFullAlpha(hi15ToRGBInt_clean(image.getHi15Pixel_noRangeCheck(from))); for (int pixel = from; pixel < to; pixel++) pixels[pixel] = color; } return bufferedImageWithAlpha(w, h, pixels); } public void compact() { scanlines.trimToSize(); } } static public class VerticalCenterLayout extends AbstractLayoutManager { public void layoutContainer(Container parent) { List components = getComponents(parent); if (l(components) > 1) { print("VerticalCenterLayout fail"); return; } Component c = first(components); if (c == null) return; int w = parent.getWidth(), h = parent.getHeight(); Dimension size = c.getPreferredSize(); int y = (h - size.height) / 2; c.setBounds(0, y, w, size.height); preferredSize(size); } } static public class LASValueDescriptor { public LASValueDescriptor() { } public boolean knownValue() { return false; } public Object value() { return null; } public Class javaClass() { return null; } public boolean javaClassIsExact() { return false; } public boolean canBeNull() { return true; } public boolean canFail() { return false; } public boolean willFail() { return false; } static public class Exact extends LASValueDescriptor implements IFieldsToList { public Class c; public boolean canBeNull = false; public Exact() { } public Exact(Class c, boolean canBeNull) { this.canBeNull = canBeNull; this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ", " + canBeNull + ")"; } public boolean equals(Object o) { if (!(o instanceof Exact)) return false; Exact __1 = (Exact) o; return eq(c, __1.c) && eq(canBeNull, __1.canBeNull); } public int hashCode() { int h = 67394271; h = boostHashCombine(h, _hashCode(c)); h = boostHashCombine(h, _hashCode(canBeNull)); return h; } public Object[] _fieldsToList() { return new Object[] { c, canBeNull }; } public Class javaClass() { return c; } public boolean javaClassIsExact() { return true; } public boolean canBeNull() { return canBeNull; } } static public class NonExact extends LASValueDescriptor implements IFieldsToList { public Class c; public boolean canBeNull = false; public NonExact() { } public NonExact(Class c, boolean canBeNull) { this.canBeNull = canBeNull; this.c = c; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + c + ", " + canBeNull + ")"; } public boolean equals(Object o) { if (!(o instanceof NonExact)) return false; NonExact __2 = (NonExact) o; return eq(c, __2.c) && eq(canBeNull, __2.canBeNull); } public int hashCode() { int h = 1445514322; h = boostHashCombine(h, _hashCode(c)); h = boostHashCombine(h, _hashCode(canBeNull)); return h; } public Object[] _fieldsToList() { return new Object[] { c, canBeNull }; } public Class javaClass() { return c; } public boolean javaClassIsExact() { return false; } public boolean canBeNull() { return canBeNull; } } static public LASValueDescriptor nonExactCanBeNull(Type c) { return new NonExact(typeToClass(c), true); } static public class KnownValue extends LASValueDescriptor implements IFieldsToList { public Object value; public KnownValue() { } public KnownValue(Object value) { this.value = value; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + value + ")"; } public boolean equals(Object o) { if (!(o instanceof KnownValue)) return false; KnownValue __3 = (KnownValue) o; return eq(value, __3.value); } public int hashCode() { int h = -1456305138; h = boostHashCombine(h, _hashCode(value)); return h; } public Object[] _fieldsToList() { return new Object[] { value }; } public boolean knownValue() { return true; } public Object value() { return value; } public Class javaClass() { return value == null ? null : value.getClass(); } public boolean javaClassIsExact() { return value != null; } public boolean canBeNull() { return value == null; } } static public class WillFail extends LASValueDescriptor { public boolean canFail() { return true; } public boolean willFail() { return true; } } static public LASValueDescriptor fromClass(Class c) { return new NonExact(c, true); } } public interface IFuturesMarket { static public class OpenOrder { final public OpenOrder setHoldSide(HoldSide holdSide) { return holdSide(holdSide); } public OpenOrder holdSide(HoldSide holdSide) { this.holdSide = holdSide; return this; } final public HoldSide getHoldSide() { return holdSide(); } public HoldSide holdSide() { return holdSide; } public HoldSide holdSide; final public OpenOrder setCryptoAmount(double cryptoAmount) { return cryptoAmount(cryptoAmount); } public OpenOrder cryptoAmount(double cryptoAmount) { this.cryptoAmount = cryptoAmount; return this; } final public double getCryptoAmount() { return cryptoAmount(); } public double cryptoAmount() { return cryptoAmount; } public double cryptoAmount; final public OpenOrder setLeverage(double leverage) { return leverage(leverage); } public OpenOrder leverage(double leverage) { this.leverage = leverage; return this; } final public double getLeverage() { return leverage(); } public double leverage() { return leverage; } public double leverage = 1; final public OpenOrder setIsCross(boolean isCross) { return isCross(isCross); } public OpenOrder isCross(boolean isCross) { this.isCross = isCross; return this; } final public boolean getIsCross() { return isCross(); } public boolean isCross() { return isCross; } public boolean isCross = false; } static public class CloseOrder { final public CloseOrder setHoldSide(HoldSide holdSide) { return holdSide(holdSide); } public CloseOrder holdSide(HoldSide holdSide) { this.holdSide = holdSide; return this; } final public HoldSide getHoldSide() { return holdSide(); } public HoldSide holdSide() { return holdSide; } public HoldSide holdSide; final public CloseOrder setCryptoAmount(double cryptoAmount) { return cryptoAmount(cryptoAmount); } public CloseOrder cryptoAmount(double cryptoAmount) { this.cryptoAmount = cryptoAmount; return this; } final public double getCryptoAmount() { return cryptoAmount(); } public double cryptoAmount() { return cryptoAmount; } public double cryptoAmount; } public void openPosition(OpenOrder order); public void closePosition(CloseOrder order); static public class SwappableImplementation implements IFuturesMarket { public transient IVF1 openPosition; public void openPosition(OpenOrder order) { if (openPosition != null) openPosition.get(order); else openPosition_base(order); } final public void openPosition_fallback(IVF1 _f, OpenOrder order) { if (_f != null) _f.get(order); else openPosition_base(order); } public void openPosition_base(OpenOrder order) { } public transient IVF1 closePosition; public void closePosition(CloseOrder order) { if (closePosition != null) closePosition.get(order); else closePosition_base(order); } final public void closePosition_fallback(IVF1 _f, CloseOrder order) { if (_f != null) _f.get(order); else closePosition_base(order); } public void closePosition_base(CloseOrder order) { } public transient IF0 drift; public double drift() { return drift != null ? drift.get() : drift_base(); } final public double drift_fallback(IF0 _f) { return _f != null ? _f.get() : drift_base(); } public double drift_base() { throw unimplemented(); } public FutureCoinParameters getCoinParameters() { throw unimplemented(); } } public double drift(); public FutureCoinParameters getCoinParameters(); } static public class LASCompileResult { final public LASCompileResult setScript(String script) { return script(script); } public LASCompileResult script(String script) { this.script = script; return this; } final public String getScript() { return script(); } public String script() { return script; } public String script; final public LASCompileResult setParser(GazelleV_LeftArrowScriptParser parser) { return parser(parser); } public LASCompileResult parser(GazelleV_LeftArrowScriptParser parser) { this.parser = parser; return this; } final public GazelleV_LeftArrowScriptParser getParser() { return parser(); } public GazelleV_LeftArrowScriptParser parser() { return parser; } public GazelleV_LeftArrowScriptParser parser; final public LASCompileResult setCompileError(Throwable compileError) { return compileError(compileError); } public LASCompileResult compileError(Throwable compileError) { this.compileError = compileError; return this; } final public Throwable getCompileError() { return compileError(); } public Throwable compileError() { return compileError; } public Throwable compileError; public GazelleV_LeftArrowScript.Script parsedScript; public RunResultWithTimestamps compileLog; public String toString() { if (compileError != null) return errorToString(); if (parsedScript == null) return "Not compiled yet"; return "Compiled OK" + (compileLog == null ? "" : " in " + n2(max(1, compileLog.duration().toMillis())) + " ms"); } public boolean hasError() { return compileError != null; } public String errorToString() { return exceptionToStringShorter_dontDropOuterExceptions(compileError); } public boolean runnable() { return parsedScript != null; } public void compile() { compileLog = runResultWithTimestamps_dontPrintStackTrace(() -> { if (parser == null) parser = makeParser(); return parsedScript = parser.parse(script); }); if (compileLog.isError()) { var e = compileLog.getError(); compileError(e); } } final public GazelleV_LeftArrowScript.Script get() { return parsedScript(); } public GazelleV_LeftArrowScript.Script parsedScript() { return parsedScript; } public GazelleV_LeftArrowScript.Script parsedScriptMandatory() { if (compileError != null) throw fail(compileError); return parsedScript; } transient public IF0 makeParser; public GazelleV_LeftArrowScriptParser makeParser() { return makeParser != null ? makeParser.get() : makeParser_base(); } final public GazelleV_LeftArrowScriptParser makeParser_fallback(IF0 _f) { return _f != null ? _f.get() : makeParser_base(); } public GazelleV_LeftArrowScriptParser makeParser_base() { return null; } public LineAndColumn errorLineAndCol() { return parseLineAndColumn(str(compileError)); } public Timestamp compilationStart() { return compileLog == null ? null : compileLog.started; } } static public class G22NetworkElement extends MetaWithChangeListeners { public G22NetworkElement() { } final public G22NetworkElement setNetwork(G22Network network) { return network(network); } public G22NetworkElement network(G22Network network) { this.network = network; return this; } final public G22Network getNetwork() { return network(); } public G22Network network() { return network; } public G22Network network; final public G22NetworkElement setBounds(Rect bounds) { return bounds(bounds); } public G22NetworkElement bounds(Rect bounds) { this.bounds = bounds; return this; } final public Rect getBounds() { return bounds(); } public Rect bounds() { return bounds; } public Rect bounds; public transient FieldVar varIdentifier_cache; public FieldVar varIdentifier() { if (varIdentifier_cache == null) varIdentifier_cache = varIdentifier_load(); return varIdentifier_cache; } public FieldVar varIdentifier_load() { return new FieldVar(this, "identifier", () -> identifier(), identifier -> identifier(identifier)); } final public G22NetworkElement setIdentifier(String identifier) { return identifier(identifier); } public G22NetworkElement identifier(String identifier) { if (!eq(this.identifier, identifier)) { this.identifier = identifier; change(); } return this; } final public String getIdentifier() { return identifier(); } public String identifier() { return identifier; } public String identifier; public transient FieldVar varCode_cache; public FieldVar varCode() { if (varCode_cache == null) varCode_cache = varCode_load(); return varCode_cache; } public FieldVar varCode_load() { return new FieldVar(this, "code", () -> code(), code -> code(code)); } final public G22NetworkElement setCode(String code) { return code(code); } public G22NetworkElement code(String code) { if (!eq(this.code, code)) { this.code = code; change(); } return this; } final public String getCode() { return code(); } public String code() { return code; } public String code; public Map properties = syncMap(); public transient FieldVar varCodeVisible_cache; public FieldVar varCodeVisible() { if (varCodeVisible_cache == null) varCodeVisible_cache = varCodeVisible_load(); return varCodeVisible_cache; } public FieldVar varCodeVisible_load() { return new FieldVar(this, "codeVisible", () -> codeVisible(), codeVisible -> codeVisible(codeVisible)); } final public G22NetworkElement setCodeVisible(boolean codeVisible) { return codeVisible(codeVisible); } public G22NetworkElement codeVisible(boolean codeVisible) { if (!eq(this.codeVisible, codeVisible)) { this.codeVisible = codeVisible; change(); } return this; } final public boolean getCodeVisible() { return codeVisible(); } public boolean codeVisible() { return codeVisible; } public boolean codeVisible = true; { onChange(() -> { { if (network != null) network.change(); } }); } public class Port extends MetaWithChangeListeners implements IUnstructured { public transient FieldVar varPosition_cache; public FieldVar varPosition() { if (varPosition_cache == null) varPosition_cache = varPosition_load(); return varPosition_cache; } public FieldVar varPosition_load() { return new FieldVar(this, "position", () -> position(), position -> position(position)); } final public Port setPosition(DoublePt position) { return position(position); } public Port position(DoublePt position) { if (!eq(this.position, position)) { this.position = position; change(); } return this; } final public DoublePt getPosition() { return position(); } public DoublePt position() { return position; } public DoublePt position; public transient FieldVar varName_cache; public FieldVar varName() { if (varName_cache == null) varName_cache = varName_load(); return varName_cache; } public FieldVar varName_load() { return new FieldVar(this, "name", () -> name(), name -> name(name)); } final public Port setName(String name) { return name(name); } public Port name(String name) { if (!eq(this.name, name)) { this.name = name; change(); } return this; } final public String getName() { return name(); } public String name() { return name; } public String name; public transient FieldVar varCable_cache; public FieldVar varCable() { if (varCable_cache == null) varCable_cache = varCable_load(); return varCable_cache; } public FieldVar varCable_load() { return new FieldVar(this, "cable", () -> cable(), cable -> cable(cable)); } final public Port setCable(G22NetworkCable cable) { return cable(cable); } public Port cable(G22NetworkCable cable) { if (!eq(this.cable, cable)) { this.cable = cable; change(); } return this; } final public G22NetworkCable getCable() { return cable(); } public G22NetworkCable cable() { return cable; } public G22NetworkCable cable; public transient FieldVar varIsOutput_cache; public FieldVar varIsOutput() { if (varIsOutput_cache == null) varIsOutput_cache = varIsOutput_load(); return varIsOutput_cache; } public FieldVar varIsOutput_load() { return new FieldVar(this, "isOutput", () -> isOutput(), isOutput -> isOutput(isOutput)); } final public Port setIsOutput(boolean isOutput) { return isOutput(isOutput); } public Port isOutput(boolean isOutput) { if (!eq(this.isOutput, isOutput)) { this.isOutput = isOutput; change(); } return this; } final public boolean getIsOutput() { return isOutput(); } public boolean isOutput() { return isOutput; } public boolean isOutput = false; public transient FieldVar varDataType_cache; public FieldVar varDataType() { if (varDataType_cache == null) varDataType_cache = varDataType_load(); return varDataType_cache; } public FieldVar varDataType_load() { return new FieldVar(this, "dataType", () -> dataType(), dataType -> dataType(dataType)); } final public Port setDataType(Class dataType) { return dataType(dataType); } public Port dataType(Class dataType) { if (!eq(this.dataType, dataType)) { this.dataType = dataType; change(); } return this; } final public Class getDataType() { return dataType(); } public Class dataType() { return dataType; } public Class dataType; public G22NetworkElement element() { return G22NetworkElement.this; } public String toString() { return (isOutput ? "Output" : "Input") + " port" + " " + quote(name) + " of type " + shortClassName(dataType); } public Rect bounds() { int size = 10; Rect r = element().bounds; if (r == null) return null; r = growRectTopAndLeft(r, size); return rect(r.x + iround(position.x * r.w), r.y + iround(position.y * r.h), size, size); } public void delete() { disconnect(); ports.remove(this); change(); } public void disconnect() { { if (cable != null) cable.remove(); } } public boolean isConnected() { return cable != null; } public void _doneLoading() { onChange(() -> element().change()); } } public List ports = syncL(); public LASCompileResult newCompileResult() { return new LASCompileResult(); } transient public LASCompileResult compileResult; public LASCompileResult compile(G22Utils g22utils) { String code = unnull(this.code); var cr = compileResult; if (cr != null && eq(cr.script, code)) return cr; cr = newCompileResult(); var parser = g22utils.leftArrowParser(); configureParser(parser); cr.script(code).parser(parser).compile(); return compileResult = cr; } public void configureParser(GazelleV_LeftArrowScriptParser parser) { parser.addVar("blueprint"); parser.addVar("instance"); } public GazelleV_LeftArrowScript.Script compileScript(G22Utils g22utils) { var compiled = compile(g22utils); if (compiled == null) return null; if (!compiled.runnable()) return null; return compiled.get(); } public void configureBlueprint(G22Utils g22utils) { var script = compileScript(g22utils); if (script == null) return; FlexibleVarContext ctx = new FlexibleVarContext(); var f = script.getFunction("configure"); if (f != null) f.call(ctx, this); } public Object makeInstance(G22Utils g22utils, G22NetworkInstance networkInstance) { var script = compileScript(g22utils); if (script == null) return null; FlexibleVarContext ctx = new FlexibleVarContext(); for (var port : ports) if (!port.isOutput() && port.cable != null) { var outputPort = port.cable.from; if (outputPort != null) ctx.set(port.name, networkInstance.getObjectForBlueprint(outputPort.element())); } return script.get(ctx); } public Set upstreamNodes() { Set set = new HashSet(); for (var port : ports) if (!port.isOutput() && port.cable != null) { var outputPort = port.cable.from; if (outputPort != null) set.add(outputPort.element()); } return set; } public Set downstreamNodes() { Set set = new HashSet(); for (var port : ports) if (port.isOutput() && port.cable != null) { var outputPort = port.cable.to; if (outputPort != null) set.add(outputPort.element()); } return set; } public String toString() { return or2(identifier(), "Unnamed element"); } public Port getPort(String name) { return firstThat(ports, p -> eq(p.name, name)); } public void addPort(Port port) { port.onChange(() -> change()); ports.add(port); } final public void addSlot(String name, double position_x, double position_y) { addSlot(name, doublePt(position_x, position_y)); } final public void addSlot(String name, DoublePt position) { addPort(name, position); } public void addPort(String name, double position_x, double position_y) { addPort(name, doublePt(position_x, position_y)); } public void addPort(String name, DoublePt position) { printFunctionCall("addPort", "name", name, "position", position); Port p = getPort(name); if (p != null) return; addPort(new Port().name(name).position(position)); change(); } public void addInputPort(String name, double position_x, double position_y, Class type) { addInputPort(name, doublePt(position_x, position_y), type); } public void addInputPort(String name, DoublePt position, Class type) { Port p = getPort(name); if (p != null) return; addPort(new Port().name(name).position(position).isOutput(false).dataType(type)); change(); } public void addOutputPort(String name, double position_x, double position_y, Class type) { addOutputPort(name, doublePt(position_x, position_y), type); } public void addOutputPort(String name, DoublePt position, Class type) { Port p = getPort(name); if (p != null) return; p = new Port().name(name).position(position).isOutput(true).dataType(type); addPort(p); print("Made port " + p); change(); } final public void deletePorts() { removePorts(); } final public void removeSlots() { removePorts(); } final public void deleteSlots() { removePorts(); } public void removePorts() { while (nempty(ports)) last(ports).delete(); } public void removeOutputPorts() { for (var p : filter(ports, p -> p.isOutput())) p.delete(); } public void removeInputPorts() { for (var p : antiFilter(ports, p -> p.isOutput())) p.delete(); } public List ports() { return cloneList(ports); } public void setProperty(Object key, Object value) { properties.put(key, value); change(); } public Object getProperty(Object key) { return properties.get(key); } public void autoCreateOutputPort(G22NetworkInstance.Value myValue) { if (myValue == null) return; removeOutputPorts(); Object o = myValue.object(); Class type = or(_getClass(o), Object.class); addOutputPort("output", 1, 0.5, type); } public void autoCreateInputPorts(G22Utils g22utils) { removeInputPorts(); var script = compile(g22utils).get(); int n = l(script.params); int i = 0; for (var __1 : _entrySet(unnullForIteration(script.params))) { var name = __1.getKey(); var valueDescriptor = __1.getValue(); double y = doubleRatio(++i, (n + 1)); addInputPort(name, 0, y, or(valueDescriptor.javaClass(), Object.class)); } } public G22NetworkElement defaultName(String name) { if (empty(identifier())) identifier(name); return this; } } static public class G22Challenge extends G22LeftArrowScript { static final public String _fieldOrder = "type usesRNG type_singleImage type_animation types lvType lvUsesRNG"; public String type = "Single Image"; public boolean usesRNG = false; static public String type_singleImage = "Single Image"; static public String type_animation = "Animation"; static public List types = ll(type_singleImage, type_animation); public void _onChange() { super._onChange(); { if (lvType != null) lvType.set(type); } { if (lvUsesRNG != null) lvUsesRNG.set(usesRNG); } } transient public SimpleLiveValue lvType; synchronized public SimpleLiveValue lvType() { { if (lvType == null) lvType = new SimpleLiveValue(String.class, type).onChange(new Runnable() { public void run() { try { setField("type", lvType.get()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setField(type := lvType!);"; } }); return lvType; } } transient public SimpleLiveValue lvUsesRNG; synchronized public SimpleLiveValue lvUsesRNG() { { if (lvUsesRNG == null) lvUsesRNG = new SimpleLiveValue(Boolean.class, usesRNG).onChange(new Runnable() { public void run() { try { setField("usesRNG", lvUsesRNG.get()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "setField(usesRNG := lvUsesRNG!);"; } }); return lvUsesRNG; } } } static public class MRUAndAllTimeTop_optimized { public MRUAndAllTimeTop_optimized() { } public Map mru = syncMRUCache(10); public OptimizedMultiSet allTimeTop = new OptimizedMultiSet(); public int allTimeMaxSize = 100; synchronized public void add(A a) { mru.remove(a); mru.put(a, true); allTimeTop.add(a); allTimeTop.truncate(allTimeMaxSize); } synchronized public void addAll(Iterable l) { for (A a : unnullForIteration(l)) add(a); } synchronized public int size() { return l(mru) + allTimeTop.uniqueSize(); } synchronized public IterableIterator mixedIterator() { return uniqueIterator(roundRobinCombinedIterator(reversedIterator(keysList(mru)), iterator(allTimeTop.highestFirst()))); } public String toString() { return shortClassName(this) + " (" + n2(size()) + ")"; } public Collection recent() { return reversedKeysList(mru); } public A mostRecent() { return last(keys(mru)); } } static public class G22SignatureMismatch implements IFieldsToList { public G22Mesh mesh1; public G22Mesh mesh2; public G22SignatureMismatch() { } public G22SignatureMismatch(G22Mesh mesh1, G22Mesh mesh2) { this.mesh2 = mesh2; this.mesh1 = mesh1; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + mesh1 + ", " + mesh2 + ")"; } public boolean equals(Object o) { if (!(o instanceof G22SignatureMismatch)) return false; G22SignatureMismatch __1 = (G22SignatureMismatch) o; return eq(mesh1, __1.mesh1) && eq(mesh2, __1.mesh2); } public int hashCode() { int h = -1709880161; h = boostHashCombine(h, _hashCode(mesh1)); h = boostHashCombine(h, _hashCode(mesh2)); return h; } public Object[] _fieldsToList() { return new Object[] { mesh1, mesh2 }; } } static public class BlurAndPosterizeSettings extends MetaWithChangeListeners { final public BlurAndPosterizeSettings setBlur(int blur) { return blur(blur); } public BlurAndPosterizeSettings blur(int blur) { this.blur = blur; return this; } final public int getBlur() { return blur(); } public int blur() { return blur; } public int blur = 0; final public BlurAndPosterizeSettings setColors(int colors) { return colors(colors); } public BlurAndPosterizeSettings colors(int colors) { this.colors = colors; return this; } final public int getColors() { return colors(); } public int colors() { return colors; } public int colors = 64; final public BlurAndPosterizeSettings setColorDrift(RGB colorDrift) { return colorDrift(colorDrift); } public BlurAndPosterizeSettings colorDrift(RGB colorDrift) { this.colorDrift = colorDrift; return this; } final public RGB getColorDrift() { return colorDrift(); } public RGB colorDrift() { return colorDrift; } public RGB colorDrift = noColorDrift(); final public BlurAndPosterizeSettings setAntiDrift(RGB antiDrift) { return antiDrift(antiDrift); } public BlurAndPosterizeSettings antiDrift(RGB antiDrift) { this.antiDrift = antiDrift; return this; } final public RGB getAntiDrift() { return antiDrift(); } public RGB antiDrift() { return antiDrift; } public RGB antiDrift = noColorDrift(); static public RGB noColorDrift() { return new RGB(0f); } public BlurAndPosterizeSettings cloneMe() { return shallowClone(this).colorDrift(colorDrift.cloneMe()).antiDrift(antiDrift.cloneMe()); } public String toString() { return stdToString(this); } @Override public boolean equals(Object o) { return stdEq_nonTransient(this, o); } @Override public int hashCode() { return stdHash_nonTransient(this); } } static public class WrappedCloseable implements IAutoCloseableF0 { public WrappedCloseable() { } public A closeable; public WrappedCloseable(A closeable) { this.closeable = closeable; } public A get() { return closeable; } public void close() { try { beforeClose(); loadableUtils.utils.close(closeable); } catch (Exception __e) { throw rethrow(__e); } } public void beforeClose() { } } static public class JGallery_v2 { public JPanel panel = jpanel(new VScrollingWrapLayout()); final public JGallery_v2 setThumbnailCache(ThumbnailCache thumbnailCache) { return thumbnailCache(thumbnailCache); } public JGallery_v2 thumbnailCache(ThumbnailCache thumbnailCache) { this.thumbnailCache = thumbnailCache; return this; } final public ThumbnailCache getThumbnailCache() { return thumbnailCache(); } public ThumbnailCache thumbnailCache() { return thumbnailCache; } public ThumbnailCache thumbnailCache = new ThumbnailCache(); transient public Set> onAdaptingButton; public JGallery_v2 onAdaptingButton(IVF1 f) { onAdaptingButton = createOrAddToSyncLinkedHashSet(onAdaptingButton, f); return this; } public JGallery_v2 removeAdaptingButtonListener(IVF1 f) { loadableUtils.utils.remove(onAdaptingButton, f); return this; } public void adaptingButton(JThumbnailButton btn) { if (onAdaptingButton != null) for (var listener : onAdaptingButton) pcallF_typed(listener, btn); } transient public Set> onFileClicked; public JGallery_v2 onFileClicked(IVF1 f) { onFileClicked = createOrAddToSyncLinkedHashSet(onFileClicked, f); return this; } public JGallery_v2 removeFileClickedListener(IVF1 f) { loadableUtils.utils.remove(onFileClicked, f); return this; } public void fileClicked(File imageFile) { if (onFileClicked != null) for (var listener : onFileClicked) pcallF_typed(listener, imageFile); } public void add(File imageFile) { if (imageFile == null) return; addComponent(panel, makeButton(imageFile)); } public JThumbnailButton makeButton(File imageFile) { var btn = new JThumbnailButton(thumbnailCache, imageFile); onClick(btn, runnableThread(new Runnable() { public void run() { try { fileClicked(btn.imageFile()); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "fileClicked(btn.imageFile())"; } })); adaptingButton(btn); return btn; } public void setImageFiles(Collection imageFiles) { removeAllButtons(); addAll(imageFiles); } public void addAll(Iterable imageFiles) { for (var f : unnullForIteration(imageFiles)) add(f); } public List buttons() { return childrenOfType(panel, JThumbnailButton.class); } public void removeAllButtons() { removeAllComponents(panel); } public JThumbnailButton findButton(File imageFile) { if (imageFile == null) return null; return first(buttons(), btn -> eq(btn.imageFile, imageFile)); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return jscroll_vertical(panel); } public void unselectAll() { swing(() -> { for (var btn : buttons()) btn.setSelected(false); }); } public JThumbnailButton selectFile(File imageFile) { return swing(() -> { unselectAll(); var btn = findButton(imageFile); if (btn != null) { btn.setSelected(true); scrollIntoView(btn); } return btn; }); } } abstract static public class AbstractTickerPainter extends ScaledDiagram implements G2Drawable, MakesBufferedImage { final public AbstractTickerPainter setTicker(TickerSequence ticker) { return ticker(ticker); } public AbstractTickerPainter ticker(TickerSequence ticker) { this.ticker = ticker; return this; } final public TickerSequence getTicker() { return ticker(); } public TickerSequence ticker() { return ticker; } public TickerSequence ticker; final public AbstractTickerPainter setPercentLineDistance(double percentLineDistance) { return percentLineDistance(percentLineDistance); } public AbstractTickerPainter percentLineDistance(double percentLineDistance) { this.percentLineDistance = percentLineDistance; return this; } final public double getPercentLineDistance() { return percentLineDistance(); } public double percentLineDistance() { return percentLineDistance; } public double percentLineDistance; final public AbstractTickerPainter setDrawPercentLines(boolean drawPercentLines) { return drawPercentLines(drawPercentLines); } public AbstractTickerPainter drawPercentLines(boolean drawPercentLines) { this.drawPercentLines = drawPercentLines; return this; } final public boolean getDrawPercentLines() { return drawPercentLines(); } public boolean drawPercentLines() { return drawPercentLines; } public boolean drawPercentLines = false; final public AbstractTickerPainter setPriceCells(PriceCells priceCells) { return priceCells(priceCells); } public AbstractTickerPainter priceCells(PriceCells priceCells) { this.priceCells = priceCells; return this; } final public PriceCells getPriceCells() { return priceCells(); } public PriceCells priceCells() { return priceCells; } public PriceCells priceCells; public List positions = new ArrayList(); public List additionalObjects = new ArrayList(); final public BufferedImage getBufferedImage() { return render(); } public BufferedImage render() { var img = blackImage(w, h); var g = img.createGraphics(); drawOn(g); return img; } public void drawPercentLines(Graphics2D g) { if (priceCells != null) { int cellNumber = ifloor(priceCells.toCellNumber(verticalRange.end)); int safety = 250; while (safety-- > 0) { double y = priceCells.fromCellNumber(cellNumber); if (y < verticalRange.start) break; var yy = iround(yToScreen(y)); drawLine(g, 0, yy, w - 1, yy, Color.gray); cellNumber--; } } } public void drawPositions(Graphics2D g) { for (var position : positions) { var time = position.openingTime(); var price = position.openingPrice(); var x = xToScreen(time); var y = yToScreen(price); var color = directionToCandleColor(position.relativeValue()); fillRect(g, rectAroundPt(iround(x), iround(y), 10), color); if (not(position.isOpen())) { time = position.closingTime(); price = position.closingPrice(); var x2 = xToScreen(time); var y2 = yToScreen(price); drawArrowBetweenPoints(g, toPt_round(doublePt(x, y)), toPt_round(doublePt(x2, y2)), color); } } } public void drawAdditionalObjects(Graphics2D g) { for (var o : additionalObjects) o.drawOn(g); } public void addVerticalLine(double x) { addVerticalLine(x, Color.gray); } public void addVerticalLine(double x, Color color) { additionalObjects.add(g -> drawVerticalLine(g, x, color)); } public void add(G2Drawable object) { addIfNotNull(additionalObjects, object); } public void drawVerticalLine(Graphics2D g, double x) { drawVerticalLine(g, x, Color.gray); } public void drawVerticalLine(Graphics2D g, double x, Color color) { int xScreen = iround(xToScreen(x)); drawLine(g, xScreen, 0, xScreen, h - 1, color); } public void addHorizontalLine(double y) { addHorizontalLine(y, Color.gray); } public void addHorizontalLine(double y, Color color) { additionalObjects.add(g -> drawHorizontalLine(g, y, color)); } public void drawHorizontalLine(Graphics2D g, double y) { drawHorizontalLine(g, y, Color.gray); } public void drawHorizontalLine(Graphics2D g, double y, Color color) { int yScreen = iround(yToScreen(y)); drawLine(g, 0, yScreen, w - 1, yScreen, color); } public DoubleRange horizontalRangeForTicker(TickerSequence ticker) { var timeRange = ticker.timeRange(); if (timeRange == null) return null; return doubleRange(timeRange.startTime().unixDate(), timeRange.endTime().unixDate()); } public DoubleRange verticalRangeForTicker(TickerSequence ticker) { return doubleRange(ticker.minPrice(), ticker.maxPrice()); } public void addTimeGrid(double minutes) { additionalObjects.add(g -> drawTimeGrid(g, minutes)); } public void drawTimeGrid(Graphics2D g, double minutes) { double ms = minutesToMS(minutes); assertTrue(ms >= 100); double time = roundUpTo(ms, horizontalRange().start); while (time < horizontalRange().end) { drawVerticalLine(g, time); time += ms; } } public class LineIndicator implements G2Drawable { final public LineIndicator setValues(TickerSequence values) { return values(values); } public LineIndicator values(TickerSequence values) { this.values = values; return this; } final public TickerSequence getValues() { return values(); } public TickerSequence values() { return values; } public TickerSequence values; final public LineIndicator setColor(Color color) { return color(color); } public LineIndicator color(Color color) { this.color = color; return this; } final public Color getColor() { return color(); } public Color color() { return color; } public Color color = Color.yellow; public LineIndicator() { } public LineIndicator(TickerSequence values) { this.values = values; } public LineIndicator(TickerSequence values, Color color) { this.color = color; this.values = values; } public void drawOn(Graphics2D g) { g.setColor(color); var xRange = roundToIntRange(xRange()); var sub = values.subSequenceByTimestamps(lround(xFromScreen(xRange.start)), lround(xFromScreen(xRange.end))); int lastx = 0, lasty = 0; for (int i = 0; i < sub.size(); i++) { double price = sub.getPrice(i); long time = sub.getTimestamp(i); int x = iround(xToScreen(time)); int y = iround(yToScreen(price)); if (i != 0) g.drawLine(lastx, lasty, x, y); lastx = x; lasty = y; } } } public AbstractTickerPainter priceCells(double cellSize) { return priceCells(new GeometricPriceCells(cellSize)); } } static public class G22MaskSize extends Concept implements WidthAndHeight { static final public String _fieldOrder = "width height"; public int width = g22defaultMaskSideLength(), height = g22defaultMaskSideLength(); public int getWidth() { return width; } public int getHeight() { return height; } public G22MaskSize() { } public G22MaskSize(int widthHeight) { width = height = widthHeight; } public boolean square() { return width == height; } public String toString() { return spaceCombine("Mask Size", square() ? width + "²" : width + "*" + height); } } static public class Stage implements Runnable { public String name; public boolean done = false; public Object result; public PersistableThrowable error; public IF0 code; static public String _fieldOrder = "name done result"; public Stage() { } public Stage(String name) { this.name = name; } public Stage(String name, IF0 code) { this.code = code; this.name = name; } transient public Set onComputed; public Stage onComputed(Runnable r) { onComputed = createOrAddToSyncLinkedHashSet(onComputed, r); return this; } public Stage removeComputedListener(Runnable r) { loadableUtils.utils.remove(onComputed, r); return this; } public void computed() { if (onComputed != null) for (var listener : onComputed) pcallF_typed(listener); } public void run() { try { if (done || code == null) return; try { result = code.get(); computed(); } catch (Throwable e) { printStackTrace(e); error = persistableThrowable(e); } finally { done = true; } } catch (Exception __e) { throw rethrow(__e); } } } abstract static public class AbstractProfiler implements AutoCloseable { final public AbstractProfiler setInterval(int interval) { return interval(interval); } public AbstractProfiler interval(int interval) { this.interval = interval; return this; } final public int getInterval() { return interval(); } public int interval() { return interval; } public int interval = 40; final public AbstractProfiler setSkipSleeping(boolean skipSleeping) { return skipSleeping(skipSleeping); } public AbstractProfiler skipSleeping(boolean skipSleeping) { this.skipSleeping = skipSleeping; return this; } final public boolean getSkipSleeping() { return skipSleeping(); } public boolean skipSleeping() { return skipSleeping; } public boolean skipSleeping = false; public MultiSet stackTraceMultiSet = new MultiSet(); final public int getSamples() { return samples(); } public int samples() { return samples; } volatile public int samples; public java.util.Timer timer; public Lock lock = lock(); public void start() { Lock __0 = lock; lock(__0); try { assertCanStart(); printWithMS("Starting " + this); stop(); clear(); timer = doEvery_daemon("Profiler", interval, new Runnable() { public void run() { try { stepImpl(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "stepImpl();"; } }); } finally { unlock(__0); } } public void assertCanStart() { } abstract public void stepImpl(); final public void close() { stop(); } public void stop() { Lock __1 = lock; lock(__1); try { if (timer != null) { stopTimer(timer); timer = null; printWithMS("Stopped " + this); } } finally { unlock(__1); } } public void clear() { Lock __2 = lock; lock(__2); try { stackTraceMultiSet.clear(); samples = 0; } finally { unlock(__2); } } public MultiSet results() { Lock __3 = lock; lock(__3); try { return cloneMultiSet(stackTraceMultiSet); } finally { unlock(__3); } } public MultiSet stopAndGetResults() { Lock __4 = lock; lock(__4); try { stop(); return results(); } finally { unlock(__4); } } public String renderFullResults(boolean mostImportantLast) { var traces = results(); int n = traces.size(); int percent = ratioToIntPercent(l(traces), samples); return (samples == 0 ? "Nothing sampled" : percent + "% core activity [" + n2(samples, "sample") + " taken]") + "\n\n" + joinMap(mostImportantLast ? traces.lowestFirst() : traces.highestFirst(), trace -> traces.get(trace) + "/" + n + "\n" + trace + "\n\n"); } public void addSample(StackTraceElement[] stackTrace) { stackTraceMultiSet.add(stackTraceToString(stackTrace)); } } static public class G22RegionThinner_LookupTable { public byte[] table; final public G22RegionThinner_LookupTable setLastPhaseThreshold1(int lastPhaseThreshold1) { return lastPhaseThreshold1(lastPhaseThreshold1); } public G22RegionThinner_LookupTable lastPhaseThreshold1(int lastPhaseThreshold1) { this.lastPhaseThreshold1 = lastPhaseThreshold1; return this; } final public int getLastPhaseThreshold1() { return lastPhaseThreshold1(); } public int lastPhaseThreshold1() { return lastPhaseThreshold1; } public int lastPhaseThreshold1 = 2; final public G22RegionThinner_LookupTable setLastPhaseThreshold(int lastPhaseThreshold) { return lastPhaseThreshold(lastPhaseThreshold); } public G22RegionThinner_LookupTable lastPhaseThreshold(int lastPhaseThreshold) { this.lastPhaseThreshold = lastPhaseThreshold; return this; } final public int getLastPhaseThreshold() { return lastPhaseThreshold(); } public int lastPhaseThreshold() { return lastPhaseThreshold; } public int lastPhaseThreshold = 5; static public byte[] defaultTable = null; public List> regions; public int sides; final public byte[] table() { return get(); } final public byte[] getTable() { return get(); } public byte[] get() { if (table == null) { if (defaultTable != null && lastPhaseThreshold1 == 2 && lastPhaseThreshold == 5) table = defaultTable; else { table = new byte[256 / 8]; for (int imgPattern = 0; imgPattern < 256; imgPattern++) setBit(table, imgPattern, calculatePattern(imgPattern)); } } return table; } public String toHex() { return bytesToHex(table()); } public boolean calculatePattern(int imgPattern) { if (imgPattern == 0b01011010) return false; Image2B img = new Image2B(3, 3); imgPattern = ~imgPattern; img.setPixel(0, 0, testBit(imgPattern, 0)); img.setPixel(1, 0, testBit(imgPattern, 1)); img.setPixel(2, 0, testBit(imgPattern, 2)); img.setPixel(0, 1, testBit(imgPattern, 3)); img.setPixel(1, 1, true); img.setPixel(2, 1, testBit(imgPattern, 4)); img.setPixel(0, 2, testBit(imgPattern, 5)); img.setPixel(1, 2, testBit(imgPattern, 6)); img.setPixel(2, 2, testBit(imgPattern, 7)); var bwImage = img.toBW(); FastRegions_BWImage regionMaker = new FastRegions_BWImage(bwImage); regionMaker.withDiagonals(true); regionMaker.run(); regions = regionMaker.regions(); regions = filter(regions, r -> r.brightness() == 0); boolean delete = false; int pixels = 0; if (empty(regions)) { } else if (l(regions) == 1) { pixels = first(regions).numberOfPixels(); if (pixels <= lastPhaseThreshold1) delete = false; else { if (pixels < lastPhaseThreshold) delete = true; else if (pixels == lastPhaseThreshold) { sides = 4 - (int) (bwImage.getFloatPixel(1, 0) + bwImage.getFloatPixel(0, 1) + bwImage.getFloatPixel(2, 1) + bwImage.getFloatPixel(1, 2)); delete = sides <= 3; } } } else { } return delete; } } static public class PricePoint implements IFieldsToList { static final public String _fieldOrder = "timestamp price"; public long timestamp; public double price; public PricePoint() { } public PricePoint(long timestamp, double price) { this.price = price; this.timestamp = timestamp; } public boolean equals(Object o) { if (!(o instanceof PricePoint)) return false; PricePoint __1 = (PricePoint) o; return timestamp == __1.timestamp && price == __1.price; } public int hashCode() { int h = 516290023; h = boostHashCombine(h, _hashCode(timestamp)); h = boostHashCombine(h, _hashCode(price)); return h; } public Object[] _fieldsToList() { return new Object[] { timestamp, price }; } public String toString() { return formatPrice(price) + " @ " + formatLocalDateWithSeconds(timestamp); } } public interface PriceCells { public boolean isCellLimit(double price); public double nextCellLimit(double price); public double previousCellLimit(double price); public double nCellLimitsDown(double price, int n); public double nCellLimitsUp(double price, int n); default public double toCellNumber(double price) { return priceToCellNumber(price); } public double priceToCellNumber(double price); default public double fromCellNumber(double cellNumber) { return cellNumberToPrice(cellNumber); } public double cellNumberToPrice(double cellNumber); default public double basePrice() { return cellNumberToPrice(0); } } static public class PatchworkImage extends AbstractWAndH implements MakesBufferedImage { public List patches = new ArrayList(); final public PatchworkImage setBackgroundColor(Color backgroundColor) { return backgroundColor(backgroundColor); } public PatchworkImage backgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; return this; } final public Color getBackgroundColor() { return backgroundColor(); } public Color backgroundColor() { return backgroundColor; } public Color backgroundColor = grayToColor(0.9); public class Patch { public Rect bounds; public BufferedImage image; final public Patch setUserValue(A userValue) { return userValue(userValue); } public Patch userValue(A userValue) { this.userValue = userValue; return this; } final public A getUserValue() { return userValue(); } public A userValue() { return userValue; } public A userValue; public Patch(Rect bounds, BufferedImage image) { this.image = image; this.bounds = bounds; } } public PatchworkImage() { } public PatchworkImage(int w, int h) { super(w, h); } public void addPatch(BufferedImage image, int p_x, int p_y, A userValue) { addPatch(image, pt(p_x, p_y), userValue); } public void addPatch(BufferedImage image, Pt p, A userValue) { addPatch(p, image, userValue); } public void addPatch(int p_x, int p_y, BufferedImage image, A userValue) { addPatch(pt(p_x, p_y), image, userValue); } public void addPatch(Pt p, BufferedImage image, A userValue) { patches.add(new Patch(rect(p.x, p.y, image.getWidth(), image.getHeight()), image).userValue(userValue)); } public BufferedImage getBufferedImage() { BufferedImage out = newBufferedImage(w(), h(), backgroundColor); for (var patch : patches) copyBufferedImage(patch.image, out, topLeft(patch.bounds)); return out; } } static public class ResolvableLASClass implements IResolvableClass { public ResolvableLASClass() { } transient public ILASClassLoader lasClassLoader; public LASClassDef classDef; public Class resolvedClass; public ResolvableLASClass(ILASClassLoader lasClassLoader, LASClassDef classDef) { this.classDef = classDef; this.lasClassLoader = lasClassLoader; } public String resolveToClassName() { return classDef.finalClassName(); } final public Class resolveToClass() { return get(); } public Class get() { if (resolvedClass == null) { if (lasClassLoader == null) throw fail("Need LASClassLoader to define " + classDef.userGivenName); resolvedClass = lasClassLoader.defineLASClass(classDef.finalClassName(), () -> classDef.toBytes()); classDef.init(resolvedClass); } return resolvedClass; } public String toString() { if (resolvedClass != null) return className(resolvedClass); { var __1 = userGivenName(); if (__1 != null) return __1; } if (classDef.classHash_cache != null) return classDef.finalClassNameWithoutPrefix(); return or2(userGivenName(), "script-defined class") + " [unresolved]"; } public String userGivenName() { return classDef.userGivenName; } } static public class LeftArrowScriptAutoCompleter extends Meta implements IFieldsToList { public GazelleV_LeftArrowScriptParser parser; public LeftArrowScriptAutoCompleter() { } public LeftArrowScriptAutoCompleter(GazelleV_LeftArrowScriptParser parser) { this.parser = parser; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + parser + ")"; } public Object[] _fieldsToList() { return new Object[] { parser }; } public List tok; public CharInToken cursor; public String typedCharacters; public ScoredStringSearcher searcher; final public LeftArrowScriptAutoCompleter setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public LeftArrowScriptAutoCompleter g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; public TreeMap> knownVarsByTokenIdx = new TreeMap(); public Map typeHooks = new HashMap(); transient public Set onAdaptingSearcher; public LeftArrowScriptAutoCompleter onAdaptingSearcher(Runnable r) { onAdaptingSearcher = createOrAddToSyncLinkedHashSet(onAdaptingSearcher, r); return this; } public LeftArrowScriptAutoCompleter removeAdaptingSearcherListener(Runnable r) { loadableUtils.utils.remove(onAdaptingSearcher, r); return this; } public void adaptingSearcher() { if (onAdaptingSearcher != null) for (var listener : onAdaptingSearcher) pcallF_typed(listener); } public LeftArrowScriptAutoCompleter(G22Utils g22utils, GazelleV_LeftArrowScriptParser parser) { this.parser = parser; this.g22utils = g22utils; } public void seekEnd(String text) { seek(text, l(text)); } public void seek(String text, int iChar) { if (tok != null) throw fail("Don't reuse instance"); parser.setText(text); parser.init(); tok = parser.tok; cursor = charIndexToCharInToken(tok, iChar); if (even(cursor.iTok) && cursor.iTok > 0 && cursor.iChar == 0) { cursor.iTok--; cursor.iChar = l(token()); } if (cursor.iTok > 1 && cursor.iChar == 0 && empty(space())) { cursor.iTok -= 2; cursor.iChar = l(token()); } typedCharacters = takeFirst(cursor.token(), cursor.iChar); parser.onKnownVarsSnapshot(knownVars -> knownVarsByTokenIdx.put(parser.tokIdx(), cloneKeys(knownVars))); parser.onTypeHook(type -> typeHooks.put(parser.tokIdx(), type)); try { parser.parse(); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } } public String typedCharacters() { return typedCharacters; } public String space() { return get(tok, cursor.iTok - 1); } public String token() { return get(tok, cursor.iTok); } public String prevToken() { return get(tok, cursor.iTok - 2); } public boolean beginningOfCmd() { return eqOneOf(prevToken(), ";", "{", "}") || containsNewLine(space()); } public Collection getCompletions() { return searcher().get_transformListWithinScore(__1 -> stringsSortedByLength(__1)); } public ScoredStringSearcher searcher() { searcher = new ScoredStringSearcher(typedCharacters); searcher.uniquify(true); if (empty(typedCharacters)) searcher.returnAll = true; String prev = prevToken(); if (scaffoldingEnabled(this)) printVars("LeftArrowScriptAutoCompleter", "beginningOfCmd", beginningOfCmd(), "prev", prev, "cursor", cursor, "typedCharacters", typedCharacters, "globalClassNames", l(parser.globalClassNames())); LASValueDescriptor typeHook = typeHooks.get(cursor.iTok); if (typeHook != null && !beginningOfCmd()) { Class c = typeHook.javaClass(); if (c == null) c = Object.class; addToSearcher(methodNames(c)); addToSearcher(fieldNames(c)); } else { if (beginningOfCmd() || !isIdentifier(prev) || eqOneOf(prev, "if", "else")) addToSearcher(globalMethodNames()); addToSearcher(keys(parser.globalClassNames())); addToSearcher(predefinedExpressions()); Collection knownVars = floorValue(knownVarsByTokenIdx, cursor.iTok); addToSearcher(knownVars); } adaptingSearcher(); return searcher; } public Collection predefinedExpressions() { return ll("true", "false", "null"); } transient public IF0> globalMethodNames; public Collection globalMethodNames() { return globalMethodNames != null ? globalMethodNames.get() : globalMethodNames_base(); } final public Collection globalMethodNames_fallback(IF0> _f) { return _f != null ? _f.get() : globalMethodNames_base(); } public Collection globalMethodNames_base() { List names = new ArrayList(); for (var fc : parser.functionContainers) addAll(names, methodNames(fc)); addAll(names, keys(parser.functionDefs)); return names; } public void addToSearcher(String... l) { addToSearcher(asList(l)); } public void addToSearcher(Iterable l) { for (var s : unnullForIteration(l)) if (!eq(s, typedCharacters)) searcher.add(s); } } public interface IImageSurfaceMaker { public ImageSurface newImageSurface(); } static public class JG22NetworkPort extends JPanel implements IFieldsToList { public G22Utils g22utils; public JG22NetworkElement element; public G22NetworkElement.Port port; public JG22NetworkPort() { } public JG22NetworkPort(G22Utils g22utils, JG22NetworkElement element, G22NetworkElement.Port port) { this.port = port; this.element = element; this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ", " + element + ", " + port + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils, element, port }; } public int size = 10; public Color outputColor() { return Color.green; } public Color inputColor() { return Color.red; } public void init() { bindChangeListenerToComponent(this, port, () -> update()); componentPopupMenuItems(this, "Show value", runnableThread(new Runnable() { public void run() { try { showValue(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showValue();"; } }), "Disconnect", runnableThread(new Runnable() { public void run() { try { disconnect(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "disconnect();"; } }), "Delete port", runnableThread(new Runnable() { public void run() { try { delete(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "delete();"; } })); onMouseDown(this, event -> { var dragger = new ComponentDragger(this, event); dragger.updatePosition = (x, y) -> { Pt p = pt(x, y); Rect r = toRect(loadableUtils.utils.getBounds(element.visualize())); double dTop = distancePointToLineSegment(pt(r.x, r.y), pt(r.x2(), r.y), p); double dBottom = distancePointToLineSegment(pt(r.x, r.y2()), pt(r.x2(), r.y2()), p); double dLeft = distancePointToLineSegment(pt(r.x, r.y), pt(r.x, r.y2()), p); double dRight = distancePointToLineSegment(pt(r.x2(), r.y), pt(r.x2(), r.y2()), p); double min = doubleMin(dTop, dBottom, dLeft, dRight); DoublePt pos = doublePt(clampZeroToOne(doubleRatio(x - r.x, r.w)), clampZeroToOne(doubleRatio(y - r.y, r.h))); if (min == dTop) pos.y = 0; else if (min == dBottom) pos.y = 1; else if (min == dLeft) pos.x = 0; else pos.x = 1; port.position(pos); }; dragger.bringToFront(true).start(); }); update(); } public void update() { _print("Updating port " + port); setOpaque(true); setBackground(port.isOutput() ? outputColor() : inputColor()); setSize(size, size); Rect r = toRect(loadableUtils.utils.getBounds(element.visualize())); r = growRectTopAndLeft(r, size); setLocation(r.x + iround(port.position.x * r.w), r.y + iround(port.position.y * r.h)); setToolTip(this, str(port)); _print("Port " + port.name + " : " + getBounds()); } public void showValue() { G22NetworkElement e; if (port.isOutput()) e = port.element(); else e = port.cable.from.element(); var value = element.parent.networkInstance.getObjectForBlueprint(e); showFrame("Port value", new G22JavaObjectVisualizer(g22utils, value)); } public void disconnect() { port.disconnect(); } public void delete() { port.delete(); } } static public class MapI extends IterableIterator { public IF1 f; public Iterator it; public MapI(IF1 f, Iterator it) { this.it = it; this.f = f; } public boolean hasNext() { return it.hasNext(); } public B next() { return f.get(it.next()); } } static public class G22GhostImage implements IBWImage { public G22GhostImage() { } public int w, h; public int getWidth() { return w; } public int getHeight() { return h; } public int imageCount; public int[] pixels; public G22GhostImage(List maskImages) { imageCount = l(maskImages); if (imageCount == 0) return; var img = first(maskImages); w = img.w(); h = img.h(); pixels = sumOfBinaryImages(maskImages); } public float getFloatPixel(int x, int y) { return imageCount == 0 ? 0.5f : floatRatio(pixels[y * w + x], imageCount); } public FloatBWImage toFloatBWImage() { float[] floatPixels = new float[pixels.length]; if (imageCount == 0) fillArray(floatPixels, 0.5f); else for (int i = 0; i < l(pixels); i++) floatPixels[i] = floatRatio(pixels[i], imageCount); return new FloatBWImage(w, h, floatPixels); } public BufferedImage getBufferedImage() { return toFloatBWImage().getBufferedImage(); } public FloatBWImage certaintyImage() { return preciseCertaintyImage(this); } public Double certainty_cache; public double certainty() { if (certainty_cache == null) certainty_cache = certainty_load(); return certainty_cache; } public double certainty_load() { if (imageCount == 0) return 0; double sum = 0; int n = pixels.length; for (int i = 0; i < n; i++) sum += g22pixelCertainty(doubleRatio(pixels[i], imageCount)); return sum / (w * h); } public G22GhostImage minus(G22GhostImage img) { G22GhostImage ghost = new G22GhostImage(); ghost.w = w; ghost.h = h; ghost.imageCount = imageCount - img.imageCount; ghost.pixels = intArray_minus(pixels, img.pixels); return ghost; } } public enum UpDown { up(true), down(false); public boolean bit = false; private UpDown(boolean bit) { this.bit = bit; } static public UpDown fromBool(boolean bit) { return bit ? up : down; } public boolean isUp() { return bit; } public boolean isDown() { return !bit; } public int direction() { return isUp() ? 1 : -1; } } static public class G22DriftSystem extends MetaWithChangeListeners { final public G22DriftSystem setCryptoCoin(String cryptoCoin) { return cryptoCoin(cryptoCoin); } public G22DriftSystem cryptoCoin(String cryptoCoin) { this.cryptoCoin = cryptoCoin; return this; } final public String getCryptoCoin() { return cryptoCoin(); } public String cryptoCoin() { return cryptoCoin; } public String cryptoCoin; final public G22DriftSystem setDriftOnPlatform(double driftOnPlatform) { return driftOnPlatform(driftOnPlatform); } public G22DriftSystem driftOnPlatform(double driftOnPlatform) { this.driftOnPlatform = driftOnPlatform; return this; } final public double getDriftOnPlatform() { return driftOnPlatform(); } public double driftOnPlatform() { return driftOnPlatform; } public double driftOnPlatform; final public G22DriftSystem setTargetDrift(double targetDrift) { return targetDrift(targetDrift); } public G22DriftSystem targetDrift(double targetDrift) { this.targetDrift = targetDrift; return this; } final public double getTargetDrift() { return targetDrift(); } public double targetDrift() { return targetDrift; } public double targetDrift; final public G22DriftSystem setMarket(IFuturesMarket market) { return market(market); } public G22DriftSystem market(IFuturesMarket market) { this.market = market; return this; } final public IFuturesMarket getMarket() { return market(); } public IFuturesMarket market() { return market; } transient public IFuturesMarket market; public transient FieldVar varCoinParams_cache; public FieldVar varCoinParams() { if (varCoinParams_cache == null) varCoinParams_cache = varCoinParams_load(); return varCoinParams_cache; } public FieldVar varCoinParams_load() { return new FieldVar(this, "coinParams", () -> coinParams(), coinParams -> coinParams(coinParams)); } final public G22DriftSystem setCoinParams(FutureCoinParameters coinParams) { return coinParams(coinParams); } public G22DriftSystem coinParams(FutureCoinParameters coinParams) { if (!eq(this.coinParams, coinParams)) { this.coinParams = coinParams; change(); } return this; } final public FutureCoinParameters getCoinParams() { return coinParams(); } public FutureCoinParameters coinParams() { return coinParams; } public FutureCoinParameters coinParams; public Set activeStrategies = syncLinkedHashSet(); public double calculateTargetDrift() { double drift = 0; for (var strat : cloneList(activeStrategies)) drift += strat.drift(); targetDrift(drift); return drift; } } abstract static public class AbstractJuicer extends MetaWithChangeListeners { public AbstractJuicer() { } public transient FieldVar varJuiceable_cache; public FieldVar varJuiceable() { if (varJuiceable_cache == null) varJuiceable_cache = varJuiceable_load(); return varJuiceable_cache; } public FieldVar varJuiceable_load() { return new FieldVar(this, "juiceable", () -> juiceable(), juiceable -> juiceable(juiceable)); } final public AbstractJuicer setJuiceable(Juiceable juiceable) { return juiceable(juiceable); } public AbstractJuicer juiceable(Juiceable juiceable) { if (!eq(this.juiceable, juiceable)) { this.juiceable = juiceable; change(); } return this; } final public Juiceable getJuiceable() { return juiceable(); } public Juiceable juiceable() { return juiceable; } public Juiceable juiceable; public transient FieldVar varJuiceValue_cache; public FieldVar varJuiceValue() { if (varJuiceValue_cache == null) varJuiceValue_cache = varJuiceValue_load(); return varJuiceValue_cache; } public FieldVar varJuiceValue_load() { return new FieldVar(this, "juiceValue", () -> juiceValue(), juiceValue -> juiceValue(juiceValue)); } final public AbstractJuicer setJuiceValue(double juiceValue) { return juiceValue(juiceValue); } public AbstractJuicer juiceValue(double juiceValue) { if (!eq(this.juiceValue, juiceValue)) { this.juiceValue = juiceValue; change(); } return this; } final public double getJuiceValue() { return juiceValue(); } public double juiceValue() { return juiceValue; } public double juiceValue; public transient FieldVar varClosingAllowed_cache; public FieldVar varClosingAllowed() { if (varClosingAllowed_cache == null) varClosingAllowed_cache = varClosingAllowed_load(); return varClosingAllowed_cache; } public FieldVar varClosingAllowed_load() { return new FieldVar(this, "closingAllowed", () -> closingAllowed(), closingAllowed -> closingAllowed(closingAllowed)); } final public AbstractJuicer setClosingAllowed(boolean closingAllowed) { return closingAllowed(closingAllowed); } public AbstractJuicer closingAllowed(boolean closingAllowed) { if (!eq(this.closingAllowed, closingAllowed)) { this.closingAllowed = closingAllowed; change(); } return this; } final public boolean getClosingAllowed() { return closingAllowed(); } public boolean closingAllowed() { return closingAllowed; } public boolean closingAllowed = true; public transient FieldVar> varCurrentSignals_cache; public FieldVar> varCurrentSignals() { if (varCurrentSignals_cache == null) varCurrentSignals_cache = varCurrentSignals_load(); return varCurrentSignals_cache; } public FieldVar> varCurrentSignals_load() { return new FieldVar>(this, "currentSignals", () -> currentSignals(), currentSignals -> currentSignals(currentSignals)); } final public AbstractJuicer setCurrentSignals(List currentSignals) { return currentSignals(currentSignals); } public AbstractJuicer currentSignals(List currentSignals) { if (!eq(this.currentSignals, currentSignals)) { this.currentSignals = currentSignals; change(); } return this; } final public List getCurrentSignals() { return currentSignals(); } public List currentSignals() { return currentSignals; } public List currentSignals; public transient FieldVar> varSuppressedSignals_cache; public FieldVar> varSuppressedSignals() { if (varSuppressedSignals_cache == null) varSuppressedSignals_cache = varSuppressedSignals_load(); return varSuppressedSignals_cache; } public FieldVar> varSuppressedSignals_load() { return new FieldVar>(this, "suppressedSignals", () -> suppressedSignals(), suppressedSignals -> suppressedSignals(suppressedSignals)); } final public AbstractJuicer setSuppressedSignals(List suppressedSignals) { return suppressedSignals(suppressedSignals); } public AbstractJuicer suppressedSignals(List suppressedSignals) { if (!eq(this.suppressedSignals, suppressedSignals)) { this.suppressedSignals = suppressedSignals; change(); } return this; } final public List getSuppressedSignals() { return suppressedSignals(); } public List suppressedSignals() { return suppressedSignals; } public List suppressedSignals; transient public Set>> onCalculatingCloseSignals; public AbstractJuicer onCalculatingCloseSignals(IVF1> f) { onCalculatingCloseSignals = createOrAddToSyncLinkedHashSet(onCalculatingCloseSignals, f); return this; } public AbstractJuicer removeCalculatingCloseSignalsListener(IVF1> f) { loadableUtils.utils.remove(onCalculatingCloseSignals, f); return this; } public void calculatingCloseSignals(List outList) { if (onCalculatingCloseSignals != null) for (var listener : onCalculatingCloseSignals) pcallF_typed(listener, outList); } transient public IF0> calculateCloseSignals; public List calculateCloseSignals() { return calculateCloseSignals != null ? calculateCloseSignals.get() : calculateCloseSignals_base(); } final public List calculateCloseSignals_fallback(IF0> _f) { return _f != null ? _f.get() : calculateCloseSignals_base(); } public List calculateCloseSignals_base() { grabJuiceValue(); List signals = new ArrayList(); calculatingCloseSignals(signals); if (closingAllowed) { suppressedSignals(emptyList()); currentSignals(signals); } else { suppressedSignals(signals); currentSignals(emptyList()); } return currentSignals; } public void grabJuiceValue() { juiceValue(juiceable.juiceValue()); } public AbstractJuicer configClone() { return restructure(this); } public void copyTransientValuesFrom(AbstractJuicer juicer) { } } static public class G22AutoStarter extends MetaWithChangeListeners implements AutoCloseable, IFieldsToList { public G22Utils g22utils; public G22AutoStarter() { } public G22AutoStarter(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public transient FieldVar varEnabled_cache; public FieldVar varEnabled() { if (varEnabled_cache == null) varEnabled_cache = varEnabled_load(); return varEnabled_cache; } public FieldVar varEnabled_load() { return new FieldVar(this, "enabled", () -> enabled(), enabled -> enabled(enabled)); } final public G22AutoStarter setEnabled(boolean enabled) { return enabled(enabled); } public G22AutoStarter enabled(boolean enabled) { if (!eq(this.enabled, enabled)) { this.enabled = enabled; change(); } return this; } final public boolean getEnabled() { return enabled(); } public boolean enabled() { return enabled; } volatile public boolean enabled = true; public transient FieldVar varInitialDelay_cache; public FieldVar varInitialDelay() { if (varInitialDelay_cache == null) varInitialDelay_cache = varInitialDelay_load(); return varInitialDelay_cache; } public FieldVar varInitialDelay_load() { return new FieldVar(this, "initialDelay", () -> initialDelay(), initialDelay -> initialDelay(initialDelay)); } final public G22AutoStarter setInitialDelay(int initialDelay) { return initialDelay(initialDelay); } public G22AutoStarter initialDelay(int initialDelay) { if (!eq(this.initialDelay, initialDelay)) { this.initialDelay = initialDelay; change(); } return this; } final public int getInitialDelay() { return initialDelay(); } public int initialDelay() { return initialDelay; } volatile public int initialDelay = 1; public transient FieldVar varNScriptsRun_cache; public FieldVar varNScriptsRun() { if (varNScriptsRun_cache == null) varNScriptsRun_cache = varNScriptsRun_load(); return varNScriptsRun_cache; } public FieldVar varNScriptsRun_load() { return new FieldVar(this, "nScriptsRun", () -> nScriptsRun(), nScriptsRun -> nScriptsRun(nScriptsRun)); } final public G22AutoStarter setNScriptsRun(int nScriptsRun) { return nScriptsRun(nScriptsRun); } public G22AutoStarter nScriptsRun(int nScriptsRun) { if (!eq(this.nScriptsRun, nScriptsRun)) { this.nScriptsRun = nScriptsRun; change(); } return this; } final public int getNScriptsRun() { return nScriptsRun(); } public int nScriptsRun() { return nScriptsRun; } volatile public int nScriptsRun; public transient FieldVar varCurrentScript_cache; public FieldVar varCurrentScript() { if (varCurrentScript_cache == null) varCurrentScript_cache = varCurrentScript_load(); return varCurrentScript_cache; } public FieldVar varCurrentScript_load() { return new FieldVar(this, "currentScript", () -> currentScript(), currentScript -> currentScript(currentScript)); } final public G22AutoStarter setCurrentScript(AutoStartScript currentScript) { return currentScript(currentScript); } public G22AutoStarter currentScript(AutoStartScript currentScript) { if (!eq(this.currentScript, currentScript)) { this.currentScript = currentScript; change(); } return this; } final public AutoStartScript getCurrentScript() { return currentScript(); } public AutoStartScript currentScript() { return currentScript; } volatile public AutoStartScript currentScript; public transient FieldVar varCancelOnCtrl_cache; public FieldVar varCancelOnCtrl() { if (varCancelOnCtrl_cache == null) varCancelOnCtrl_cache = varCancelOnCtrl_load(); return varCancelOnCtrl_cache; } public FieldVar varCancelOnCtrl_load() { return new FieldVar(this, "cancelOnCtrl", () -> cancelOnCtrl(), cancelOnCtrl -> cancelOnCtrl(cancelOnCtrl)); } final public G22AutoStarter setCancelOnCtrl(boolean cancelOnCtrl) { return cancelOnCtrl(cancelOnCtrl); } public G22AutoStarter cancelOnCtrl(boolean cancelOnCtrl) { if (!eq(this.cancelOnCtrl, cancelOnCtrl)) { this.cancelOnCtrl = cancelOnCtrl; change(); } return this; } final public boolean getCancelOnCtrl() { return cancelOnCtrl(); } public boolean cancelOnCtrl() { return cancelOnCtrl; } volatile public boolean cancelOnCtrl = false; transient public Set onDone; public G22AutoStarter onDone(Runnable r) { onDone = createOrAddToSyncLinkedHashSet(onDone, r); return this; } public G22AutoStarter removeDoneListener(Runnable r) { loadableUtils.utils.remove(onDone, r); return this; } public void fireDone() { if (onDone != null) for (var listener : onDone) pcallF_typed(listener); } public Flag started = new Flag(); public Flag waited = new Flag(); public Flag ctrlPressed = new Flag(); public List scripts = syncL(); public AutoCloseable ctrlListener; public ReliableSingleThread rst = rst(() -> _run()); public JComponent topStackComponent; public JProgressBar progressBar; public class AutoStartScript extends RunResultWithTimestamps implements IFieldsToList { public G22LeftArrowScript script; public AutoStartScript() { } public AutoStartScript(G22LeftArrowScript script) { this.script = script; } public Object[] _fieldsToList() { return new Object[] { script }; } public void run() { try { LASCompileResult cr = script.compileForAutoRun(); if (cr == null) cr = script.compileSaved(); var _cr_2 = cr; run(() -> { G22AutoStarter.this.change(); if (_cr_2 == null) throw fail("Script is not saved: " + script); var parsed = _cr_2.parsedScriptMandatory(); return parsed.get(); }); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return str(script); } } public void init() { if (ctrlListener != null) return; scripts.clear(); var scripts = conceptsWhere(g22utils.concepts, G22LeftArrowScript.class, "runOnProjectOpen", true); var sorted = sortByCalculatedFieldAlphaNumIC(scripts, s -> s.runOrder); for (var script : sorted) this.scripts.add(new AutoStartScript(script)); change(); ctrlListener = tempAddGlobalCtrlKeyListener(b -> { if (cancelOnCtrl && b) { ctrlPressed.raise(); cancel(); } }); } public void start() { print("G22AutoStarter: Start"); if (enabled) { var topStack = g22utils.projectActions().topStack(); progressBar = jProgressBarWithText(l(scripts)); topStackComponent = withTopMargin(jCenteredSection("Booting project", centerAndEastWithMargin(progressBar, jThreadedButton("Cancel", () -> { disableButton(heldButton()); cancel(); })))); topStack.addComponent(topStackComponent); rst.get(); } } public void _run() { if (!enabled) return; AutoCloseable __1 = g22utils.backgroundProcessesUI.tempAdd("Auto-Start Scripts"); try { if (started.raise()) change(); if (!waited.get()) { print("G22AutoStarter: Sleeping"); while (initialDelay > 0) { sleepSeconds(1); initialDelay(initialDelay - 1); } waited.raise(); change(); print("G22AutoStarter: Slept"); } while (enabled && !done()) { var script = scripts.get(nScriptsRun); currentScript(script); setProgressBarValue(progressBar, nScriptsRun); setProgressBarText(progressBar, str(script)); change(); script.run(); nScriptsRun(nScriptsRun + 1); currentScript(null); change(); } var topStack = g22utils.projectActions().topStack(); topStack.removeComponent(topStackComponent); topStackComponent = null; progressBar = null; fireDone(); change(); close(); } finally { _close(__1); } } public boolean done() { return nScriptsRun >= l(scripts); } public boolean waitedAndDone() { return waited.get() && done(); } public void cancel() { setEnabled(false); } public boolean canResume() { return !done() && !enabled; } public void resume() { if (done()) { infoBox("Nothing to resume - auto-start is done"); return; } if (enabled) { infoBox("Already running"); return; } infoBox("Resuming auto-start"); setEnabled(true); rst.get(); } public String status() { return !enabled ? ctrlPressed.get() ? "Cancelled due to ctrl key" : "Cancelled" : done() ? "Done" : waited.get() ? "Started" : started.get() ? "Pre-start wait (" + formatDouble1(initialDelay) + "s)" : "Not started"; } public String stats() { return status() + ". " + scriptsRunStats(); } public String scriptsRunStats() { return "Scripts run: " + nScriptsRun() + "/" + l(scripts); } public String currentScriptStats() { var s = currentScript; if (s == null) return ""; return "Running: " + s.script; } public void close() { try { if (ctrlListener != null) { { cleanUp(ctrlListener); ctrlListener = null; } change(); } } catch (Exception __e) { throw rethrow(__e); } } public void waitUntilDone() { waitForVarPredicate(varNScriptsRun(), () -> done()); } public boolean ctrlEnabled() { return ctrlListener != null; } public boolean cancelled() { return !enabled; } } static final public class FloatBWImage implements IBWImage { public int width, height; public float[] pixels; public float borderColor = 0.0f; public FloatBWImage() { } public FloatBWImage(int width, int height) { this.height = height; this.width = width; pixels = new float[width * height]; } public FloatBWImage(int width, int height, float brightness) { this.height = height; this.width = width; pixels = new float[width * height]; fillArrayUnlessZero(pixels, brightness); } public FloatBWImage(int width, int height, float[] pixels) { this.pixels = pixels; this.height = height; this.width = width; } final public float getFloatPixel(int x, int y) { return getPixel(x, y); } public float getPixel(int x, int y) { return inRange(x, y) ? getPixel_noRangeCheck(x, y) : borderColor; } public float getFloatPixel(int index) { return pixels[index]; } public float getPixel(Pt p) { return getPixel(p.x, p.y); } private boolean inRange(int x, int y) { return x >= 0 && x < width && y >= 0 && y < height; } public int getWidth() { return width; } public int getHeight() { return height; } public void setPixel(int x, int y, float brightness) { pixels[y * width + x] = brightness; } public float getPixel_noRangeCheck(int x, int y) { return pixels[y * width + x]; } public byte getByte(int x, int y) { return inRange(x, y) ? getByte_noRangeCheck(x, y) : _toByte(borderColor); } public byte getByte_noRangeCheck(int x, int y) { return _toByte(pixels[y * width + x]); } static public byte _toByte(float pixel) { return (byte) (Math.max(0, Math.min(1, pixel)) * 255f); } public BufferedImage getBufferedImage() { BufferedImage img = bufferedImage(width, height); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { int b = ((int) getByte(x, y) & 0xFF); img.setRGB(x, y, b * 0x010101); } return img; } public double averageBrightness() { return floatSumAsDouble(pixels) / (width * height); } } abstract static public class Convergent extends IterableIterator { public A value; public boolean stepped, done; public boolean hasNext() { if (done) return false; if (!stepped) { stepped = true; step(); } return !done; } public A next() { assertTrue(hasNext()); stepped = false; return value; } abstract public void step(); } static public class TickerPoint implements IFieldsToList { public TickerSequence ticker; public long currentTime; public TickerPoint() { } public TickerPoint(TickerSequence ticker, long currentTime) { this.currentTime = currentTime; this.ticker = ticker; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + ticker + ", " + currentTime + ")"; } public Object[] _fieldsToList() { return new Object[] { ticker, currentTime }; } public double currentPrice() { return lookback(0); } public double lookback(long time) { return ticker.priceAtTimestamp(currentTime - time); } public boolean canLookback(long time) { return currentTime - time >= ticker.startTime(); } public TickerSequence ticker() { return ticker; } final public long time() { return currentTime(); } public long currentTime() { return currentTime; } } abstract static public class CandleBasedIndicator { final public CandleBasedIndicator setLength(int length) { return length(length); } public CandleBasedIndicator length(int length) { this.length = length; return this; } final public int getLength() { return length(); } public int length() { return length; } public int length = 20; transient public Set> onCandleAdded; public CandleBasedIndicator onCandleAdded(IVF1 f) { onCandleAdded = createOrAddToSyncLinkedHashSet(onCandleAdded, f); return this; } public CandleBasedIndicator removeCandleAddedListener(IVF1 f) { loadableUtils.utils.remove(onCandleAdded, f); return this; } public void candleAdded(TradingCandle candle) { if (onCandleAdded != null) for (var listener : onCandleAdded) pcallF_typed(listener, candle); } transient public Set> onCandleRemoved; public CandleBasedIndicator onCandleRemoved(IVF1 f) { onCandleRemoved = createOrAddToSyncLinkedHashSet(onCandleRemoved, f); return this; } public CandleBasedIndicator removeCandleRemovedListener(IVF1 f) { loadableUtils.utils.remove(onCandleRemoved, f); return this; } public void candleRemoved(TradingCandle candle) { if (onCandleRemoved != null) for (var listener : onCandleRemoved) pcallF_typed(listener, candle); } final public A get() { return value(); } abstract public A value(); public SimpleCircularBuffer candles_cache; public SimpleCircularBuffer candles() { if (candles_cache == null) candles_cache = candles_load(); return candles_cache; } public SimpleCircularBuffer candles_load() { return new SimpleCircularBuffer(candlesNeeded()); } public int candlesNeeded() { return length; } public TradingCandle lastCandle() { return candles().last(); } public CandleBasedIndicator feed(TradingCandleMaker candleMaker) { if (candleMaker != null) for (var candle : candleMaker.candles()) add(candle); return this; } final public CandleBasedIndicator feed(Iterable candles) { return add(candles); } public CandleBasedIndicator add(Iterable candles) { for (var candle : unnullForIteration(candles)) add(candle); return this; } final public CandleBasedIndicator feed(TradingCandle candle) { return add(candle); } public CandleBasedIndicator add(TradingCandle candle) { if (candle.ongoing()) return this; if (lastCandle() != null && lessOrEq(candle.startTime, lastCandle().startTime)) return this; while (candles().size() > max(length - 1, 0)) candleRemoved(candles().remove()); candles().add(candle); candleAdded(candle); return this; } public void reset() { resetFields(this, "candles_cache"); } public CandleBasedIndicator emptyClone() { var clone = shallowNonTransientClone(this); clone.reset(); return clone; } } static public class JG22NetworkElement implements Swingable, IFieldsToList { public G22Utils g22utils; public JG22Network parent; public G22NetworkElement element; public JG22NetworkElement() { } public JG22NetworkElement(G22Utils g22utils, JG22Network parent, G22NetworkElement element) { this.element = element; this.parent = parent; this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils, parent, element }; } public CollapsibleLeftPanel collapsiblePanel; public JLeftArrowScriptIDE ide; public SingleComponentPanel scpContent = scp(); public JLabel lblDirty = jlabel(); transient public BoolVarWithNotify visualizing = new BoolVarWithNotify(); { visualizing.onChange(() -> updateDirtyFlag()); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { ide = g22utils.leftArrowIDE(); ide.makeParser = () -> { var parser = ide.makeParser_base(); element.configureParser(parser); return parser; }; ide.withResultPanel(false); ide.lvScript(element.varCode()); ide.runScript = () -> calculate(); var popDownButton = withRightMargin(jfullcenter(jPopDownButton_noText("Calculate", runnableThread(new Runnable() { public void run() { try { calculate(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "calculate();"; } }), "Visualize", runnableThread(new Runnable() { public void run() { try { visualizeNode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "visualizeNode();"; } }), "Configure", runnableThread(new Runnable() { public void run() { try { configureNode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "configureNode();"; } }), "Create input ports", runnableThread(new Runnable() { public void run() { try { autoCreateInputPorts(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "autoCreateInputPorts();"; } }), "Create output port", runnableThread(new Runnable() { public void run() { try { autoCreateOutputPort(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "autoCreateOutputPort();"; } }), "Copy code", runnableThread(new Runnable() { public void run() { try { copyCode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "copyCode();"; } }), "Delete node", runnableThread(new Runnable() { public void run() { try { deleteElement(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "deleteElement();"; } })))); var lblNodeID = toolTip("Click here to drag node around", jlabel("Node:")); componentPopupMenuItem(lblDirty, "Show error", runnableThread(new Runnable() { public void run() { try { showError(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showError();"; } })); collapsiblePanel = new CollapsibleLeftPanel(false, "Code", jMinWidth(0, ide.visualize()), jMinWidth(0, northAndCenter(centerAndEastWithMargin(withLabel(lblNodeID, centerTextField(jVarTextField(element.varIdentifier()))), jline(lblDirty, popDownButton)), scpContent))); bindVarToVar(element.varCodeVisible(), collapsiblePanel.varExpanded()); var box = collapsiblePanel.visualize(); jMinSize(80, 50, box); setBorder(box, BorderFactory.createLineBorder(Color.green, 5)); onMouseDown(lblNodeID, event -> { new ComponentDragger(box, event).bringToFront(true).start(); }); new ComponentResizeDragger(box, box); var bounds = or(element.bounds, rect(50, 50, 400, 300)); setBounds(box, bounds); onBoundsChange(box, new Runnable() { public void run() { try { element.bounds(toRect(getBounds(box))); element.network.change(); parent.mainPanel.revalidateMe(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "element.bounds(toRect(getBounds(box)));\r\n element.network.change();\r\n ..."; } }); return box; } public void deleteElement() { parent.deleteElement(this); } public void calculate() { try { parent.networkInstance.calculateNode(g22utils, element); visualizeNode(); } catch (Throwable __e) { infoBox(__e); } } public void configureNode() { try { element.configureBlueprint(g22utils); } catch (Throwable __e) { infoBox(__e); } } public void visualizeNode() { try { AutoCloseable __1 = tempSetBoolVar(visualizing); try { var parsedScript = element.compile(g22utils).get(); callVisualizeFunction(parsedScript); } finally { _close(__1); } } catch (Throwable __e) { infoBox(__e); } } public void callVisualizeFunction(GazelleV_LeftArrowScript.Script parsedScript) { var visualizeFunction = parsedScript.getFunction("visualize"); Object elementInstance = myInstance(); Component visualized = null; if (visualizeFunction != null) { var val = myValue(); Object valueHandler = new Object() { public void setValue(Object o) { parent.networkInstance.setObject(element, val, o); } }; RunResultWithTimestamps value = runResultWithTimestamps(() -> wrap(visualizeFunction.call(new FlexibleVarContext(), elementInstance, valueHandler, element))); ide.showScriptResult(value); if (value.isOK()) visualized = wrap(value.get()); else visualized = jErrorView(value.error()); } else visualized = new G22JavaObjectVisualizer(g22utils, elementInstance).visualize(); print("visualized", visualized); scpContent.set(visualized); } public void updateDirtyFlag() { var value = myValue(); setText(lblDirty, value == null ? " " : visualizing.get() ? "Visualizing" : value.calculating() ? "Calculating" : value.hasError() ? "Error" : value.dirty() ? "Dirty" : "Clean"); } public Object myInstance() { Object elementInstance = null; var ni = parent.networkInstance; if (ni != null) elementInstance = ni.getObjectForBlueprint(element); return elementInstance; } public G22NetworkInstance.Value myValue() { Object elementInstance = null; var ni = parent.networkInstance; return ni == null ? null : ni.valuesByBlueprint.get(element); } public void copyCode() { copyTextToClipboardVerbose(element.code()); } public void showError() { showErrorFrame(myValue().error()); } public void autoCreateOutputPort() { element.autoCreateOutputPort(myValue()); } public void autoCreateInputPorts() { element.autoCreateInputPorts(g22utils); } } static public class G22MeshMapping implements IFieldsToList { public G22Mesh mesh1; public G22Mesh mesh2; public G22MeshMapping() { } public G22MeshMapping(G22Mesh mesh1, G22Mesh mesh2) { this.mesh2 = mesh2; this.mesh1 = mesh1; } public Object[] _fieldsToList() { return new Object[] { mesh1, mesh2 }; } static public class MappedCurve implements IFieldsToList { public G22Mesh.Curve curve; public boolean flipped = false; public MappedCurve() { } public MappedCurve(G22Mesh.Curve curve, boolean flipped) { this.flipped = flipped; this.curve = curve; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + curve + ", " + flipped + ")"; } public boolean equals(Object o) { if (!(o instanceof MappedCurve)) return false; MappedCurve __5 = (MappedCurve) o; return eq(curve, __5.curve) && eq(flipped, __5.flipped); } public int hashCode() { int h = 913498716; h = boostHashCombine(h, _hashCode(curve)); h = boostHashCombine(h, _hashCode(flipped)); return h; } public Object[] _fieldsToList() { return new Object[] { curve, flipped }; } public G22Mesh.Curve get() { return curve; } public G22Mesh.Anchor start() { return curve.anchor(flipped); } public G22Mesh.Anchor end() { return curve.anchor(!flipped); } } public BijectiveMap anchorMap = new BijectiveMap(true); public LinkedHashMap curveMap = new LinkedHashMap(); public LinkedHashMap curveBackwardMap = new LinkedHashMap(); public void validityCheck() { if (mesh1 == mesh2) throw fail("Mesh1 and mesh2 must not be the same object"); for (var __1 : _entrySet(anchorMap)) { var a1 = __1.getKey(); var a2 = __1.getValue(); assertAnchorInMesh(a1, "mesh1", mesh1); assertAnchorInMesh(a2, "mesh2", mesh2); } for (var __0 : _entrySet(curveMap)) { var c1 = __0.getKey(); var c2 = __0.getValue(); assertTrue(c1 + " is in mesh1", mesh1.containsCurve(c1)); assertTrue(c2 + " is in mesh2", mesh2.containsCurve(c2.get())); assertEquals("Start point", c2.start(), getAnchorMapping(c1.start)); assertEquals("End point", c2.end(), getAnchorMapping(c1.end)); } } public String validityError() { try { validityCheck(); return null; } catch (Throwable e) { return "Validity error: " + e.getMessage(); } } public boolean isValid() { return validityError() == null; } public boolean isComplete() { return allEq(l(anchorMap), l(mesh1.anchors()), l(mesh2.anchors())) && allEq(l(curveMap), l(mesh1.curves()), l(mesh2.curves())); } public void assertAnchorInMesh(G22Mesh.Anchor a, String meshName, G22Mesh mesh) { assertTrue(a + " is in " + meshName, mesh.containsAnchor(a)); } public AutoCloseable tempMapAnchor(G22Mesh.Anchor a1, G22Mesh.Anchor a2) { assertAnchorInMesh(a1, "mesh1", mesh1); assertAnchorInMesh(a2, "mesh2", mesh2); return tempMapPut(anchorMap, a1, a2); } public void mapAnchor(G22Mesh.Anchor a1, G22Mesh.Anchor a2) { assertAnchorInMesh(a1, "mesh1", mesh1); assertAnchorInMesh(a2, "mesh2", mesh2); anchorMap.put(a1, a2); } public void unmapAnchor(G22Mesh.Anchor a1) { anchorMap.remove(a1); } public AutoCloseable tempMapCurve(G22Mesh.Curve c1, G22Mesh.Curve c2, boolean flipped) { List closers = new ArrayList(); var forwardMapping = new MappedCurve(c2, flipped); var backwardMapping = new MappedCurve(c1, flipped); closers.add(tempMapPut(curveMap, c1, forwardMapping)); closers.add(tempMapPut(curveBackwardMap, c2, backwardMapping)); closers.add(tempMapAnchor(c1.start, forwardMapping.start())); closers.add(tempMapAnchor(c1.end, forwardMapping.end())); return combineAutoCloseables(closers); } public void mapCurve(G22Mesh.Curve c1, G22Mesh.Curve c2, boolean flipped) { var forwardMapping = new MappedCurve(c2, flipped); var backwardMapping = new MappedCurve(c1, flipped); curveMap.put(c1, forwardMapping); curveBackwardMap.put(c2, backwardMapping); mapAnchor(c1.start, forwardMapping.start()); mapAnchor(c1.end, forwardMapping.end()); } final public G22Mesh.Anchor get(G22Mesh.Anchor a) { return getAnchorMapping(a); } public G22Mesh.Anchor getAnchorMapping(G22Mesh.Anchor a) { { var __3 = anchorMap.get(a); if (__3 != null) return __3; } return anchorMap.inverseGet(a); } final public MappedCurve get(G22Mesh.Curve c) { return getCurveMapping(c); } public MappedCurve getCurveMapping(G22Mesh.Curve c) { { var __4 = curveMap.get(c); if (__4 != null) return __4; } return curveBackwardMap.get(c); } public boolean isMapped(G22Mesh.Anchor a) { return get(a) != null; } public boolean isMapped(G22Mesh.Curve c) { return get(c) != null; } public List anchorMappingIndices() { var idx = mapItemsToListIndex(mesh2.anchorList()); return map(mesh1.anchorList(), a -> idx.get(get(a))); } public List curveMappingIndices() { var idx = mapItemsToListIndex(mesh2.curveList()); return map(mesh1.curveList(), a -> { var c = get(a); return c == null ? null : idx.get(c.get()); }); } public String toString() { return "Mapped anchors: " + anchorMappingIndices() + ", mapped curves: " + curveMappingIndices(); } public void drawMappedPartOfMesh1(Graphics2D g) { for (var anchor : keys(anchorMap)) new G22VisualizeMeshes().drawAnchor(g, anchor.pt); for (var curve : keys(curveMap)) new G22VisualizeMeshes().drawCurve(g, curve); } public void drawMappedPartOfMesh2(Graphics2D g) { for (var anchor : values(anchorMap)) new G22VisualizeMeshes().drawAnchor(g, anchor.pt); for (var curve : values(curveMap)) { G22VisualizeMeshes vm = new G22VisualizeMeshes(); if (curve.flipped) vm.curveColor(Color.green); vm.drawCurve(g, curve.get()); } } } static public class G22MaskConcept extends ConceptWithChangeListeners { public String description; public IBinaryImage maskImage; public String toString() { return colonCombine(super.toString(), description); } } static public class CloseSignal extends SignalWithStrength { public CloseSignal() { } { type("Close"); } } static public class G22ScriptResultPanel implements Swingable { public JTabbedPane tabs; public JFastLogView_noWrap logView = jFastLogView_noWrap(); public SingleComponentPanel scpResult = singleComponentPanel(); public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { return tabs = jtabs("Result", scpResult, "Log", jscroll_borderless(logView)); } } abstract static public class G22CRUDAndDetailPanel extends ConceptWithChangeListeners implements Swingable, IUnstructured { static final public String _fieldOrder = "selected collapsiblePanel g22utils crud scpDetail handleSelectionVar"; public Ref selected = new Ref(); public CollapsibleNorthPanel collapsiblePanel = new CollapsibleNorthPanel(true); final public G22CRUDAndDetailPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22CRUDAndDetailPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; transient public SimpleCRUD_v2 crud; transient public SingleComponentPanel scpDetail; abstract public SimpleCRUD_v2 makeCRUD(); transient public RSTVar handleSelectionVar = new RSTVar<>(__1 -> handleSelection_impl(__1)); public JComponent makeDetailView(A a) { return jTodo(); } { _doneLoading2(); } public void _doneLoading2() { super._doneLoading2(); collapsiblePanel.wrappedSideComponent = () -> centerAndEastWithMargin(collapsiblePanel.sideComponent(), vstack(collapsiblePanel.collapseButton())); } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { crud = makeCRUD(); putCRUDButtonsNextToSearchBar(crud); scpDetail = singleComponentPanel(); if (collapsiblePanel.expanded) selectAfterUpdate(selected.get()); var crudVis = crud.visualize(); crudVisualized(); handleSelectionVar.forceUpdate(); crud.onSelectionChanged(() -> { var selected = crud.selected(); this.selected.set(selected); handleSelectionVar.set(selected); }); collapsiblePanel.defaultSplitPoint(0.3); collapsiblePanel.init(crud.entityName() + " List", jCenteredSection(crud.entityNamePlural(), crudVis), scpDetail); collapsiblePanel.onChange(() -> change()); return collapsiblePanel.visualize(); } public void handleSelection_impl(A selected) { if (selected == null) scpDetail.set(emptyDetailView()); else { var view = makeDetailView(selected); var lvTitle = liveValue_hasChangeListeners(selected, () -> detailTitle(selected)); scpDetail.set(jCenteredRaisedBoldLiveValueSection(lvTitle, view)); } } transient public IF1 detailTitle; public String detailTitle(A item) { return detailTitle != null ? detailTitle.get(item) : detailTitle_base(item); } final public String detailTitle_fallback(IF1 _f, A item) { return _f != null ? _f.get(item) : detailTitle_base(item); } public String detailTitle_base(A item) { return appendPrefix(crud.entityName() + " " + item.id + ": ", str(item)); } public JComponent emptyDetailView() { return jGazelleLogo(); } public void crudVisualized() { } public void addCountToEnclosingTab(boolean b) { crud.addCountToEnclosingTab(b); } public void updateCount() { crud.update(); } final public void setSelected(A A) { edit(A); } public void edit(A A) { var searcher = crud().tableSearcher(); { if (searcher != null) searcher.clearSearchField(); } crud().setSelected(A); } public void selectAfterUpdate(A A) { crud.selectAfterUpdate(A); } public SimpleCRUD_v2 crud() { visualize(); return crud; } } public interface IG22MasksHolder { public WidthAndHeight maskSize(); public List maskImages(); public List> masks(); public G22GhostImage ghost(); public double certainty(); default public int nMasks() { return l(masks()); } default public String renderCountAndCertainty() { return main.nMasks(nMasks()) + " with c=" + formatDouble3(certainty()); } default public boolean canSplit() { return nMasks() > 1; } default public List> subHolders() { return null; } default public void transformSubHolders(IF1, IG22MasksHolder> f) { } default public PStackComputable findSimilarMasks(G22FindSimilarMasksTask task) { return new FindSimilarMasks_BruteForce(this, task); } static public class FindSimilarMasks_BruteForce extends PStackComputableWithStep implements IFieldsToList { public IG22MasksHolder masksHolder; public G22FindSimilarMasksTask task; public FindSimilarMasks_BruteForce() { } public FindSimilarMasks_BruteForce(IG22MasksHolder masksHolder, G22FindSimilarMasksTask task) { this.task = task; this.masksHolder = masksHolder; } public Object[] _fieldsToList() { return new Object[] { masksHolder, task }; } public IG22Mask maskBeingTested; public String toString() { return formatFunctionCall(shortClassName(this), masksHolder, "step=" + step); } public void step(IPStack stack) { if (task.ended()) { stack._return(); return; } if (step == 0) { ++step; stack.optionsOrReturn(this, map(masksHolder.masks(), mask -> self -> self.maskBeingTested = mask)); } else { task.tryMask(maskBeingTested); stack._return(); } } } public IG22MasksHolder cloneTreeWithLabelTransform(IF1 transformLabel); } static public class G22AnalyzerIDE extends G22LAScriptIDE { public G22AnalyzerIDE(G22Utils g22utils) { super(g22utils); } final public G22AnalyzerIDE setTimeoutToRecognizeAnImage(double timeoutToRecognizeAnImage) { return timeoutToRecognizeAnImage(timeoutToRecognizeAnImage); } public G22AnalyzerIDE timeoutToRecognizeAnImage(double timeoutToRecognizeAnImage) { this.timeoutToRecognizeAnImage = timeoutToRecognizeAnImage; return this; } final public double getTimeoutToRecognizeAnImage() { return timeoutToRecognizeAnImage(); } public double timeoutToRecognizeAnImage() { return timeoutToRecognizeAnImage; } public double timeoutToRecognizeAnImage = 10.0; transient public IF0 exampleExampleImage; public BufferedImage exampleExampleImage() { return exampleExampleImage != null ? exampleExampleImage.get() : exampleExampleImage_base(); } final public BufferedImage exampleExampleImage_fallback(IF0 _f) { return _f != null ? _f.get() : exampleExampleImage_base(); } public BufferedImage exampleExampleImage_base() { return loadImage2("#1101126"); } transient public ConceptsComboBox cbExampleImage; public BufferedImage exampleImage() { var selected = script.exampleImage.get(); { var __1 = selected == null ? null : selected.load(); if (__1 != null) return __1; } return exampleExampleImage(); } { onSettingUpIDE(ide -> { ide.runScript = () -> { G22Analyzer.CompiledAnalyzer analyzer = (G22Analyzer.CompiledAnalyzer) (ide.freshCompileResult()); if (!analyzer.runnable()) return; var image = exampleImage(); var bg = g22utils.backgroundProcessesUI(); AutoCloseable __2 = bg == null ? null : bg.tempAdd("Run recognizer on example image"); try { var result = runResultWithTimestamps(() -> analyzer.get(image)); ide.showScriptResult(result); } finally { _close(__2); } }; }); } public JComponent visualize_impl() { cbExampleImage = new ConceptsComboBox<>(g22utils.concepts, G22GalleryImage.class).allowNull(true); var varExampleImage = new FieldVar(script, "exampleImage", () -> script.exampleImage.get(), img -> cset(script, "exampleImage", img)); bindComboBoxToVar_withUserChangeListener(cbExampleImage, varExampleImage, runnableThread(new Runnable() { public void run() { try { visibleIDE().runScript(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "visibleIDE().runScript()"; } })); return centerAndSouthWithMargin(super.visualize_impl(), rightAlignedLine(withLabel("Image to analyze:", cbExampleImage))); } } static public class G22NetworkCable { final public G22NetworkCable setFrom(G22NetworkElement.Port from) { return from(from); } public G22NetworkCable from(G22NetworkElement.Port from) { this.from = from; return this; } final public G22NetworkElement.Port getFrom() { return from(); } public G22NetworkElement.Port from() { return from; } public G22NetworkElement.Port from; final public G22NetworkCable setTo(G22NetworkElement.Port to) { return to(to); } public G22NetworkCable to(G22NetworkElement.Port to) { this.to = to; return this; } final public G22NetworkElement.Port getTo() { return to(); } public G22NetworkElement.Port to() { return to; } public G22NetworkElement.Port to; final public G22NetworkCable setIsAutomatic(boolean isAutomatic) { return isAutomatic(isAutomatic); } public G22NetworkCable isAutomatic(boolean isAutomatic) { this.isAutomatic = isAutomatic; return this; } final public boolean getIsAutomatic() { return isAutomatic(); } public boolean isAutomatic() { return isAutomatic; } public boolean isAutomatic = false; public void connect() { from.cable(this); to.cable(this); } public void remove() { { if (from != null) from.cable(null); } { if (to != null) to.cable(null); } } public String toString() { return renderVars("G22NetworkCable", "from", from, "to", to, "isAutomatic", isAutomatic); } } static public class GenericallyScored> extends Var { public B score; public GenericallyScored() { } public GenericallyScored(A a, B score) { super(a); this.score = score; } public B score() { return score; } public String toString() { return score + ": " + str(get()); } } static public class G22VariablesPanel implements Swingable, IFieldsToList { public G22VariablesPanel() { } public String toString() { return shortClassName_dropNumberPrefix(this); } public Object[] _fieldsToList() { return null; } final public G22VariablesPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22VariablesPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; final public G22VariablesPanel setCompactView(boolean compactView) { return compactView(compactView); } public G22VariablesPanel compactView(boolean compactView) { this.compactView = compactView; return this; } final public boolean getCompactView() { return compactView(); } public boolean compactView() { return compactView; } public boolean compactView = false; final public G22VariablesPanel setUpdateInterval(double updateInterval) { return updateInterval(updateInterval); } public G22VariablesPanel updateInterval(double updateInterval) { this.updateInterval = updateInterval; return this; } final public double getUpdateInterval() { return updateInterval(); } public double updateInterval() { return updateInterval; } public double updateInterval = 1.0; transient public SimpleCRUD_v2 crud; transient public SingleComponentPanel scpDetail; transient public ReliableSingleThread rstUpdateDetail = rst(() -> _updateDetail()); public SimpleCRUD_v2 crud() { if (crud == null) { crud = new SimpleCRUD_v2<>(g22utils.concepts(), G22Variable.class); crud.updateInterval(updateInterval); } return crud; } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { crud().iconButtons(true); crud.entityName = () -> "Variable"; crud.renderValue = __1 -> strOrNull(__1); var vis = jCenteredSection("Project Variables", crud.visualize()); IVF1 rUpdate = v -> crud.update(); bindToComponent(vis, () -> g22utils.onBigVariableLoaded(rUpdate), () -> g22utils.removeBigVariableLoadedListener(rUpdate)); if (compactView) return vis; crud.onSingleSelectionChanged(rstUpdateDetail); scpDetail = scp(); return jvsplit(vis, scpDetail); } public void updateCount() { crud().update(); } public void setSelected(G22Variable var) { crud().setSelected(var); } public void _updateDetail() { var var = crud.selected(); if (var == null) { scpDetail.clear(); return; } Object value = var.value(); var vis = new G22JavaObjectVisualizer(g22utils, value).visualize(); bindChangeListenerToComponent(vis, var.varValue(), () -> { if (!eq(var.value(), value)) rstUpdateDetail.get(); }); scpDetail.set(jCenteredSection("Variable " + var.name, vis)); } } static public class LASScope { final public LASScope setUseFixedVars(boolean useFixedVars) { return useFixedVars(useFixedVars); } public LASScope useFixedVars(boolean useFixedVars) { this.useFixedVars = useFixedVars; return this; } final public boolean getUseFixedVars() { return useFixedVars(); } public boolean useFixedVars() { return useFixedVars; } public boolean useFixedVars = false; final public Map getDeclaredVars() { return declaredVars(); } public Map declaredVars() { return declaredVars; } public Map declaredVars = new HashMap(); final public LASScope setParentScope(LASScope parentScope) { return parentScope(parentScope); } public LASScope parentScope(LASScope parentScope) { this.parentScope = parentScope; return this; } final public LASScope getParentScope() { return parentScope(); } public LASScope parentScope() { return parentScope; } public LASScope parentScope; final public LASScope setParentIsDetached(boolean parentIsDetached) { return parentIsDetached(parentIsDetached); } public LASScope parentIsDetached(boolean parentIsDetached) { this.parentIsDetached = parentIsDetached; return this; } final public boolean getParentIsDetached() { return parentIsDetached(); } public boolean parentIsDetached() { return parentIsDetached; } public boolean parentIsDetached = false; public String[] names; public LASScope() { } public LASScope(LASScope parentScope) { this.parentScope = parentScope; } public boolean resolved() { return names != null; } public void addDeclaredVar(String name, LASValueDescriptor type) { if (resolved()) throw fail("Can't add variables to resolved scope"); declaredVars.put(name, type); } public int resolveVar(String name) { resolve(); int idx = indexOfInSortedArray(names, name); if (idx < 0) throw fail("Variable not found in scope: " + name); return idx; } public void resolve() { if (names != null) return; names = empty(declaredVars) ? null : toStringArray(sortedKeys(declaredVars)); } } static public class ConvertLASToJava extends Meta { public String typeToJava(Type type) { return type == null ? null : shortenClassNames(type.getTypeName()); } public String typeToJava(LASValueDescriptor desc) { return typeToJava(or(desc == null ? null : desc.javaClass(), Object.class)); } public Object convert(LASClassDef.FieldDef field) { return "settable " + typeToJava(field.type()) + " " + field.name() + (field.initializer == null ? "" : " = " + convert(field.initializer)) + ";"; } public Object convert(GazelleV_LeftArrowScript.FunctionDef f) { return typeToJava(f.returnType) + " " + f.name + "(" + joinWithComma(countIterator(l(f.args), i -> typeToJava(f.argTypes[i]) + " " + f.args[i])) + ") {\n" + indentx(convert(f.body, true)) + "}\n"; } public Object convertWithLeadingSpace(GazelleV_LeftArrowScript.Evaluable o) { return leadingSpace(o, "") + convert(o); } public Object convertWithLeadingSpace2(GazelleV_LeftArrowScript.Evaluable o) { return replaceIfEqual(leadingSpace(o, ""), " ", "") + convert(o); } public String leadingSpace(GazelleV_LeftArrowScript.Evaluable o, String defaultSpace) { String space = null; var src = o.tokenRangeWithSrc(); if (src != null) space = src.startPtr().mapIdx(idx -> idx & ~1).get(); return or2(space, defaultSpace); } public String trailingSpace(GazelleV_LeftArrowScript.Evaluable o, String defaultSpace) { String space = null; var src = o.tokenRangeWithSrc(); if (src != null) { String rawSpace = src.endPtr().mapIdx(idx -> idx & ~1).get(); space = replaceRegexp(rawSpace, "\n[ \t]+$", "\n"); if (scaffoldingEnabled()) printVars("trailingSpace", "rawSpace", quote(rawSpace), "space", quote(space)); } return or2(space, defaultSpace); } public Object getInstruction(GazelleV_LeftArrowScript.Evaluable o) { Object inner = convert(o); boolean needSemicolon = !(o instanceof GazelleV_LeftArrowScript.ClassDef) && !(o instanceof GazelleV_LeftArrowScript.ForEachBase); String space = trailingSpace(o, "\n"); if (scaffoldingEnabled()) printVars("space", space, "o", className(o), "srcText", quote(o.srcText()), "inner", inner); return inner + (needSemicolon ? ";" : "") + space; } public Object convert(GazelleV_LeftArrowScript.Script script, boolean returnLastResult) { var steps = asList(script.steps); if (returnLastResult) { if (empty(steps)) return "return null;"; var last = last(steps); if (!(last instanceof GazelleV_LeftArrowScript.ReturnFromScript) && !(last instanceof GazelleV_LeftArrowScript.ClassDef)) setLast(steps, new GazelleV_LeftArrowScript.ReturnFromScript(script, last)); } return concatMapStrings(i -> str(getInstruction(i)), steps); } public Object convert(GazelleV_LeftArrowScript.Evaluable o, boolean returnLastResult) { if (o instanceof GazelleV_LeftArrowScript.Script) return convert(((GazelleV_LeftArrowScript.Script) o), returnLastResult); return convert(o); } public Object convert(GazelleV_LeftArrowScript.Evaluable o) { if (o == null) return null; if (o instanceof GazelleV_LeftArrowScript.GetVar) return ((GazelleV_LeftArrowScript.GetVar) o).var; if (o instanceof GazelleV_LeftArrowScript.Script) return convert(((GazelleV_LeftArrowScript.Script) o), false); if (o instanceof GazelleV_LeftArrowScript.ClassDef) { LASClassDef c = ((GazelleV_LeftArrowScript.ClassDef) o).lasClass.classDef; return spaceCombine("class", c.userGivenName, c.superClass == null ? null : "extends " + typeToJava(c.superClass), empty(c.interfaces) ? null : "is " + map(__73 -> typeToJava(__73), c.interfaces), curly("\n" + appendNewLineIfNempty(indentx(joinNemptiesWithEmptyLines(lines_rtrim(map(__74 -> convert(__74), c.fields)), convertInitializers(c), lines_rtrim(map(__75 -> convert(__75), c.methods))))))); } if (o instanceof GazelleV_LeftArrowScript.Assignment) return ((GazelleV_LeftArrowScript.Assignment) o).var + " = " + convert(((GazelleV_LeftArrowScript.Assignment) o).expression); if (o instanceof GazelleV_LeftArrowScript.VarDeclaration) return "var " + ((GazelleV_LeftArrowScript.VarDeclaration) o).var + " = " + convert(((GazelleV_LeftArrowScript.VarDeclaration) o).expression); if (o instanceof GazelleV_LeftArrowScript.CallMethod) { String targetStr = null; var targetType = ((GazelleV_LeftArrowScript.CallMethod) o).target.returnType(); if (targetType != null && targetType.knownValue()) { Object target = targetType.value(); if (target instanceof Class && eqOneOf(shortClassName((Class) target), "main", "utils")) targetStr = ""; } if (targetStr == null) targetStr = str(convert(((GazelleV_LeftArrowScript.CallMethod) o).target)); return (empty(targetStr) ? "" : targetStr + ".") + new FunctionCall(((GazelleV_LeftArrowScript.CallMethod) o).methodName, map(__76 -> convertWithLeadingSpace2(__76), ((GazelleV_LeftArrowScript.CallMethod) o).args)); } if (o instanceof GazelleV_LeftArrowScript.SetField) return convert(((GazelleV_LeftArrowScript.SetField) o).target) + "." + ((GazelleV_LeftArrowScript.SetField) o).name + " = " + convert(((GazelleV_LeftArrowScript.SetField) o).expr); if (o instanceof GazelleV_LeftArrowScript.CallMethodOrGetField) return convert(((GazelleV_LeftArrowScript.CallMethodOrGetField) o).target) + "." + ((GazelleV_LeftArrowScript.CallMethodOrGetField) o).name + "()"; if (o instanceof GazelleV_LeftArrowScript.NewObject) { String className; var o2 = (GazelleV_LeftArrowScript.NewObject) o; if (o2 instanceof GazelleV_LeftArrowScript.NewObject_LASClass) { className = ((GazelleV_LeftArrowScript.NewObject_LASClass) o2).lasClass.userGivenName(); } else className = typeToJava(((GazelleV_LeftArrowScript.NewObject) o).c); return "new " + new FunctionCall(className, map(__77 -> convert(__77), ((GazelleV_LeftArrowScript.NewObject) o).args)); } if (o instanceof GazelleV_LeftArrowScript.IfThen) return "if (" + convert(((GazelleV_LeftArrowScript.IfThen) o).condition) + ") " + curlyIfScript(((GazelleV_LeftArrowScript.IfThen) o).body) + (((GazelleV_LeftArrowScript.IfThen) o).elseBranch == null ? "" : " else " + curlyIfScript(((GazelleV_LeftArrowScript.IfThen) o).elseBranch)); if (o instanceof GazelleV_LeftArrowScript.Const) { Object val = ((GazelleV_LeftArrowScript.Const) o).value; if (val instanceof GazelleV_LeftArrowScript.FunctionDef) return convert((GazelleV_LeftArrowScript.FunctionDef) val); var c = (GazelleV_LeftArrowScript.Const) o; { var __1 = c == null ? null : c.srcText(); if (__1 != null) return __1; } try { return toJava(val); } catch (Throwable __e) { pcallFail(__e); } } if (o instanceof GazelleV_LeftArrowScript.ForEach) return "fOr (" + ((GazelleV_LeftArrowScript.ForEach) o).var + " : " + convert(((GazelleV_LeftArrowScript.ForEach) o).collection) + ") {\n" + indentx(convert(((GazelleV_LeftArrowScript.ForEach) o).body, false)) + "\n}"; if (o instanceof GazelleV_LeftArrowScript.ForIntTo) return "for " + ((GazelleV_LeftArrowScript.ForIntTo) o).var + " to " + convert(((GazelleV_LeftArrowScript.ForIntTo) o).endValue) + ": {\n" + indentx(convert(((GazelleV_LeftArrowScript.ForIntTo) o).body, false)) + "\n}"; if (o instanceof GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) { int nArgs = ((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).implementedMethod.getParameterCount(); List args = countIteratorToList_incl(1, nArgs, i -> "_" + i); List fullArgs = concatLists(allToString(map(__78 -> convert(__78), ((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).curriedArgs)), args); return roundBracketed(typeToJava(((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).intrface)) + " " + lambdaArgsToString_pureJava(args) + " -> " + new FunctionCall(((GazelleV_LeftArrowScript.CurriedScriptFunctionLambda) o).f.name, fullArgs); } if (o instanceof GazelleV_LeftArrowScript.LambdaDef) return roundBracketed(typeToJava(((GazelleV_LeftArrowScript.LambdaDef) o).intrface)) + " " + joinNemptiesWithSpace(lambdaArgsToString_pureJava(((GazelleV_LeftArrowScript.LambdaDef) o).args), "-> " + curlyIfScript(((GazelleV_LeftArrowScript.LambdaDef) o).body)); if (o instanceof GazelleV_LeftArrowScript.ReturnFromScript) return "ret " + convert(((GazelleV_LeftArrowScript.ReturnFromScript) o).value); if (o instanceof GazelleV_LeftArrowScript.GetStaticField) return typeToJava(((GazelleV_LeftArrowScript.GetStaticField) o).field.getDeclaringClass()) + "." + ((GazelleV_LeftArrowScript.GetStaticField) o).field.getName(); if (o instanceof GazelleV_LeftArrowScript.BoolAnd) return roundBracketed(str(convert(((GazelleV_LeftArrowScript.BoolAnd) o).a))) + " && " + roundBracketed(str(convert(((GazelleV_LeftArrowScript.BoolAnd) o).b))); if (o instanceof GazelleV_LeftArrowScript.BoolOr) return roundBracketed(str(convert(((GazelleV_LeftArrowScript.BoolOr) o).a))) + " || " + roundBracketed(str(convert(((GazelleV_LeftArrowScript.BoolOr) o).b))); warn("Can't convert to Java: " + className(o)); if (o instanceof GazelleV_LeftArrowScript.Base) { var b = (GazelleV_LeftArrowScript.Base) o; { var __2 = b == null ? null : b.srcText(); if (__2 != null) return __2; } } warn("No source reference in script object: " + className(o)); return str(o); } public Object curlyIfScript(GazelleV_LeftArrowScript.Evaluable o) { if (o instanceof GazelleV_LeftArrowScript.Script) return "{\n" + indentx(convert((GazelleV_LeftArrowScript.Script) o)) + "\n}"; return convert(o); } public String get(GazelleV_LeftArrowScript.Evaluable o, boolean returnLastResult) { String src = strOrEmpty(convert(o, returnLastResult)); List tok = javaTok(src); jreplace(tok, "this.", ""); JavaXPeepholeShortener shortener = new JavaXPeepholeShortener(tok); shortener.run(); return join(shortener.tok); } public String convertInitializers(LASClassDef c) { return lines_rtrim(nempties(mapWithIndex(c.initializers, (idx, i) -> { if (c.isFieldInitializer.get(idx)) return null; return "{ " + addSuffix(rtrim(str(convert(i))), ";") + " }"; }))); } } public enum HoldSide { SHORT, LONG; static public HoldSide fromInt(double direction) { if (direction > 0) return LONG; if (direction < 0) return SHORT; throw fail("direction 0"); } public boolean isLong() { return this == LONG; } public boolean isShort() { return this == SHORT; } } static public class G22NetworkInstance implements IFieldsToList { public boolean _isTransient() { return true; } public G22Network network; public G22NetworkInstance() { } public G22NetworkInstance(G22Network network) { this.network = network; } public Object[] _fieldsToList() { return new Object[] { network }; } public Map valuesByIdentifier = new HashMap(); public Map valuesByBlueprint = new HashMap(); transient public Set onDirtyStatesChanged; public G22NetworkInstance onDirtyStatesChanged(Runnable r) { onDirtyStatesChanged = createOrAddToSyncLinkedHashSet(onDirtyStatesChanged, r); return this; } public G22NetworkInstance removeDirtyStatesChangedListener(Runnable r) { loadableUtils.utils.remove(onDirtyStatesChanged, r); return this; } public void dirtyStatesChanged() { if (onDirtyStatesChanged != null) for (var listener : onDirtyStatesChanged) pcallF_typed(listener); } static public class Value { final public Value setObject(Object object) { return object(object); } public Value object(Object object) { this.object = object; return this; } final public Object getObject() { return object(); } public Object object() { return object; } public Object object; final public Value setCalculatedWhen(Timestamp calculatedWhen) { return calculatedWhen(calculatedWhen); } public Value calculatedWhen(Timestamp calculatedWhen) { this.calculatedWhen = calculatedWhen; return this; } final public Timestamp getCalculatedWhen() { return calculatedWhen(); } public Timestamp calculatedWhen() { return calculatedWhen; } public Timestamp calculatedWhen; final public Value setDirty(boolean dirty) { return dirty(dirty); } public Value dirty(boolean dirty) { this.dirty = dirty; return this; } final public boolean getDirty() { return dirty(); } public boolean dirty() { return dirty; } volatile public boolean dirty = false; final public Value setCalculating(boolean calculating) { return calculating(calculating); } public Value calculating(boolean calculating) { this.calculating = calculating; return this; } final public boolean getCalculating() { return calculating(); } public boolean calculating() { return calculating; } volatile public boolean calculating = false; final public Value setError(Throwable error) { return error(error); } public Value error(Throwable error) { this.error = error; return this; } final public Throwable getError() { return error(); } public Throwable error() { return error; } volatile public Throwable error; public Object get() { return object; } public String toString() { return classNameWithIdentity(this) + ": " + object; } public boolean hasError() { return error != null; } } public void calculateNode(G22Utils g22utils, G22NetworkElement e) { if (e == null) return; Value value = valueForBlueprint(e); value.calculating(true); try { dirtyStatesChanged(); Object instance = e.makeInstance(g22utils, this); print("Calculated: " + instance); value.error(null); setObject(e, value, instance); } catch (Throwable exception) { printStackTrace(exception); value.error(exception); value.dirty(false); } finally { value.calculating(false); dirtyStatesChanged(); } } public void setObject(G22NetworkElement e, Value value, Object instance) { value.object(instance).calculatedWhen(tsNow()); if (value.dirty()) { value.dirty(false); dirtyStatesChanged(); } invalidateDependentNodes(e); } public void init(G22Utils g22utils) { for (var e : network.elements) { Value value = new Value(); value.dirty(true); dirtyStatesChanged(); valuesByBlueprint.put(e, value); mapPut(valuesByIdentifier, e.identifier(), value); } } public Object getObjectForBlueprint(G22NetworkElement element) { var value = valueForBlueprint(element); Object object = value.get(); printVars("getObjectForBlueprint", "element", element, "value", value, "object", object); return object; } public void invalidateDependentNodes(G22NetworkElement element) { if (element == null) return; print("invalidateDependentNodes", element); for (var e : element.downstreamNodes()) invalidateNode(e); } public boolean isCalculable(G22NetworkElement element) { return all(element.upstreamNodes(), e -> !isDirty(e)); } public Value valueForBlueprint(G22NetworkElement element) { return syncGetOrCreate(valuesByBlueprint, element, () -> new Value()); } public boolean isDirty(G22NetworkElement element) { return valueForBlueprint(element).dirty(); } public void invalidateNode(G22NetworkElement element) { print("invalidateNode", element); var value = valueForBlueprint(element); if (value.dirty()) return; value.dirty(true); dirtyStatesChanged(); invalidateDependentNodes(element); } public G22NetworkElement calculateOneNode(G22Utils g22utils) { var calculableElements = filter(e -> isDirty(e) && isCalculable(e), keys(valuesByBlueprint)); var e = random(calculableElements); calculateNode(g22utils, e); return e; } } static public class G22ScriptUtil implements IFieldsToList { public G22Utils g22utils; public G22ScriptUtil() { } public G22ScriptUtil(G22Utils g22utils) { this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ")"; } public boolean equals(Object o) { if (!(o instanceof G22ScriptUtil)) return false; G22ScriptUtil __1 = (G22ScriptUtil) o; return eq(g22utils, __1.g22utils); } public int hashCode() { int h = 5814164; h = boostHashCombine(h, _hashCode(g22utils)); return h; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public File scriptToDBDir(G22LeftArrowScript script) { return script == null ? null : script._concepts.conceptsDir(); } public String renderScript(String header, String mode, String text) { return header + "[" + mode + "]\n" + "----\n" + rtrim(text) + "\n" + "----"; } public String makeHugeText(List scripts) { List out = new ArrayList(); for (var script : unnullForIteration(scripts)) { String header = formatColonProperties("Script Name", str(script), "Script ID", script.id, "DB", f2s(scriptToDBDir(script))); String editedText = script.editedText(); if (editedText != null) out.add(renderScript(header, "Editing", editedText)); if (script.text != null) out.add(renderScript(header, "Saved", script.text)); String codeForAutoRun = script.codeForAutoRun(); if (codeForAutoRun != null) out.add(renderScript(header, "Clear for auto-run", codeForAutoRun)); } return paragraphs(out); } } public interface IG22SimpleMasksHolder extends IG22MasksHolder { } public interface ILASClassLoader { public Class defineLASClass(String name, IF0 generateClass); public Object rememberClassBytes(boolean rememberClassBytes); } static public class LASClassDef extends HasTokenRangeWithSrc { final public LASClassDef setUserGivenName(String userGivenName) { return userGivenName(userGivenName); } public LASClassDef userGivenName(String userGivenName) { this.userGivenName = userGivenName; return this; } final public String getUserGivenName() { return userGivenName(); } public String userGivenName() { return userGivenName; } public String userGivenName; final public LASClassDef setClassDefPrefix(String classDefPrefix) { return classDefPrefix(classDefPrefix); } public LASClassDef classDefPrefix(String classDefPrefix) { this.classDefPrefix = classDefPrefix; return this; } final public String getClassDefPrefix() { return classDefPrefix(); } public String classDefPrefix() { return classDefPrefix; } public String classDefPrefix = "userCode."; final public LASClassDef setFullCompilation(boolean fullCompilation) { return fullCompilation(fullCompilation); } public LASClassDef fullCompilation(boolean fullCompilation) { this.fullCompilation = fullCompilation; return this; } final public boolean getFullCompilation() { return fullCompilation(); } public boolean fullCompilation() { return fullCompilation; } public boolean fullCompilation = false; final public LASClassDef setVerbose(boolean verbose) { return verbose(verbose); } public LASClassDef verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = true; final public LASClassDef setSuperClass(Type superClass) { return superClass(superClass); } public LASClassDef superClass(Type superClass) { this.superClass = superClass; return this; } final public Type getSuperClass() { return superClass(); } public Type superClass() { return superClass; } public Type superClass = Object.class; public List fields = new ArrayList(); public List methods = new ArrayList(); public List methodBodies = new ArrayList(); public List interfaces = new ArrayList(); public GazelleV_LeftArrowScript.FunctionDef initializerMethod; public List initializers = new ArrayList(); public BitSet isFieldInitializer = new BitSet(); static public class FieldDef { final public FieldDef setName(String name) { return name(name); } public FieldDef name(String name) { this.name = name; return this; } final public String getName() { return name(); } public String name() { return name; } public String name; final public FieldDef setType(Type type) { return type(type); } public FieldDef type(Type type) { this.type = type; return this; } final public Type getType() { return type(); } public Type type() { return type; } public Type type; final public FieldDef setInitializer(GazelleV_LeftArrowScript.Evaluable initializer) { return initializer(initializer); } public FieldDef initializer(GazelleV_LeftArrowScript.Evaluable initializer) { this.initializer = initializer; return this; } final public GazelleV_LeftArrowScript.Evaluable getInitializer() { return initializer(); } public GazelleV_LeftArrowScript.Evaluable initializer() { return initializer; } public GazelleV_LeftArrowScript.Evaluable initializer; } public String structForHash() { return GazelleV_LeftArrowScript.scriptStruct(litorderedmap("userGivenName", userGivenName, "fields", fields, "methods", methods, "fullCompilation", fullCompilation)); } public String classHash_cache; public String classHash() { if (classHash_cache == null) classHash_cache = classHash_load(); return classHash_cache; } public String classHash_load() { String struct = structForHash(); if (verbose) print("structForHash", struct); return md5(struct); } public String finalClassName() { return classDefPrefix() + finalClassNameWithoutPrefix(); } public String finalClassNameWithoutPrefix() { return or2(userGivenName, "C") + "_" + classHash(); } public byte[] toBytes_cache; public byte[] toBytes() { if (toBytes_cache == null) toBytes_cache = toBytes_load(); return toBytes_cache; } public byte[] toBytes_load() { ClassMaker classMaker = new ClassMaker(finalClassName(), className(typeToClass(superClass)), mapToStringArray(interfaces, i -> className(typeToClass(i)))); var cp = classMaker.getConstantPool(); for (var field : fields) { var type = field.type; var fg = new FieldGen(Const.ACC_PUBLIC, typeToBCELType(type), field.name, cp); if (type instanceof ParameterizedType) fg.addAttribute(new org.apache.bcel.classfile.Signature(cp.addUtf8("Signature"), 2, cp.addUtf8(typeToVMSignature((ParameterizedType) type)), cp.getConstantPool())); classMaker.addField(fg); } if (nempty(initializers)) { methods.add(initializerMethod = new GazelleV_LeftArrowScript.FunctionDef("$initFields", new String[0], new GazelleV_LeftArrowScript.Script(initializers)).returnType(void.class)); if (!hasUserDefinedDefaultConstructor()) methods.add(new GazelleV_LeftArrowScript.FunctionDef("", new String[0], new GazelleV_LeftArrowScript.Script(emptyList())).returnType(void.class)); } for (var method : methods) if (fullCompilation) fullyCompileMethod(classMaker, method); else semiCompileMethod(classMaker, method); if (!hasUserDefinedDefaultConstructor()) classMaker.addDefaultConstructor(); if (srcRef() != null) classMaker.addField(new FieldGen(Const.ACC_PUBLIC | Const.ACC_STATIC, classToBCELType(TokenRangeWithSrc.class), srcRefField(), classMaker.getConstantPool())); return classMaker.toBytes(); } public TokenRangeWithSrc srcRef() { return tokenRangeWithSrc(); } public void addToInitializerMethod(FieldDef field) { isFieldInitializer.set(l(initializers)); initializers.add(new GazelleV_LeftArrowScript.SetField(new GazelleV_LeftArrowScript.GetVar("this"), field.name, field.initializer)); } public boolean hasUserDefinedDefaultConstructor() { return any(methods, m -> m.isConstructor() && empty(m.args)); } public void semiCompileMethod(ClassMaker classMaker, GazelleV_LeftArrowScript.FunctionDef method) { int iMethod = l(methodBodies); methodBodies.add(method); String bodyFieldName = "_body" + iMethod; classMaker.addField(new FieldGen(Const.ACC_PUBLIC | Const.ACC_STATIC, classToBCELType(GazelleV_LeftArrowScript.Evaluable.class), bodyFieldName, classMaker.getConstantPool())); int nArgs = l(method.args); MethodMaker mm = new MethodMaker(classMaker.cg(), Const.ACC_PUBLIC, typeToBCEL(method.returnType), method.name, mapToArray(__79 -> typeToBCEL(__79), method.argTypes)); int iThis = 0, iCtx = mm.frameSize; if (method.isConstructor()) { mm.aload(iThis); mm.invokeConstructor(typeToClass(superClass)); if (initializerMethod != null) { mm.aload(iThis); mm.il.append(mm.factory.createInvoke(classMaker.className(), initializerMethod.name, mm.wrapType(void.class), mm.wrapTypes(new Class[0]), Const.INVOKESPECIAL)); } } mm.newObject(FlexibleVarContext.class); mm.astore(iCtx); mm.aload(iCtx); mm.stringConstant("this"); mm.aload(iThis); mm.invokeVirtual(VarContext.class, void.class, "put", String.class, Object.class); for (int iArg = 0; iArg < nArgs; iArg++) { mm.aload(iCtx); mm.stringConstant(method.args[iArg]); mm.aloadArgWithAutoboxing(iArg); mm.invokeVirtual(VarContext.class, void.class, "put", String.class, Object.class); } mm.getStaticField(classMaker.className(), bodyFieldName, GazelleV_LeftArrowScript.Evaluable.class); mm.aload(iCtx); mm.invokeInterface(GazelleV_LeftArrowScript.Evaluable.class, Object.class, "get", VarContext.class); Type type = method.returnType(); if (type == void.class) mm._return(); else { if (type instanceof Class && isPrimitiveType((Class) type)) { Class c = (Class) type; Class boxed = primitiveToBoxedType(c); mm.checkCast(typeToBCEL(boxed)); mm.invokeVirtual(boxed, c, c + "Value"); mm.returnPrimitive(c); } else { if (type != Object.class) mm.checkCast(typeToBCEL(type)); mm.areturn(); } } mm.done(); } public void fullyCompileMethod(ClassMaker classMaker, GazelleV_LeftArrowScript.FunctionDef method) { MethodMaker mm = new MethodMaker(classMaker, typeToClass(method.returnType()), method.name, repArray(Class.class, Object.class, l(method.args))); var tbc = new LASToByteCode(mm) { public JVMStackCellType compileGetVar(GazelleV_LeftArrowScript.GetVar code) { if (eq(code.var, "this")) { mm.aload(0); return JVMStackCellType.objValue; } int iArg = indexOf(method.args, code.var); if (iArg >= 0) { mm.aload(iArg + 1); return JVMStackCellType.objValue; } return super.compileGetVar(code); } }; tbc.postConversion = stackTop -> mm.convertToObject(stackTop); tbc.compileScript(method.body); mm.areturn(); mm.done(); } public void init(Class c) { for (int iMethod = 0; iMethod < l(methodBodies); iMethod++) { String bodyFieldName = "_body" + iMethod; set(c, bodyFieldName, methodBodies.get(iMethod).body); } setOpt(c, srcRefField(), srcRef()); } public ResolvableLASClass resolvable(ILASClassLoader lasClassLoader) { return new ResolvableLASClass(lasClassLoader, this); } public Object typeToBCEL(LASValueDescriptor descriptor) { return or(descriptor == null ? null : descriptor.javaClass(), Object.class); } public Object typeToBCEL(Type type) { { var __1 = resolvableClassToName(type); if (__1 != null) return __1; } return typeToClass(type); } public void addField(FieldDef field) { fields.add(field); if (field.initializer != null) addToInitializerMethod(field); } public String srcRefField() { return "__srcRef"; } } public interface IPStack extends IStackWithOptions { public void probabilisticOptions(B currentFrame, Iterable>> options); } static public class TradingPosition { final public TradingPosition setCoin(String coin) { return coin(coin); } public TradingPosition coin(String coin) { this.coin = coin; return this; } final public String getCoin() { return coin(); } public String coin() { return coin; } public String coin; final public TradingPosition setIsLong(boolean isLong) { return isLong(isLong); } public TradingPosition isLong(boolean isLong) { this.isLong = isLong; return this; } final public boolean getIsLong() { return isLong(); } public boolean isLong() { return isLong; } public boolean isLong = false; final public TradingPosition setLeverage(int leverage) { return leverage(leverage); } public TradingPosition leverage(int leverage) { this.leverage = leverage; return this; } final public int getLeverage() { return leverage(); } public int leverage() { return leverage; } public int leverage; final public TradingPosition setMarginInvestment(double marginInvestment) { return marginInvestment(marginInvestment); } public TradingPosition marginInvestment(double marginInvestment) { this.marginInvestment = marginInvestment; return this; } final public double getMarginInvestment() { return marginInvestment(); } public double marginInvestment() { return marginInvestment; } public double marginInvestment; final public TradingPosition setMargin(double margin) { return margin(margin); } public TradingPosition margin(double margin) { this.margin = margin; return this; } final public double getMargin() { return margin(); } public double margin() { return margin; } public double margin; final public TradingPosition setAmount(double amount) { return amount(amount); } public TradingPosition amount(double amount) { this.amount = amount; return this; } final public double getAmount() { return amount(); } public double amount() { return amount; } public double amount; final public TradingPosition setOngoing(boolean ongoing) { return ongoing(ongoing); } public TradingPosition ongoing(boolean ongoing) { this.ongoing = ongoing; return this; } final public boolean getOngoing() { return ongoing(); } public boolean ongoing() { return ongoing; } public boolean ongoing = false; final public TradingPosition setOpeningTime(long openingTime) { return openingTime(openingTime); } public TradingPosition openingTime(long openingTime) { this.openingTime = openingTime; return this; } final public long getOpeningTime() { return openingTime(); } public long openingTime() { return openingTime; } public long openingTime; final public TradingPosition setClosingTime(long closingTime) { return closingTime(closingTime); } public TradingPosition closingTime(long closingTime) { this.closingTime = closingTime; return this; } final public long getClosingTime() { return closingTime(); } public long closingTime() { return closingTime; } public long closingTime; final public TradingPosition setOpeningPrice(double openingPrice) { return openingPrice(openingPrice); } public TradingPosition openingPrice(double openingPrice) { this.openingPrice = openingPrice; return this; } final public double getOpeningPrice() { return openingPrice(); } public double openingPrice() { return openingPrice; } public double openingPrice; final public TradingPosition setClosingPrice(double closingPrice) { return closingPrice(closingPrice); } public TradingPosition closingPrice(double closingPrice) { this.closingPrice = closingPrice; return this; } final public double getClosingPrice() { return closingPrice(); } public double closingPrice() { return closingPrice; } public double closingPrice; final public TradingPosition setOpeningFees(double openingFees) { return openingFees(openingFees); } public TradingPosition openingFees(double openingFees) { this.openingFees = openingFees; return this; } final public double getOpeningFees() { return openingFees(); } public double openingFees() { return openingFees; } public double openingFees; final public TradingPosition setClosingFees(double closingFees) { return closingFees(closingFees); } public TradingPosition closingFees(double closingFees) { this.closingFees = closingFees; return this; } final public double getClosingFees() { return closingFees(); } public double closingFees() { return closingFees; } public double closingFees; final public TradingPosition setProfit(double profit) { return profit(profit); } public TradingPosition profit(double profit) { this.profit = profit; return this; } final public double getProfit() { return profit(); } public double profit() { return profit; } public double profit = Double.NaN; final public TradingPosition setCandle(TradingCandle candle) { return candle(candle); } public TradingPosition candle(TradingCandle candle) { this.candle = candle; return this; } final public TradingCandle getCandle() { return candle(); } public TradingCandle candle() { return candle; } public TradingCandle candle; final public TradingPosition setAfterSignal(TradingSignal afterSignal) { return afterSignal(afterSignal); } public TradingPosition afterSignal(TradingSignal afterSignal) { this.afterSignal = afterSignal; return this; } final public TradingSignal getAfterSignal() { return afterSignal(); } public TradingSignal afterSignal() { return afterSignal; } public TradingSignal afterSignal; public double openingFeePercentage() { return doubleRatio(openingFees, margin * leverage); } public double priceDifference() { return closingPrice - openingPrice; } public double leveragedPriceDifference() { return priceDifference() * leverage; } final public double relativeValue() { return expectedPNL(); } public double expectedPNL() { return !isNaN(profit) ? profit : (isLong() ? 1 : -1) * leveragedPriceDifference() * amount; } public boolean isOpen() { return ongoing; } } public interface Juiceable { public double juiceValue(); } static public class JG22Label extends SingleComponentPanel { public G22Label label; public JLabel jLabel; public JTextField tf; transient public Set> onDoneEditing; public JG22Label onDoneEditing(IVF1 f) { onDoneEditing = createOrAddToSyncLinkedHashSet(onDoneEditing, f); return this; } public JG22Label removeDoneEditingListener(IVF1 f) { loadableUtils.utils.remove(onDoneEditing, f); return this; } public void doneEditing(String text) { if (onDoneEditing != null) for (var listener : onDoneEditing) pcallF_typed(listener, text); } public JG22Label() { init(); } public JG22Label(G22Label label) { this.label = label; init(); } public A print(A a) { return loadableUtils.utils.print(a); } public void init() { onDoneEditing(text -> print("Done editing label")); if (label == null) { tf = jTextField(); onEnter(tf, runnableThread(new Runnable() { public void run() { try { doneEditing(getTextTrim(tf)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "doneEditing(getTextTrim(tf))"; } })); setComponent(tf); } else { jLabel = jLabel(label.name); setComponent(jLabel); } } public JComponent focusablePart() { return tf; } } static public class G22ChallengePanel extends HasChangeListeners implements Swingable, IFieldsToList { public G22Challenge challenge; public G22ChallengePanel() { } public G22ChallengePanel(G22Challenge challenge) { this.challenge = challenge; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + challenge + ")"; } public Object[] _fieldsToList() { return new Object[] { challenge }; } final public G22ChallengePanel setRandomSeed(long randomSeed) { return randomSeed(randomSeed); } public G22ChallengePanel randomSeed(long randomSeed) { if (!eq(this.randomSeed, randomSeed)) { this.randomSeed = randomSeed; change(); } return this; } final public long getRandomSeed() { return randomSeed(); } public long randomSeed() { return randomSeed; } public long randomSeed = 1; transient public DynamicHStack imagesPanel; transient public List entries = syncL(); transient public JComponent imagesSection; transient public GazelleV_LeftArrowScript.Script parsedScript; final public G22ChallengePanel setSolutionTypes(Set solutionTypes) { return solutionTypes(solutionTypes); } public G22ChallengePanel solutionTypes(Set solutionTypes) { if (!eq(this.solutionTypes, solutionTypes)) { this.solutionTypes = solutionTypes; change(); } return this; } final public Set getSolutionTypes() { return solutionTypes(); } public Set solutionTypes() { return solutionTypes; } public Set solutionTypes = syncSet(); transient public JButton btnShowSolutions; transient public G22LAScriptIDE recognizerIDE; final public G22ChallengePanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22ChallengePanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; final public G22ChallengePanel setAutoRunChallenge(boolean autoRunChallenge) { return autoRunChallenge(autoRunChallenge); } public G22ChallengePanel autoRunChallenge(boolean autoRunChallenge) { this.autoRunChallenge = autoRunChallenge; return this; } final public boolean getAutoRunChallenge() { return autoRunChallenge(); } public boolean autoRunChallenge() { return autoRunChallenge; } public boolean autoRunChallenge = false; final public G22ChallengePanel setTimeoutToMakeAnImage(double timeoutToMakeAnImage) { return timeoutToMakeAnImage(timeoutToMakeAnImage); } public G22ChallengePanel timeoutToMakeAnImage(double timeoutToMakeAnImage) { this.timeoutToMakeAnImage = timeoutToMakeAnImage; return this; } final public double getTimeoutToMakeAnImage() { return timeoutToMakeAnImage(); } public double timeoutToMakeAnImage() { return timeoutToMakeAnImage; } public double timeoutToMakeAnImage = 10.0; final public G22ChallengePanel setTimeoutToRecognizeAnImage(double timeoutToRecognizeAnImage) { return timeoutToRecognizeAnImage(timeoutToRecognizeAnImage); } public G22ChallengePanel timeoutToRecognizeAnImage(double timeoutToRecognizeAnImage) { this.timeoutToRecognizeAnImage = timeoutToRecognizeAnImage; return this; } final public double getTimeoutToRecognizeAnImage() { return timeoutToRecognizeAnImage(); } public double timeoutToRecognizeAnImage() { return timeoutToRecognizeAnImage; } public double timeoutToRecognizeAnImage = 10.0; final public G22ChallengePanel setImagesToPaint(int imagesToPaint) { return imagesToPaint(imagesToPaint); } public G22ChallengePanel imagesToPaint(int imagesToPaint) { this.imagesToPaint = imagesToPaint; return this; } final public int getImagesToPaint() { return imagesToPaint(); } public int imagesToPaint() { return imagesToPaint; } public int imagesToPaint = 3; final public G22ChallengePanel setInterval(int interval) { return interval(interval); } public G22ChallengePanel interval(int interval) { this.interval = interval; return this; } final public int getInterval() { return interval(); } public int interval() { return interval; } public int interval = 100; final public G22ChallengePanel setImageDisplaySize(int imageDisplaySize) { return imageDisplaySize(imageDisplaySize); } public G22ChallengePanel imageDisplaySize(int imageDisplaySize) { this.imageDisplaySize = imageDisplaySize; return this; } final public int getImageDisplaySize() { return imageDisplaySize(); } public int imageDisplaySize() { return imageDisplaySize; } public int imageDisplaySize = 100; final public G22ChallengePanel setImageBorderColor1(Color imageBorderColor1) { return imageBorderColor1(imageBorderColor1); } public G22ChallengePanel imageBorderColor1(Color imageBorderColor1) { this.imageBorderColor1 = imageBorderColor1; return this; } final public Color getImageBorderColor1() { return imageBorderColor1(); } public Color imageBorderColor1() { return imageBorderColor1; } public Color imageBorderColor1 = Color.green; final public G22ChallengePanel setImageBorderColor2(Color imageBorderColor2) { return imageBorderColor2(imageBorderColor2); } public G22ChallengePanel imageBorderColor2(Color imageBorderColor2) { this.imageBorderColor2 = imageBorderColor2; return this; } final public Color getImageBorderColor2() { return imageBorderColor2(); } public Color imageBorderColor2() { return imageBorderColor2; } public Color imageBorderColor2 = Color.red; final public G22ChallengePanel setImageBorderSize(int imageBorderSize) { return imageBorderSize(imageBorderSize); } public G22ChallengePanel imageBorderSize(int imageBorderSize) { this.imageBorderSize = imageBorderSize; return this; } final public int getImageBorderSize() { return imageBorderSize(); } public int imageBorderSize() { return imageBorderSize; } public int imageBorderSize = 1; public void init() { recognizerIDE = new G22LAScriptIDE(g22utils); recognizerIDE.modifyIDE = ide -> { ide.runScript = () -> { var compileResult = ide.freshCompileResult(); var script = compileResult.parsedScript; if (script == null) return; var bg = g22utils.backgroundProcessesUI(); AutoCloseable __1 = bg == null ? null : bg.tempAdd("Run recognizer on " + challenge); try { FlexibleVarContext ctx = new FlexibleVarContext(); try { List results = syncL(); long time = sysNow(); for (Entry entry : filter(entries, e -> e.image != null)) { ctx.put("image", entry.image); var result = okOrError(() -> ide.callCompiledObjectWithTimeout(timeoutToRecognizeAnImage, script, ctx)); results.add(result); entry.computerResult(result); } time = sysNow() - time; ide.showScriptResult(OKOrError.ok("Got " + nResults(results) + " in " + formatSeconds(time, 3) + " s")); } catch (Throwable e) { printStackTrace(e); ide.showScriptResult(OKOrError.error(e)); } } finally { _close(__1); } }; }; } public JComponent visualize() { if (recognizerIDE == null) init(); imagesPanel = (DynamicHStack) dynamicHStack().spacing(20); awtCalcEvery(imagesPanel, interval, new Runnable() { public void run() { try { _paintAnImage(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_paintAnImage();"; } }); return withCenteredBoldTitle("Challenge: " + challenge, withTopMargin(jvsplit(northCenterAndSouthWithMargin(centerAndEastWithMargin(centeredLiveValueLabel(liveValue_hasChangeListeners(this, () -> "Looking for: " + solutionTypeDesc())), swing(() -> new JPopDownButton(menu -> menu.add(jMenuItem("Random seed " + n2(randomSeed)))))), imagesSection = jCenteredRaisedSection("Images", jBorderlessHigherScrollPane(jfullcenter(imagesPanel))), withBottomMargin(jCenteredLine(btnShowSolutions = jbutton("Show solutions", () -> showSolutions())))), recognizerIDE.visualize()))); } public void _paintAnImage() { if (!autoRunChallenge) return; if (l(entries) >= imagesToPaint) return; int index = l(entries) + 1; Entry entry = new Entry(index, (int) (randomSeed + index - 1)); entries.add(entry); try { if (parsedScript == null) { var parser = g22utils.leftArrowParser(); var cleared = challenge.clearedForAutoRun(); parsedScript = parser.parse(cleared == null ? null : cleared.get()); } FlexibleVarContext ctx = new FlexibleVarContext(); var returnedObject = evalWithTimeoutOrTypedException(timeoutToMakeAnImage, () -> { AutoCloseable __2 = tempSetRandomSeed((int) entry.seed); try { return parsedScript.get(ctx); } finally { _close(__2); } }); if (returnedObject == null) returnedObject = ctx.get("image"); if (returnedObject == null) returnedObject = ctx.get("img"); if (returnedObject instanceof MakesBufferedImage || returnedObject instanceof Image) returnedObject = toBufferedImage(returnedObject); if (returnedObject instanceof BufferedImage) { entry.solution(ctx.get("solution")); updateSolutionType(entry.solution); addImage(entry, ((BufferedImage) returnedObject)); } else if (returnedObject == null) addImage(entry, null, jcenteredlabel("No image")); else addImage(entry, null, jcenteredlabel("Not an image: " + shortClassName(returnedObject))); } catch (Throwable e) { printStackTrace(e); entry.error(e); addImage(entry, null, jSmallErrorView(e)); } finally { entry.calculating(false); } } public void addImage(Entry entry, BufferedImage image, JComponent component) { entry.image(image).component(component); addAndRevalidate(imagesPanel, component); setSectionTitle(imagesSection, firstToUpper(nImages(entries)) + " calculated"); } public void addImage(Entry entry, BufferedImage image) { entry.image(image); addImage(entry, image, new EntryComponent(entry).visualize()); } public class EntryComponent implements Swingable, IFieldsToList { public Entry entry; public EntryComponent() { } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + entry + ")"; } public Object[] _fieldsToList() { return new Object[] { entry }; } public EntryComponent(Entry entry) { this.entry = entry; entry.entryComponent(this); } public SingleComponentPanel scpSolution = singleComponentPanel(); public SingleComponentPanel scpComputerResult = singleComponentPanel(); public SingleComponentPanel scpCheckmark = singleComponentPanel(); public JComponent visualize() { var image = entry.image; double scale = calcFitScale(image, imageDisplaySize); var image2 = scaleImageWithOp(image, scale, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); for (var color : ll(imageBorderColor1, imageBorderColor2)) image2 = addBorderToImage(image2, color, imageBorderSize); String toolTip = "Image " + n2(entry.index) + " of " + challenge + " (seed " + n2(entry.seed) + ", " + image.getWidth() + "*" + image.getHeight() + " px)"; JButton b = withToolTip(toolTip, jimageButton(image2)); setMargin(10, b); return centerAndSouthWithMargin(b, vstackWithSpacing(scpCheckmark, scpSolution, scpComputerResult)); } public JComponent answerToComponent(Object answer) { JComponent c; try { c = jCenteredLabel(shorten(g22utils.stringify(answer))); } catch (Throwable e) { c = jSmallErrorView(e); } return jMaxWidth(imageDisplaySize + 20, c); } public void showSolution() { scpSolution.set(withCenteredTitle("Solution", answerToComponent(entry.solution))); } public void computerResult(OKOrError result) { scpComputerResult.set(withCenteredTitle("Computer Result", result.isOK() ? answerToComponent(result) : jSmallErrorView(result.error()))); scpCheckmark.set(entry.computerIsCorrect() ? jImage_scaledToHeight(32, checkmarkIconID(), "Computer is correct!!") : null); } } public class Entry { public int index; public long seed; final public Entry setImage(BufferedImage image) { return image(image); } public Entry image(BufferedImage image) { this.image = image; return this; } final public BufferedImage getImage() { return image(); } public BufferedImage image() { return image; } public BufferedImage image; final public Entry setError(Throwable error) { return error(error); } public Entry error(Throwable error) { this.error = error; return this; } final public Throwable getError() { return error(); } public Throwable error() { return error; } public Throwable error; final public Entry setSolution(Object solution) { return solution(solution); } public Entry solution(Object solution) { this.solution = solution; return this; } final public Object getSolution() { return solution(); } public Object solution() { return solution; } public Object solution; public OKOrError computerResult; final public Entry setCalculating(boolean calculating) { return calculating(calculating); } public Entry calculating(boolean calculating) { this.calculating = calculating; return this; } final public boolean getCalculating() { return calculating(); } public boolean calculating() { return calculating; } public boolean calculating = true; final public Entry setComponent(JComponent component) { return component(component); } public Entry component(JComponent component) { this.component = component; return this; } final public JComponent getComponent() { return component(); } public JComponent component() { return component; } public JComponent component; final public Entry setEntryComponent(EntryComponent entryComponent) { return entryComponent(entryComponent); } public Entry entryComponent(EntryComponent entryComponent) { this.entryComponent = entryComponent; return this; } final public EntryComponent getEntryComponent() { return entryComponent(); } public EntryComponent entryComponent() { return entryComponent; } public EntryComponent entryComponent; final public Entry setComputerIsCorrect(boolean computerIsCorrect) { return computerIsCorrect(computerIsCorrect); } public Entry computerIsCorrect(boolean computerIsCorrect) { this.computerIsCorrect = computerIsCorrect; return this; } final public boolean getComputerIsCorrect() { return computerIsCorrect(); } public boolean computerIsCorrect() { return computerIsCorrect; } public boolean computerIsCorrect = false; public Entry(int index, long seed) { this.seed = seed; this.index = index; } public void computerResult(OKOrError result) { this.computerResult = result; computerIsCorrect(result.isOK() && eq(solution, result.get())); { if (entryComponent != null) entryComponent.computerResult(result); } } } public void updateSolutionType(Object solution) { Class c = _getClass(solution); if (solutionTypes.add(c)) change(); } public String solutionTypeDesc() { List types = map(__80 -> solutionTypeDesc(__80), solutionTypes); return textOut_or(types, "Calculating..."); } public String solutionTypeDesc(Class c) { if (c == null) return "no solution given"; if (c == Rect.class) return "a rectangular area in the image"; return aOrAn(shortClassName(c)); } public void showSolutions() { disableButton(btnShowSolutions); for (var e : cloneList(entries)) if (e.entryComponent != null) e.entryComponent.showSolution(); } } static public class G22PixelSplitMasks implements IG22OptimizedMasksHolder { public G22PixelSplitMasks() { } final public G22PixelSplitMasks setSplitPixel(Pt splitPixel) { return splitPixel(splitPixel); } public G22PixelSplitMasks splitPixel(Pt splitPixel) { this.splitPixel = splitPixel; return this; } final public Pt getSplitPixel() { return splitPixel(); } public Pt splitPixel() { return splitPixel; } public Pt splitPixel; final public G22PixelSplitMasks setDarkHolder(IG22MasksHolder darkHolder) { return darkHolder(darkHolder); } public G22PixelSplitMasks darkHolder(IG22MasksHolder darkHolder) { this.darkHolder = darkHolder; return this; } final public IG22MasksHolder getDarkHolder() { return darkHolder(); } public IG22MasksHolder darkHolder() { return darkHolder; } public IG22MasksHolder darkHolder; final public G22PixelSplitMasks setBrightHolder(IG22MasksHolder brightHolder) { return brightHolder(brightHolder); } public G22PixelSplitMasks brightHolder(IG22MasksHolder brightHolder) { this.brightHolder = brightHolder; return this; } final public IG22MasksHolder getBrightHolder() { return brightHolder(); } public IG22MasksHolder brightHolder() { return brightHolder; } public IG22MasksHolder brightHolder; final public G22PixelSplitMasks setBias(double bias) { return bias(bias); } public G22PixelSplitMasks bias(double bias) { this.bias = bias; return this; } final public double getBias() { return bias(); } public double bias() { return bias; } public double bias = 0.9; public List> masks() { return new ConcatOnDemandList(darkHolder.masks(), brightHolder.masks()); } public List> subHolders() { return ll(darkHolder, brightHolder); } public void transformSubHolders(IF1, IG22MasksHolder> f) { darkHolder = f.get(darkHolder); brightHolder = f.get(brightHolder); } @Override public PStackComputable findSimilarMasks(G22FindSimilarMasksTask task) { return new FindSimilarMasks(task); } public class FindSimilarMasks extends PStackComputableWithStep implements IMakeEmptyClone, IFieldsToList { public G22FindSimilarMasksTask task; public FindSimilarMasks() { } public FindSimilarMasks(G22FindSimilarMasksTask task) { this.task = task; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + task + ")"; } public Object[] _fieldsToList() { return new Object[] { task }; } public boolean brightBranch = false; public FindSimilarMasks makeEmptyClone() { return new FindSimilarMasks(); } public void step(IPStack stack) { if (task.ended()) { stack._return(); return; } if (step == 0) { ++step; boolean bright = isMaskBright(task.queryImage); if (task.verbose()) printVars("step 0", "splitPixel", splitPixel, "bright", bright); stack.probabilisticOptions(this, ll(withProbability(1.0, self -> self.brightBranch = bright), withProbability(1 - bias, self -> self.brightBranch = !bright))); } else { if (task.verbose()) printVars("step 1", "splitPixel", splitPixel, "brightBranch", brightBranch); IG22MasksHolder branch = brightBranch ? brightHolder : darkHolder; stack.tailCall(branch.findSimilarMasks(task)); } } } public boolean isMaskBright(Image2B maskImage) { return maskImage.getBoolPixel(splitPixel); } public IG22MasksHolder cloneTreeWithLabelTransform(IF1 f) { return new G22PixelSplitMasks().splitPixel(splitPixel).darkHolder(darkHolder.cloneTreeWithLabelTransform(f)).brightHolder(brightHolder.cloneTreeWithLabelTransform(f)); } final public G22PixelSplitMasks setMaskSize(WidthAndHeight maskSize) { return maskSize(maskSize); } public G22PixelSplitMasks maskSize(WidthAndHeight maskSize) { this.maskSize = maskSize; return this; } final public WidthAndHeight getMaskSize() { return maskSize(); } public WidthAndHeight maskSize() { return maskSize; } public WidthAndHeight maskSize; { maskSize(g22defaultMaskSideLength()); } public G22PixelSplitMasks maskSize(int size) { return maskSize(widthAndHeight(size)); } public Image2B regionToMaskImage(IImageRegion region) { return g22standardRegionToMaskImage(region, maskSize()); } public List maskImages() { return map(masks(), mask -> mask.image()); } public BufferedImage masksSquare() { return mergeBufferedImagesAsSquare(allToBufferedImage(maskImages())); } public PatchworkImage> masksPatchworkSquare() { return patchworkImagesAsSquare(map(masks(), mask -> pair(toBufferedImage(mask.image()), mask))); } public String toString() { return renderVars(shortClassName(this), "maskSize", maskSize, "masks", n2(masks())); } public G22GhostImage ghost_cache; public G22GhostImage ghost() { if (ghost_cache == null) ghost_cache = ghost_load(); return ghost_cache; } public G22GhostImage ghost_load() { return new G22GhostImage(maskImages()); } public Double certainty_cache; public double certainty() { if (certainty_cache == null) certainty_cache = certainty_load(); return certainty_cache; } public double certainty_load() { return ghost().certainty(); } } abstract static public class PStackComputable implements VStack.Computable { public double probability = 1; } static public class HashedByteArray implements Comparable { public byte[] data; public int hashCode; public HashedByteArray() { } public 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 int compareTo(HashedByteArray a) { return Arrays.compareUnsigned(data, a.data); } public String toString() { return bytesToHex(data); } } static public class PriceDigitizer2 implements IFieldsToList { public PriceCells cells; public PriceDigitizer2() { } public PriceDigitizer2(PriceCells cells) { this.cells = cells; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + cells + ")"; } public Object[] _fieldsToList() { return new Object[] { cells }; } final public PriceDigitizer2 setCellNumber(int cellNumber) { return cellNumber(cellNumber); } public PriceDigitizer2 cellNumber(int cellNumber) { this.cellNumber = cellNumber; return this; } final public int getCellNumber() { return cellNumber(); } public int cellNumber() { return cellNumber; } public int cellNumber = Integer.MIN_VALUE; final public PriceDigitizer2 setLastCellNumber(int lastCellNumber) { return lastCellNumber(lastCellNumber); } public PriceDigitizer2 lastCellNumber(int lastCellNumber) { this.lastCellNumber = lastCellNumber; return this; } final public int getLastCellNumber() { return lastCellNumber(); } public int lastCellNumber() { return lastCellNumber; } public int lastCellNumber = Integer.MIN_VALUE; final public PriceDigitizer2 setVerbose(boolean verbose) { return verbose(verbose); } public PriceDigitizer2 verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; final public PriceDigitizer2 setUpDownSequence(UpDownSequence upDownSequence) { return upDownSequence(upDownSequence); } public PriceDigitizer2 upDownSequence(UpDownSequence upDownSequence) { this.upDownSequence = upDownSequence; return this; } final public UpDownSequence getUpDownSequence() { return upDownSequence(); } public UpDownSequence upDownSequence() { return upDownSequence; } public UpDownSequence upDownSequence = new UpDownSequence(); public double digitize(double price) { double cn = cells.toCellNumber(price); if (cellNumber == Integer.MIN_VALUE) { cellNumber = lastCellNumber = iround(cn); } else { lastCellNumber = cellNumber; cellNumber = iroundTowardsWithOutwardEpsilon(cn, cellNumber, epsilon()); if (cellNumber > lastCellNumber) { if (upDownSequence != null) upDownSequence.addUp(); } else if (cellNumber < lastCellNumber) { if (upDownSequence != null) upDownSequence.addDown(); } } return digitizedPrice(); } public double epsilon() { return 1e-4; } public double digitizedPrice() { return cells.fromCellNumber(cellNumber); } public double lastDigitizedPrice() { return cells.fromCellNumber(lastCellNumber); } public double digitizeIndividually(double price) { double cn = cells.toCellNumber(price); return cells.fromCellNumber(round(cn)); } public PriceCells priceCells() { return cells; } public void swapPriceCells(PriceCells newPriceCells) { cells = newPriceCells; } } static public class CompactHashSet extends java.util.AbstractSet { final static public int INITIAL_SIZE = 0; final static public int FIRST_INCREMENT = 3; public final static double LOAD_FACTOR = 0.75; final static public Object nullObject = new Object(); final static public Object deletedObject = new Object(); public int elements; public int freecells; public A[] objects; public int modCount; public CompactHashSet() { this(INITIAL_SIZE); } public CompactHashSet(int size) { objects = (A[]) (size == 0 ? emptyObjectArray() : new Object[size]); elements = 0; freecells = objects.length; modCount = 0; } public CompactHashSet(Collection c) { this(c.size()); addAll(c); } @Override public Iterator iterator() { return new CompactHashIterator(); } @Override public int size() { return elements; } @Override public boolean isEmpty() { return elements == 0; } @Override public boolean contains(Object o) { return find(o) != null; } synchronized public A find(Object o) { if (objects.length == 0) return null; if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } return objects[index]; } public boolean removeIfSame(Object o) { A value = find(o); if (value == o) { remove(value); return true; } return false; } @Override synchronized public boolean add(Object o) { if (objects.length == 0) rehash(FIRST_INCREMENT); if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; int deletedix = -1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { if (objects[index] == deletedObject) deletedix = index; index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] == null) { if (deletedix != -1) index = deletedix; else freecells--; modCount++; elements++; objects[index] = (A) o; if (1 - (freecells / (double) objects.length) > LOAD_FACTOR) rehash(); return true; } else return false; } @Override synchronized public boolean remove(Object o) { if (objects.length == 0) return false; if (o == null) o = nullObject; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(objects[index].hashCode() == hash && objects[index].equals(o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] != null) { objects[index] = (A) deletedObject; modCount++; elements--; return true; } else return false; } @Override synchronized public void clear() { elements = 0; for (int ix = 0; ix < objects.length; ix++) objects[ix] = null; freecells = objects.length; modCount++; } @Override synchronized public Object[] toArray() { Object[] result = new Object[elements]; Object[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) result[pos++] = null; else result[pos++] = objects[i]; } return result; } @Override synchronized public T[] toArray(T[] a) { int size = elements; if (a.length < size) a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); A[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) a[pos++] = null; else a[pos++] = (T) objects[i]; } return a; } public void rehash() { int garbagecells = objects.length - (elements + freecells); if (garbagecells / (double) objects.length > 0.05) rehash(objects.length); else rehash(objects.length * 2 + 1); } public void rehash(int newCapacity) { int oldCapacity = objects.length; @SuppressWarnings("unchecked") A[] newObjects = (A[]) new Object[newCapacity]; for (int ix = 0; ix < oldCapacity; ix++) { Object o = objects[ix]; if (o == null || o == deletedObject) continue; int hash = o.hashCode(); int index = (hash & 0x7FFFFFFF) % newCapacity; int offset = 1; while (newObjects[index] != null) { index = ((index + offset) & 0x7FFFFFFF) % newCapacity; offset = offset * 2 + 1; if (offset == -1) offset = 2; } newObjects[index] = (A) o; } objects = newObjects; freecells = objects.length - elements; } public class CompactHashIterator implements Iterator { public int index; public int lastReturned = -1; public int expectedModCount; @SuppressWarnings("empty-statement") public CompactHashIterator() { synchronized (CompactHashSet.this) { for (index = 0; index < objects.length && (objects[index] == null || objects[index] == deletedObject); index++) ; expectedModCount = modCount; } } @Override public boolean hasNext() { synchronized (CompactHashSet.this) { return index < objects.length; } } @SuppressWarnings("empty-statement") @Override public T next() { synchronized (CompactHashSet.this) { int length = objects.length; if (index >= length) { lastReturned = -2; throw new NoSuchElementException(); } lastReturned = index; for (index += 1; index < length && (objects[index] == null || objects[index] == deletedObject); index++) ; if (objects[lastReturned] == nullObject) return null; else return (T) objects[lastReturned]; } } @Override public void remove() { synchronized (CompactHashSet.this) { if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (lastReturned == -1 || lastReturned == -2) throw new IllegalStateException(); if (objects[lastReturned] != null && objects[lastReturned] != deletedObject) { objects[lastReturned] = (A) deletedObject; elements--; modCount++; expectedModCount = modCount; } } } } synchronized public int capacity() { return objects.length; } synchronized public boolean shrinkToFactor(double factor) { if (factor > LOAD_FACTOR) throw fail("Shrink factor must be equal to or smaller than load factor: " + factor + " / " + LOAD_FACTOR); int newCapacity = max(INITIAL_SIZE, iround(size() / factor)); if (newCapacity >= capacity()) return false; rehash(newCapacity); return true; } } abstract static public class DifferentialRegionsMaker implements Runnable, IImageRegions, IFieldsToList { public Img image; public DifferentialRegionsMaker() { } public DifferentialRegionsMaker(Img image) { this.image = image; } public Object[] _fieldsToList() { return new Object[] { image }; } public int w, h, runner; final public int getSize() { return size(); } public int size() { return size; } public int size; public IntBuffer stack = new IntBuffer(); final public int[] getRegionMatrix() { return regionMatrix(); } public int[] regionMatrix() { return regionMatrix; } public int[] regionMatrix; public IntBuffer regionPixels = new IntBuffer(); final public DifferentialRegionsMaker setWithDiagonals(boolean withDiagonals) { return withDiagonals(withDiagonals); } public DifferentialRegionsMaker withDiagonals(boolean withDiagonals) { this.withDiagonals = withDiagonals; return this; } final public boolean getWithDiagonals() { return withDiagonals(); } public boolean withDiagonals() { return withDiagonals; } public boolean withDiagonals = false; final public DifferentialRegionsMaker setTolerance(double tolerance) { return tolerance(tolerance); } public DifferentialRegionsMaker tolerance(double tolerance) { this.tolerance = tolerance; return this; } final public double getTolerance() { return tolerance(); } public double tolerance() { return tolerance; } public double tolerance = 0.05; public IntBuffer regionFirstPixel = new IntBuffer(); public IntBuffer regionSize = new IntBuffer(); public IntBuffer regionBounds = new IntBuffer(); public List regionsBySize = new ArrayList(); public int regionCounter; public boolean verbose = false; public double regionStep = .1; public int x(int pos) { return pos % w; } public int y(int pos) { return pos / w; } public int pos(int x, int y) { return y * w + x; } public Pt pt(int pos) { return new Pt(x(pos), y(pos)); } public boolean validPos(int x, int y) { return x >= 0 && y >= 0 && x < w && y < h; } abstract public int getRGB(int pos); public boolean similarPixels(int pos1, int pos2) { int col1 = getRGB(pos1); int col2 = getRGB(pos2); return rgbDiff(col1, col2) <= tolerance; } public void run() { try { if (regionMatrix != null) return; if (withDiagonals) throw fail("Can't handle diagonals yet"); w = image.getWidth(); h = image.getHeight(); size = w * h; regionMatrix = new int[size]; { if (regionFirstPixel != null) regionFirstPixel.add(0); } { if (regionSize != null) regionSize.add(0); } { if (regionPixels != null) regionPixels.setSize(size); } while (runner < size) { if (regionMatrix[runner] != 0) { ++runner; continue; } makeRegion_fast(); } } catch (Exception __e) { throw rethrow(__e); } } public void makeRegion_fast() { int region = ++regionCounter; { if (regionFirstPixel != null) regionFirstPixel.add(regionPixels != null ? l(regionPixels) : runner); } stack.add(runner); int rsize = 0, x1 = w, y1 = h, x2 = 0, y2 = 0; while (nempty(stack)) { int pos = stack.popLast(); if (regionMatrix[pos] != 0) continue; int x = x(pos), y = y(pos); int lineStart = pos - x; int xLeft = x; while (xLeft > 0 && addable(lineStart + xLeft - 1, -1)) --xLeft; int xRight = x + 1; while (xRight < w && addable(lineStart + xRight, 1)) ++xRight; for (x = xLeft; x < xRight; x++) { regionMatrix[lineStart + x] = region; { if (regionPixels != null) regionPixels.add(lineStart + x); } } rsize += xRight - xLeft; if (xLeft < x1) x1 = xLeft; if (xRight - 1 > x2) x2 = xRight - 1; if (y < y1) y1 = y; if (y > y2) y2 = y; int xLeft2 = withDiagonals ? max(0, xLeft - 1) : xLeft; int xRight2 = withDiagonals ? min(w, xRight + 1) : xRight; if (y > 0) addStreaks(lineStart - w, xLeft2, xRight2, -w); if (y < h - 1) addStreaks(lineStart + w, xLeft2, xRight2, w); } { if (regionSize != null) regionSize.add(rsize); } { if (regionBounds != null) regionBounds.addAll(x1, y1, x2 + 1, y2 + 1); } if (regionsBySize != null) { int iBucket = dualLog(rsize); var buffer = listGetOrCreate(regionsBySize, iBucket, () -> new IntBuffer()); buffer.add(region); } } public boolean addable(int pos, int lastDirection) { if (regionMatrix[pos] != 0) return false; if (!similarPixels(pos, pos - lastDirection)) return false; return true; } public boolean addIfAddable(int pos, int lastDirection) { if (!addable(pos, lastDirection)) return false; stack.add(pos); return true; } public void addStreaks(int lineStart, int xLeft, int xRight, int lastDirection) { int x = xLeft; while (x < xRight) { if (addIfAddable(lineStart + x, lastDirection)) while (x + 1 < xRight && addable(lineStart + x + 1, 1) && addable(lineStart + x + 1, lastDirection)) ++x; ++x; } } public IBWImage regionsImage() { return iBWImageFromFunction((x, y) -> { var region = regionMatrix[pos(x, y)]; return ((region - 1) * regionStep) % (1.0 + regionStep - 0.0001); }, w, h); } final public int nRegions() { return regionCount(); } public int regionCount() { return regionCounter; } abstract public class RegionIterator { public int pos; abstract public boolean next(); public int pos() { return pos; } public int x() { return DifferentialRegionsMaker.this.x(pos); } public int y() { return DifferentialRegionsMaker.this.y(pos); } public int[] pixelsAsIntArray() { throw todo(); } } public class FloodRegionIterator extends RegionIterator { public int region; public IntBuffer stack = new IntBuffer(); public BitSet seen = new BitSet(size); public FloodRegionIterator(int region) { this.region = region; int pos = regionFirstPixel.get(region); printVars("region", region, "pos", pos); seen.set(pos); stack.add(pos); } public boolean next() { if (empty(stack)) return false; pos = stack.popLast(); int x = x(), y = y(); if (x > 0) tryPosition(pos - 1); if (x < w - 1) tryPosition(pos + 1); if (y > 0) tryPosition(pos - w); if (y < h - 1) tryPosition(pos + w); return true; } private void tryPosition(int p) { if (!seen.get(p) && regionMatrix[p] == region) { seen.set(p); stack.add(p); } } } public class CachedRegionIterator extends RegionIterator { public int i, to; public CachedRegionIterator(int region) { i = regionFirstPixel.get(region); to = region + 1 < l(regionFirstPixel) ? regionFirstPixel.get(region + 1) : l(regionPixels); } public boolean next() { if (i >= to) return false; pos = regionPixels.get(i++); return true; } public int[] pixelsAsIntArray() { return regionPixels.subArray(i, to); } } public int regionSize(int iRegion) { return regionSize.get(iRegion); } final public Pt firstPixel(int iRegion) { return samplePixel(iRegion); } public Pt samplePixel(int iRegion) { return pt(firstPixelPos(iRegion)); } public int firstPixelPos(int iRegion) { int i = regionFirstPixel.get(iRegion); return regionPixels != null ? regionPixels.get(i) : i; } public boolean inRegion(int iRegion, int x, int y) { return validPos(x, y) && regionMatrix[pos(x, y)] == iRegion; } public Rect regionBounds(int iRegion) { return rectFromPoints(regionBounds.get((iRegion - 1) * 4), regionBounds.get((iRegion - 1) * 4 + 1), regionBounds.get((iRegion - 1) * 4 + 2), regionBounds.get((iRegion - 1) * 4 + 3)); } public int regionAt(Pt p) { return regionAt(p.x, p.y); } public int regionAt(int x, int y) { return !validPos(x, y) ? 0 : regionMatrix[pos(x, y)]; } public int regionAt(int pos) { return regionMatrix[pos]; } public RegionIterator regionIterator(int iRegion) { return regionPixels != null ? new CachedRegionIterator(iRegion) : new FloodRegionIterator(iRegion); } public List regionPixels(int iRegion) { var it = regionIterator(iRegion); List l = new ArrayList(); while (it.next()) l.add(new Pt(it.x(), it.y())); return l; } public void collectFirstPixels() { } public void collectBounds() { } public Matrix regionBitMatrix(int iRegion) { return new AbstractMatrix(w, h) { public Boolean get(int x, int y) { return inRegion(iRegion, x, y); } }; } public void markRegionInPixelArray(int[] pixels, int iRegion, int rgba) { if (iRegion <= 0) return; for (int i = 0; i < l(pixels); i++) if (regionAt(i) == iRegion) pixels[i] = rgba; } public List regionIndices() { return virtualCountList(1, nRegions() + 1); } public IterableIterator regionsRoughlyByDecreasingSize() { return nestedIterator(countIterator_inclusive_backwards(regionsBySize.size() - 1, 0), iBucket -> iterator(regionsBySize.get(iBucket))); } final public IImageRegion get(int iRegion) { return getRegion(iRegion); } public IImageRegion getRegion(int iRegion) { return new ImageRegion(iRegion); } final public List> get() { return regions(); } public List> regions() { run(); return listFromFunction(i -> getRegion(i + 1), nRegions()); } public class ImageRegion implements IImageRegion, IFieldsToList { public int iRegion; public ImageRegion() { } public ImageRegion(int iRegion) { this.iRegion = iRegion; } public Object[] _fieldsToList() { return new Object[] { iRegion }; } public int hashCode() { return iRegion; } public boolean equals(Object o) { if (!(o instanceof DifferentialRegionsMaker.ImageRegion)) return false; return ((DifferentialRegionsMaker.ImageRegion) o).creator() == creator() && ((DifferentialRegionsMaker.ImageRegion) o).iRegion == iRegion; } public Img image() { return image; } public Object creator() { return DifferentialRegionsMaker.this; } public int indexInCreator() { return iRegion; } public Boolean createdWithDiagonals() { return withDiagonals; } public Rect bounds() { return regionBounds(iRegion); } public int numberOfPixels() { return regionSize(iRegion); } public Pt firstPixel() { return pt(firstPixelPos()); } public int firstPixelPos() { return DifferentialRegionsMaker.this.firstPixelPos(iRegion); } public IterableIterator pixelIterator() { var it = regionIterator(iRegion); return iteratorFromFunction(() -> it.next() ? pt(it.pos()) : null); } public int[] pixelsAsIntArray() { return regionIterator(iRegion).pixelsAsIntArray(); } public boolean contains(int x, int y) { return inRegion(iRegion, x, y); } public Color color() { return toColor(rgbForRegion(this)); } public int firstPixelRGB() { return getRGB(firstPixelPos()); } public String toString() { return renderRecordVars("Region", "brightness", brightness(), "color", color(), "pixels", numberOfPixels(), "bounds", bounds()); } } public RGB rgbForRegion(ImageRegion r) { return new RGB(r.firstPixelRGB()); } public Img image() { return image; } } final static public class CompactIdentityHashSet extends AbstractSet { final static public int INITIAL_SIZE = 3; final static public double LOAD_FACTOR = 0.75; final static public Object nullObject = new Object(); final static public Object deletedObject = new Object(); public int elements; public int freecells; public A[] objects; public int modCount; public CompactIdentityHashSet() { this(INITIAL_SIZE); } public CompactIdentityHashSet(int size) { objects = (A[]) new Object[(size == 0 ? 1 : size)]; elements = 0; freecells = objects.length; modCount = 0; } public CompactIdentityHashSet(Collection c) { this(c.size()); addAll(c); } @Override public Iterator iterator() { return new CompactHashIterator(); } @Override public int size() { return elements; } @Override public boolean isEmpty() { return elements == 0; } @Override public boolean contains(Object o) { return find(o) != null; } synchronized public A find(Object o) { if (o == null) o = nullObject; int hash = elementHashCode(o); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(elementHashCode(objects[index]) == hash && elementEquals(objects[index], o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } return objects[index]; } public boolean removeIfSame(Object o) { A value = find(o); if (value == o) { remove(value); return true; } return false; } @Override synchronized public boolean add(Object o) { if (o == null) o = nullObject; int hash = elementHashCode(o); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; int deletedix = -1; while (objects[index] != null && !(elementHashCode(objects[index]) == hash && elementEquals(objects[index], o))) { if (objects[index] == deletedObject) deletedix = index; index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] == null) { if (deletedix != -1) index = deletedix; else freecells--; modCount++; elements++; objects[index] = (A) o; if (1 - (freecells / (double) objects.length) > LOAD_FACTOR) rehash(); return true; } else return false; } @Override synchronized public boolean remove(Object o) { if (o == null) o = nullObject; int hash = elementHashCode(o); int index = (hash & 0x7FFFFFFF) % objects.length; int offset = 1; while (objects[index] != null && !(elementHashCode(objects[index]) == hash && elementEquals(objects[index], o))) { index = ((index + offset) & 0x7FFFFFFF) % objects.length; offset = offset * 2 + 1; if (offset == -1) offset = 2; } if (objects[index] != null) { objects[index] = (A) deletedObject; modCount++; elements--; return true; } else return false; } @Override synchronized public void clear() { elements = 0; for (int ix = 0; ix < objects.length; ix++) objects[ix] = null; freecells = objects.length; modCount++; } @Override synchronized public Object[] toArray() { Object[] result = new Object[elements]; Object[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) result[pos++] = null; else result[pos++] = objects[i]; } return result; } @Override synchronized public T[] toArray(T[] a) { int size = elements; if (a.length < size) a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); A[] objects = this.objects; int pos = 0; for (int i = 0; i < objects.length; i++) if (objects[i] != null && objects[i] != deletedObject) { if (objects[i] == nullObject) a[pos++] = null; else a[pos++] = (T) objects[i]; } return a; } public void rehash() { int gargagecells = objects.length - (elements + freecells); if (gargagecells / (double) objects.length > 0.05) rehash(objects.length); else rehash(objects.length * 2 + 1); } public void rehash(int newCapacity) { int oldCapacity = objects.length; @SuppressWarnings("unchecked") A[] newObjects = (A[]) new Object[newCapacity]; for (int ix = 0; ix < oldCapacity; ix++) { Object o = objects[ix]; if (o == null || o == deletedObject) continue; int hash = elementHashCode(o); int index = (hash & 0x7FFFFFFF) % newCapacity; int offset = 1; while (newObjects[index] != null) { index = ((index + offset) & 0x7FFFFFFF) % newCapacity; offset = offset * 2 + 1; if (offset == -1) offset = 2; } newObjects[index] = (A) o; } objects = newObjects; freecells = objects.length - elements; } public class CompactHashIterator implements Iterator { public int index; public int lastReturned = -1; public int expectedModCount; @SuppressWarnings("empty-statement") public CompactHashIterator() { synchronized (CompactIdentityHashSet.this) { for (index = 0; index < objects.length && (objects[index] == null || objects[index] == deletedObject); index++) ; expectedModCount = modCount; } } @Override public boolean hasNext() { synchronized (CompactIdentityHashSet.this) { return index < objects.length; } } @SuppressWarnings("empty-statement") @Override public T next() { synchronized (CompactIdentityHashSet.this) { int length = objects.length; if (index >= length) { lastReturned = -2; throw new NoSuchElementException(); } lastReturned = index; for (index += 1; index < length && (objects[index] == null || objects[index] == deletedObject); index++) ; if (objects[lastReturned] == nullObject) return null; else return (T) objects[lastReturned]; } } @Override public void remove() { synchronized (CompactIdentityHashSet.this) { if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (lastReturned == -1 || lastReturned == -2) throw new IllegalStateException(); if (objects[lastReturned] != null && objects[lastReturned] != deletedObject) { objects[lastReturned] = (A) deletedObject; elements--; modCount++; expectedModCount = modCount; } } } } public int elementHashCode(Object o) { return identityHashCode(o); } public boolean elementEquals(Object a, Object b) { return a == b; } } public enum G22ScriptMode { edit, saved, autoRunnable } static public interface Htmlable { default public String headStuff() { return ""; } public String html(); } static public class Stages2 implements Steppable, Runnable, IFieldsToList { static final public String _fieldOrder = "stages iStage stage timings"; public List stages; public Stages2() { } public Stages2(List stages) { this.stages = stages; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + stages + ")"; } public boolean equals(Object o) { if (!(o instanceof Stages2)) return false; Stages2 __1 = (Stages2) o; return eq(stages, __1.stages); } public int hashCode() { int h = -232873603; h = boostHashCombine(h, _hashCode(stages)); return h; } public Object[] _fieldsToList() { return new Object[] { stages }; } public int iStage; public Stage stage; final public Stages2 setTimings(FunctionTimings timings) { return timings(timings); } public Stages2 timings(FunctionTimings timings) { this.timings = timings; return this; } final public FunctionTimings getTimings() { return timings(); } public FunctionTimings timings() { return timings; } public FunctionTimings timings; { stages = new ArrayList(); } public class Stage implements IFieldsToList { public String name; public Runnable body; public Stage() { } public Stage(String name, Runnable body) { this.body = body; this.name = name; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + name + ", " + body + ")"; } public Object[] _fieldsToList() { return new Object[] { name, body }; } public void run() { try { if (timings != null) timings.dO(name, body); else callF(body); } catch (Exception __e) { throw rethrow(__e); } } } public boolean step() { if (iStage >= l(stages)) return false; var stage = stages.get(iStage++); stage.run(); return true; } public Stage stage(Stage stage) { stages.add(stage); return stage; } public Stage stage(String name, Runnable body) { return stage(new Stage(name, body)); } public void run() { try { stepAll(this); } catch (Exception __e) { throw rethrow(__e); } } public int indexOfStage(Stage stage) { return stages.indexOf(stage); } public void stepUntilStage(Stage stage) { int index = indexOfStage(stage); while (iStage <= index && step()) { } } } static public class SimpleMovingAverage implements IFieldsToList { public int length; public SimpleMovingAverage() { } public SimpleMovingAverage(int length) { this.length = length; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + length + ")"; } public Object[] _fieldsToList() { return new Object[] { length }; } public SimpleMovingAverage length(int length) { this.length = length; return this; } public SimpleCircularBuffer values_cache; public SimpleCircularBuffer values() { if (values_cache == null) values_cache = values_load(); return values_cache; } public SimpleCircularBuffer values_load() { return new SimpleCircularBuffer(length); } public Average avg = new Average(); public double get() { return avg.get(); } public double add(double x) { while (values().size() > max(length - 1, 0)) avg.remove(values().remove()); values().add(x); avg.add(x); return get(); } } abstract static public class PStackComputableWithStep extends PStackComputable { public int step; public final void step(VStack stack, Object subComputationResult) { step((IPStack) stack); } public void step(IPStack stack) { } public String toString() { return shortClassName(this) + " step " + step; } } static public class G22RunSingleAnalyzerPanel implements Swingable, IFieldsToList { public G22Utils g22utils; public BufferedImage image; public G22Analyzer analyzer; public G22RunSingleAnalyzerPanel() { } public G22RunSingleAnalyzerPanel(G22Utils g22utils, BufferedImage image, G22Analyzer analyzer) { this.analyzer = analyzer; this.image = image; this.g22utils = g22utils; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + g22utils + ", " + image + ", " + analyzer + ")"; } public Object[] _fieldsToList() { return new Object[] { g22utils, image, analyzer }; } transient public ReliableSingleThread rst = new ReliableSingleThread(new Runnable() { public void run() { try { _run(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_run();"; } }); transient public SingleComponentPanel scp = singleComponentPanel(); transient public String pleaseSelectMsg = ""; transient public Set> onAnalyzerResult; public G22RunSingleAnalyzerPanel onAnalyzerResult(IVF2 f) { onAnalyzerResult = createOrAddToSyncLinkedHashSet(onAnalyzerResult, f); return this; } public G22RunSingleAnalyzerPanel removeAnalyzerResultListener(IVF2 f) { loadableUtils.utils.remove(onAnalyzerResult, f); return this; } public void analyzerResult(G22Analyzer.CompiledAnalyzer analyzer, Object result) { if (onAnalyzerResult != null) for (var listener : onAnalyzerResult) pcallF_typed(listener, analyzer, result); } transient public Set> onAnalyzerError; public G22RunSingleAnalyzerPanel onAnalyzerError(IVF2 f) { onAnalyzerError = createOrAddToSyncLinkedHashSet(onAnalyzerError, f); return this; } public G22RunSingleAnalyzerPanel removeAnalyzerErrorListener(IVF2 f) { loadableUtils.utils.remove(onAnalyzerError, f); return this; } public void analyzerError(G22Analyzer.CompiledAnalyzer analyzer, Throwable error) { if (onAnalyzerError != null) for (var listener : onAnalyzerError) pcallF_typed(listener, analyzer, error); } public JComponent visualize() { reRun(); return scp; } public void reRun() { rst.trigger(); } public void setImage(BufferedImage image) { this.image = image; reRun(); } public void _run() { if (analyzer == null) { scp.set(jcenteredlabel(pleaseSelectMsg)); return; } if (image == null) { scp.set(jcenteredlabel("No image")); return; } G22Analyzer.CompiledAnalyzer compiled = analyzer.compileForAutoRun(); if (compiled == null) { scp.set(jcenteredlabel(analyzer + " is not cleared for auto-run")); return; } if (compiled.compileError != null) { scp.set(jErrorView(compiled.compileError)); return; } if (scp.isEmpty()) scp.set(jcenteredlabel("Running analyzer...")); try { long time = nanoTime(); Object result = compiled.get(image); time = nanoTime() - time; analyzerResult(compiled, result); var visualizer = new G22JavaObjectVisualizer(g22utils, result).horizontal(true); visualizer.nanos(time); scp.set(visualizer); } catch (Throwable e) { scp.set(jErrorView(e)); analyzerError(compiled, e); } } } static public class G22LAScriptIDE implements Swingable { final public G22LAScriptIDE setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22LAScriptIDE g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } public G22Utils g22utils; final public G22LAScriptIDE setNoScriptSelectedMsg(String noScriptSelectedMsg) { return noScriptSelectedMsg(noScriptSelectedMsg); } public G22LAScriptIDE noScriptSelectedMsg(String noScriptSelectedMsg) { this.noScriptSelectedMsg = noScriptSelectedMsg; return this; } final public String getNoScriptSelectedMsg() { return noScriptSelectedMsg(); } public String noScriptSelectedMsg() { return noScriptSelectedMsg; } public String noScriptSelectedMsg = "Please select or create a script to edit it"; final public A getScript() { return script(); } public A script() { return script; } public A script; transient public SingleComponentPanel scp; transient public JLeftArrowScriptIDE[] ides; transient public JExtendedTabbedPane tabs; transient public JButton btnSave, btnDiscardChanges, btnClearForAutoRun; transient public CollapsibleLeftPanel collapsibleResultPanel; transient public G22ScriptResultPanel resultPanel; transient public Mode lastVisibleMode; abstract public class Mode { public G22ScriptMode modeEnum; public String name; final public boolean getEditable() { return editable(); } public boolean editable() { return editable; } public boolean editable = false; public Mode(G22ScriptMode modeEnum, String name, boolean editable) { this.editable = editable; this.name = name; this.modeEnum = modeEnum; } public IVarWithNotify scriptVar_cache; public IVarWithNotify scriptVar() { if (scriptVar_cache == null) scriptVar_cache = scriptVar_load(); return scriptVar_cache; } abstract public IVarWithNotify scriptVar_load(); public void addButtons(JPanel panel) { } public String toString() { return name; } public String tabName() { return scriptVar().has() ? name : "Not " + firstToLower(name); } } public class ModeClearedForAutoRun extends Mode { public ModeClearedForAutoRun() { super(G22ScriptMode.autoRunnable, "Cleared for auto-run", false); } public IVarWithNotify scriptVar_load() { var var = new VirtualVar(() -> script.codeForAutoRun(), null); addWeakChangeListener(script.varClearedForAutoRun(), var); return var; } public void addButtons(JPanel panel) { panel.add(jbutton("Forget auto-run code", runnableThread(new Runnable() { public void run() { try { forgetAutoRunCode(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "forgetAutoRunCode();"; } }))); } } public class ModeSaved extends Mode { public ModeSaved() { super(G22ScriptMode.saved, "Saved", false); } public IVarWithNotify scriptVar_load() { return getterVarOnly(script.varText()); } public void addButtons(JPanel panel) { panel.add(btnClearForAutoRun = jbutton("Clear for auto-run", runnableThread(new Runnable() { public void run() { try { clearForAutoRun(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "clearForAutoRun();"; } }))); panel.add(jbutton("Forget code", runnableThread(new Runnable() { public void run() { try { forgetSaved(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "forgetSaved();"; } }))); } } public class ModeEdit extends Mode { public ModeEdit() { super(G22ScriptMode.edit, "Edit", true); } public IVarWithNotify scriptVar_load() { var var = new VirtualVar(() -> script.textForEditing(), text -> script.receiveEditingText(text)); addWeakChangeListener(script, var); return var; } public void addButtons(JPanel panel) { panel.add(btnSave = jbutton("Save", runnableThread(new Runnable() { public void run() { try { saveEdit(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveEdit();"; } }))); panel.add(btnDiscardChanges = jbutton("Discard changes", runnableThread(new Runnable() { public void run() { try { discardEdit(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "discardEdit();"; } }))); } } transient public ModeEdit modeEdit = new ModeEdit(); transient public ModeSaved modeSaved = new ModeSaved(); transient public ModeClearedForAutoRun modeClearedForAutoRun = new ModeClearedForAutoRun(); transient public List modes = ll(modeEdit, modeSaved, modeClearedForAutoRun); public G22LAScriptIDE(G22Utils g22utils) { this.g22utils = g22utils; } public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { ides = new JLeftArrowScriptIDE[l(modes)]; if (scp == null) scp = singleComponentPanel(); loadScript(script); return scp; } public void setScript(A script) { if (this.script != script) if (this.script != null) throw fail("Can't set script after initialisation"); else loadScript(script); } public void loadScript(A script) { this.script = script; if (scp == null) return; if (script == null) scp.set(jcenteredlabel(noScriptSelectedMsg())); else { tabs = jExtendedTabs(); resultPanel = new G22ScriptResultPanel(); collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), tabs.visualize()); collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c); for (Pair __0 : iterateWithIndex(modes)) { int i = pairA(__0); Mode mode = pairB(__0); var ide = ides[i] = g22utils.leftArrowIDE(); ide.withResultPanel(false); ide.resultPanel = resultPanel; ide.collapsibleResultPanel = collapsibleResultPanel; ide.wrapSection = c -> wrapEditorSection(mode, c); ide.newCompileResult = () -> script.newCompileResult(); ide.makeParser = () -> script.makeParser(); modifyIDE(ide); var varScript = mode.scriptVar(); ide.lvScript(varWithNotifyToLiveValue(String.class, varScript)); addTab(tabs, str(mode)); mode.addButtons(ide.buttons()); ide.visualize(); ide.setEditable(mode.editable()); varScript.onChangeAndNow(text -> setTab(tabs, i, text == null ? jcenteredlabel("Empty") : wrapIDE(mode, ide))); ide.popDownButton.onFillingMenu(menu -> addMenuItem(menu, "Show History", runnableThread(new Runnable() { public void run() { try { showHistory(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "showHistory();"; } }))); } script.onChangeAndNow(new Runnable() { public void run() { try { for (Pair __1 : iterateWithIndex(modes)) { int i = pairA(__1); Mode mode = pairB(__1); setTabTitle(tabs, i, mode.tabName()); } setEnabled(script.isEditing(), btnSave, btnDiscardChanges); setEnabled(btnClearForAutoRun, script.isSavedDistinctFromAutoRunVersion()); for (var ide : ides) ide.sectionTitle(str(script)); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "for (Pair __1 : iterateWithIndex(modes))\r\n { int i = ..."; } }); onTabSelectedAndNow(tabs, () -> { var mode = visibleMode(); if (lastVisibleMode != null && lastVisibleMode != mode) { var lastIDE = ide(lastVisibleMode); var ide = visibleIDE(); awtLater(0.5, () -> { LineAndColumn lac = caretLineAndCol(lastIDE.textArea()); moveCaretToLineAndCol(ide.textArea(), lac); setEnclosingViewPosition(ide.textArea(), enclosingViewPosition(lastIDE.textArea())); }); } lastVisibleMode = mode; tabs.setComponentBesideTabs(mode != modeEdit ? jfullcenter(withRightMargin(jbutton("Edit script", () -> setMode(modeEdit)))) : null); }); setMode(script.isEditing() ? modeEdit : modeSaved); scp.set(collapsibleResultPanel); } } transient public IF2 wrapEditorSection; public JComponent wrapEditorSection(Mode mode, JComponent editorSection) { return wrapEditorSection != null ? wrapEditorSection.get(mode, editorSection) : wrapEditorSection_base(mode, editorSection); } final public JComponent wrapEditorSection_fallback(IF2 _f, Mode mode, JComponent editorSection) { return _f != null ? _f.get(mode, editorSection) : wrapEditorSection_base(mode, editorSection); } public JComponent wrapEditorSection_base(Mode mode, JComponent editorSection) { return editorSection; } transient public IF2 wrapIDE; public JComponent wrapIDE(Mode mode, JLeftArrowScriptIDE ide) { return wrapIDE != null ? wrapIDE.get(mode, ide) : wrapIDE_base(mode, ide); } final public JComponent wrapIDE_fallback(IF2 _f, Mode mode, JLeftArrowScriptIDE ide) { return _f != null ? _f.get(mode, ide) : wrapIDE_base(mode, ide); } public JComponent wrapIDE_base(Mode mode, JLeftArrowScriptIDE ide) { return ide.visualize(); } transient public Set> onSettingUpIDE; public G22LAScriptIDE onSettingUpIDE(IVF1 f) { onSettingUpIDE = createOrAddToSyncLinkedHashSet(onSettingUpIDE, f); return this; } public G22LAScriptIDE removeSettingUpIDEListener(IVF1 f) { loadableUtils.utils.remove(onSettingUpIDE, f); return this; } public void settingUpIDE(JLeftArrowScriptIDE ide) { if (onSettingUpIDE != null) for (var listener : onSettingUpIDE) pcallF_typed(listener, ide); } transient public IVF1 modifyIDE; public void modifyIDE(JLeftArrowScriptIDE ide) { if (modifyIDE != null) modifyIDE.get(ide); else modifyIDE_base(ide); } final public void modifyIDE_fallback(IVF1 _f, JLeftArrowScriptIDE ide) { if (_f != null) _f.get(ide); else modifyIDE_base(ide); } public void modifyIDE_base(JLeftArrowScriptIDE ide) { ide.showTitle(false); settingUpIDE(ide); } public void saveEdit() { script.completeEdit(); setMode(modeSaved); } public JLeftArrowScriptIDE ide(Mode mode) { if (ides == null) visualize(); return _get(ides, indexOf(modes, mode)); } public RSyntaxTextArea visibleTextArea() { var ide = visibleIDE(); return ide == null ? null : ide.textArea(); } public void setMode(Mode mode) { var caretPos = caretLineAndCol(visibleTextArea()); printVars("setMode", "caretPos", caretPos); selectTab(tabs, indexOf(modes, mode)); var ide = visibleIDE(); printVars("setMode", "ide", ide, "mode", visibleMode()); ide.goToPosition_noFocus(caretPos); if (mode == modeEdit) focus(visibleTextArea()); } public Mode visibleMode() { return _get(modes, indexOfSelectedTab(tabs)); } public JLeftArrowScriptIDE visibleIDE() { return ide(visibleMode()); } public void discardEdit() { setMode(modeSaved); script.discardEdit(); } public void forgetSaved() { script.setTextWithHistory(null); } public void clearForAutoRun() { script.clearForAutoRun(); setMode(modeClearedForAutoRun); } public void forgetAutoRunCode() { script.forgetAutoRunCode(); } private void selfTest_impl() { G22LeftArrowScript script = new G22LeftArrowScript(); setScript((A) script); ide(modeEdit).setText("hello"); assertEqualsVerbose(null, script.text()); assertEqualsVerbose("hello", script.editedText()); saveEdit(); assertEqualsVerbose("hello", script.text()); assertEqualsVerbose(null, script.editedText()); } static public void selfTest(G22Utils g22utils) { new G22LAScriptIDE(g22utils).selfTest_impl(); } public void showHistory() { showText("Edit history of " + script, loadTextFile(script.historyFile())); } public void goToPositionInAllModes(LineAndColumn lac) { for (var ide : ides) { if (ide != null) ide.goToPosition_noFocus(lac); } } } static public class G22ScriptView extends JOnDemandWithReloadButton { public G22LeftArrowScript script; public G22ScriptView(G22LeftArrowScript script) { this.script = script; if (script != null) makeComponent = () -> g22utils().visualizeAutoRunnableScript(script); } public G22Utils g22utils() { return script.g22utils(); } public void makeControls() { super.makeControls(); if (script != null) controls.add(g22utils().editScriptButton(script)); } } public interface IG22LoadedDB { public boolean hidden(); public Concepts concepts(); public JFrame mainWindow(); public G22Utils g22utils(); public void activate(); public G22ProjectActions projectActions(); public void hide(); } static public class G22ChallengeIDE extends G22LAScriptIDE { public G22ChallengeIDE(G22Utils g22utils) { super(g22utils); } public JComponent wrapIDE_base(JLeftArrowScriptIDE ide) { ide.showTitle(false); return jCenteredSection(script + " [Code]", northAndCenterWithMargin(rightAlignedLine(liveValueCheckBox(script.lvUsesRNG(), "Randomized"), jLiveValueComboBox(script.lvType(), G22Challenge.types)), ide.visualize())); } } static public class G22TypeDesc { public String exactClassName; public Set implementedClassNames; } static public class G22POIPanel implements Swingable, IFieldsToList { public G22PointOfInterest poi; public G22POIPanel() { } public G22POIPanel(G22PointOfInterest poi) { this.poi = poi; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + poi + ")"; } public Object[] _fieldsToList() { return new Object[] { poi }; } public G22Utils g22utils; public G22GalleryImage img; public G22DataWrangler wrangler; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { g22utils = g22utils(poi); img = poi.galleryImage(); List parts = new ArrayList(); if (img == null) return jCenteredLabel("Image not found: " + poi.imageMD5); var is1 = g22utils.stdImageSurface(img); g22markPointAnimation(is1, poi.pt); parts.add(jCenteredSection("Original image", g22utils.wrap(is1))); wrangler = poi.wrangler(); wrangler.stepUntilStage(wrangler.regionsStage); var is2 = g22utils.stdImageSurface(wrangler.posterizedImage); g22markPointAnimation(is2, poi.pt); parts.add(jCenteredSection("Blurred & Posterized", g22utils.wrap(is2))); IImageRegion region = poi.regionAroundPoint(wrangler); parts.add(jCenteredSection("Region around point", new G22RegionPanel(region).g22utils(g22utils).originalImage(wrangler.inputImage))); return hgridWithSpacing(map(__81 -> jMinWidth0(__81), parts)); } } static public class SynchronizedLongBufferStoredAsLinearInts implements ILongBuffer { public SynchronizedLongBufferStoredAsLinearInts() { } public int[] data; public int size; public long base, factor; public SynchronizedLongBufferStoredAsLinearInts(long base, long factor) { this.factor = factor; this.base = base; } public SynchronizedLongBufferStoredAsLinearInts(long base, long factor, int size) { this.factor = factor; this.base = base; if (size != 0) data = new int[size]; } public SynchronizedLongBufferStoredAsLinearInts(long base, long factor, Iterable l) { this.factor = factor; this.base = base; if (l instanceof Collection) allocate(((Collection) l).size()); addAll(l); } public synchronized void addRaw(int i) { if (size >= lIntArray(data)) { data = resizeIntArray(data, Math.max(1, toInt(Math.min(maximumSafeArraySize(), lIntArray(data) * 2L)))); if (size >= data.length) throw fail(shortClassName(this) + " too large: " + size); } data[size++] = i; } public synchronized void add(long i) { addRaw(compress(i)); } synchronized public void allocate(int n) { data = resizeIntArray(data, max(n, size())); } public synchronized void addAll(Iterable l) { if (l != null) for (long i : l) add(i); } public synchronized long[] toArray() { if (size == 0) return null; long[] out = new long[size]; for (int i = 0; i < size; i++) out[i] = expand(data[i]); return out; } public synchronized List asVirtualList() { return listFromFunction(__82 -> get(__82), size); } synchronized public void reset() { size = 0; } public void clear() { reset(); } synchronized public int size() { return size; } public synchronized boolean isEmpty() { return size == 0; } public synchronized int getRaw(int idx) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); return data[idx]; } public synchronized long get(int idx) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); return expand(data[idx]); } synchronized public void set(int idx, long value) { if (idx >= size) throw fail("Index out of range: " + idx + "/" + size); data[idx] = compress(value); } public synchronized long popLast() { if (size == 0) throw fail("empty buffer"); return expand(data[--size]); } public synchronized long last() { return expand(data[size - 1]); } synchronized public long nextToLast() { return expand(data[size - 2]); } public String toString() { return squareBracket(joinWithSpace(asVirtualList())); } public synchronized Iterator iterator() { return new IterableIterator() { public int i = 0; public boolean hasNext() { return i < size(); } public Long next() { synchronized (SynchronizedLongBufferStoredAsLinearInts.this) { if (!hasNext()) throw fail("Index out of bounds: " + i); return expand(data[i++]); } } }; } public synchronized void trimToSize() { data = resizeIntArray(data, size); } synchronized public void remove(int idx) { arraycopy(data, idx + 1, data, idx, size - 1 - idx); --size; } public synchronized long poll() { return size == 0 ? -1 : expand(data[--size]); } public long expand(int value) { return base + value * factor; } public int compress(long value) { return toInt(ldiv_round(value - base, factor)); } } final static public class SimpleStack extends RandomAccessAbstractList { public ArrayList l = new ArrayList(); public int peak; public A get(int i) { return l.get(i); } public int size() { return l.size(); } public A set(int i, A a) { return l.set(i, a); } public void add(int i, A a) { l.add(i, a); checkSize(); } public A remove(int i) { A a = l.remove(i); checkSize(); return a; } public void checkSize() { int n = size(); if (n > peak) peak = n; if (n * 2 < peak) { trimToSize(l); peak = n; } } } static public class G22AutoStartPanel implements Swingable, IFieldsToList { public G22Utils g22utils; public G22AutoStartPanel() { } public G22AutoStartPanel(G22Utils g22utils) { this.g22utils = g22utils; } public Object[] _fieldsToList() { return new Object[] { g22utils }; } public G22AutoStarter autoStarter; public JButton btnCancel, btnResume; public JLabel lblStatus1, lblStatus2, lblCurrentScript, lblCtrl; public JPanel stack; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { autoStarter = g22utils.autoStarter(); btnResume = jbutton("Resume", new Runnable() { public void run() { try { resume(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "resume();"; } }); var vis = jCenteredSection("Auto Start", stack = vstack2(centerAndEastWithMargin(btnCancel = jThreadedButton("CANCEL", new Runnable() { public void run() { try { autoStarter.cancel(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "autoStarter.cancel()"; } }), jimageButtonScaledToWidth(16, editImageID(), "Edit auto-run scripts", runnableThread(new Runnable() { public void run() { try { g22utils.projectActions().editScripts(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "g22utils.projectActions().editScripts()"; } }))), lblCtrl = jCenteredLabel(autoStarter.cancelOnCtrl() ? "(Hammer Ctrl to cancel)" : ""), jVerticalStrut(10), lblStatus1 = jCenteredLabel(), lblCurrentScript = jCenteredLabel(), lblStatus2 = jCenteredLabel())); bindListenerToComponent(lblStatus1, autoStarter, new Runnable() { public void run() { try { update(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "update();"; } }); return vis; } public void update() { boolean done = autoStarter.waitedAndDone(); if (done) setText(btnCancel, "Auto-start done"); setEnabled(lblCtrl, autoStarter.ctrlEnabled()); setEnabled(btnCancel, autoStarter.enabled() && !done); setText(lblStatus1, autoStarter.scriptsRunStats()); setText(lblStatus2, done ? "" : autoStarter.status()); setText(lblCurrentScript, autoStarter.currentScriptStats()); addOrRemoveComponent(autoStarter.canResume(), stack, btnResume); } public void resume() { autoStarter.resume(); } } abstract static public class G22AbstractTiler implements Runnable, Steppable, IFieldsToList { public Img image; public G22AbstractTiler() { } public G22AbstractTiler(Img image) { this.image = image; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + image + ")"; } public Object[] _fieldsToList() { return new Object[] { image }; } public int w, h, runner; final public int getSize() { return size(); } public int size() { return size; } public int size; transient public Set> onTileStarted; public G22AbstractTiler onTileStarted(IVF1 f) { onTileStarted = createOrAddToSyncLinkedHashSet(onTileStarted, f); return this; } public G22AbstractTiler removeTileStartedListener(IVF1 f) { loadableUtils.utils.remove(onTileStarted, f); return this; } public void tileStarted(GrowingTile tile) { if (onTileStarted != null) for (var listener : onTileStarted) pcallF_typed(listener, tile); } transient public Set> onTileDone; public G22AbstractTiler onTileDone(IVF1 f) { onTileDone = createOrAddToSyncLinkedHashSet(onTileDone, f); return this; } public G22AbstractTiler removeTileDoneListener(IVF1 f) { loadableUtils.utils.remove(onTileDone, f); return this; } public void tileDone(GrowingTile tile) { if (onTileDone != null) for (var listener : onTileDone) pcallF_typed(listener, tile); } public IndexIterator pointIterator; public IntBuffer stack = new IntBuffer(); public G22Tiling tiling; public int tileCounter; public GrowingTile growingTile; public boolean verbose = false; abstract public int getColor(int pos); public int x(int pos) { return pos % w; } public int y(int pos) { return pos / w; } public int pos(int x, int y) { return y * w + x; } public Pt pt(int pos) { return new Pt(x(pos), y(pos)); } public boolean validPos(int x, int y) { return x >= 0 && y >= 0 && x < w && y < h; } public int getColor(int x, int y) { return getColor(pos(x, y)); } public class GrowingTile implements Steppable { public G22Tiling.Tile tile; public int color; public boolean growingN = true; public boolean growingE = true; public boolean growingS = true; public boolean growingW = true; public GrowingTile(int pos) { int x = x(pos), y = y(pos); color = getColor(x, y); int iTile = tileCounter++; tile = tiling.new Tile(iTile, color, rect(x, y, 1, 1)); tiling.tiles.add(tile); } public void finish() { Rect r = tile.position(); int rx = r.x, ry = r.y, rw = r.w, rh = r.h; int[] matrix = tiling.tileMatrix; int iTile = tile.index; for (int y = 0; y < rh; y++) for (int x = 0; x < rw; x++) { int pos = (ry + y) * w + (rx + x); if (matrix[pos] != 0) throw fail("Overlapping tiles!"); matrix[pos] = iTile + 1; } tiling.pixelsCovered += rw * rh; } public boolean step() { Rect r = nextRect(); if (r == null) { finish(); return false; } tile.position(r); return true; } public boolean isContinuation(int x, int y) { return validPos(x, y) && isContinuation_impl(x, y); } public boolean isContinuation_impl(int x, int y) { return tiling.tileMatrix[pos(x, y)] == 0 && getColor(x, y) == color; } public boolean isContinuation(int x1, int y1, int w, int h) { if (!validPos(x1, y1) || !validPos(x1 + w - 1, y1 + h - 1)) return false; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) if (!isContinuation_impl(x1 + x, y1 + y)) return false; return true; } public Rect nextRect() { Rect r = tile.position(); growingN = growingN && isContinuation(r.x, r.y - 1, r.w, 1); growingS = growingS && isContinuation(r.x, r.y2(), r.w, 1); growingW = growingW && isContinuation(r.x - 1, r.y, 1, r.h); growingE = growingE && isContinuation(r.x2(), r.y, 1, r.h); boolean cornerNW = growingN && growingW && isContinuation(r.x - 1, r.y - 1); boolean cornerNE = growingN && growingE && isContinuation(r.x2(), r.y - 1); boolean cornerSW = growingS && growingW && isContinuation(r.x - 1, r.y2()); boolean cornerSE = growingS && growingE && isContinuation(r.x2(), r.y2()); if (cornerNW) { int x2 = r.x2(), y2 = r.y2(); if (cornerSW && cornerNE && cornerSE) { x2++; y2++; } else if (cornerNE) x2++; else if (cornerSW) y2++; return rectFromPoints(r.x - 1, r.y - 1, x2, y2); } else if (cornerNE) { int y2 = r.y2(); if (cornerSE) y2++; return rectFromPoints(r.x, r.y - 1, r.x2() + 1, y2); } else if (cornerSW) { int x2 = r.x2(); if (cornerSE) x2++; return rectFromPoints(r.x - 1, r.y, x2, r.y2() + 1); } else if (cornerSE) { return rectFromPoints(r.x, r.y, r.x2() + 1, r.y2() + 1); } else { if (growingW || growingE) return rectFromPoints(r.x - (growingW ? 1 : 0), r.y, r.x2() + (growingE ? 1 : 0), r.y2()); else if (growingN || growingS) return rectFromPoints(r.x, r.y - (growingN ? 1 : 0), r.x2(), r.y2() + (growingS ? 1 : 0)); } return null; } } public void run() { try { stepAll(this); } catch (Exception __e) { throw rethrow(__e); } } public boolean step() { init(); if (growingTile != null) { if (growingTile.step()) return true; tileDone(growingTile); growingTile = null; } int pos = pointIterator.nextIndex(); if (pos < 0) return false; if (tiling.tileMatrix[pos] != 0) return true; growingTile = new GrowingTile(pos); tileStarted(growingTile); return true; } public void init() { if (tiling != null) return; w = image.getWidth(); h = image.getHeight(); size = w * h; tiling = new G22Tiling(image); tiling.initTileMatrix(); pointIterator = new WeightlessShuffledIterator(size); } public G22Tiling get() { if (tiling == null) run(); return tiling; } } static public class JuiceStrategy extends G22TradingStrategy { public class Position extends G22TradingStrategy.Position { public Position() { } final public Position setJuicer(AbstractJuicer juicer) { return juicer(juicer); } public Position juicer(AbstractJuicer juicer) { this.juicer = juicer; return this; } final public AbstractJuicer getJuicer() { return juicer(); } public AbstractJuicer juicer() { return juicer; } public AbstractJuicer juicer; } static public class ProfitBeforeLeverageJuiceable implements Juiceable, IFieldsToList { public Position p; public ProfitBeforeLeverageJuiceable() { } public ProfitBeforeLeverageJuiceable(Position p) { this.p = p; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + p + ")"; } public boolean equals(Object o) { if (!(o instanceof ProfitBeforeLeverageJuiceable)) return false; ProfitBeforeLeverageJuiceable __116 = (ProfitBeforeLeverageJuiceable) o; return eq(p, __116.p); } public int hashCode() { int h = -1988713406; h = boostHashCombine(h, _hashCode(p)); return h; } public Object[] _fieldsToList() { return new Object[] { p }; } public double juiceValue() { return p.profitBeforeLeverage(); } } public void juiceStrategy_price(double price) { if (currentPrice == price) return; currentPrice = price; AutoCloseable __114 = tempAfterwards(new Runnable() { public void run() { try { change(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "change();"; } }); try { for (var p : openPositions()) { if (((Position) p).juicer != null) { var signals = ((Position) p).juicer.calculateCloseSignals(); var strongest = highestBy(signals, s -> s.strength()); if (strongest != null && strongest.isTrigger()) { ((Position) p).close(strongest); } } } } finally { _close(__114); } } public Position openShort() { return openPosition(-1); } public Position openLong() { return openPosition(1); } public Position openPosition(int direction) { return openPosition(direction, null); } public Position openPosition(int direction, Object openReason) { Position p = new Position(); p.marginToUse = marginPerPosition; addJuicer(p); return openPosition(p, direction, openReason); } public void addJuicer(Position p) { p.juicer(makeJuicer()); p.juicer.juiceable(new ProfitBeforeLeverageJuiceable(p)); } public void recreateJuicersForExistingPositions() { for (var p : openPositions()) { addJuicer((Position) p); } } public List openPositions() { return (List) super.openPositions(); } public List allJuicers() { return map(openPositions(), __115 -> __115.juicer()); } public AbstractJuicer makeJuicer() { return new StopLossJuicer(); } public void price(double price) { juiceStrategy_price(price); } } static public class GazelleVScript implements IFieldsToList { public String text; public GazelleVScript() { } public GazelleVScript(String text) { this.text = text; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + text + ")"; } public Object[] _fieldsToList() { return new Object[] { text }; } public List tok; static public String helpText = "Gazelle 22 \"Linear Script\"\r\n--------------------------\r\n\r\n\"Linear script\" is one of Gazelle 22's two scripting languages. It is the simpler (and older) one of the two with limited use.\r\n\r\n-You just write one line\r\n-Separate commands with spaces\r\n-The language is case-insensitive\r\n-You can add comments like in Java with /* */ or //\r\n\r\nCommands are:\r\n\r\n1p, 2p etc: Scale image down to x pixels\r\n1c, 2c, ..., 256c: Reduce gray scale levels\r\n1w, 2w etc: Scale image width only to x pixels\r\nstruct: show object structure\r\nniceStruct: show object structure indented\r\nrasters: reproduce horizontal bars\r\nclassName: show type of object on stack\r\nq1...q4: select quadrant\r\noriginal: show input image in color\r\n"; public class Sequence { public Map vars = new HashMap(); } public class Run implements Steppable { public ListAndIndex ptr; public String token; public Stack stack = new Stack(); final public Run setInputImage(IBWIntegralImage inputImage) { return inputImage(inputImage); } public Run inputImage(IBWIntegralImage inputImage) { this.inputImage = inputImage; return this; } final public IBWIntegralImage getInputImage() { return inputImage(); } public IBWIntegralImage inputImage() { return inputImage; } public IBWIntegralImage inputImage; public IBWIntegralImage integralImage; final public Run setBwImage(BWImage bwImage) { return bwImage(bwImage); } public Run bwImage(BWImage bwImage) { this.bwImage = bwImage; return this; } final public BWImage getBwImage() { return bwImage(); } public BWImage bwImage() { return bwImage; } public BWImage bwImage; public Run setIntegralImage(IBWIntegralImage ii) { push(integralImage = ii); return this; } public Run() { parse(); ptr = new ListAndIndex(tok, 1); } public void push(Object o) { stack.add(o); } public Object value() { return last(stack); } public boolean step() { token = ptr.get(); if (token == null) return false; next(); if (isInteger(token)) { int i = parseInt(token); token = tpp(); if (is("p")) scaleToHeight(i); else if (is("c")) posterize(i); else if (is("w")) scaleWidthOnly(i); else warn("Unknown token: " + token); } else if (is("rasters")) push(reproduceRasterBars(bwIntegralImage())); else if (is("struct")) push(struct(value())); else if (is("niceStruct")) push(sfuIndent(value())); else if (is("className")) push(className(value())); else if (is("borderImage")) push(bwImage = gazelle22_borderImage(bwImage)); else if (is("gradientImage")) push(bwImage = new Gazelle22_GradientImage(bwImage).get()); else if (is("q1")) clip(0, .5, 0, .5); else if (is("q2")) clip(.5, 1, 0, .5); else if (is("q3")) clip(0, .5, .5, 1); else if (is("q4")) clip(.5, 1, .5, 1); else if (is("original")) push(toBufferedImage(inputImage)); else { warn("Unknown token: " + token); } return true; } public boolean is(String t) { return eqic(token, t); } public String tpp() { var token = ptr.get(); next(); return token; } public void next() { if (!ptr.atEnd()) ptr = ptr.plus(2); } public void scaleToHeight(int pixelRows) { pixelRows = min(pixelRows, 512); if (integralImage == null) { warn("No integral image to scale down"); return; } push(bwImage = scaledBWImageFromBWIntegralImage_withMeta_height(pixelRows, integralImage)); } public void posterize(int colors) { colors = clamp(colors, 2, 256); if (bwImage == null) { warn("No image to posterize"); return; } else push(bwImage = posterizeBWImage_withMeta(colors, bwImage)); } public IBWIntegralImage bwIntegralImage() { Object val = value(); if (val instanceof IBWIntegralImage) return ((IBWIntegralImage) val); if (val instanceof BWImage) { var ii = loadableUtils.utils.bwIntegralImage((BWImage) val); setIntegralImage(ii); return ii; } throw fail("Not an image on stack"); } public void scaleWidthOnly(int w) { var ii = bwIntegralImage(); push(bwImage = scaledBWImageFromBWIntegralImage_withMeta(ii, w, ii.getHeight())); } public void clip(double x1, double x2, double y1, double y2) { Object val = value(); if (val instanceof IBWIntegralImage) { int w = ((IBWIntegralImage) val).getWidth(), h = ((IBWIntegralImage) val).getHeight(); Rect r = toRect_round(scaleRect(w, h, doubleRectFromPoints(x1, y1, x2, y2))); setIntegralImage(new IIBWVirtualClip(((IBWIntegralImage) val), r)); } else if (val instanceof BWImage) throw todo(); else throw fail("Not an image on stack"); } public Object result() { return last(stack); } public void run() { try { stepAll(this); } catch (Exception __e) { throw rethrow(__e); } } } public void parse() { if (tok == null) tok = javaTok(text); } } static public class ATR extends CandleBasedIndicator { public ATR() { } public Average initialAverage = new Average(); final public ATR setSma(SmoothedMovingAverage sma) { return sma(sma); } public ATR sma(SmoothedMovingAverage sma) { this.sma = sma; return this; } final public SmoothedMovingAverage getSma() { return sma(); } public SmoothedMovingAverage sma() { return sma; } public SmoothedMovingAverage sma; final public ATR setTr(double tr) { return tr(tr); } public ATR tr(double tr) { this.tr = tr; return this; } final public double getTr() { return tr(); } public double tr() { return tr; } public double tr = Double.NaN; final public ATR setAtr(double atr) { return atr(atr); } public ATR atr(double atr) { this.atr = atr; return this; } final public double getAtr() { return atr(); } public double atr() { return atr; } public double atr = Double.NaN; final public TickerSequence getAtrHistory() { return atrHistory(); } public TickerSequence atrHistory() { return atrHistory; } public TickerSequence atrHistory = new TickerSequence("ATR"); public Double value() { return atr(); } public ATR(int length) { this.length = length; } { length = 14; onCandleAdded((IVF1) candle -> { var x = candle.move(); var u = max(x, 0.0); var d = neg(min(x, 0.0)); if (candles().size() < 2) return; tr(trueRange(ll(candles().nextToLast(), candles().last()))); if (initialAverage.count() < length()) { initialAverage.add(tr); return; } if (sma == null) { sma(new SmoothedMovingAverage(length())); sma().add(initialAverage.get()); } else sma().add(tr); atr(sma().get()); long time = candle.endTime().toLong(); { if (atrHistory != null) atrHistory.addIfPriceChanged(atr, time); } }); } public TickerSequence asTicker(List candles) { feed(candles); return atrHistory; } public void reset() { super.reset(); resetFields(this, "initialAverage sma tr atr atrHistory"); } } static public class G22RegionPanel extends MetaWithChangeListeners implements Swingable, IFieldsToList { public IImageRegion region; public G22RegionPanel() { } public G22RegionPanel(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public G22RegionPanel setG22utils(G22Utils g22utils) { return g22utils(g22utils); } public G22RegionPanel g22utils(G22Utils g22utils) { this.g22utils = g22utils; return this; } final public G22Utils getG22utils() { return g22utils(); } public G22Utils g22utils() { return g22utils; } transient public G22Utils g22utils; final public G22RegionPanel setOriginalImage(BufferedImage originalImage) { return originalImage(originalImage); } public G22RegionPanel originalImage(BufferedImage originalImage) { this.originalImage = originalImage; return this; } final public BufferedImage getOriginalImage() { return originalImage(); } public BufferedImage originalImage() { return originalImage; } public BufferedImage originalImage; public transient FieldVar varShowOriginalColors_cache; public FieldVar varShowOriginalColors() { if (varShowOriginalColors_cache == null) varShowOriginalColors_cache = varShowOriginalColors_load(); return varShowOriginalColors_cache; } public FieldVar varShowOriginalColors_load() { return new FieldVar(this, "showOriginalColors", () -> showOriginalColors(), showOriginalColors -> showOriginalColors(showOriginalColors)); } final public G22RegionPanel setShowOriginalColors(boolean showOriginalColors) { return showOriginalColors(showOriginalColors); } public G22RegionPanel showOriginalColors(boolean showOriginalColors) { if (!eq(this.showOriginalColors, showOriginalColors)) { this.showOriginalColors = showOriginalColors; change(); } return this; } final public boolean getShowOriginalColors() { return showOriginalColors(); } public boolean showOriginalColors() { return showOriginalColors; } public boolean showOriginalColors = true; transient public ImageSurface is; public transient JComponent visualize_cache; public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache; } public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); } public JComponent visualize_impl() { is = g22utils.stdImageSurface(); imageSurfaceCheckerBoardBackground(is); varShowOriginalColors().onChangeAndNow(() -> updateImage()); return northAndCenterWithMargins(jcenteredline(liveValueCheckBox(varShowOriginalColors(), "Show original colors"), jbutton("Save mask", runnableThread(new Runnable() { public void run() { try { saveMask(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "saveMask();"; } }))), g22utils.wrap(is)); } public void updateImage() { if (showOriginalColors) is.setImage(new CutOutRegionFromImage(region).margin(10).fullImage(originalImage).get()); else is.setImage(regionToBinaryImage(region)); } public void saveMask() { var maskSize = g22utils.projectInfo().defaultMaskSize(); var maskImage = g22standardRegionToMaskImage(region, maskSize); G22MaskConcept mask = new G22MaskConcept(); mask.maskImage = maskImage; g22utils.registerConcept(mask); } } static public class JThumbnailButton extends JToggleButton { public ThumbnailCache thumbnailCache; final public File getImageFile() { return imageFile(); } public File imageFile() { return imageFile; } public File imageFile; public JThumbnailButton(ThumbnailCache thumbnailCache, File imageFile) { this.imageFile = imageFile; this.thumbnailCache = thumbnailCache; toolTip(this, fileInfo(imageFile)); setButtonImage(this, whiteImage(thumbnailCache.thumbnailSize())); thumbnailCache.get(imageFile, img -> { setButtonImage(this, centerImageOnBackground(Color.gray, thumbnailCache.thumbnailSize(), img)); }); } } static public class LASToByteCode implements IFieldsToList { public MethodMaker m; public LASToByteCode() { } public LASToByteCode(MethodMaker m) { this.m = m; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + m + ")"; } public Object[] _fieldsToList() { return new Object[] { m }; } public boolean callPing = true; final public LASToByteCode setIVarContext(int iVarContext) { return iVarContext(iVarContext); } public LASToByteCode iVarContext(int iVarContext) { this.iVarContext = iVarContext; return this; } final public int getIVarContext() { return iVarContext(); } public int iVarContext() { return iVarContext; } public int iVarContext = -1; public GazelleV_LeftArrowScript.Script returnableScript; final public LASToByteCode setPostConversion(IF1 postConversion) { return postConversion(postConversion); } public LASToByteCode postConversion(IF1 postConversion) { this.postConversion = postConversion; return this; } final public IF1 getPostConversion() { return postConversion(); } public IF1 postConversion() { return postConversion; } public IF1 postConversion; public JVMStackCellType compileScript(GazelleV_LeftArrowScript.Script script) { returnableScript = script; var stackTop = compile(script); if (postConversion != null) stackTop = postConversion.get(stackTop); return stackTop; } public void compileToObject(GazelleV_LeftArrowScript.Evaluable code) { m.convertToObject(compile(code)); } public JVMStackCellType compile(GazelleV_LeftArrowScript.Evaluable code) { if (code instanceof GazelleV_LeftArrowScript.Const) { Object o = ((GazelleV_LeftArrowScript.Const) code).value; if (o == null) { m.add(new ACONST_NULL()); return JVMStackCellType.objValue; } else if (o instanceof String) { m.stringConstant((String) o); return JVMStackCellType.objValue; } else if (o instanceof Integer) { m.intConstant((Integer) o); return JVMStackCellType.intValue; } else if (o instanceof Double) { m.doubleConstant((Double) o); return JVMStackCellType.doubleValue; } else if (o instanceof Class) { m.classConstant((Class) o); return JVMStackCellType.objValue; } else if (o instanceof Boolean) { m.boolConstant((Boolean) o); return JVMStackCellType.intValue; } else throw fail("Can't compile const value: " + toStringWithClass(o)); } else if (code instanceof GazelleV_LeftArrowScript.Script) { var stackTop = JVMStackCellType.none; for (var step : ((GazelleV_LeftArrowScript.Script) code).steps) { if (stackTop != JVMStackCellType.none) m.add(new POP()); stackTop = compile(step); } return stackTop; } else if (code instanceof GazelleV_LeftArrowScript.CallMethod) { compileToObject(((GazelleV_LeftArrowScript.CallMethod) code).target); m.stringConstant(((GazelleV_LeftArrowScript.CallMethod) code).methodName); argumentsAsArray(((GazelleV_LeftArrowScript.CallMethod) code).args); m.invokeStatic(loadableUtils.utils.class, Object.class, "call", Object.class, String.class, Object[].class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.CallMethodOrGetField) { compileToObject(((GazelleV_LeftArrowScript.CallMethodOrGetField) code).target); m.stringConstant(((GazelleV_LeftArrowScript.CallMethodOrGetField) code).name); m.invokeStatic(loadableUtils.utils.class, Object.class, "preciseGetOrCallMethod", Object.class, String.class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.SetField) { compileToObject(((GazelleV_LeftArrowScript.SetField) code).target); m.stringConstant(((GazelleV_LeftArrowScript.SetField) code).name); compileToObject(((GazelleV_LeftArrowScript.SetField) code).expr); m.invokeStatic(loadableUtils.utils.class, Object.class, "set", Object.class, String.class, Object.class); return JVMStackCellType.none; } else if (code instanceof GazelleV_LeftArrowScript.NewObject) { m.classConstant(((GazelleV_LeftArrowScript.NewObject) code).c); argumentsAsArray(((GazelleV_LeftArrowScript.NewObject) code).args); m.invokeStatic(loadableUtils.utils.class, Object.class, "nuObject", Class.class, Object[].class); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.Assignment) { compileToObject(((GazelleV_LeftArrowScript.Assignment) code).expression); m.astore(iTemp()); loadVarContext(); m.stringConstant(((GazelleV_LeftArrowScript.Assignment) code).var); m.aload(iTemp()); m.invokeVirtual(VarContext.class, void.class, "set", String.class, Object.class); m.aload(iTemp()); return JVMStackCellType.objValue; } else if (code instanceof GazelleV_LeftArrowScript.While) { var loopStart = m.il.append(new NOP()); BranchInstruction branch1 = null; if (callPing) { m.invokeStatic(loadableUtils.utils.class, boolean.class, "ping"); branch1 = new IFEQ(null); m.add(branch1); } compileToBool(((GazelleV_LeftArrowScript.While) code).condition); var branch2 = new IFEQ(null); m.add(branch2); m.discardStackTop(compile(((GazelleV_LeftArrowScript.While) code).body)); m.add(new GOTO(loopStart)); var loopEnd = m.il.append(new NOP()); { if (branch1 != null) branch1.setTarget(loopEnd); } branch2.setTarget(loopEnd); return JVMStackCellType.none; } else if (code instanceof GazelleV_LeftArrowScript.IfThen) { compileToBool(((GazelleV_LeftArrowScript.IfThen) code).condition); var branch1 = new IFEQ(null); m.add(branch1); var stackTop = compile(((GazelleV_LeftArrowScript.IfThen) code).body); if (stackTop == JVMStackCellType.none) { branch1.setTarget(m.here()); return stackTop; } else { m.convertToObject(stackTop); var jumpToEnd = m.forwardGoto(); branch1.setTarget(m.here()); m.loadNull(); jumpToEnd.setTarget(m.here()); return JVMStackCellType.objValue; } } else if (code instanceof GazelleV_LeftArrowScript.GetVar) { return compileGetVar((GazelleV_LeftArrowScript.GetVar) code); } else if (code instanceof GazelleV_LeftArrowScript.ReturnFromScript) { if (((GazelleV_LeftArrowScript.ReturnFromScript) code).script != returnableScript) throw fail("Can only return from current script"); var stackTop = compile(((GazelleV_LeftArrowScript.ReturnFromScript) code).value); if (postConversion != null) stackTop = postConversion.get(stackTop); m.returnWithType(stackTop); return JVMStackCellType.none; } throw fail("Can't compile yet: " + className(code)); } public void argumentsAsArray(GazelleV_LeftArrowScript.Evaluable[] args) { int n = l(args); m.intConst(n); m.add(new ANEWARRAY(m.classRef(Object.class))); for (int iArg = 0; iArg < n; iArg++) { m.dup(); m.intConst(iArg); compileToObject(args[iArg]); m.add(new AASTORE()); } } public void loadVarContext() { assertTrue("Need VarContext", iVarContext >= 0); m.aload(iVarContext); } public Integer iTemp_cache; public int iTemp() { if (iTemp_cache == null) iTemp_cache = iTemp_load(); return iTemp_cache; } public int iTemp_load() { return m.newLocalVar(); } public void compileToBool(GazelleV_LeftArrowScript.Evaluable condition) { var stackTop = compile(condition); if (stackTop == JVMStackCellType.objValue) { m.checkCast(Boolean.class); m.invokeVirtual(Boolean.class, boolean.class, "booleanValue"); } else if (stackTop == JVMStackCellType.intValue) { } else throw fail("Can't convert to bool: " + stackTop); } public JVMStackCellType compileGetVar(GazelleV_LeftArrowScript.GetVar code) { loadVarContext(); m.stringConstant(code.var); m.invokeVirtual(VarContext.class, Object.class, "get", String.class); return JVMStackCellType.objValue; } } static public class StopLossJuicer extends AbstractJuicer { public StopLossJuicer() { } final public StopLossJuicer setStopLossLimit(double stopLossLimit) { return stopLossLimit(stopLossLimit); } public StopLossJuicer stopLossLimit(double stopLossLimit) { this.stopLossLimit = stopLossLimit; return this; } final public double getStopLossLimit() { return stopLossLimit(); } public double stopLossLimit() { return stopLossLimit; } public double stopLossLimit = -0.5; final public StopLossJuicer setStopLossEnabled(boolean stopLossEnabled) { return stopLossEnabled(stopLossEnabled); } public StopLossJuicer stopLossEnabled(boolean stopLossEnabled) { this.stopLossEnabled = stopLossEnabled; return this; } final public boolean getStopLossEnabled() { return stopLossEnabled(); } public boolean stopLossEnabled() { return stopLossEnabled; } public boolean stopLossEnabled = true; final public StopLossJuicer setStartStopLossSignalAt(double startStopLossSignalAt) { return startStopLossSignalAt(startStopLossSignalAt); } public StopLossJuicer startStopLossSignalAt(double startStopLossSignalAt) { this.startStopLossSignalAt = startStopLossSignalAt; return this; } final public double getStartStopLossSignalAt() { return startStopLossSignalAt(); } public double startStopLossSignalAt() { return startStopLossSignalAt; } public double startStopLossSignalAt; { onCalculatingCloseSignals(signals -> { if (stopLossEnabled && stopLossLimit > -infinity()) { var signal = new CloseSignal().createdBy(this).reason("Stop loss"); if (juiceValue <= stopLossLimit) signal.strength(100); else { double startAt = max(startStopLossSignalAt, 0); if (startAt > stopLossLimit) signal.strength(doubleRatio(startAt - juiceValue, startAt - stopLossLimit) * 100); } signals.add(signal); } }); } } static public class ConcatOnDemandList extends RandomAccessAbstractList { public ConcatOnDemandList() { } public List> parts = new ArrayList(); public List completeList; public ConcatOnDemandList(List... parts) { for (var part : unnullForIteration(parts)) addPart(part); } public void addPart(List part) { parts.add(part); } public int size() { return completeList().size(); } public A get(int i) { return completeList().get(i); } public List completeList() { if (parts != null) { List out = new ArrayList(); for (var part : parts) collect(part, out); parts = null; completeList = out; } return completeList; } public void collect(List part, List out) { if (part == null) return; if (part instanceof ConcatOnDemandList) ((ConcatOnDemandList) part).collectInto(out); else out.addAll(part); } public void collectInto(List out) { if (parts != null) for (var part : parts) collect(part, out); else out.addAll(completeList); } } static public class ThumbnailCache { public boolean _isTransient() { return true; } final public ThumbnailCache setThumbnailSize(WidthAndHeightImpl thumbnailSize) { return thumbnailSize(thumbnailSize); } public ThumbnailCache thumbnailSize(WidthAndHeightImpl thumbnailSize) { this.thumbnailSize = thumbnailSize; return this; } final public WidthAndHeightImpl getThumbnailSize() { return thumbnailSize(); } public WidthAndHeightImpl thumbnailSize() { return thumbnailSize; } public WidthAndHeightImpl thumbnailSize = new WidthAndHeightImpl(100); final public ThumbnailCache setMaxBytes(long maxBytes) { return maxBytes(maxBytes); } public ThumbnailCache maxBytes(long maxBytes) { this.maxBytes = maxBytes; return this; } final public long getMaxBytes() { return maxBytes(); } public long maxBytes() { return maxBytes; } public long maxBytes = oneMegabyte(); final public long getUsedBytes() { return usedBytes(); } public long usedBytes() { return usedBytes; } public long usedBytes; public Q q = startQ(); public TheMap map = new TheMap(); transient public Lock lock = lock(); public class TheMap extends LinkedHashMap { @Override public boolean removeEldestEntry(Map.Entry eldest) { if (usedBytes > maxBytes) { usedBytes -= guessImageBytes(eldest.getValue()); return true; } return false; } } public int guessImageBytes(BufferedImage image) { return 24 + guessImageSizeInMemory(image); } public BufferedImage makeThumbnail(File file) { var fullSize = loadImage2(file); return scaleBufferedImageToMaxWidthOrHeight(thumbnailSize, fullSize); } public ThumbnailCache thumbnailSize(int wAndH) { return thumbnailSize(new WidthAndHeightImpl(wAndH)); } public void get(File imageFile, IVF1 onLoad) { Lock __0 = lock; lock(__0); try { if (map.containsKey(imageFile)) onLoad.get(map.get(imageFile)); else q.add(() -> { BufferedImage img = null; try { img = makeThumbnail(imageFile); } catch (Throwable __e) { pcallFail(__e); } { Lock __1 = lock; lock(__1); try { usedBytes += guessImageBytes(img); map.put(imageFile, img); } finally { unlock(__1); } } onLoad.get(img); }); } finally { unlock(__0); } } } public interface IResolvableClass extends Type { public String resolveToClassName(); public Class resolveToClass(); } static public class G22Tiling implements IFieldsToList { public Img img; public G22Tiling() { } public G22Tiling(Img img) { this.img = img; } public Object[] _fieldsToList() { return new Object[] { img }; } public List tiles = new ArrayList(); public int pixelsCovered; public int[] tileMatrix; public class Tile extends Rect { public int index; public int color; public Tile(int index, int color, Rect position) { this.color = color; this.index = index; position(position); } public Rect position() { return this; } public Tile position(Rect r) { x = r.x; y = r.y; w = r.w; h = r.h; return this; } public String area_str() { return nPixels(area()); } public double ratioToImage() { return doubleRatio(area(), imageArea()); } public String percent_str() { return formatDoubleX(ratioToImage() * 100, 2) + "% of image"; } public String toString() { return intToHex_fullLength(color) + " colored tile covering " + percent_str() + " at " + super.toString(); } } public int w() { return img.w(); } public int h() { return img.h(); } public int imageArea() { return img.area(); } public void initTileMatrix() { tileMatrix = new int[w() * h()]; } public int numTiles() { return l(tiles); } public List get() { return tiles; } } public interface IG22OptimizedMasksHolder extends IG22MasksHolder { } static public class G22FindSimilarMasksTask { final public G22FindSimilarMasksTask setQueryImage(Image2B queryImage) { return queryImage(queryImage); } public G22FindSimilarMasksTask queryImage(Image2B queryImage) { this.queryImage = queryImage; return this; } final public Image2B getQueryImage() { return queryImage(); } public Image2B queryImage() { return queryImage; } public Image2B queryImage; final public G22FindSimilarMasksTask setOutList(ProbabilisticList outList) { return outList(outList); } public G22FindSimilarMasksTask outList(ProbabilisticList outList) { this.outList = outList; return this; } final public ProbabilisticList getOutList() { return outList(); } public ProbabilisticList outList() { return outList; } public ProbabilisticList outList = new ProbabilisticList(); final public G22FindSimilarMasksTask setPstack(PStack pstack) { return pstack(pstack); } public G22FindSimilarMasksTask pstack(PStack pstack) { this.pstack = pstack; return this; } final public PStack getPstack() { return pstack(); } public PStack pstack() { return pstack; } public PStack pstack = new PStack(); public int comparisons; final public G22FindSimilarMasksTask setVerbose(boolean verbose) { return verbose(verbose); } public G22FindSimilarMasksTask verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose() { return verbose(); } public boolean verbose() { return verbose; } public boolean verbose = false; final public G22FindSimilarMasksTask setEnded(boolean ended) { return ended(ended); } public G22FindSimilarMasksTask ended(boolean ended) { this.ended = ended; return this; } final public boolean getEnded() { return ended(); } public boolean ended() { return ended; } public boolean ended = false; public class FoundMask { final public FoundMask setMask(IG22Mask mask) { return mask(mask); } public FoundMask mask(IG22Mask mask) { this.mask = mask; return this; } final public IG22Mask getMask() { return mask(); } public IG22Mask mask() { return mask; } public IG22Mask mask; final public FoundMask setSimilarity(double similarity) { return similarity(similarity); } public FoundMask similarity(double similarity) { this.similarity = similarity; return this; } final public double getSimilarity() { return similarity(); } public double similarity() { return similarity; } public double similarity; final public FoundMask setCandidateNumber(int candidateNumber) { return candidateNumber(candidateNumber); } public FoundMask candidateNumber(int candidateNumber) { this.candidateNumber = candidateNumber; return this; } final public int getCandidateNumber() { return candidateNumber(); } public int candidateNumber() { return candidateNumber; } public int candidateNumber; final public FoundMask setStepCount(long stepCount) { return stepCount(stepCount); } public FoundMask stepCount(long stepCount) { this.stepCount = stepCount; return this; } final public long getStepCount() { return stepCount(); } public long stepCount() { return stepCount; } public long stepCount; final public FoundMask setFoundAtProbability(double foundAtProbability) { return foundAtProbability(foundAtProbability); } public FoundMask foundAtProbability(double foundAtProbability) { this.foundAtProbability = foundAtProbability; return this; } final public double getFoundAtProbability() { return foundAtProbability(); } public double foundAtProbability() { return foundAtProbability; } public double foundAtProbability; public Image2B image() { return mask.image(); } } public G22FindSimilarMasksTask() { } public G22FindSimilarMasksTask(IG22Mask mask) { queryImage(mask.image()); } public G22FindSimilarMasksTask(Image2B image) { queryImage(image); } public IProbabilisticScheduler scheduler() { return pstack.scheduler(); } public void tryMask(IG22Mask candidate) { if (candidate == null) return; comparisons++; var candidateImage = candidate.image(); long diff = binaryImagePixelDifference_sameSize(queryImage, candidateImage); double p = liftProbabilityOffGround(1 - doubleRatio(diff, area(candidateImage))); if (verbose) printVars("Candidate tested", "diff", diff, "p", p, "candidate", candidate); foundMask(candidate, p); } public void foundMask(IG22Mask mask, double similarity) { long stepCount = scheduler().stepCount(); if (verbose) print("Found mask with similarity " + formatDouble3X(similarity) + " in step " + stepCount); outList.at(similarity, new FoundMask().mask(mask).similarity(similarity).candidateNumber(comparisons).stepCount(stepCount).foundAtProbability(scheduler().currentProbability())); } public void endSearch() { ended(true); } } static public class FutureCoinParameters extends MetaWithChangeListeners { final public FutureCoinParameters setCryptoCoin(String cryptoCoin) { return cryptoCoin(cryptoCoin); } public FutureCoinParameters cryptoCoin(String cryptoCoin) { this.cryptoCoin = cryptoCoin; return this; } final public String getCryptoCoin() { return cryptoCoin(); } public String cryptoCoin() { return cryptoCoin; } public String cryptoCoin; public transient FieldVar varMinCrypto_cache; public FieldVar varMinCrypto() { if (varMinCrypto_cache == null) varMinCrypto_cache = varMinCrypto_load(); return varMinCrypto_cache; } public FieldVar varMinCrypto_load() { return new FieldVar(this, "minCrypto", () -> minCrypto(), minCrypto -> minCrypto(minCrypto)); } final public FutureCoinParameters setMinCrypto(double minCrypto) { return minCrypto(minCrypto); } public FutureCoinParameters minCrypto(double minCrypto) { if (!eq(this.minCrypto, minCrypto)) { this.minCrypto = minCrypto; change(); } return this; } final public double getMinCrypto() { return minCrypto(); } public double minCrypto() { return minCrypto; } public double minCrypto = 0.0001; public transient FieldVar varCryptoStep_cache; public FieldVar varCryptoStep() { if (varCryptoStep_cache == null) varCryptoStep_cache = varCryptoStep_load(); return varCryptoStep_cache; } public FieldVar varCryptoStep_load() { return new FieldVar(this, "cryptoStep", () -> cryptoStep(), cryptoStep -> cryptoStep(cryptoStep)); } final public FutureCoinParameters setCryptoStep(double cryptoStep) { return cryptoStep(cryptoStep); } public FutureCoinParameters cryptoStep(double cryptoStep) { if (!eq(this.cryptoStep, cryptoStep)) { this.cryptoStep = cryptoStep; change(); } return this; } final public double getCryptoStep() { return cryptoStep(); } public double cryptoStep() { return cryptoStep; } public double cryptoStep = 0.0001; public transient FieldVar varMaxLeverage_cache; public FieldVar varMaxLeverage() { if (varMaxLeverage_cache == null) varMaxLeverage_cache = varMaxLeverage_load(); return varMaxLeverage_cache; } public FieldVar varMaxLeverage_load() { return new FieldVar(this, "maxLeverage", () -> maxLeverage(), maxLeverage -> maxLeverage(maxLeverage)); } final public FutureCoinParameters setMaxLeverage(int maxLeverage) { return maxLeverage(maxLeverage); } public FutureCoinParameters maxLeverage(int maxLeverage) { if (!eq(this.maxLeverage, maxLeverage)) { this.maxLeverage = maxLeverage; change(); } return this; } final public int getMaxLeverage() { return maxLeverage(); } public int maxLeverage() { return maxLeverage; } public int maxLeverage = 1; public transient FieldVar varFeesPerAction_cache; public FieldVar varFeesPerAction() { if (varFeesPerAction_cache == null) varFeesPerAction_cache = varFeesPerAction_load(); return varFeesPerAction_cache; } public FieldVar varFeesPerAction_load() { return new FieldVar(this, "feesPerAction", () -> feesPerAction(), feesPerAction -> feesPerAction(feesPerAction)); } final public FutureCoinParameters setFeesPerAction(double feesPerAction) { return feesPerAction(feesPerAction); } public FutureCoinParameters feesPerAction(double feesPerAction) { if (!eq(this.feesPerAction, feesPerAction)) { this.feesPerAction = feesPerAction; change(); } return this; } final public double getFeesPerAction() { return feesPerAction(); } public double feesPerAction() { return feesPerAction; } public double feesPerAction = 0.6; public transient FieldVar varSlippage_cache; public FieldVar varSlippage() { if (varSlippage_cache == null) varSlippage_cache = varSlippage_load(); return varSlippage_cache; } public FieldVar varSlippage_load() { return new FieldVar(this, "slippage", () -> slippage(), slippage -> slippage(slippage)); } final public FutureCoinParameters setSlippage(double slippage) { return slippage(slippage); } public FutureCoinParameters slippage(double slippage) { if (!eq(this.slippage, slippage)) { this.slippage = slippage; change(); } return this; } final public double getSlippage() { return slippage(); } public double slippage() { return slippage; } public double slippage = 0.4; } static public class ScaledDiagram { final public ScaledDiagram setW(int w) { return w(w); } public ScaledDiagram w(int w) { this.w = w; return this; } final public int getW() { return w(); } public int w() { return w; } public int w = 600; final public ScaledDiagram setH(int h) { return h(h); } public ScaledDiagram h(int h) { this.h = h; return this; } final public int getH() { return h(); } public int h() { return h; } public int h = 400; final public ScaledDiagram setHorizontalMargin(int horizontalMargin) { return horizontalMargin(horizontalMargin); } public ScaledDiagram horizontalMargin(int horizontalMargin) { this.horizontalMargin = horizontalMargin; return this; } final public int getHorizontalMargin() { return horizontalMargin(); } public int horizontalMargin() { return horizontalMargin; } public int horizontalMargin = 10; final public ScaledDiagram setVerticalMargin(int verticalMargin) { return verticalMargin(verticalMargin); } public ScaledDiagram verticalMargin(int verticalMargin) { this.verticalMargin = verticalMargin; return this; } final public int getVerticalMargin() { return verticalMargin(); } public int verticalMargin() { return verticalMargin; } public int verticalMargin = 10; final public ScaledDiagram setHorizontalRange(DoubleRange horizontalRange) { return horizontalRange(horizontalRange); } public ScaledDiagram horizontalRange(DoubleRange horizontalRange) { this.horizontalRange = horizontalRange; return this; } final public DoubleRange getHorizontalRange() { return horizontalRange(); } public DoubleRange horizontalRange() { return horizontalRange; } public DoubleRange horizontalRange; final public ScaledDiagram setVerticalRange(DoubleRange verticalRange) { return verticalRange(verticalRange); } public ScaledDiagram verticalRange(DoubleRange verticalRange) { this.verticalRange = verticalRange; return this; } final public DoubleRange getVerticalRange() { return verticalRange(); } public DoubleRange verticalRange() { return verticalRange; } public DoubleRange verticalRange; public DoubleRange xRange() { return doubleRange(horizontalMargin, w - horizontalMargin); } public DoubleRange yRange() { return doubleRange(h - verticalMargin, verticalMargin); } public double xToScreen(double x) { return transformBetweenDoubleRanges(x, horizontalRange(), xRange()); } public double yToScreen(double y) { return transformBetweenDoubleRanges(y, verticalRange(), yRange()); } public double xFromScreen(double x) { return transformBetweenDoubleRanges(x, xRange(), horizontalRange()); } public double yFromScreen(double y) { return transformBetweenDoubleRanges(y, yRange(), verticalRange()); } public int getWidth() { return w; } public int getHeight() { return h; } public boolean hasScale() { return horizontalRange != null && verticalRange != null; } } static public class OptimizedMultiSet implements IMultiSet { public OptimizedMultiSet() { } public Map map = new HashMap(); transient public MultiSetMap byCount = multiSetMap_innerLinkedHashSet_outerRevTreeMap(); public int size; public int add(A a) { return add(a, 1); } public int add(A a, int count) { if (count <= 0) return 0; size += count; Integer i = map.get(a); if (i != null) byCount.remove(i += count, a); else i = count; map.put(a, i); byCount.add(i, a); return i; } public void remove(A a) { Integer i = map.get(a); if (i != null) { --size; byCount.remove(i, a); if (--i > 0) { map.put(a, i); byCount.add(i, a); } else map.remove(a); } } public void removeAll(A a) { Integer i = map.get(a); if (i == null) return; map.remove(a); byCount.remove(i, a); size -= i; } public boolean isEmpty() { return map.isEmpty(); } public String toString() { return str(map); } public A getMostPopularEntry() { return firstValue(byCount); } public A leastPopularEntry() { return first(lastValue(castMultiSetMapToNavigableMap(byCount))); } public void _doneLoading() { rebuildByCount(); } public void rebuildByCount() { byCount.clear(); for (Map.Entry __0 : _entrySet(map)) { A entry = __0.getKey(); int count = __0.getValue(); byCount.put(count, entry); } } public int get(A a) { return map.get(a); } public int size() { return size; } public int uniqueSize() { return map.size(); } final public List getSortedListDescending() { return highestFirst(); } public List highestFirst() { return asList(multiSetMapValuesIterator(byCount)); } public void truncate(int maxSize) { assertTrue(maxSize >= 0); while (uniqueSize() > maxSize) removeAll(leastPopularEntry()); } } abstract static public class AbstractWAndH extends Meta implements WidthAndHeight { public AbstractWAndH() { } public int w, h; public int getWidth() { return w; } public int getHeight() { return h; } public AbstractWAndH(int w, int h) { this.h = h; this.w = w; } public String sizeToString() { return n2(w) + "*" + n2(h) + " px"; } } static public class CutOutRegionFromImage implements IFieldsToList { public IImageRegion region; public CutOutRegionFromImage() { } public CutOutRegionFromImage(IImageRegion region) { this.region = region; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + region + ")"; } public Object[] _fieldsToList() { return new Object[] { region }; } final public CutOutRegionFromImage setAlphaNonContained(double alphaNonContained) { return alphaNonContained(alphaNonContained); } public CutOutRegionFromImage alphaNonContained(double alphaNonContained) { this.alphaNonContained = alphaNonContained; return this; } final public double getAlphaNonContained() { return alphaNonContained(); } public double alphaNonContained() { return alphaNonContained; } public double alphaNonContained = 0.5; final public CutOutRegionFromImage setFullImage(BufferedImage fullImage) { return fullImage(fullImage); } public CutOutRegionFromImage fullImage(BufferedImage fullImage) { this.fullImage = fullImage; return this; } final public BufferedImage getFullImage() { return fullImage(); } public BufferedImage fullImage() { return fullImage; } public BufferedImage fullImage; final public CutOutRegionFromImage setMargin(int margin) { return margin(margin); } public CutOutRegionFromImage margin(int margin) { this.margin = margin; return this; } final public int getMargin() { return margin(); } public int margin() { return margin; } public int margin; final public CutOutRegionFromImage setRect(Rect rect) { return rect(rect); } public CutOutRegionFromImage rect(Rect rect) { this.rect = rect; return this; } final public Rect getRect() { return rect(); } public Rect rect() { return rect; } public Rect rect; public BufferedImage get() { if (region == null) return null; if (fullImage == null) fullImage = toBufferedImage(region.image()); if (fullImage == null) return null; rect = region.bounds(); rect = intersectRects(growRect(rect, margin), imageRect(fullImage)); var clipped = clipBufferedImage(fullImage, rect); int[] pixels = pixelsOfBufferedImage(clipped); int w = rect.w, h = rect.h, i = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (!region.contains(rect.x + x, rect.y + y)) pixels[i] = withAlpha(alphaNonContained, pixels[i]); ++i; } return bufferedImageWithAlpha(w, h, pixels); } } static public interface IMultiSet { public int add(A key); public int get(A key); } static public int countDifferingBits(byte[] array1, byte[] array2) { int n = array1.length; int diff = 0; for (int i = 0; i < n; i++) diff += Integer.bitCount(ubyteToInt(array1[i]) ^ ubyteToInt(array2[i])); return diff; } static public int countDifferingBits(int[] array1, int[] array2) { int n = array1.length; int diff = 0; for (int i = 0; i < n; i++) diff += Integer.bitCount(array1[i] ^ array2[i]); return diff; } static public int countDifferingBits(long[] array1, long[] array2) { int n = array1.length; int diff = 0; for (int i = 0; i < n; i++) diff += Long.bitCount(array1[i] ^ array2[i]); return diff; } static public int countDifferingBits(long[] array1, long[] array2, int i1) { int n = array1.length; int diff = 0; for (int i = 0; i < n; i++) diff += Long.bitCount(array1[i] ^ array2[i1 + i]); return diff; } static public FloatBWImage floatBWImageFromFunction(int w, IF2_IntInt_Double f) { return floatBWImageFromFunction(w, w, f); } static public FloatBWImage floatBWImageFromFunction(int w, int h, IF2_IntInt_Double f) { FloatBWImage img = new FloatBWImage(w, h); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) img.setPixel(x, y, (float) f.get(x, y)); return img; } static public FloatBWImage floatBWImageFromFunction(int w, IF0 f) { return floatBWImageFromFunction(w, w, f); } static public FloatBWImage floatBWImageFromFunction(int w, int h, IF0 f) { return floatBWImageFromFunction(w, (x, y) -> f.get()); } static public Object time(Object f) { long time = sysNow(); Object o = callF(f); done2_always(str(f), time); return o; } static public A time(F0 f) { return (A) time((Object) f); } static public A time(IF0 f) { return (A) time((Object) f); } static public A time(String msg, IF0 f) { long time = sysNow(); A o = f.get(); done2_always(msg, time); return o; } static public void time(Runnable f) { time(str(f), f); } static public void time(String msg, Runnable f) { time(msg, runnableToIF0(f)); } static public String combineWithSeparator(String separator, Object... l) { return customSeparatorCombine(separator, l); } static public JComponent getControls() { return showControls_controls; } static public JComponent showControls_controls; static public void showControls(final JComponent controls) { { swing(() -> { hideControls(); JComponent _controls = withMargin(controls); showControls_controls = _controls; addToConsole2(showControls_controls); }); } } static public JButton jReloadButton(Runnable action) { return jReloadButton("Reload", action); } static public JButton jReloadButton(String desc, Runnable action) { return jimageButton("#1101440", desc, rThread(action)); } static public IterableIterator range(int start, int stop) { return new IterableIterator() { public int i = start; public boolean hasNext() { return i < stop; } public Integer next() { return i++; } }; } static public long fromSeconds(double seconds) { return toMS(seconds); } static public Duration duration(TimestampRange r) { return r == null ? Duration.ZERO : r.duration(); } static public void resetFields(Object object, String fields) { if (object == null) return; Object emptyInstance = newInstance(object.getClass()); for (String field : identifiers(fields)) setOpt(object, field, getOpt(emptyInstance, field)); } static public List lmapMethod(IF1 f, Iterable l) { return lambdaMapMethod(f, l); } static public List lmapMethod(IF1 f, A[] l) { return lambdaMapMethod(f, l); } static public void arrayfill(byte[] a, byte value) { fillArray(a, value); } static public void arrayfill(int[] a, int value) { fillArray(a, value); } static public void arrayfill(float[] a, float value) { fillArray(a, value); } static public void arrayfill(double[] a, double value) { fillArray(a, value); } static public List wideningListCast(Class c, List l) { return (List) l; } static public Collection wideningListCast(Class c, Collection l) { return (Collection) l; } static public List wideningListCast(List l) { return (List) l; } static public byte[] byteArrayForNBits(int n) { return byteArrayBitSet_new(n); } static public Pair, List> filterAntiFilterByBitSet(List list, byte[] bitSet) { int n = l(list), nSet = bitCount(bitSet); List l1 = emptyList(nSet); List l2 = emptyList(n - nSet); for (int i = 0; i < n; i++) (getBit(bitSet, i) ? l1 : l2).add(list.get(i)); return pair(l1, l2); } static public double transformToZeroToOne(double x, DoubleRange src) { return doubleRatio(x - src.start, src.length()); } static public double transformToZeroToOne(double x, double srcStart, double srcEnd) { return doubleRatio(x - srcStart, srcEnd - srcStart); } static public List pixelsByBrightness(IBWImage image) { float[] data = image.toFloatArray(); int n = l(data); int[] indices = new int[n]; for (int i = 0; i < n; i++) indices[i] = i; timSortIntArrayWithComparator(indices, (i, j) -> cmp(data[i], data[j])); int w = image.w(); return listFromFunction(n, i -> ptFromPixelIndex(indices[i], w)); } static public List pixelsInImage(BufferedImage image) { return pixelsInImage(image.getWidth(), image.getHeight()); } static public List pixelsInImage(Dimension size) { return pixelsInImage(toWidthAndHeight(size)); } static public List pixelsInImage(int size_w, int size_h) { return pixelsInImage(widthAndHeight(size_w, size_h)); } static public List pixelsInImage(WidthAndHeight size) { int h = size.h(), w = size.w(); return listFromFunction(w * h, idx -> pt(idx % w, idx / w)); } static public List mapCloseables_pcall(Iterable l, IF1 f) { List x = emptyList(l); if (l != null) for (A o : l) try { try { x.add(f.get(o)); } catch (Throwable __e) { pcallFail(__e); } } finally { _close(o); } return x; } static public List mapCloseables_pcall(IF1 f, Iterable l) { return mapCloseables_pcall(l, f); } static public void moveCaretAndScroll(JTextArea ta, LineAndColumn lac) { swing(() -> { moveCaretToLineAndCol(ta, lac); scrollTextAreaToLineAndCol(ta, lac); }); } static public SingleComponentPanel jReloadEvery(double interval, IF0 makeComponent) { SingleComponentPanel scp = singleComponentPanel(); if (makeComponent != null) awtEveryAndNow(scp, interval, () -> scp.setComponent(makeComponent.get())); return scp; } static public List vmArguments() { return runtimeMXBean().getInputArguments(); } static public A elementBefore(Collection l, A a) { A last = null; if (l != null) for (var b : l) { if (eq(a, b)) return last; last = b; } return null; } static public NotifyingList notifyingList(List innerList, Runnable onChange) { return new NotifyingList(innerList) { public void change() { onChange.run(); } }; } static public NotifyingList notifyingList(Runnable onChange) { return listWithNotify(onChange); } static public A getCyclic(List l, int i) { return cyclicGet(l, i); } static public boolean getCyclic(BitSet bs, int n, int i) { return cyclicGet(bs, n, i); } static public long getCyclic(LongBuffer l, int i) { return cyclicGet(l, i); } static public ISleeper_v2 sleeper() { var ps = pingSource(); return ps == null ? new MultiSleeper() : ps.sleeper(); } static public int intBufferBinarySearch(IntBuffer buf, int key) { return buf == null ? -1 : intArrayBinarySearch(buf.data, 0, buf.size(), key); } static public String nlToSpace(String s) { return newLinesToSpaces_trim(s); } static public void guarantee(Object o) { assertTrue(o); } static public boolean guarantee(String msg, boolean b) { return assertTrue(msg, b); } static public boolean guarantee(boolean b) { return assertTrue(b); } static public boolean guarantee(Scorer scorer, boolean b) { return assertTrue(scorer, b); } static public String nValues(long n) { return n2(n, "value"); } static public String nValues(Collection l) { return nValues(l(l)); } static public String nValues(Map map) { return nValues(l(map)); } static public void addMouseMotionListener(final JComponent c, final MouseMotionListener l) { if (c != null) { swing(() -> { c.addMouseMotionListener(l); }); } } static public Set addToSet_create(Set set, A a) { return createOrAddToSet(set, a); } static public String hjs(String script) { return hjs(script, (Object[]) null); } static public String hjs(String script, Object... __) { return hjavascript(script, __); } static public String hjs(JS script) { return hjs(script, (Object[]) null); } static public String hjs(JS script, Object... __) { return hjavascript(script == null ? null : script.get(), __); } static public List wrapLongArrayAsList(long[] l) { return new RandomAccessAbstractList() { public int size() { return l.length; } public Long get(int i) { return l[i]; } public Long set(int i, Long val) { Long a = l[i]; l[i] = val; return a; } }; } static public long lceil(double d) { return (long) Math.ceil(d); } static public double[] addToArrayWithDoublingStrategy(double[] array, int currentSize, double element) { if (currentSize >= l(array)) { array = resizeArray(array, max(1, limitToSafeArraySize(l(array) * 2L))); if (currentSize >= l(array)) throw fail("Can't handle more than 2 billion elements at once"); } array[currentSize++] = element; return array; } static public float[] addToArrayWithDoublingStrategy(float[] array, int currentSize, float element) { if (currentSize >= l(array)) { array = resizeArray(array, max(1, limitToSafeArraySize(l(array) * 2L))); if (currentSize >= l(array)) throw fail("Can't handle more than 2 billion elements at once"); } array[currentSize++] = element; return array; } static public long[] addToArrayWithDoublingStrategy(long[] array, int currentSize, long element) { if (currentSize >= l(array)) { array = resizeArray(array, max(1, limitToSafeArraySize(l(array) * 2L))); if (currentSize >= l(array)) throw fail("Can't handle more than 2 billion elements at once"); } array[currentSize++] = element; return array; } static public Double maxAllowingNull(Double a, Double b) { if (a == null) return b; if (b == null) return a; return Math.max(a, b); } static public void tok_ifdef(List tok, IF1 isDefined) { jreplace_dyn(tok, "ifdef or ", (_tok, cIdx) -> { String flag1 = tok.get(cIdx + 2), flag2 = tok.get(cIdx + 6); boolean value = isDefined.get(flag1) || isDefined.get(flag2); return "ifdef " + value; }); tok_conditionals(tok, "ifdef", "endifdef", isDefined, true, false); } static public void tok_pcall_script(List tok) { replaceKeywordBlock(tok, "pcall", "try {", "} catch __e { pcallFail __e }"); } static public void tok_script_settable(List tok) { int i; while ((i = jfind(tok, "settable :")) >= 0) { String id = tok.get(i + 2); int iType = i + 6; String type = tok_script_scanType(tok, i + 6); String getter = "def " + id + ": " + type + " { this !_getField_ " + id + "}"; String setter = "def " + id + " " + id + ": " + type + " { this " + id + " <- " + id + "; this }"; replaceToken_reTok(tok, i, joinWithSpace(getter, setter)); } } static public Class classForNameOpt_noCache(String name) { try { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; } } catch (Exception __e) { throw rethrow(__e); } } static public B[] valuesArray(Class valueType, Map map) { if (map == null) return null; synchronized (collectionMutex(map)) { int n = map.size(); B[] array = newArray(valueType, n); var it = valueIterator(map); for (int i = 0; i < n; i++) array[i] = it.next(); return array; } } static public List standardImports_singleClasses() { return notEndingWith(standardImports(), ".*"); } static public IterableIterator pixelIterator(Rect r) { return new IterableIterator() { public int x2 = r.x2(), y2 = r.y2(); public int x = r.x, y = r.y; public boolean hasNext() { return y < y2 && x < x2; } public Pt next() { Pt p = pt(x, y); if (++x >= x2) { x = r.x; ++y; } return p; } }; } static public String renderRecord(String recordName, Object... params) { return renderRecordVars(recordName, params); } static public String formatDouble3(double d) { return formatDouble(d, 3); } static public String signToUpDown(int sign) { return sign == 0 ? "" : sign > 0 ? "up" : "down"; } static public Rect combinedScreenBounds() { return mergeRects(allScreenBounds()); } static public long secondsToMS(double seconds) { return toMS(seconds); } static public String nCandles(long n) { return n2(n, "candle"); } static public String nCandles(Collection l) { return nCandles(l(l)); } static public String nCandles(Map map) { return nCandles(l(map)); } static public GridBagConstraints gridBagConstraints_vstack_1(int spacing) { return gridBagConstraints_vstack_1(spacing / 2, spacing / 2); } static public GridBagConstraints gridBagConstraints_vstack_1(int spacingTop, int spacingBottom) { GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = new Insets(spacingTop, 0, spacingBottom, 0); return gbc; } static public GridBagConstraints gridBagConstraints_vstack_rest() { GridBagConstraints gbc = gridBagConstraints_vstack_1(0); gbc.weighty = 1; return gbc; } static public Hi15Image posterizeBufferedImageToHi15(int brightnessLevels, MakesBufferedImage img) { return posterizeBufferedImageToHi15(brightnessLevels, toBufferedImage(img)); } static public Hi15Image posterizeBufferedImageToHi15(int brightnessLevels, BufferedImage img) { PosterizeBufferedImageToHi15 x = new PosterizeBufferedImageToHi15(brightnessLevels, img); return x.get(); } static public Hi15Image posterizeBufferedImageToHi15(IPosterizer posterizer, MakesBufferedImage img) { return posterizeBufferedImageToHi15(posterizer, toBufferedImage(img)); } static public Hi15Image posterizeBufferedImageToHi15(IPosterizer posterizer, BufferedImage img) { PosterizeBufferedImageToHi15 x = new PosterizeBufferedImageToHi15(posterizer, img); return x.get(); } static public Hi15Image posterizeBufferedImageToHi15(MakesBufferedImage img, IPosterizer posterizer) { return posterizeBufferedImageToHi15(toBufferedImage(img), posterizer); } static public Hi15Image posterizeBufferedImageToHi15(BufferedImage img, IPosterizer posterizer) { return posterizeBufferedImageToHi15(posterizer, img); } static public String shortClassName2(Object o) { if (o == null) return null; Class c = o.getClass(); String name = c.getName(); return shortenClassName(name); } static public JComponent jverticalCenter(Component c) { return jVerticalCenter(c); } static public String assertMD5(String s) { return assertPossibleMD5(s); } static public A setAndReturn(A o, String field, Object value) { set(o, field, value); return o; } static public A setAndReturn(IVar v, A value) { setVar(v, value); return value; } static public List listFilesWithExtension(File dir, String ext) { return listFilesWithSuffix(dir, addPrefixOptIfNempty(".", ext)); } static public List listFilesWithExtension(String ext, File dir) { return listFilesWithExtension(dir, ext); } static public String quoteOrEmpty(String s) { return quoteIfNempty(s); } static public A getSecretValue(SecretValue s) { return s == null ? null : s.get(); } static public boolean anyContainsIgnoreCase(Iterable strings, String pat) { return any(strings, s -> containsIgnoreCase(s, pat)); } static public A pollWaitUntilNotNull(int interval, double timeout, IF0 condition) { if (condition == null) return null; long start = sysNow(); while (sysNow() < start + toMS(timeout)) { { var __1 = condition.get(); if (__1 != null) return __1; } sleep(interval); } return null; } volatile static public boolean loading_value = true; static public boolean loading() { return loading_value; } static public boolean differentByEpsilonRatio(double a, double b, double epsilon) { return sign(a) != sign(b) || diffRatio(abs(a), abs(b)) > epsilon; } static public int[] subArray(int[] b, int start, int end) { int[] x = new int[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public byte[] subArray(byte[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start >= end) return new byte[0]; byte[] x = new byte[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public long[] subArray(long[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start >= end) return new long[0]; long[] x = new long[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public short[] subArray(short[] b, int start, int end) { if (start <= 0 && end >= l(b)) return b; short[] x = new short[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public float[] subArray(float[] b, int start, int end) { float[] x = new float[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public Object[] subArray(Object[] b, int start) { return subArray(b, start, l(b)); } static public Object[] subArray(Object[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start >= end) return new Object[0]; Object[] x = new Object[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public int clampToLength(int length, int i) { return clamp(i, 0, length - 1); } static public Map parseJSONMap(String s) { return jsonDecodeMap(s); } static public PriceDigitizer2 geometricPriceDigitizer(double c0, double cellSizeInPercent) { return new PriceDigitizer2(new GeometricPriceCells(c0, cellSizeInPercent)); } static public boolean guessDeepObjectSize_shouldIgnoreObject(Object o) { return o instanceof Component || o instanceof Thread || o instanceof ThreadLocal || startsWith(className(o), "sun."); } static public String getRealm(Object o) { if (o == null) return null; Object classLoader = _getClass(o).getClassLoader(); return (String) getOpt(classLoader, "progID"); } static public Map unsafe_sizeOf_cache = weakHashMap(); static public long unsafe_sizeOf(Object o) { if (isArray(o)) if (o instanceof Object[]) return inMemorySizeOfObjectArray(((Object[]) o).length); else return inMemorySizeOfPrimitiveArray(o); Class c = _getClass(o); Integer l = unsafe_sizeOf_cache.get(c); if (l == null) unsafe_sizeOf_cache.put(c, l = unsafe_sizeOf_uncached(c)); return l; } static public int unsafe_sizeOf_uncached(Class src) { int WORD = javaDataModelWordSize(); int MIN_SIZE = 16; List instanceFields = new ArrayList(); while (src != null && src != Object.class && empty(instanceFields)) { for (Field f : src.getDeclaredFields()) if ((f.getModifiers() & Modifier.STATIC) == 0) instanceFields.add(f); src = src.getSuperclass(); } long maxOffset = MIN_SIZE - 1; for (Field f : instanceFields) { long offset = unsafe_objectFieldOffset(f); if (offset > maxOffset) maxOffset = offset; } return (((int) maxOffset / WORD) + 1) * WORD; } static public TreeSet sizeCalculation_shouldSkipObject_set = asTreeSet(tlft("\r\n java.io.\r\n java.lang.reflect.\r\n java.awt.\r\n javax.swing.\r\n")); static public boolean sizeCalculation_shouldSkipObject(Object o) { if (o instanceof Reference) return true; return startsWithOneOf_treeSet(className(o), sizeCalculation_shouldSkipObject_set); } static final public Map> nonStaticNonPrimitiveFieldObjects_cache = dangerousWeakMap(); static public List nonStaticNonPrimitiveFieldObjects(Object o) { Class c = o.getClass(); List fields; synchronized (nonStaticNonPrimitiveFieldObjects_cache) { fields = nonStaticNonPrimitiveFieldObjects_cache.get(c); if (fields == null) nonStaticNonPrimitiveFieldObjects_cache.put(c, fields = nonStaticNonPrimitiveFieldObjects_uncached(c)); } return fields; } static public boolean isTransient(Field f) { return (f.getModifiers() & java.lang.reflect.Modifier.TRANSIENT) != 0; } static public void g22_adaptSyntaxTextAreaForHashRefs(RSyntaxTextArea ta, G22Utils g22utils) { onLeftClick(ta, (IVF1) pt -> { int ofs = ta.viewToModel2D(toPoint(pt)); List tok = hashRefTok(ta.getText()); int iTok = charToTokenIndex_left(tok, ofs); if (odd(iTok) && inRange(iTok, tok)) { String t = tok.get(iTok); String url = deRoundBracket(dropPrefix("#", t)); g22utils.projectActions.openPathInProject(url); } }); ((RSyntaxDocument) ta.getDocument()).setSyntaxStyle(new HashRefTokenMaker()); for (var token : ll(org.fife.ui.rsyntaxtextarea.Token.WHITESPACE, org.fife.ui.rsyntaxtextarea.Token.IDENTIFIER)) ta.getSyntaxScheme().setStyle(token, new org.fife.ui.rsyntaxtextarea.Style(Color.black)); } static public int lFloatArray(float[] a) { return a == null ? 0 : a.length; } static public float[] resizeFloatArray(float[] a, int n) { return resizeArray(a, n); } static public ArrayList floatArrayToList(float[] a) { if (a == null) return null; return floatArrayToList(a, 0, a.length); } static public ArrayList floatArrayToList(float[] a, int from, int to) { if (a == null) return null; ArrayList l = new ArrayList<>(to - from); for (int i = from; i < to; i++) l.add(a[i]); return l; } static public float[] subFloatArray(float[] b, int start) { return subFloatArray(b, start, l(b)); } static public float[] subFloatArray(float[] b, int start, int end) { start = max(start, 0); end = min(end, l(b)); if (start == 0 && end == l(b)) return b; if (start >= end) return new float[0]; float[] x = new float[end - start]; System.arraycopy(b, start, x, 0, end - start); return x; } static public List toBufferedImages(Iterable l) { return allToBufferedImage(l); } static public IterableIterator mapI_pcall(final Object f, final Iterator i) { return new IterableIterator() { public boolean hasNext() { return i.hasNext(); } public Object next() { return pcallF(f, i.next()); } }; } static public IterableIterator mapI_pcall(IterableIterator i, Object f) { return mapI_pcall((Iterator) i, f); } static public IterableIterator mapI_pcall(Object f, IterableIterator i) { return mapI_pcall((Iterator) i, f); } static public IterableIterator mapI_pcall(Iterator i, Object f) { return mapI_pcall(f, i); } static public IterableIterator mapI_pcall(Iterable i, IF1 f) { return mapI_pcall(i, (Object) f); } static public IterableIterator mapI_pcall(Iterable i, Object f) { return mapI_pcall(f, i.iterator()); } static public IterableIterator mapI_pcall(Object f, Iterable i) { return mapI_pcall(i, f); } static public A conceptWhereCI(Class c, Object... params) { return findConceptWhereCI(c, params); } static public Concept conceptWhereCI(String c, Object... params) { return findConceptWhereCI(db_mainConcepts(), c, params); } static public A conceptWhereCI(Concepts concepts, Class c, Object... params) { return findConceptWhereCI(concepts, c, params); } static public Concept conceptWhereCI(Concepts concepts, String c, Object... params) { return findConceptWhereCI(concepts, c, params); } static public A optimizedUniqCI(Class c, Object... params) { return optimizedUniqCI(db_mainConcepts(), c, params); } static public A optimizedUniqCI(Concepts cc, Class c, Object... params) { { var __1 = conceptWhereCI(cc, c, params); if (__1 != null) return __1; } return uniqCI(cc, c, params); } static public IF0 toIF0(final Object f) { if (f == null) return null; if (f instanceof IF0) return ((IF0) f); if (f instanceof Runnable) return () -> { ((Runnable) f).run(); return null; }; if (isString(f)) return mainFunctionToIF0((String) f); return (IF0) () -> callF(f); } static public boolean directoryIsEmpty(File f) { return !fileExists(f) || isDirectory(f) && empty(listFiles(f)); } static public boolean validFileName(String s) { return isValidFileName(s); } static public String dropHashFromClassName(String className) { return regexpReplace(className, "_[0-9a-f]{32}$", ""); } static public List allCausesIncludingSelf(Throwable t) { List out = new ArrayList(); while (t != null) { out.add(t); t = t.getCause(); } return out; } static public List mapNotNulls(Iterable l, Object f) { return mapNonNulls(l, f); } static public List mapNotNulls(Object f, Object[] l) { return mapNonNulls(f, l); } static public List mapNotNulls(Object f, Iterable l) { return mapNonNulls(f, l); } static public List mapNotNulls(Iterable l, F1 f) { return mapNonNulls(l, f); } static public List mapNotNulls(IF1 f, Iterable l) { return mapNonNulls(f, l); } static public List mapNotNulls(Iterable l, IF1 f) { return mapNonNulls(l, f); } static public List mapNotNulls(F1 f, Iterable l) { return mapNonNulls(f, l); } static public List uniquifyWith(IF1 f, Collection l) { return uniquifyBy(f, l); } static public List uniquifyWith(Collection l, IF1 f) { return uniquifyBy(l, f); } static public JComboBox centerComboBoxAndItems(JComboBox cb) { return swing(() -> { if (cb != null) { var r = cb.getRenderer(); cb.setRenderer(new CenteredComboBoxRenderer(r).centerItems(true)); centerTextField(textFieldFromComboBox(cb)); } return cb; }); } static public List sortedByFieldAlphanumIC(Collection c, final String field) { List l = new ArrayList(c); sort(l, (a, b) -> cmpAlphanumIC(getString(a, field), getString(b, field))); return l; } static public List sortedByFieldAlphanumIC(String field, Collection c) { return sortedByFieldAlphanumIC(c, field); } static public long hashImage2B(IBinaryImage img) { return hashBinaryImage(img); } static public IF0 g22defaultMaskSideLength; static public int g22defaultMaskSideLength() { return g22defaultMaskSideLength != null ? g22defaultMaskSideLength.get() : g22defaultMaskSideLength_base(); } final static public int g22defaultMaskSideLength_fallback(IF0 _f) { return _f != null ? _f.get() : g22defaultMaskSideLength_base(); } static public int g22defaultMaskSideLength_base() { return 32; } static public Image2B g22standardRegionToMaskImage(IImageRegion region, WidthAndHeight maskSize) { return toImage2B(scaledIBinaryImage(maskSize, regionToIBinaryImage(region))); } static public PatchworkImage patchworkImagesAsSquare(Iterable> l) { return patchworkImagesVH(listToSquareishChunks(asList(l))); } static public String formatPrice(double price) { return formatDouble_significant(price, 6); } static public void changeKeyAndModifyValue(Map map, A oldKey, A newKey, IF1 f) { if (map == null || eq(oldKey, newKey) || !map.containsKey(oldKey)) return; B value = map.get(oldKey); map.put(newKey, f.get(value)); map.remove(oldKey); } static public String tok_extractRoundBracketBody(String s) { List tok = javaTok(s); IntRange r = tok_findRoundBracketBody(tok); return r == null ? null : joinSubList(tok, r.start + 1, r.end - 1); } static public void changeKey(Map map, Object oldKey, Object newKey) { if (map == null || eq(oldKey, newKey) || !map.containsKey(oldKey)) return; map.put(newKey, map.get(oldKey)); map.remove(oldKey); } static public JSlider looselyBindLiveValueToSlider(IVarWithNotify lv, JSlider slider) { onChange(slider, () -> lv.set(intFromSlider(slider))); bindToComponent(slider, () -> { Integer value = lv.get(); if (value != null) setSliderValue(slider, value); else lv.set(intFromSlider(slider)); }); return slider; } static public A onComponentShown(A component, Runnable onShow) { return bindToComponent(component, onShow, null); } static public A toJComponent(A c) { return c; } static public JComponent toJComponent(Swingable c) { return c == null ? null : c.visualize(); } static public String dropTrailingBackslashR(String s) { int i = l(s); while (i > 0 && s.charAt(i - 1) == '\r') --i; return substring(s, 0, i); } static public Decolorizer defaultDecolorizer() { return new Decolorizer.Simple(); } static public boolean securelyTossCoin() { return odd(new SecureRandom().nextInt()); } static public String squareBracketUnlessEmpty(String s) { return empty(s) ? "" : squareBracket(s); } static public String formatPercentage(double percent) { return formatPercentage(percent, 1); } static public String formatPercentage(double percent, int decimals) { return formatDouble(percent, decimals) + "%"; } static public String simpleQuoteOpt(String s) { return s == null ? null : isNormalQuoted_dirty(s) ? s : simpleQuote(s); } static public double[] mapToDoubleArray(Collection l, IF1 f) { int n = l(l); double[] a = new double[n]; Iterator it = iterator(l); for (int i = 0; i < n; i++) a[i] = f.get(it.next()); return a; } static public double[] mapToDoubleArray(double[] l, IF1_DoubleToDouble f) { int n = l(l); double[] a = new double[n]; for (int i = 0; i < n; i++) a[i] = f.get(l[i]); return a; } static public long[] longArrayFromBytes_littleEndian_flexLength(byte[] a) { long[] b = new long[(a.length + 7) / 8]; for (int i = 0; i < b.length; i++) b[i] = longFromBytes_littleEndian_partial(a, i * 8); return b; } static public long[] cloneLongArray(long[] a) { if (a == null) return null; long[] b = new long[a.length]; System.arraycopy(a, 0, b, 0, a.length); return b; } static public A printIf(boolean b, A a) { if (b) print(a); return a; } static public A printIf(boolean b, String s, A a) { if (b) print(s, a); return a; } static public List llNempties(String... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (String x : a) if (nempty(x)) l.add(x); return l; } static public String trading_directionToPositionType(double direction) { return direction == 0 ? null : direction > 0 ? "long" : "short"; } static public String formatHoursMinutesColonSeconds(double seconds) { return formatHoursMinutesColonSeconds(toMS(seconds)); } static public String formatHoursMinutesColonSeconds(long ms) { long seconds = iround(toSeconds(ms)); long hours = seconds / (60 * 60); String s = ""; if (hours > 0) { s = hours + ":"; seconds -= hours * 60 * 60; s += formatInt(seconds / 60, 2); } else s = str(seconds / 60); return s + ":" + formatInt(mod(seconds, 60), 2); } static public double diffRatio(double a, double b) { return 1 - doubleRatio(min(a, b), max(a, b)); } static public double roundTo(double n, double x) { return round(doubleRatio(x, n)) * n; } static public A shallowCloneToUnlistedConcept(Class c, Object o) { if (o == null) return null; A cc = unlisted(c); copyFields(o, cc, conceptFields(c)); return cc; } static public A shallowCloneToUnlistedConcept(A o) { return o == null ? null : (A) shallowCloneToUnlistedConcept(o.getClass(), o); } static public double msToHours(long ms) { return toHours(ms); } static public ImageSurface imageSurfaceWithToolTip() { var is = newImageSurface(); new ImageSurface_PositionToolTip(is); return is; } static public JScrollPane jscroll_horizontal_borderless(JComponent c) { return borderlessScrollPane(jscrollHorizontal(c)); } static public IntRange roundToIntRange(DoubleRange r) { return r == null ? null : new IntRange(iround(r.start), iround(r.end)); } static public String formatDouble3X(double d) { return formatDoubleX(d, 3); } static public String formatDouble_significant(double d, int digits) { return formatDouble_significant2(d, digits); } static public int withFullAlpha(int rgb) { return rgb | fullAlphaMask(); } static public Color withFullAlpha(Color color) { return hasAlpha(color) ? new Color(color.getRGB()) : color; } static public BufferedImage bufferedImageWithAlpha(int w, int h, int[] pixels) { return newBufferedImageWithAlpha(w, h, pixels); } static public BufferedImage bufferedImageWithAlpha(int[] pixels, int w, int h) { return newBufferedImageWithAlpha(w, h, pixels); } static public IterableIterator uniqueIterator(Iterator it) { HashSet set = new HashSet(); return iff(() -> { while (licensed()) { if (!it.hasNext()) return endMarker(); A a = it.next(); if (set.add(a)) return a; } return endMarker(); }); } static public IterableIterator reversedIterator(final List l) { return new IterableIterator() { public int i = l(l) - 1; public boolean hasNext() { return i >= 0; } public A next() { return l.get(i--); } }; } static public List reversedKeysList(Map map) { return reversedList(keysList(map)); } static public List reversedKeysList(MultiSet ms) { return ms == null ? null : reversedKeysList(ms.map); } static public boolean stdEq_nonTransient(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 : nonTransientNonStaticFields(a)) if (neq(getOpt(a, field), getOpt(b, field))) return false; return true; } static public int stdHash_nonTransient(Object a) { if (a == null) return 0; return stdHash(a, toStringArray(nonTransientNonStaticFields(a))); } static public A addComponent(final A c, final Component component) { if (component != null) { swing(() -> { c.add(component); revalidate(c); }); } return c; } static public void scrollIntoView(JComponent c) { if (c != null) { swing(() -> { c.scrollRectToVisible(new Rectangle(0, 0, c.getWidth(), c.getHeight())); }); } } static public Pt topLeft(Rect r) { return rectTopLeftCorner(r); } static public int[] sumOfBinaryImages(List images) { int n = l(images); if (n == 0) return null; var it = iterator(images); var img = it.next(); int w = img.getWidth(), h = img.getHeight(); int[] pixels = new int[w * h]; int nBytes = (w * h + 7) / 8; var pingSource = pingSource(); while (true) { ping(pingSource); Image2B realizedImage = img.toImage2B(); byte[] imgPixels = realizedImage.pixels; int j = 0; for (int i = 0; i < nBytes; i++) { int b = imgPixels[i]; for (int bit = 0; bit < 8; bit++) { pixels[j++] += b & 1; b >>= 1; } } if (!it.hasNext()) break; img = it.next(); } return pixels; } static public FloatBWImage preciseCertaintyImage(IBWImage img) { return floatBWImageFromFunction(img.getWidth(), img.getHeight(), (x, y) -> g22pixelCertainty(img.getFloatPixel(x, y))); } static public double g22pixelCertainty(double pixel) { return absdiff(pixel, 0.5) * 2; } static public int[] intArray_minus(int[] array, int x) { if (x == 0 || empty(array)) return array; int n = array.length; int[] b = new int[n]; for (int i = 0; i < n; i++) b[i] = array[i] - x; return b; } static public int[] intArray_minus(int x, int[] array) { return intArray_minus(array, x); } static public int[] intArray_minus(int[] array1, int[] array2) { int n = l(array1); if (l(array2) != n) throw fail("Need same size"); if (n == 0) return array1; int[] b = new int[n]; for (int i = 0; i < n; i++) b[i] = array1[i] - array2[i]; return b; } static public JButton heldButton() { return heldInstance(JButton.class); } static public void fillArrayUnlessZero(byte[] a, byte value) { if (value != 0) Arrays.fill(a, value); } static public void fillArrayUnlessZero(int[] a, int value) { if (value != 0) Arrays.fill(a, value); } static public void fillArrayUnlessZero(float[] a, float value) { if (value != 0) Arrays.fill(a, value); } static public double floatSumAsDouble(Iterable l) { double sum = 0; for (Float i : unnull(l)) if (i != null) sum += i; return sum; } static public double floatSumAsDouble(float... l) { double sum = 0; if (l != null) for (float i : l) sum += i; return sum; } static public JComponent jTodo() { return jcenteredlabel("TODO"); } static public void putCRUDButtonsNextToSearchBar(SimpleCRUD_v2 crud) { var searcher = crud.tableSearcher(); searcher.scpRightOfSearchPanel.set(crud.wrappedButtonBar); } static public String appendPrefix(String prefix, String s) { return addPrefix(prefix, s); } static public String nMasks(long n) { return n2(n, "mask"); } static public String nMasks(Collection l) { return nMasks(l(l)); } static public String nMasks(Map map) { return nMasks(l(map)); } static public String shortenClassNames(String s) { return regexpReplace(s, "[\\w\\.\\$]+", matcher -> shortenClassName(matcher.group())); } static public String[] mapToStringArray(Map map) { List l = new ArrayList(); for (Object o : keys(map)) { l.add(o); l.add(map.get(o)); } return toStringArray(l); } static public String[] mapToStringArray(IF1 f, Iterable l) { return toStringArray(map(f, l)); } static public String[] mapToStringArray(Iterable l, IF1 f) { return mapToStringArray(f, l); } static public String resolvableClassToName(Type type) { if (type instanceof IResolvableClass) return ((IResolvableClass) type).resolveToClassName(); return null; } static public int oneIfZero(int i) { return i == 0 ? 1 : i; } static public int arrayHashCode(byte[] a) { return Arrays.hashCode(a); } static public int iroundTowardsWithOutwardEpsilon(double a, double b, double epsilon) { return a > b ? ifloor(a + epsilon) : iceil(a - epsilon); } static public 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; } static public 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)) * (1 / (3f * 255)); } static public LineAndColumn caretLineAndCol(JTextComponent tc) { Pair p = textAndCaretPosition(tc); return charIndexToLineAndColumn(p.a, p.b); } static public void g22markPointAnimation(ImageSurface is, Pt pt) { is.addOverlay(g -> { var p = scalePt(pt, is.getZoomX(), is.getZoomY()); double blend = zeroToOneSine(frac(sysSeconds())); drawSquareAround(g, p, 1, blendColor(blend, Color.green, Color.red)); drawSquareAround(g, p, 2, blendColor(blend, Color.red, Color.green)); drawSquareAround(g, p, 3, blendColor(blend, Color.white, Color.black)); }); repaintEvery(is, 100); } static public JPanel hgridWithSpacing(Object... _parts) { return swing(() -> { int spacing = 6; Object[] parts = _parts; if (first(parts) instanceof Integer) { spacing = (Integer) first(parts); parts = dropFirst(parts); } JPanel panel = hgrid(parts); GridLayout gl = (GridLayout) (panel.getLayout()); gl.setHgap(spacing); gl.setVgap(spacing); return panel; }); } static public A jMinWidth0(A c) { return jMinWidth_pure(0, c); } static public List trimToSize(List l) { synchronized (l) { if (l instanceof ArrayList) ((ArrayList) l).trimToSize(); else if (l instanceof SynchronizedArrayList) ((SynchronizedArrayList) l).trimToSize(); } return l; } static public BWImage gazelle22_borderImage(BWImage posterizedWithMeta) { PosterizeBWImage op = (PosterizeBWImage) (getMetaSrc(posterizedWithMeta)); return gazelle22_borderImage(op.img, posterizedWithMeta, op.brightnessLevels); } static public BWImage gazelle22_borderImage(BWImage unposterized, BWImage posterized, int brightnessLevels) { assertSameSize(unposterized, posterized); int w = posterized.getWidth(), h = posterized.getHeight(); BWImage out = new BWImage(w * 2 + 1, h * 2 + 1); int singleStep = iceil(doubleRatio(255, brightnessLevels - 1)); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (x < w - 1) { int posterizedContrast = absDiff(posterized.getInt(x, y), posterized.getInt(x + 1, y)); float result; if (posterizedContrast != 0) { if (posterizedContrast > singleStep) result = 1f; else { int realContrast = absDiff(unposterized.getInt(x, y), unposterized.getInt(x + 1, y)); result = floatRatio(realContrast, singleStep); } out.setPixel(x * 2 + 1, y * 2, result); out.setPixel(x * 2 + 1, y * 2 + 1, result); } } if (y < h - 1) { int posterizedContrast = absDiff(posterized.getInt(x, y), posterized.getInt(x, y + 1)); float result; if (posterizedContrast != 0) { if (posterizedContrast > singleStep) result = 1f; else { int realContrast = absDiff(unposterized.getInt(x, y), unposterized.getInt(x + 1, y)); result = floatRatio(realContrast, singleStep); } out.setPixel(x * 2, y * 2 + 1, result); out.setPixel(x * 2 + 1, y * 2 + 1, result); } } } return out; } static public double trueRange(List lastCandles) { if (l(lastCandles) < 2) return Double.NaN; var c1 = nextToLast(lastCandles); var c2 = last(lastCandles); return max(c2.high(), c1.close()) - min(c2.low(), c1.close()); } static public ImageSurface imageSurfaceCheckerBoardBackground(ImageSurface is) { if (is.drawBackground != null) return is; double pixelsPerSecond = 8; is.drawBackground = (w, h, g) -> { var cb = new CheckerBoard2().w(w).h(h); double time = sysSeconds(); int shift = iround(time * pixelsPerSecond); cb.shiftX(shift).shiftY(shift); cb.drawOn(g); }; setDoubleBuffered(is); repaintEvery(1.0 / pixelsPerSecond, is); return is; } static public Image2B regionToBinaryImage(IImageRegion region) { return new RegionToImage2B(region).get(); } static public BufferedImage centerImageOnBackground(Color bg, WidthAndHeight size, BufferedImage img) { if (img == null) return null; BufferedImage canvas = newBufferedImage(size, bg); drawImageOnImage(img, canvas, (size.w() - img.getWidth()) / 2, (size.h() - img.getHeight()) / 2); return canvas; } static public long oneMegabyte() { return 1024 * 1024; } static public int guessImageSizeInMemory(BufferedImage image) { if (image == null) return 0; var buf = image.getRaster().getDataBuffer(); return (int) (buf.getDataTypeSize(buf.getDataType()) * (long) buf.getSize() / 8); } static public BufferedImage scaleBufferedImageToMaxWidthOrHeight(WidthAndHeight size, BufferedImage img) { return img == null ? null : scaleBufferedImageToMaxWidthOrHeight(size.w(), size.h(), img); } static public BufferedImage scaleBufferedImageToMaxWidthOrHeight(int maxW, BufferedImage img) { return scaleBufferedImageToMaxWidthOrHeight(maxW, maxW, img); } static public BufferedImage scaleBufferedImageToMaxWidthOrHeight(int maxW, int maxH, BufferedImage img) { if (img == null) return null; int w = img.getWidth(), h = img.getHeight(); if (w <= maxW && h <= maxH) return img; double scale = min(doubleRatio(maxW, w), doubleRatio(maxH, h)); return scaleImage(img, scale); } static public BufferedImage scaleBufferedImageToMaxWidthOrHeight(BufferedImage img, int max) { return scaleBufferedImageToMaxWidthOrHeight(max, img); } static public int binaryImagePixelDifference_sameSize(Image2B img1, Image2B img2) { assertSameSize(img1, img2); return countDifferingBits(img1.pixels, img2.pixels); } static public int binaryImagePixelDifference_sameSize(Image2BAsInts img1, Image2BAsInts img2) { assertSameSize(img1, img2); return countDifferingBits(img1.pixels, img2.pixels); } static public int binaryImagePixelDifference_sameSize(Image2BAsLongs img1, Image2BAsLongs img2) { assertSameSize(img1, img2); return countDifferingBits(img1.pixels, img2.pixels); } static public double liftProbabilityOffGround(double p) { double epsilon = 0.01; return 1 - (1 - p) * (1 - epsilon); } static public MultiSetMap multiSetMap_innerLinkedHashSet_outerRevTreeMap() { return multiSetMap_outerDescTreeMap_innerLinkedHashSet(); } static public B lastValue(NavigableMap map) { if (map == null) return null; Map.Entry entry = map.lastEntry(); return entry == null ? null : entry.getValue(); } static public NavigableMap> castMultiSetMapToNavigableMap(MultiSetMap m) { return (NavigableMap) multiSetMapToMap(m); } static public IterableIterator multiSetMapValuesIterator(MultiSetMap mm) { return nestedIterator(values(mm.data), __1 -> iterator(__1)); } static public void hideControls() { { swing(() -> { removeFromConsole2(showControls_controls); showControls_controls = null; }); } } static public void addToConsole2(Component toAdd) { Container cp = consoleMainContainer(); if (cp == null) return; Container cp2 = (Container) getCenterComponent(cp); replaceCenterComponent(cp, centerAndSouth(cp2, toAdd)); validateFrame(cp); } static public Runnable rThread(final Object f) { return new Runnable() { public void run() { try { { startThread(new Runnable() { public void run() { try { callF(f); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(f);"; } }); } } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "thread { callF(f); }"; } }; } static public byte[] byteArrayBitSet_new(int n) { return n == 0 ? null : new byte[(n + 7) >> 3]; } static final public int timSortIntArrayWithComparator_RUN = 32; static public void timSortIntArrayWithComparator_insertionSort(int[] arr, IntComparator comparator, int left, int right) { for (int i = left + 1; i <= right; i++) { int temp = arr[i]; int j = i - 1; while (j >= left && comparator.compare(arr[j], temp) > 0) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = temp; } } static public void timSortIntArrayWithComparator_merge(int[] arr, IntComparator comparator, int l, int m, int r) { int len1 = m - l + 1, len2 = r - m; int[] left = new int[len1]; int[] right = new int[len2]; for (int x = 0; x < len1; x++) { left[x] = arr[l + x]; } for (int x = 0; x < len2; x++) { right[x] = arr[m + 1 + x]; } int i = 0; int j = 0; int k = l; while (i < len1 && j < len2) { if (comparator.compare(left[i], right[j]) <= 0) { arr[k] = left[i]; i++; } else { arr[k] = right[j]; j++; } k++; } while (i < len1) { arr[k] = left[i]; k++; i++; } while (j < len2) { arr[k] = right[j]; k++; j++; } } static public void timSortIntArrayWithComparator(int[] arr, IntComparator comparator) { timSortIntArrayWithComparator(arr, lIntArray(arr), comparator); } static public void timSortIntArrayWithComparator(int[] arr, int n, IntComparator comparator) { for (int i = 0; i < n; i += timSortIntArrayWithComparator_RUN) { timSortIntArrayWithComparator_insertionSort(arr, comparator, i, Math.min((i + 31), (n - 1))); } for (int size = timSortIntArrayWithComparator_RUN; size < n; size = 2 * size) { for (int left = 0; left < n; left += 2 * size) { int mid = Math.min(left + size - 1, n - 1); int right = Math.min(left + 2 * size - 1, n - 1); timSortIntArrayWithComparator_merge(arr, comparator, left, mid, right); } } } static public Pt ptFromPixelIndex(int index, int w) { return pt(index % w, index / w); } static public void scrollTextAreaToLineAndCol(JTextArea ta, LineAndColumn lac) { try { swing(() -> { try { int pos = ta.getLineStartOffset(lac.line - 1) + lac.col - 1; Rectangle viewRect = ta.modelToView(pos); printVars("scrollTextAreaToLineAndCol", "lac", lac, "pos", pos, "viewRect", viewRect); if (viewRect != null) setEnclosingViewPosition(ta, viewRect.x, viewRect.y); } catch (Exception __e) { throw rethrow(__e); } }); } catch (Throwable __e) { pcallFail(__e); } } static public RuntimeMXBean runtimeMXBean() { return ManagementFactory.getRuntimeMXBean(); } static public NotifyingList listWithNotify(Runnable onChange) { return listWithNotify(new ArrayList(), onChange); } static public NotifyingList listWithNotify(List l, Runnable onChange) { return new NotifyingList(l) { public void change() { onChange.run(); } }; } static public int intArrayBinarySearch(int[] a, int key) { return intArrayBinarySearch(a, 0, a.length, key); } static public int intArrayBinarySearch(int[] a, int fromIndex, int toIndex, int key) { int low = fromIndex; int high = toIndex - 1; while (low <= high) { int mid = (low + high) >>> 1; int midVal = a[mid]; if (midVal < key) low = mid + 1; else if (midVal > key) high = mid - 1; else return mid; } return -(low + 1); } static public String newLinesToSpaces_trim(String s) { return s == null ? null : trim(s).replaceAll("\\s*\r?\n\\s*", " "); } static public String hjavascript(String scriptOrURL, Object... __) { if (isRelativeOrAbsoluteURL(scriptOrURL) && !startsWithOneOf(scriptOrURL, "//", "/*")) return hjavascript_src(scriptOrURL, __); else return tag("script", scriptOrURL, paramsPlus(__, "type", "text/javascript")); } static public Object[] resizeArray(Object[] a, int n) { if (n == l(a)) return a; Object[] b = new Object[n]; arraycopy(a, 0, b, 0, min(l(a), n)); return b; } static public double[] resizeArray(double[] a, int n) { if (n == l(a)) return a; double[] b = new double[n]; arraycopy(a, 0, b, 0, min(l(a), n)); return b; } static public float[] resizeArray(float[] a, int n) { if (n == l(a)) return a; float[] b = new float[n]; arraycopy(a, 0, b, 0, min(l(a), n)); return b; } static public long[] resizeArray(long[] a, int n) { if (n == l(a)) return a; long[] b = new long[n]; arraycopy(a, 0, b, 0, min(l(a), n)); return b; } static public int limitToSafeArraySize(long n) { return (int) Math.min(maximumSafeArraySize(), n); } static public String jreplace_dyn(String s, String in, Object out) { return jreplace_dyn(s, in, out, null); } static public String jreplace_dyn(String s, String in, Object out, Object condition) { List tok = javaTok(s); jreplace_dyn(tok, in, out, condition); return join(tok); } static public boolean jreplace_dyn(List tok, String in, Object out) { return jreplace_dyn(tok, in, out, false, true, null); } static public boolean jreplace_dyn(List tok, String in, IF0 out) { return jreplace_dyn(tok, in, if0ToIF2(out)); } static public boolean jreplace_dyn(List tok, String in, ITokCondition cond, IF0 out) { return jreplace_dyn(tok, in, cond, if0ToIF2(out)); } static public boolean jreplace_dyn(List tok, String in, IF1 out) { return jreplace_dyn(tok, in, (_tok, cIdx) -> out.get(cIdx)); } static public boolean jreplace_dyn(List tok, String in, IF2, Integer, String> out) { return jreplace_dyn(tok, in, (Object) out); } static public boolean jreplace_dyn(List tok, String in, IF2, Integer, String> out, IF2, Integer, Boolean> condition) { return jreplace_dyn(tok, in, (Object) out, (Object) condition); } static public boolean jreplace_dyn(List tok, String in, Object out, Object condition) { return jreplace_dyn(tok, in, out, false, true, condition); } static public boolean jreplace_dyn(List tok, String in, Object out, boolean ignoreCase, boolean reTok, Object condition) { List tokin = javaTok(in); jfind_preprocess(tokin); String[] toks = toStringArray(codeTokensOnly(tokin)); boolean anyChange = false; for (int n = 0; n < 10000; n++) { int i = findCodeTokens(tok, 1, ignoreCase, toks, condition); if (i < 0) return anyChange; String expansion = (String) (callF(out, tok, i)); int end = i + l(tokin) - 2; clearAllTokens(tok, i, end); tok.set(i, expansion); if (reTok) reTok(tok, i, end); anyChange = true; } throw fail("woot? 10000! " + quote(in) + " => " + quote(out)); } static public int tok_conditionals(List tok, String keyword, String keywordEnd, IF1 pred, boolean reTokImmediately, boolean noReTok) { int changes = 0; if (tok instanceof IContentsIndexedList) { int[] l = ((IContentsIndexedList) tok).indicesOf(keyword); for (int j = l(l) - 1; j >= 0; j--) { int i = l[j]; if (isIdentifier(get(tok, i + 2))) { tok_conditionals_processConditional(tok, i, keyword, keywordEnd, pred, reTokImmediately && !noReTok); ++changes; } } } else { if (!tok.contains(keyword)) return changes; int i = l(tok); while ((i = rjfind(tok, 1, i - 1, keyword + " ")) >= 0) { ++changes; tok_conditionals_processConditional(tok, i, keyword, keywordEnd, pred, reTokImmediately && !noReTok); } } if (changes != 0 && !reTokImmediately && !noReTok) reTok(tok); return changes; } static public void tok_conditionals_processConditional(List tok, int i, String keyword, String keywordEnd, IF1 pred, boolean reTokImmediately) { int j = jfind(tok, i + 4, keywordEnd); if (j < 0) j = l(tok) - 1; String name = tok.get(i + 2); boolean has = pred.get(name); if (has) { clearTokens_maybeReTok(tok, j, j + 1, reTokImmediately); clearTokens_maybeReTok(tok, i, i + 3, reTokImmediately); } else clearTokens_maybeReTok(tok, i, j + 1, reTokImmediately); } static public List replaceKeywordBlock(List tok, String keyword, String beg, String end) { return replaceKeywordBlock(tok, keyword, beg, end, false, null); } static public List replaceKeywordBlock(List tok, String keyword, String beg, String end, Object cond) { return replaceKeywordBlock(tok, keyword, beg, end, false, cond); } static public List replaceKeywordBlock(List tok, String keyword, String beg, String end, boolean debug, Object cond) { for (int n = 0; n < 1000; n++) { int i = jfind(tok, keyword + " {", cond); if (i < 0) break; int idx = findCodeTokens(tok, i, false, "{"); int j = findEndOfBracketPart(tok, idx); if (debug) { print(toUpper(keyword) + " BEFORE\n" + join(subList(tok, i, j))); print(" THEN " + join(subList(tok, j, j + 10))); } List subList = subList(tok, i - 1, idx); tok.set(j - 1, jreplaceExpandRefs(end, subList)); replaceTokens(tok, i, idx + 1, jreplaceExpandRefs(beg, subList)); reTok(tok, i, j); if (debug) print(toUpper(keyword) + "\n" + join(subList(tok, i, j)) + "\n"); } return tok; } static public String tok_script_scanType(List tok, int iTypeStart) { int iEndOfType = tok_script_findEndOfType(tok, iTypeStart); return joinSubList_cToC(tok, iTypeStart, iEndOfType); } static public void replaceToken_reTok(List tok, int i, String t) { tokSet_withReTok(tok, i, t); } static public A[] newArray(Class c, int n) { return typedArray(c, n); } static public Iterator valueIterator(Map map) { return map == null ? emptyItIt() : map.values().iterator(); } static public List notEndingWith(Collection l, final String suffix) { return filter(unnull(l), new F1() { public Boolean get(String s) { try { return !endsWith(s, suffix); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "!endsWith(s, suffix)"; } }); } static public List notEndingWith(String suffix, Collection l) { return notEndingWith(l, suffix); } static public String assertPossibleMD5(String s) { if (!possibleMD5(s)) throw fail("Not an MD5 signature: " + s); return s; } static public void setVar(IVar v, A value) { if (v != null) v.set(value); } static public IVF1 setVar(IVar v) { return a -> { if (v != null) v.set(a); }; } static public String quoteIfNempty(String s) { return empty(s) ? "" : quote(s); } static public long inMemorySizeOfObjectArray(int length) { return roundUpTo(javaDataModelWordSize(), unsafe_sizeOf(_SimulatedArrayStub.class) + java_pointerSize() * ((long) length)); } static public long inMemorySizeOfPrimitiveArray(Object o) { return roundUpTo(javaDataModelWordSize(), unsafe_sizeOf(_SimulatedArrayStub.class) + primitiveTypeSize(arrayElementType(o)) * ((long) Array.getLength(o))); } static public int javaDataModelWordSize_value; static public int javaDataModelWordSize() { if (javaDataModelWordSize_value == 0) javaDataModelWordSize_value = Integer.valueOf(System.getProperty("sun.arch.data.model")) / 8; return javaDataModelWordSize_value; } static public long unsafe_objectFieldOffset(Field f) { return (long) call(theUnsafe_gen(), "objectFieldOffset", f); } static public boolean startsWithOneOf_treeSet(String s, TreeSet set) { if (set == null || s == null) return false; while (licensed()) { String key = set.floor(s); if (key == null) return false; int n = lCommonPrefix(key, s); if (n == l(key)) return true; s = takeFirst(s, n); } return false; } static public Map dangerousWeakMap() { return newDangerousWeakHashMap(); } static public Map dangerousWeakMap(Object initFunction) { return newDangerousWeakHashMap(initFunction); } static public List nonStaticNonPrimitiveFieldObjects_uncached(Object o) { List fields = new ArrayList(); Class _c = _getClass(o); do { for (Field f : _c.getDeclaredFields()) if ((f.getModifiers() & Modifier.STATIC) == 0 && !isPrimitiveType(f.getType())) fields.add(makeAccessible(f)); _c = _c.getSuperclass(); } while (_c != null); return fields; } static public IF0 mainFunctionToIF0(final String fname) { return (IF0) () -> callMC(fname); } static public List uniquifyBy(IF1 f, 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(f.get(a))) out.add(a); return out; } static public List uniquifyBy(Collection l, IF1 f) { return uniquifyBy(f, l); } static public PatchworkImage patchworkImagesVH(Collection>> l) { return mergePatchworkImagesVertically(map(__122 -> patchworkBufferedImagesHorizontally(__122), l)); } static public IntRange tok_findRoundBracketBody(List tok) { return tok_findRoundBracketBody(tok, 1); } static public IntRange tok_findRoundBracketBody(List tok, int i) { int idx = findCodeTokens(tok, i, false, "("); if (idx < 0) return null; int j = findEndOfBracketPart(tok, idx); return intRange(idx, j); } static public boolean isNormalQuoted_dirty(String s) { return startsWith(s, "\"") && endsWith(s, "\"") && l(s) >= 2; } static public long longFromBytes_littleEndian_partial(byte[] a, int i) { return (ubyteToLong(i + 7 >= a.length ? 0 : a[i + 7]) << 56 | (ubyteToLong(i + 6 >= a.length ? 0 : a[i + 6]) << 48 | (ubyteToLong(i + 5 >= a.length ? 0 : a[i + 5]) << 40 | (ubyteToLong(i + 4 >= a.length ? 0 : a[i + 4]) << 32 | (ubyteToLong(i + 3 >= a.length ? 0 : a[i + 3]) << 24 | (ubyteToLong(i + 2 >= a.length ? 0 : a[i + 2]) << 16 | (ubyteToLong(i + 1 >= a.length ? 0 : a[i + 1]) << 8 | ubyteToLong(a[i])))))))); } static public ImageSurface newImageSurface() { return (ImageSurface) swing(new F0() { public Object get() { try { return new ImageSurface(); } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "return new ImageSurface;"; } }); } static public BufferedImage newBufferedImageWithAlpha(int w, int h, int[] pixels) { return intArrayToBufferedImage(pixels, w, h); } static public LineAndColumn charIndexToLineAndColumn(String text, int charIndex) { int line = 1, col = 1; charIndex = min(charIndex, l(text)); for (int i = 0; i < charIndex; i++) { if (text.charAt(i) == '\n') { ++line; col = 1; } else ++col; } return new LineAndColumn(line, col); } static public void drawSquareAround(Graphics2D g, int p_x, int p_y, int radius, Color color) { drawSquareAround(g, pt(p_x, p_y), radius, color); } static public void drawSquareAround(Graphics2D g, Pt p, int radius, Color color) { drawRect(g, p.x - radius, p.y - radius, radius * 2 + 1, radius * 2 + 1, color); } static public A repaintEvery(int ms, A c) { return awtDoEvery(c, ms, () -> c.repaint()); } static public A repaintEvery(double seconds, A c) { return awtDoEvery(c, seconds, () -> c.repaint()); } static public A repaintEvery(A c, int ms) { return repaintEvery(ms, c); } static public MultiSetMap multiSetMap_outerDescTreeMap_innerLinkedHashSet() { return new MultiSetMap(descTreeMap()) { public Set _makeEmptySet() { return new LinkedHashSet(); } }; } static public Map> multiSetMapToMap(MultiSetMap m) { return m == null ? null : m.data; } static public void removeFromConsole2(Component c) { JFrame frame = getFrame(c); if (frame == null) return; Container cp = frame.getContentPane(); cp = (Container) getCenterComponent(cp); if (cp != c.getParent()) { print("removeFromWindow fail"); return; } cp.remove(c); Container mainC = (Container) cp.getComponents()[0]; cp.remove(mainC); replaceCenterComponent(frame.getContentPane(), mainC); validateFrame(frame); } static public Container consoleMainContainer_value; static public Container consoleMainContainer() { Container c = (Container) (callOpt(creator(), "consoleMainContainer")); if (c != null) return c; if (consoleMainContainer_value != null) return consoleMainContainer_value; JFrame frame = consoleFrame(); if (frame == null) return null; return consoleMainContainer_value = frame.getContentPane(); } static public void replaceCenterComponent(Container container, Component c) { Component old = getCenterComponent(container); if (old != null) container.remove(old); container.add(c, BorderLayout.CENTER); } static public void validateFrame(Component c) { revalidateFrame(c); } static public String hjavascript_src(String src, Object... __) { return hfulltag("script", "", paramsPlus(__, "src", src)); } static public IF2 if0ToIF2(IF0 f) { return f == null ? null : (a, b) -> f.get(); } static public int rjfind(List tok, String in) { return rjfind(tok, 1, in); } static public int rjfind(List tok, int startIdx, String in) { return rjfind(tok, startIdx, in, null); } static public int rjfind(List tok, int startIdx, int endIndex, String in) { return rjfind(tok, startIdx, endIndex, in, null); } static public int rjfind(List tok, String in, ITokCondition condition) { return rjfind(tok, 1, in, (Object) condition); } static public int rjfind(List tok, String in, Object condition) { return rjfind(tok, 1, in, condition); } static public int rjfind(List tok, int startIdx, String in, Object condition) { List tokin = javaTok(in); jfind_preprocess(tokin); return rjfind(tok, startIdx, tokin, condition); } static public int rjfind(List tok, int startIdx, int endIndex, String in, Object condition) { List tokin = javaTok(in); jfind_preprocess(tokin); return rjfind(tok, startIdx, endIndex, tokin, condition); } static public int rjfind(List tok, List tokin) { return rjfind(tok, 1, tokin); } static public int rjfind(List tok, int startIdx, List tokin) { return rjfind(tok, startIdx, tokin, null); } static public int rjfind(List tok, int startIdx, List tokin, Object condition) { return rfindCodeTokens(tok, startIdx, false, toStringArray(codeTokensOnly(tokin)), condition); } static public int rjfind(List tok, int startIdx, int endIndex, List tokin, Object condition) { return rfindCodeTokens(tok, startIdx, endIndex, false, toStringArray(codeTokensOnly(tokin)), condition); } static public void clearTokens_maybeReTok(List tok, int i, int j, boolean reTok) { clearTokens(tok, i, j); if (reTok) reTok(tok, i, j); } static public String toUpper(String s) { return s == null ? null : s.toUpperCase(); } static public List toUpper(Collection s) { return allToUpper(s); } static public int tok_script_findEndOfType(List tok) { return tok_script_findEndOfType(tok, 1); } static public int tok_script_findEndOfType(List tok, int i) { while (licensed()) { if (eqGet(tok, i + 2, ".") && isIdentifier(get(tok, i + 4))) { i += 4; continue; } if (eqGet(tok, i + 2, "<") && isIdentifier(get(tok, i + 4))) { i = findEndOfTypeArgs(tok, i + 2) - 1; continue; } if (eqGet(tok, i + 2, "[")) { i = findEndOfBracketPart2(tok, i + 2) - 1; continue; } break; } return i + 2; } static public String joinSubList_cToC(List l, int i, int j) { return joinSubList(l, i | 1, j & ~1); } static public void tokSet_withReTok(List tok, int i, String t) { put(tok, i, t); reTok(tok, i, i + 1); } static public A[] typedArray(Class c, int n) { return (A[]) Array.newInstance(c, n); } static public int java_pointerSize() { boolean c = compressedOOPSEnabled(); return compressedOOPSEnabled_is64bitHotSpot && !c ? 8 : 4; } static public int primitiveTypeSize(Class c) { if (c == byte.class || c == boolean.class) return 1; if (c == short.class || c == char.class) return 2; if (c == int.class || c == float.class) return 4; if (c == long.class || c == double.class) return 8; return 0; } static public Class arrayElementType(Object o) { return _getClass(o).getComponentType(); } static public Object theUnsafe_gen_theUnsafe; static public Object theUnsafe_gen() { if (theUnsafe_gen_theUnsafe == null) theUnsafe_gen_theUnsafe = get(classForName("sun.misc.Unsafe"), "theUnsafe"); return theUnsafe_gen_theUnsafe; } static public PatchworkImage mergePatchworkImagesVertically(List> images, Object... __) { if (empty(images)) return null; int spacing = optPar("spacing", __, imageMergeSpacing()); int h = intSum(mapMethod("h", images)) + (l(images) - 1) * spacing; int w = intMax(mapMethod("w", images)); PatchworkImage out = new PatchworkImage<>(w, h); int y = 0; for (var img : images) { int x = (w - img.w()) / 2; for (var patch : img.patches) out.addPatch(patch.image, x + patch.bounds.x, y + patch.bounds.y, patch.userValue); y += img.h() + spacing; } return out; } static public PatchworkImage patchworkBufferedImagesHorizontally(List> imagesAndValues, Object... __) { if (empty(imagesAndValues)) return null; int spacing = optPar("spacing", __, imageMergeSpacing()); var images = pairsA(imagesAndValues); int w = intSum(mapMethod("getWidth", images)) + (l(images) - 1) * spacing; int h = intMax(mapMethod("getHeight", images)); PatchworkImage out = new PatchworkImage<>(w, h); int x = 0; for (var imageAndValue : imagesAndValues) { BufferedImage img = imageAndValue.a; int y = (h - img.getHeight()) / 2; out.addPatch(img, x, y, imageAndValue.b); x += img.getWidth() + spacing; } return out; } static public long ubyteToLong(byte b) { return b & 0x0FFL; } static public long ubyteToLong(char c) { return c & 0x0FFL; } static public A awtDoEvery(A component, long delay, Runnable r) { return awtEvery(component, delay, r); } static public A awtDoEvery(A component, long delay, long firstDelay, Runnable r) { return awtEvery(component, delay, firstDelay, r); } static public void awtDoEvery(RootPaneContainer frame, long delay, Runnable r) { awtEvery(frame, delay, r); } static public A awtDoEvery(A component, double delaySeconds, Runnable r) { return awtEvery(component, delaySeconds, r); } static public void revalidateFrame(Component c) { revalidate(getFrame(c)); } static public int rfindCodeTokens(List tok, String... tokens) { return rfindCodeTokens(tok, 1, false, tokens); } static public int rfindCodeTokens(List tok, boolean ignoreCase, String... tokens) { return rfindCodeTokens(tok, 1, ignoreCase, tokens); } static public int rfindCodeTokens(List tok, int startIdx, boolean ignoreCase, String... tokens) { return rfindCodeTokens(tok, startIdx, ignoreCase, tokens, null); } static public List rfindCodeTokens_specials = litlist("*", "", "", "", "\\*"); static public boolean rfindCodeTokens_debug = false; static public int rfindCodeTokens_indexed, rfindCodeTokens_unindexed; static public int rfindCodeTokens_bails, rfindCodeTokens_nonbails; static public int rfindCodeTokens(List tok, int startIdx, boolean ignoreCase, String[] tokens, Object condition) { return rfindCodeTokens(tok, startIdx, l(tok), ignoreCase, tokens, condition); } static public int rfindCodeTokens(List tok, int startIdx, int endIndex, boolean ignoreCase, String[] tokens, Object condition) { if (rfindCodeTokens_debug) { if (eq(getClassName(tok), "main$IndexedList2")) rfindCodeTokens_indexed++; else rfindCodeTokens_unindexed++; } if (!rfindCodeTokens_specials.contains(tokens[0]) && !tok.contains(tokens[0])) { ++rfindCodeTokens_bails; return -1; } ++rfindCodeTokens_nonbails; outer: for (int i = min(endIndex, tok.size() - tokens.length * 2) | 1; i >= startIdx; i -= 2) { for (int j = 0; j < tokens.length; j++) { String p = tokens[j], t = tok.get(i + j * 2); boolean match = false; if (eq(p, "*")) match = true; else if (eq(p, "")) match = isQuoted(t); else if (eq(p, "")) match = isIdentifier(t); else if (eq(p, "")) match = isInteger(t); else if (eq(p, "\\*")) match = eq("*", t); else match = ignoreCase ? eqic(p, t) : eq(p, t); if (!match) continue outer; } if (condition == null || checkTokCondition(condition, tok, i - 1)) return i; } return -1; } static public List allToUpper(Collection l) { List x = new ArrayList(l(l)); if (l != null) for (String s : l) x.add(upper(s)); return x; } static public int findEndOfTypeArgs(List cnc, int i) { int j = i + 2, level = 1; while (j < cnc.size()) { if (cnc.get(j).equals("<")) ++level; else if (cnc.get(j).equals(">")) --level; if (level == 0) return j + 1; ++j; } return cnc.size(); } static public int findEndOfBracketPart2(List cnc, int i) { int j = i + 2, level = 1; while (j < cnc.size()) { if (eqOneOf(cnc.get(j), "{", "(", "[")) ++level; else if (eqOneOf(cnc.get(j), "}", ")", "]")) --level; if (level == 0) return j + 1; ++j; } return cnc.size(); } static public boolean compressedOOPSEnabled_is64bitHotSpot = false; static public boolean compressedOOPSEnabled_compressedOOPS = false; static public boolean compressedOOPSEnabled_checked = false; static public boolean compressedOOPSEnabled() { if (compressedOOPSEnabled_checked) return compressedOOPSEnabled_compressedOOPS; String OS_ARCH = System.getProperty("os.arch"); String MANAGEMENT_FACTORY_CLASS = "java.lang.management.ManagementFactory"; String HOTSPOT_BEAN_CLASS = "com.sun.management.HotSpotDiagnosticMXBean"; String x = System.getProperty("sun.arch.data.model"); boolean is64Bit = contains(or(x, OS_ARCH), "64"); if (is64Bit) { compressedOOPSEnabled_is64bitHotSpot = true; compressedOOPSEnabled_compressedOOPS = !eq("false", getHotspotVMOption("UseCompressedOops")); } compressedOOPSEnabled_checked = true; return compressedOOPSEnabled_compressedOOPS; } static public Object getHotspotVMOption(String optionName) { try { String MANAGEMENT_FACTORY_CLASS = "java.lang.management.ManagementFactory"; String HOTSPOT_BEAN_CLASS = "com.sun.management.HotSpotDiagnosticMXBean"; Class beanClazz = Class.forName(HOTSPOT_BEAN_CLASS); Object hotSpotBean = call(Class.forName(MANAGEMENT_FACTORY_CLASS), "getPlatformMXBean", beanClazz); if (hotSpotBean == null) return null; Object vmOption = call(hotSpotBean, "getVMOption", optionName); return call(vmOption, "getValue"); } catch (Throwable __e) { print(exceptionToStringShort(__e)); } return null; } public interface IF1_DoubleToDouble { public double get(double i); } static public class PosterizeBufferedImageToHi15 { public BufferedImage img; public Hi15Image result; public IPosterizer posterizer; public PosterizeBufferedImageToHi15(int brightnessLevels, BufferedImage img) { this.img = img; if (brightnessLevels >= 256 || img == null) posterizer = new DummyPosterizer(); posterizer = new SinglePixelPosterizer(brightnessLevels); } public PosterizeBufferedImageToHi15(IPosterizer posterizer, BufferedImage img) { this.img = img; this.posterizer = posterizer; } public void run() { try { if (img == null) return; if (posterizer instanceof DummyPosterizer) { result = new Hi15Image(img); return; } GrabbableRGBBytePixels gp = grabbableRGBBytePixels(img); if (gp != null) { run(gp); return; } GrabbableIntPixels gp2 = grabbableIntPixels_fastOrSlow(img); run(gp2); } catch (Exception __e) { throw rethrow(__e); } } public void run(GrabbableIntPixels gp) { int w = img.getWidth(), h = img.getHeight(), n = w * h; int[] pixels = gp.data; short[] pixels2 = new short[n]; byte[] cache = cachePosterizer(); int extraStride = gp.scanlineStride - w; int iOut = 0, iIn = gp.offset; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int rgb = pixels[iIn++]; pixels2[iOut++] = (short) ((cache[(rgb >> 16) & 0xFF] << 10) | (cache[(rgb >> 8) & 0xFF] << 5) | cache[rgb & 0xFF]); } iIn += extraStride; } result = new Hi15Image(w, h, pixels2); } public void run(GrabbableRGBBytePixels gp) { int w = img.getWidth(), h = img.getHeight(), n = w * h; byte[] pixels = gp.data; short[] pixels2 = new short[n]; byte[] cache = cachePosterizer(); int extraStride = gp.scanlineStride - w * 3; int iOut = 0, iIn = gp.offset; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int r = pixels[iIn++] & 0xFF; int g = pixels[iIn++] & 0xFF; int b = pixels[iIn++] & 0xFF; pixels2[iOut++] = (short) ((cache[r] << 10) | (cache[g] << 5) | cache[b]); } iIn += extraStride; } result = new Hi15Image(w, h, pixels2); } public BufferedImage pixelPreservingSrcImage() { return img; } public Hi15Image get() { if (result == null) run(); return result; } public byte[] cachePosterizer() { byte[] cache = new byte[256]; for (int i = 0; i < 256; i++) cache[i] = (byte) (posterizer.get(i) >> 3); return cache; } } static public interface IntComparator { public int compare(int a, int b); } static public class MultiPullbackJuicer extends StopLossJuicer { public MultiPullbackJuicer() { } static public class Level { final public Level setMinJuiceValue(double minJuiceValue) { return minJuiceValue(minJuiceValue); } public Level minJuiceValue(double minJuiceValue) { this.minJuiceValue = minJuiceValue; return this; } final public double getMinJuiceValue() { return minJuiceValue(); } public double minJuiceValue() { return minJuiceValue; } public double minJuiceValue; final public Level setKeepPercentage(double keepPercentage) { return keepPercentage(keepPercentage); } public Level keepPercentage(double keepPercentage) { this.keepPercentage = keepPercentage; return this; } final public double getKeepPercentage() { return keepPercentage(); } public double keepPercentage() { return keepPercentage; } public double keepPercentage; public String toString() { return "Keep " + keepPercentage + "% starting at " + formatDouble2(minJuiceValue); } } public transient FieldVar> varLevels_cache; public FieldVar> varLevels() { if (varLevels_cache == null) varLevels_cache = varLevels_load(); return varLevels_cache; } public FieldVar> varLevels_load() { return new FieldVar>(this, "levels", () -> levels(), levels -> levels(levels)); } final public MultiPullbackJuicer setLevels(List levels) { return levels(levels); } public MultiPullbackJuicer levels(List levels) { if (!eq(this.levels, levels)) { this.levels = levels; change(); } return this; } final public List getLevels() { return levels(); } public List levels() { return levels; } public List levels = new ArrayList(); public transient FieldVar varCrest_cache; public FieldVar varCrest() { if (varCrest_cache == null) varCrest_cache = varCrest_load(); return varCrest_cache; } public FieldVar varCrest_load() { return new FieldVar(this, "crest", () -> crest(), crest -> crest(crest)); } final public MultiPullbackJuicer setCrest(double crest) { return crest(crest); } public MultiPullbackJuicer crest(double crest) { if (!eq(this.crest, crest)) { this.crest = crest; change(); } return this; } final public double getCrest() { return crest(); } public double crest() { return crest; } public double crest = -infinity(); public transient FieldVar varCurrentMaxPullback_cache; public FieldVar varCurrentMaxPullback() { if (varCurrentMaxPullback_cache == null) varCurrentMaxPullback_cache = varCurrentMaxPullback_load(); return varCurrentMaxPullback_cache; } public FieldVar varCurrentMaxPullback_load() { return new FieldVar(this, "currentMaxPullback", () -> currentMaxPullback(), currentMaxPullback -> currentMaxPullback(currentMaxPullback)); } final public MultiPullbackJuicer setCurrentMaxPullback(double currentMaxPullback) { return currentMaxPullback(currentMaxPullback); } public MultiPullbackJuicer currentMaxPullback(double currentMaxPullback) { if (!eq(this.currentMaxPullback, currentMaxPullback)) { this.currentMaxPullback = currentMaxPullback; change(); } return this; } final public double getCurrentMaxPullback() { return currentMaxPullback(); } public double currentMaxPullback() { return currentMaxPullback; } public double currentMaxPullback; { onCalculatingCloseSignals(signals -> { if (juiceValue > crest) crest(juiceValue); if (crest < 0) return; double keepPercentage = getKeepPercentageForJuiceValue(crest); if (keepPercentage > 100) return; double toKeep = crest * (keepPercentage / 100); currentMaxPullback(crest - toKeep); var signal = new CloseSignal().createdBy(this).reason("Profit"); if (currentMaxPullback == 0) signal.strength(100); else signal.strength(doubleRatio(crest - juiceValue, currentMaxPullback) * 100); signals.add(signal); }); } public double getKeepPercentageForJuiceValue(double juice) { for (int i = l(levels) - 1; i >= 0; i--) { Level level = levels.get(i); if (juice < level.minJuiceValue) continue; Level nextLevel = get(levels, i + 1); if (nextLevel == null) return level.keepPercentage; return blend(level.keepPercentage, nextLevel.keepPercentage, transformToZeroToOne(juice, level.minJuiceValue, nextLevel.minJuiceValue)); } return 101; } public void addLevel(double minJuiceValue, double keepPercentage) { levels.add(new Level().minJuiceValue(minJuiceValue).keepPercentage(keepPercentage)); } public String toString() { return commaCombine(shortClassName(this), !stopLossEnabled ? null : "Stop loss: " + formatDouble2(stopLossLimit()), levels, crest == -infinity() ? null : "Highest profit seen: " + formatDouble2(crest), currentMaxPullback == 0 ? null : "Current max pullback: " + formatDouble2(currentMaxPullback)); } public void copyTransientValuesFrom(AbstractJuicer juicer) { if (juicer instanceof MultiPullbackJuicer) crest(((MultiPullbackJuicer) juicer).crest); } } static public interface IContentsIndexedList extends List { public int[] indicesOf(A o); } static public class Image2BAsInts implements IBinaryImage { public Image2BAsInts() { } public int w, h; public int[] pixels; public Image2BAsInts(int w, int h, int[] pixels) { this.pixels = pixels; this.h = h; this.w = w; cleanPixelArray(); } public Image2BAsInts(Image2B img) { w = img.getWidth(); h = img.getHeight(); pixels = intArrayFromBytes_littleEndian_flexLength(img.pixels); } public Image2BAsInts(Image2BAsInts img) { w = img.getWidth(); h = img.getHeight(); pixels = cloneIntArray(img.pixels); } public Image2BAsInts(RGBImage img) { w = img.getWidth(); h = img.getHeight(); pixels = new int[(w * h + 31) / 32]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) if (img.getPixel(x, y).getBrightness() >= 0.5f) { int i = y * w + x; pixels[i / 32] |= 1 << (i & 31); } } public Image2BAsInts(BWImage img) { this(img, 1232); } public Image2BAsInts(BWImage img, int threshold) { w = img.w(); h = img.h(); int n = w * h; int nOut = (n + 31) / 32; int[] pixels = this.pixels = new int[nOut]; byte[] bwPixels = img.pixels; int iIn = 0; for (int iOut = 0; iOut < nOut - 1; iOut++) { int value = 0; for (int bit = 0; bit < 32; bit++) { value >>>= 1; if (ubyteToInt(bwPixels[iIn++]) >= threshold) value |= 0x80000000; } pixels[iOut] = value; } for (; iIn < n; iIn++) if (ubyteToInt(bwPixels[iIn]) >= threshold) pixels[nOut - 1] |= 1 << (iIn & 31); } public Image2BAsInts(BufferedImage img) { this(img, 128); } public Image2BAsInts(BufferedImage img, int threshold) { this(new BWImage(img), threshold); } public Image2BAsInts(int w, int h) { this.h = h; this.w = w; pixels = new int[(w * h + 31) / 32]; } public RGBImage toRGB() { RGBImage img = new RGBImage(w, h, Color.black); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 32] & (1 << (i & 31))) != 0) img.setPixel(x, y, Color.white); } return img; } public BWImage toBW() { BWImage img = new BWImage(w, h, 0f); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int i = y * w + x; if ((pixels[i / 32] & (1 << (i & 31))) != 0) img.setPixel(x, y, 1f); } return img; } public BufferedImage getBufferedImage() { return toBW().getBufferedImage(); } final public boolean getBoolPixel(int x, int y) { return getPixel(x, y); } public boolean getPixel(int x, int y) { int i = y * w + x; return (pixels[i / 32] & (1 << (i & 31))) != 0; } final public boolean getBoolPixel(int x, int y, boolean defaultColor) { return getPixel(x, y, defaultColor); } public boolean getPixel(int x, int y, boolean defaultColor) { if (x < 0 || y < 0 || x >= w || y >= h) return defaultColor; return getPixel(x, y); } public void setPixel(int x, int y, boolean b) { int i = y * w + x; int val = pixels[i / 32], shifted = (int) (1 << (i & 31)); val = (int) (b ? val | shifted : val & ~shifted); pixels[i / 32] = val; } public void setPixel(int x, int y) { int i = y * w + x; pixels[i / 32] |= 1 << (i & 31); } public int getWidth() { return w; } public int getHeight() { return h; } public String toString() { return "Image2B " + str_px(w, h); } public void cleanPixelArray() { int n = w * h; if ((n & 31) != 0) pixels[n / 32] &= (1 << (n & 31)) - 1; } } static public class _SimulatedArrayStub { public int len; } static public class GrabbableRGBBytePixels implements IFieldsToList { static final public String _fieldOrder = "data w h offset scanlineStride pixelStride"; public byte[] data; public int w; public int h; public int offset; public int scanlineStride; public int pixelStride; public GrabbableRGBBytePixels() { } public GrabbableRGBBytePixels(byte[] data, int w, int h, int offset, int scanlineStride, int pixelStride) { this.pixelStride = pixelStride; this.scanlineStride = scanlineStride; this.offset = offset; this.h = h; this.w = w; this.data = data; } public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + data + ", " + w + ", " + h + ", " + offset + ", " + scanlineStride + ", " + pixelStride + ")"; } public boolean equals(Object o) { if (!(o instanceof GrabbableRGBBytePixels)) return false; GrabbableRGBBytePixels __1 = (GrabbableRGBBytePixels) o; return eq(data, __1.data) && w == __1.w && h == __1.h && offset == __1.offset && scanlineStride == __1.scanlineStride && pixelStride == __1.pixelStride; } public int hashCode() { int h = 330924690; h = boostHashCombine(h, _hashCode(data)); h = boostHashCombine(h, _hashCode(w)); h = boostHashCombine(h, _hashCode(h)); h = boostHashCombine(h, _hashCode(offset)); h = boostHashCombine(h, _hashCode(scanlineStride)); h = boostHashCombine(h, _hashCode(pixelStride)); return h; } public Object[] _fieldsToList() { return new Object[] { data, w, h, offset, scanlineStride, pixelStride }; } } static public GrabbableRGBBytePixels grabbableRGBBytePixels(BufferedImage img) { Raster raster = img.getRaster(); SampleModel _sampleModel = raster.getSampleModel(); if (!(_sampleModel instanceof PixelInterleavedSampleModel)) return null; var imageModel = img.getColorModel(); if (imageModel != ColorModel.getRGBdefault()) return null; PixelInterleavedSampleModel sampleModel = (PixelInterleavedSampleModel) _sampleModel; DataBufferByte dataBuffer = (DataBufferByte) (raster.getDataBuffer()); assertEquals(1, dataBuffer.getNumBanks()); assertEquals(DataBuffer.TYPE_BYTE, dataBuffer.getDataType()); int w = img.getWidth(), h = img.getHeight(); int pixelStride = sampleModel.getPixelStride(); int scanlineStride = sampleModel.getScanlineStride(); byte[] pixels = dataBuffer.getData(); int offset = dataBuffer.getOffset(); int translateX = raster.getSampleModelTranslateX(); int translateY = raster.getSampleModelTranslateY(); offset += -translateX - translateY * scanlineStride; return new GrabbableRGBBytePixels(pixels, w, h, offset, scanlineStride, pixelStride); } static public int[] intArrayFromBytes_littleEndian_flexLength(byte[] a) { int[] b = new int[(a.length + 3) / 4]; for (int i = 0; i < b.length; i++) b[i] = intFromBytes_littleEndian_partial(a, i * 4); return b; } static public int[] cloneIntArray(int[] a) { if (a == null) return null; int[] b = new int[a.length]; System.arraycopy(a, 0, b, 0, a.length); return b; } }