Warning: session_start(): open(/var/lib/php/sessions/sess_auu4kaissg63nl8v2ss3dujgqt, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
lib 1400521 // FlatLAF
set flag PingV3.
set flag NotifyingPrintLog.
set flag SymbolAsString.
// Do the JavaX init
svoid standaloneInit {
__javax = x30.class;
x30.__javax = x30.class; // for hotwire
x30_pkg.x30_util.__setJavaX(x30.class);
x30.cleanKillMsg = "";
callOnLoadMethods(mc());
}
concept PrintLogModule > DynPrintLog {
start { setModuleName("Log"); }
S getPrintLog() {
ret printLog();
}
bool useErrorHandling() { false; }
}
concept Stem is AutoCloseable {
transient GazelleHost host;
transient LoadedDB db;
DynModule module;
Rect frameRect;
bool minimized, maximized, alwaysOnTop, minimizeToTray;
transient JFrame window;
transient JButton btnMax;
transient JLabel titleComponent;
transient gettable JButton compileButton;
//transient bool autoUpdateDisabled;
*() {}
*(LoadedDB *db) { host = db.host; }
*(LoadedDB db, DynModule *module) { this(db); }
Rect getFrameRect() {
ret toRect(getBounds(window));
}
void saveFrameRect {
setField(frameRect := getFrameRect());
}
void setAlwaysOnTop(bool alwaysOnTop) {
this.alwaysOnTop = alwaysOnTop;
change();
alwaysOnTop(window, alwaysOnTop);
}
void setMinimizeToTray(bool minimizeToTray) {
cset(this, +minimizeToTray);
}
void setWindow(JFrame window) {
this.window = window;
if (frameRect != null)
setBounds(window, frameRect);
//onWindowClosing(window, -> host.cleanExit());
onBoundsChange(window, r saveFrameRect);
alwaysOnTop(window, alwaysOnTop);
}
void activateWindow {
activateFrame_v3(window);
}
bool isMain() { ret this == db.mainStem; }
void minimize {
cset(this, minimized := true);
if (!minimizeToTray || host.trayIcon == null || !isMain())
minimizeWindow(window);
else
hideWindow(window);
}
void deleteMe {
printAlsoToSystemOut = true;
print("deleteMe " + isMain());
if (isMain())
host.closeDatabase(db);
else
delete();
}
close {
disposeWindow(window);
cleanUp(module);
}
void delete :: before {
close();
}
void grabWindowState {
setField(maximized := !isExtendedStateNormal(window));
}
void updateBtnMax {
if (!isShowing(btnMax)) ret;
grabWindowState();
setText(btnMax, maximized ? "NORM" : "MAX");
}
JComponent makeWindowBorderAndTitle(JComponent contents, S title) {
//ret jCenteredSection_fontSizePlus(10, title, vis);
var icons = jline();
if (host.allowFrameMaximization) {
icons.add(btnMax = jbutton("", rThread {
maximizeOrRestoreFrame(window);
updateBtnMax();
}));
onFirstShowing(btnMax, r updateBtnMax);
}
icons.add(toolTip("Minimize this window", jbutton("MIN", r minimize)));
icons.add(toolTip("Close this window", jimageButtonScaledToWidth(16, #1103067, rThread deleteMe)));
//setHorizontalMarginForAllButtons(icons, 4);
icons.add(jPopDownButton_noText(flattenToList(
// always on top
jCheckBoxMenuItem_dyn("Always on top",
-> alwaysOnTop,
alwaysOnTop -> setAlwaysOnTop(alwaysOnTop)),
// quit, restart + update
"---",
"Exit Gazelle", rThread { host.cleanExit() },
"Restart", rThread { host.restart() },
"Re-open project", rThread { host.reopenDB(db) },
"Update Gazelle", rThread { host.upgradeGazelle() },
!isMain() ? null : jCheckBoxMenuItem_dyn("Auto-Update",
-> db.g22utils.autoUpdateEnabled(),
b -> db.g22utils.setAutoUpdate(b)),
// debugging + screenshooting gazelle
"---",
!isMain() ? null : ll(
"Screenshoot this window", rThread shootWindow,
"Dump threads", rThread { showText("User threads", renderUserThreadsWithStackTraces()); },
!isMain() ? null : "Log", !isMain() ? null : r { db.showPrintLog() },
!isMain() ? null : "Copy log to clipboard", !isMain() ? null : rThread {
copyToClipboard(printLog());
infoBox("Copied log to clipboard");
},
),
ccallOpt(module, "popDownItems")
)));
JComponent actualTitle = titleComponent = fontSizePlus(7, jCenteredLabel(title));
installWindowDragger(actualTitle);
if (/*isMain() &&*/ host.devMode())
actualTitle = centerAndEastWithMargin(actualTitle,
jline(
compileButton = makeCompileButton(),
installWindowDragger(lblComputerAndUserCount()),
));
var spacer = gazelle_wavySpacer();
var titleBarMain = setOpaqueBackground(host.color1,
jtransparent_recursive(westCenterAndEastWithMargin(
jImage_scaledToHeight(24, host.trayIconImageID),
actualTitle,
setOpaqueBackground(host.color2, spacer)));
installWindowDragger(spacer);
var titleBar = setBackground(host.color2, centerAndEast(
titleBarMain,
icons));
var border =
// createBevelBorder();
BorderFactory.createLineBorder(host.color1, host.borderSize);
var outerPanel = withBorder(border,
northAndCenter(titleBar, contents));
installWindowResizeDraggerOnBorder(outerPanel);
ret markVisualizer(this, outerPanel);
}
JLabel lblComputerAndUserCount() {
JLabel label = jlabel();
Runnable update = -> {
Int computerCount = host.computerCount();
Int userCount = host.lvGazelleUserCount()!;
setText(label,
(computerCount == null ? "" : n2(computerCount))
+ appendSquareBracketed(
userCount == null ? "" : n2(userCount)));
};
bindChangeListenerToComponent(label, host.lvComputerCount(), update);
bindChangeListenerToComponent(label, host.lvGazelleUserCount(), update);
ret label;
}
JButton makeCompileButton() {
var gears = resizeImageIcon(imageIcon(#1103061), 16);
var btn = jimageButtonScaledToWidth(16, #1101268, "Compile & update",
rThread { host.compile() });
//enableComponentAccordingToVar(host.compileButtonEnabled, btn);
componentPopupMenuItem(btn, "Compile main library", rThread { host.compileUtils() });
ret btn;
}
void startAndShow() {
module._host = this;
setOpt_raw(module, +threadPool); // only if the field exists
setOpt_raw(module, concepts := db.concepts);
setOpt_raw(module, g22utils := db.g22utils);
copyLocalLog(module, mc());
var vis, title = unpair makeVisAndTitle();
printWithMS("Show frame");
JFrame frame = makeUndecoratedFrame(title, vis);
setFrameIcon(frame, host.trayIconImageID);
setWindow(frame);
frame.addPropertyChangeListener("title", evt ->
setText(titleComponent, frame.getTitle()));
if (minimized) minimize();
onWindowDeiconified(frame, -> cset(this, minimized := false));
showWindow(window);
if (maximized && host.allowFrameMaximization) maximizeFrame(window);
}
Pair makeVisAndTitle() {
JComponent vis;
{
printWithMS("Starting " + module);
temp module.enter();
module.start();
printWithMS("Visualize");
vis = swing(-> {
temp module.enter();
ret module.visualize();
});
}
S title = host.windowTitle;
if (isMain())
title += appendWithColon(module.moduleName());
else
title = unnull(module.moduleName());
vis = makeWindowBorderAndTitle(vis, title);
ret pair(vis, title);
}
void revisualize {
if (window == null) ret;
pcall {
module.unvisualize();
}
var vis, title = unpair makeVisAndTitle();
setFrameContents(window, vis);
}
void shootWindow {
var img = renderComponentToImage(window);
copyImageToClipboard(img);
File imgFile = saveInImageDirectoryWithCounter(gazelle22_imagesSubDirName() + "/Gazelle", img);
pcallOpt(module, "addToGallery", imgFile);
}
Component vis() { ret getFrameContents(window); }
} // end of Stem
sclass LoadedDB is AutoCloseable {
GazelleHost host;
Concepts concepts;
new G22Utils g22utils;
Stem mainStem;
*(GazelleHost *host, Concepts *concepts) {
g22utils.concepts(concepts);
g22utils.masterStuff(host);
}
S name() {
ret fileName(conceptsDir(concepts));
}
void start {
concepts.makeStructureData = -> {
structure_Data data = concepts.makeStructureData_base();
data.mcDollar = mcDollar();
ret data;
};
var lock = concepts.fileLock();
try {
lock.contentsForLockFile("Locked by computer " + computerID() + "\n");
lock.lockOrFail();
} catch print e {
if (cic(str(e), "Couldn't aquire lock")) {
if (!lock.hasExpectedContents()) {
infoBox("Overriding project lock (" + lock.actualContents() + ")");
lock.forceLock();
} else {
S msg = "This project is already opened in another process";
infoBox(msg, 10.0);
sleepSeconds(5);
fail(msg);
}
} else
throw rethrow(e);
}
concepts.fileLock().deleteOnExit();
thinAProgramsBackups(concepts.conceptsDir(), true);
concepts.persist();
//db_setMainConcepts(concepts);
//print("Concepts loaded: " + map className(allConcepts(concepts));
var stems = stems();
print("Stems in DB: " + l(stems));
mainStem = first(stems);
if (mainStem == null) {
print("Starting new module");
var module = host.makeModule();
mainStem = registerConcept(concepts, new Stem(this, module));
print("Stems in DB: " + l(stems()));
}
for (stem : stems()) {
stem.db = this;
stem.host = host;
stem.startAndShow();
}
print("Stems in DB: " + l(stems()));
}
L stems() { ret list Stem(concepts); }
Q systemQ() { ret host.systemQ; }
void showPrintLog {
systemQ().add(-> {
var logModule = firstThat(list(concepts, Stem),
stem -> stem.module instanceof PrintLogModule);
if (logModule != null)
logModule.activateWindow();
else
registerConcept(concepts, new Stem(this, new PrintLogModule)).startAndShow();
});
}
void activate {
mainStem?.activateWindow();
}
JFrame mainWindow() {
ret mainStem?.window;
}
close {
print("Cleaning up " + concepts);
print("Stems in DB: " + l(stems()));
for (Concept c : allConcepts(concepts))
cleanUp(c);
print("Releasing DB (" + n2(list(concepts, Stem), "stem") + ")");
dispose concepts;
host.loadedDBs.remove(this);
host.loadedDBsChange();
print("Remaining DBs: " + l(host.loadedDBs));
}
} // end of LoadedDB
// This replaces the Stefan's OS main class. It is not persisted
// and there is only one instance.
transient sclass GazelleHost is G22MasterStuff {
Set loadedDBs = syncLinkedHashSet();
event loadedDBsChange;
transient S windowTitle = "Gazelle 22";
transient S trayIconImageID = #1103047;
transient int borderSize = 5;
transient Color color1 = awtColor("ADD8E6");
transient Color color2 = awtColor("EEEEEE");
transient Color color3 = awtColor("A3C0AA");
transient IF0 moduleMaker;
transient ThreadPool threadPool;
transient TrayIcon trayIcon;
transient TrayIconLastPosition trayIconLastPosition;
transient Set argsSet;
transient bool incrementalDownloads = true;
transient volatile bool shuttingDown;
// This caused problems, disabled for now
transient bool allowFrameMaximization;
transient StefansOS_ConnectToServer serverConnector;
transient ComputerCountListener computerCount;
transient GazellePresenceListener gazellePresenceListener;
transient Q systemQ = startQ("System Q");
// Let's use one of these centrally because it blocks a thread
// and does next to nothing most of the time.
gettable new RunnablesReferenceQueue runnablesReferenceQueue;
transient gettable ILASClassLoader lasClassLoader =
//new LASClassLoader(getClass());
new LASMultiClassLoader(mc()).runnablesReferenceQueue(assertNotNull(runnablesReferenceQueue));
//transient BoolVarWithNotify compileButtonEnabled = new(true);
gettable EphemeralObjectIDs ephemeralObjectIDs = new()
.runnablesReferenceQueue(assertNotNull(runnablesReferenceQueue));
transient bool autoExitDisabled;
// add fields here
*(ThreadPool *threadPool, IF0 *moduleMaker) {
onLoadedDBsChange(-> {
if (!shuttingDown)
new G22Utils().setOpenDBs(openConceptDirs());
});
}
JFrame mainWindow() {
ret empty(loadedDBs) ? null : first(loadedDBs).mainWindow();
}
void trayIconLeftClick {
activateFrame_v3(mainWindow());
}
void makeTrayIcon {
pcall-short {
trayIcon_imageAutoSize = false;
trayIcon = installTrayIcon(trayIconImageID, windowTitle,
r trayIconLeftClick,
"Show Gazelle", r trayIconLeftClick,
"Exit Gazelle", r cleanExit
);
trayIconLastPosition = new TrayIconLastPosition(trayIcon);
}
}
void run(S[] args) {
try {
run2(args);
} catch print e {
//messageBox(e);
hideTrayIcon(trayIcon);
onWindowClosing(-> systemExit(1), getWindow(
showText_fast_noWrap("Gazelle Error", renderStackTrace(e))));
//AutoVMExit.install();
}
}
void run2(S[] args) {
argsSet = asSet(args);
if (!argsSet.contains("noflatlaf"))
com.formdev.flatlaf.FlatLightLaf.setup();
if (contains(args, "profile"))
profileToConsole(() -> actualMain(args));
else
actualMain(args);
if (argsSet.contains("brexit")) System.exit(0);
}
void actualMain(S... args) {
vm_generalMap_put(stefansOS := this);
System.out.println(hmsWithColonsAndMS() + ": Init");
//x30.coreInit();
// Ready to roll
printJavaVersion();
//tempAddGlobalCtrlKeyListener(b -> print("Ctrl key: " + b));
if (contains(argsSet, "profile"))
doEvery(1.0, r printRunningThreads);
if (containsOneOf(argsSet, "upgrade", "update"))
ret with upgradeGazelle();
makeTrayIcon();
initAutoUpdate();
if (devMode()) {
tempGlobalPopupMenu((c, menu) -> {
// This is for popup menus displayed via setComponentPopupMenu
// which are re-used instances
if (any(getMenuItems(menu), menuItem
-> cicOneOf(menuItem.getText(), "Component: ", "src: "))) ret;
O src = componentMetaSrc(c);
menu.add(commaCombine(
"Component: " + classNameAndEphString(c),
src == null ?: "src: " + classNameAndEphString(src)));
});
}
// Start DB
LS dbNames = new G22Utils().dbsToOpen();
for (S dbName : dbNames)
openDB(dbName);
exitIfAllDBsClosed();
printWithMS("Dudadoneski");
}
LoadedDB openDB(S dbName) {
File conceptsFile = newFile(newFile(new G22Utils().databasesMotherDir(), dbName), conceptsFileName());
ret openDB(conceptsFile);
}
LoadedDB findLoadedDBForConceptsDir(File conceptsDir) {
ret firstThat(cloneList(loadedDBs), db -> sameFile(
conceptsDir(db.concepts), conceptsDir));
}
LoadedDB findLoadedDBForConceptsFile(File conceptsFile) {
ret firstThat(cloneList(loadedDBs), db -> sameFile(
conceptsFile(db.concepts), conceptsFile));
}
LoadedDB reopenDB(LoadedDB db) {
File conceptsFile = db.concepts.conceptsFile();
try {
autoExitDisabled = true;
closeDatabase(db);
ret openDB(conceptsFile);
} finally {
autoExitDisabled = false;
}
}
LoadedDB openDB(File conceptsFile) {
var loadedDB = findLoadedDBForConceptsFile(conceptsFile);
if (loadedDB != null) {
print("Activating DB: " + conceptsFile);
loadedDB.activate();
ret loadedDB;
}
print("Loading new DB: " + f2s(conceptsFile));
Concepts concepts = newConceptsWithClassFinder(conceptsFile, makeClassFinder());
var db = new LoadedDB(this, concepts);
loadedDBs.add(db);
try {
db.start();
loadedDBsChange();
} catch print e {
loadedDBs.remove(db);
_close(db);
}
ret db;
}
public Cl openConceptDirs() {
ret cloneMap(loadedDBs, _db -> conceptsDir(_db.concepts));
}
O resolveModule(O moduleOrStem) {
ret moduleOrStem cast Stem ? moduleOrStem.module : moduleOrStem;
}
void cleanExit {
set shuttingDown;
print("Closing " + n2(loadedDBs, "database"));
closeAndClear(loadedDBs);
System.exit(0);
}
File myJar() { ret getBytecodePathForClass(this); }
AutoCloseable tempDisableCompileButtons() {
ret tempDisableButtons(compileButtons());
}
void upgradeGazelle {
try {
printAlsoToSystemOut = true;
// Show an infoBox to make sure the code for infoBox is loaded
temp tempInfoBox("Updating Gazelle...");
//temp tempSetBoolVar(compileButtonEnabled, false);
temp tempDisableCompileButtons();
for (f : allJFrames()) setFrameTitle(f, "Updating...");
File myJar = myJar();
print(+myJar);
S existingFilesComp = !incrementalDownloads ? null
: existingFilesInfo();
S date = ymdMinusHMS();
File f = javaxCodeDir("Downloaded Updates/" + "gazelle-" + date + ".jar");
temp progress = tempProgressBar_addToWindowIfPossible(mainWindow(), "Updating Gazelle");
progress.setText("Downloading Update...");
time "Downloading zip" {
postBinaryPageToFile(downloadURL(), f, +existingFilesComp);
}
printFileInfo(f);
if (!isNonEmptySingleZip_byMagicHeader(f))
ret with infoBox("Bad file downloaded... :(");
bool replaced;
if (isFile(myJar)) {
// load all my classes to be sure (TODO: could do this in parallel to downloading)
//print("Loaded " + nClasses(loadAllClassesInByteCodePath(myJar)));
progress.setText("Replacing with new version: " + renderFileInfo(myJar));
File myJarSaved = fileInSubDir("old-code",
appendToBaseName(myJar, ".bak." + date));
File myJarNew = appendToFileName(myJar, ".new");
Set toKeep = asSet(tlft(loadTextFileFromZip(f, "to-keep")));
if (nempty(toKeep)) {
int toUpdate = countFilesInZip(f)-1;
//progress.setText("Keeping " + nFiles(toKeep));
progress.setText("Updating " + nFiles(toUpdate));
int have = countFilesInZip(myJar);
if (l(toKeep) == have && countFilesInZip(f) == 1) {
infoBox("Nothing to update - will just restart");
deleteFile(myJarNew);
sleepSeconds(1);
restart();
}
/*
temp ZipOutputStream out = zipOutputStream(myJar);
zip2zip_withPredicate(myJarSaved, out, name -> toKeep.contains(name));
progress.setText("Adding new files");
int n = zip2zip_withPredicate(f, out, name -> !eq(name, "to-keep"));
progress.setText("Added " + nFiles(n));
*/
temp Zip4j_MergeZipFilesWithFilter merger = new(myJarNew);
merger.addZipFile(myJar, name -> contains(toKeep, name));
merger.addZipFile(f, name -> !eq(name, "to-keep"));
merger.finish();
} else
myJarNew = f;
if (isWindows()) {
copyFileVerbose(myJar, myJarSaved);
copyFileVerbose(myJarNew, myJar);
deleteFileVerbose_assertSuccess(myJarNew);
} else {
renameFileVerbose_assertSuccess(myJar, myJarSaved);
renameFileVerbose_assertSuccess(myJarNew, myJar);
}
printFileInfo(myJar);
set replaced;
}
progress.setText("Done");
if (replaced)
infoBox("Installed update, replaced " + f2s(myJar) + " - now starting");
else
infoBox("Updated but could not replace originally downloaded jar");
restart(replaced ? myJar : f);
} on fail e { printStackTrace(e); }
}
void restart(File jar default myJar()) {
S javaCmd = or2(currentProcessCommand(), "java");
S cmd = pqO(javaCmd) + " -jar " + pqO(jar);
print(cmd);
nohup(cmd);
cleanExit();
}
DynModule makeModule() {
ret callF(moduleMaker);
}
void reloadModuleInBackground(Stem mod) {
restart();
}
void initAutoUpdate {
print("Making server connection for updates.");
serverConnector = snippetUpdateConnector(/*verbose := true*/);
//serverConnector.verbose = true;
vmBus_onMessage snippetUpdate(voidfunc(L l) {
S uri = getString(l, 1);
new Matches m;
if (swic(uri, "/transpileOK/", m)) {
if (sameSnippetID(programID(), firstIntAsString(m.rest()))) {
if (new G22Utils().autoUpdateEnabled() /*&& autoUpdateDisabled*/)
upgradeGazelle();
//infoBox("Gazelle can be updated!");
}
} else if (swic(uri, "/edit/", m)) {
S snippetID = fsI(firstIntAsString(m.rest());
if (contains(stdFunctionListSnippetIDs(), snippetID))
stdFunctions_clearCache();
if (contains(standardClassesSnippetIDs(), snippetID))
standardClassesMap_clearCache();
}
});
pcall {
computerCount = new ComputerCountListener(serverConnector);
computerCount.init();
}
pcall {
gazellePresenceListener = GazellePresenceListener(serverConnector);
gazellePresenceListener.init();
}
}
S downloadURL() {
ret "https://botcompany.de/jar/"
+ psI(programID()) + "?withLibs=1&withX30=1"
+ "&mainClassForManifest=Starter"
+ (!downloadJarWithSrc() ? "&noSrc=1" : "")
+ (downloadUncompressedJAR() ? "&uncompressed=1" : "");
}
bool downloadJarWithSrc() { false; }
bool downloadUncompressedJAR() { false; }
// called by DynModule
void revisualizeModule(Stem stem) {
stem.revisualize();
}
Int computerCount() { ret computerCount == null ? (Int) 0 : computerCount!; }
LiveValue lvComputerCount() { ret computerCount?.liveValue(); }
public IGetterWithNotify lvGazelleUserCount() { ret gazellePresenceListener?.userCount; }
L compileButtons() { ret mapNonNulls(allStems(), s -> s.compileButton()); }
L allStems() {
ret concatLists(cloneMap(loadedDBs, db -> list(db.concepts, Stem)));
}
// compile main program
void compile {
compile(programID, null);
}
void compileUtils {
compile(utilsSnippetID(), l0 compile);
}
void compile(S snippetID, Runnable onSuccess) {
print("Compiling " + snippetID);
var gears = resizeImageIcon(imageIcon(#1103061), 16);
temp tempDisableCompileButtons();
temp tempSetButtonImages(compileButtons(), gears);
thread { existingFilesInfo(); } // precompute
transpileOnServerWithErrorWindow(snippetID, true, onSuccess);
print("Done transpilation of " + snippetID);
}
public void closeDatabase(LoadedDB db) {
db.close();
exitIfAllDBsClosed();
}
void exitIfAllDBsClosed {
if (!autoExitDisabled && empty(loadedDBs))
cleanExit();
}
public void closeDatabase(File conceptsDir) {
for (db : cloneList(loadedDBs))
if (sameFile(conceptsDir, conceptsDir(db.concepts)))
db.close();
}
public void switchToDatabase(File conceptsDir) {
if (conceptsDir == null) ret;
// open/activate the desired database first
var db = openDatabase(conceptsDir);
if (db == null) ret; // probably impossible but whatever
closeAllDBsExcept(db);
}
void closeAllDBsExcept(LoadedDB db) {
closeAll(listMinus(loadedDBs, db));
}
public LoadedDB openDatabase(File conceptsDir) {
printAlsoToSystemOut = true;
temp tempInfoBoxNoHide("Opening database...");
File conceptsFile = newFile(conceptsDir, conceptsFileName());
if (!fileExists(conceptsFile))
fail(infoBox("Database not found: " + conceptsFile));
var db = openDB(conceptsFile);
print("Database opening complete, stopping System.out");
printAlsoToSystemOut = false;
ret db;
}
Map classMigrations() {
ret litmap(
G22RecognizerScript := G22Analyzer,
GalleryImage := G22GalleryImage);
}
public IF1 makeClassFinder() {
IF1 defaultClassFinder = toIF1(_defaultClassFinder());
var migrations = classMigrations();
IF1 classFinder = name -> {
// class migration
S shortName = dropPrefixOrNull("main$", name);
if (shortName != null) {
Class c = migrations.get(shortName);
if (c != null) {
S newName = className(c);
print("Migrating legacy class " + name + " to " + newName);
name = newName;
}
}
ret defaultClassFinder.get(name);
};
// Test classFinder sanity
assertEquals(callF(classFinder, "main$Stem"), Stem.class);
ret classFinder;
}
transient cached S existingFilesInfo() {
L