NEWS
[gelöst] Javascript-Adapter Speicherproblem memRSS
-
Javascript ist einer von wenigen Adaptern, welcher auf alle Variablen zuhört.
Vielleicht hast du mega States oder Mega Objekte in deinem System? JSON Tabellen?
Und auch wenn der Adapter nichts zu tun hat hört er trotzdem auf alle Änderungen und und nimmt Speicher dafür. `
Nein, habe ich nicht. Deswegen habe ich oben genau beschrieben, was ich gemacht habe, als es dazu gekommen ist.
Ich habe auch nur einen Teil der Skripte umgezogen, die vorher auf anderen System liefen.
Das Problem ist auch mehr, dass man es nicht reparieren kann. Wenn es einmal anfängt, warum auch immer, kann man es nicht mehr in Ordnung bringen.
Siehe:
Javascript Instanz .0 hat sich nach dem 2. Reboot nach der Nacht "beruhigt". Warum? Und warum nicht nach den ersten Reboot? Beim iMac konnte ich machen was ich will. Ich habe alle Scripts deaktiviert und es lief trotzdem nie wieder.
Die Instanzen .1 bis .3 ziehen alle 4-5 mal so viel Speicher, wie sonst.
In der Instanz .2 ist gar nichts aktiv und trotzdem wird der Speicher verbraucht.
In der Instanz .3 sind die globalen Skripte eingeschaltet. Die sind 1:1 identisch, wie es vor dem Problem war. Trotzdem der Speicherverbrauch.
In Instanz .1 nur das Script zum auslesen des WIFFI 2.0 (ein kurzes JSON über Web).
Warum ziehen die Instanzen .1, .2 und .3 den Speicher? Angefangen hat das erst, als ich die Kleinigkeiten, die ich oben beschrieben hatte, angegangen bin.
Ist es ggf. ein konzeptionelles Problem mit den globalen Skripten?
Wo werden die Skripte global mit den anderen Skripten zusammengebaut? Im Filesystem nicht oder?
Es kann doch nicht sein, dass das Rauskopieren einer Minifunktion das ganze System auf den Bauch liegt.
Auch das man es nicht reparieren kann, ist für mich ein Problem.
Ich habe jetzt alle restlichen noch laufenden Skripte deaktiviert und folgendes Verhalten gehabt:
Kurz nach dem Deaktivieren des letzten Skripts:
Nach ca. 10 Minuten:
Nach einem weiteren Reboot, exemplarisch für Instanz .1:
Instanz .1
Kein Skript aktiv.
Speicher beruhigt sich nicht.
Nach dem Reboot geht der Verbrauch auf > 600 MB hoch, dann zurück auf ca. 250 MB. Normal sollten 40-50 MB sein.
Das ist aus meiner Sicht kein Problem eines großen JSON oder vieler Variablen, sondern ein grundlegendes Problem
Ich verzweifle gerade etwas. Weiss nicht, was ich tun kann. Wenn ich zum dritten Mal ein System aufsetzen muss, wüsste ich wenigstens gerne, woran das liegt/lag und was man tun kann.
-
Bevor ich jetzt wieder Stunden Arbeit über Bord werfe und dann ein drittes Mal ins Messer laufe…
Hat noch jemand eine Idee?
Eine Idee, warum die Javascript-Instanzen den kompletten Speicher ziehen, ohne dass auch nur ein Skript aktiv ist?
Gibt es Vorschläge für Reparaturversuche, die nicht die bestehenden Daten zerstören?
-
Hier ist beschrieben wie du vorgehen kannst um herauszufinden wodurch so viel Speicher belegt wird.
-
Danke Dir. Harter Tobac
Wird jetzt schwierig, da ich jetzt das gleiche Problem, wie beim iMac habe. Der Speicher bei den vier Javascript-Instanzen schaukelt sich auf das verfügbare Maximum hoch (8GB) und dann wird der js-controller Prozess beendet. Alle anderen io.* Prozesse sind noch da. Ich bekomme es nicht mehr zum laufen.
Wie ist es dazu gekommen:
Ich hatte noch einmal die Skripte aktiviert und neu gestartet. Danach alles deaktiviert. Der Speicherverbrauch hatte sich verschlimmert bis zum Totalabsturz.
Für mich unverständlich, das der Javascript-Adapter für den Absturz des js-controllers sorgt, ohne das überhaupt ein Skript aktiv ist.
-
Danke Dir. Harter Tobac
Wird jetzt schwierig, da ich jetzt das gleiche Problem, wie beim iMac habe. Der Speicher bei den vier Javascript-Instanzen schaukelt sich auf das verfügbare Maximum hoch (8GB) und dann wird der js-controller Prozess beendet. Alle anderen io.* Prozesse sind noch da. Ich bekomme es nicht mehr zum laufen.
Wie ist es dazu gekommen:
Ich hatte noch einmal die Skripte aktiviert und neu gestartet. Danach alles deaktiviert. Der Speicherverbrauch hatte sich verschlimmert bis zum Totalabsturz.
Für mich unverständlich, das der Javascript-Adapter für den Absturz des js-controllers sorgt, ohne das überhaupt ein Skript aktiv ist. `
Du kannst doch eine Instanz aktiv lassen und die allein untersuchen. Dann wird Speicher nicht so schnell weg gefressen. -
Du kannst doch eine Instanz aktiv lassen und die allein untersuchen. Dann wird Speicher nicht so schnell weg gefressen. `
Dein ernst? Die Beschreibung sieht nicht so aus, als ob ich das hin bekomme. Oder meinst Du mit "Untersuchen" was anderes?
Wie geschrieben. Alle Skripts ausgeschaltet. Wenn nur die erste Instanz aktiv ist, zieht diese trotzdem 1,5 GB RAM.
Würde mir eventuell schon bei der Fehlersuche helfen, wenn ich die Infos habe, wie der Adapter arbeitet.
Wenn die Ursache nicht erkannt wird, werde ich immer wieder in den Fehler rein laufen können. Dazu habe ich wenig Lust.
Fragen
Wo werden die globalen Skripte mit den lokalen Skripten zusammenkopiert? Im Filesystem nicht oder?
Warum zieht eine Instanz 1,5 GB RAM, ohne dass überhaupt ein Skript eingeschaltet ist?
Da muss es doch einen Ansatz geben.
Was ich noch gemacht habe
-
iobroker-data gesichert
-
js-controller 0.8.9 manuell installiert
-
alle Adapter einzeln manuell neu installiert
-
iobroker-data zurückgespielt
-
Fehler ist noch da
-
alle Javascript Instanzen deaktiviert
Der Fehler ist irgendwo in iobroker-data.
Was ich jetzt noch machen werde:
-
Alle Skripte einzeln sichern (aus dem Editor mit Copy & Paste), dann löschen
-
Javascript Adapter wieder einschalten
-
a) wenn der Fehler dann weg ist:
– alle Skripte wieder nach und nach reinkopieren
- b) wenn der Fehler nicht weg ist (ohne Skripte)
-- keine Ahnung
Eigentlich sehe ich nicht viel Sinn darin, weil es genau mit den jetzt vorhanden Skripten gut lief. Wenn es dann funktioniert (a) ist das keinerlei Gewähr, dass das auch so bleibt, wenn nicht eine Kleinigkeit geändert wird.
Ehrlich gesagt bin ich extrem frustriert von dem Fehlerbild.
-
-
Dein ernst? Die Beschreibung sieht nicht so aus, als ob ich das hin bekomme. Oder meinst Du mit "Untersuchen" was anderes?
Wie geschrieben. Alle Skripts ausgeschaltet. Wenn nur die erste Instanz aktiv ist, zieht diese trotzdem 1,5 GB RAM. `
Du hast immer noch andere 6,5 GB zu nutzen
@ruhr70:Würde mir eventuell schon bei der Fehlersuche helfen, wenn ich die Infos habe, wie der Adapter arbeitet.
Wenn die Ursache nicht erkannt wird, werde ich immer wieder in den Fehler rein laufen können. Dazu habe ich wenig Lust.
Fragen
Wo werden die globalen Skripte mit den lokalen Skripten zusammenkopiert? Im Filesystem nicht oder? `
Die globale Skripte werden nie allein ausgeführt. Bevor ein nicht globales Skript gestartet wird, werden alle globale Skripte zu einem Text zusammengefasst und vor dem normalen Skript rein kopiert. Dann wird so eine Skript ausgeführt.Warum zieht eine Instanz 1,5 GB RAM, ohne dass überhaupt ein Skript eingeschaltet ist?
Da muss es doch einen Ansatz geben. `
JS Adapter hat im Bauch eine Kopie von allen Objekten und allen States. Dann auch bei jeder Änderung von einem Objekt oder Zustand werden die neue Daten abgespeichert (über alten, es gibt keine Historie). An dieser Stelle vermute ich Memory Problem.Du kannst versuchen das zu deaktivieren und dann RAM beobachten.
Schreib hier:
https://github.com/ioBroker/ioBroker.ja … ipt.js#L47
und hier
https://github.com/ioBroker/ioBroker.ja ... pt.js#L151
ein return und beobachte RAm.
Was ich noch gemacht habe
-
iobroker-data gesichert
-
js-controller 0.8.9 manuell installiert
-
alle Adapter einzeln manuell neu installiert
-
iobroker-data zurückgespielt
-
Fehler ist noch da
-
alle Javascript Instanzen deaktiviert
Der Fehler ist irgendwo in iobroker-data.
Was ich jetzt noch machen werde:
-
Alle Skripte einzeln sichern (aus dem Editor mit Copy & Paste), dann löschen
-
Javascript Adapter wieder einschalten
-
a) wenn der Fehler dann weg ist:
– alle Skripte wieder nach und nach reinkopieren
- b) wenn der Fehler nicht weg ist (ohne Skripte)
-- keine Ahnung
Eigentlich sehe ich nicht viel Sinn darin, weil es genau mit den jetzt vorhanden Skripten gut lief. Wenn es dann funktioniert (a) ist das keinerlei Gewähr, dass das auch so bleibt, wenn nicht eine Kleinigkeit geändert wird.
Ehrlich gesagt bin ich extrem frustriert von dem Fehlerbild. `
Kannst du mir über PN dein iobroker-data schicken? Ich kann auch versuchen mal RAM zu beobachten.
-
-
Was ich jetzt noch machen werde:
-
Alle Skripte einzeln sichern (aus dem Editor mit Copy & Paste), dann löschen
-
Javascript Adapter wieder einschalten
-
a) wenn der Fehler dann weg ist:
– alle Skripte wieder nach und nach reinkopieren
- b) wenn der Fehler nicht weg ist (ohne Skripte)
-- keine Ahnung
Eigentlich sehe ich nicht viel Sinn darin, weil es genau mit den jetzt vorhanden Skripten gut lief. Wenn es dann funktioniert (a) ist das keinerlei Gewähr, dass das auch so bleibt, wenn nicht eine Kleinigkeit geändert wird.
Kannst du mir über PN dein iobroker-data schicken? Ich kann auch versuchen mal RAM zu beobachten.
Danke Bluefox. Da komme ich mit Sicherheit noch drauf zurück. :twisted:
Momentan teste ich noch wild und Du würdest mir riesig helfen, wenn Du ein Feedback hast sobald Dir was auffällt.
Ich habe jetzt erst einmal die Schritte oben durchgeführt:
-
diverse Reboots
-
bis auf die nackten Verzeichnisse common und global all Skripte im Admin gelöscht
-
in den Objekten unter scripte.js sind keine Skripte mehr vorhanden
-
reboot
-
die Javascriptinstanz .0 wieder gestartet
Für .0 ging der Speicher auf 1,5 GB hich und dann runter auf 400 MB,
Was bisher aufgefallen ist:
-
ohne Skripte besteht das Speicherproblem immer noch
-
in den Instanzen waren alle javascript.x.sriptEnable.SCRIPTNAME noch vorhanden
(diese Einträge musste ich alle manuell löschen)
-
das Skript reinstall.sh in /opt/iobroker kann nicht ausgeführt werden
(als root: ./reinstall.sh
bash: ./reinstall.sh: /bin/bash^M: Defekter Interpreter: Datei oder Verzeichnis nicht gefunden)
Ich suche weiter.
Wo kann den in iobroker-data noch was stehen, was "nicht normal" ist?
./files - habe ich durchgesehen, eher nein
./sqlite - auch nein
./history - auch nein
./node-red - nein. War in dieser Installation noch nie aktiv
bleiben:
states.json und
objects.json
Die sehen mittlerweile "sauber" aus. Ich forsche hier weiter.
Für einen Schubser, wo ich sonst gucken kann, wäre ich dankbar.
-
-
Ich habe in meinem letzten Antwort was mit Formatierung vertauscht.
Schaue bitte mein Antwort noch mal an:
-
Du hast immer noch andere 6,5 GB zu nutzen `
Der ESXi Host hat 32 GB. Zur Not schraube ich das auch noch hoch :lol:
Ich habe ja bei jeder Javascript-Instanz den Speicher auf 200 MB begrenzt und trotzdem geht der Speicher je Instanz auf bis zu 1,5 GB hoch. Greift das nicht oder verstehe ich die Speicherbegrenzung falsch?
JS Adapter hat im Bauch eine Kopie von allen Objekten und allen States. Dann auch bei jeder Änderung von einem Objekt oder Zustand werden die neue Daten abgespeichert (über alten, es gibt keine Historie). An dieser Stelle vermute ich Memory Problem. `
mmh… dann könnte doch auch ein Objekt/State von einem anderen Adapter das Problem verursachen, wenn sich dort viele Zustände schnell ändern würden? Ich kann ja mal nach und nach die anderen Adapter deaktivieren.
Das passt allerdings nicht zu dem Vorgang, ab wann das Problem aufgetreten ist (Änderungen bei den Skripten).
Du kannst versuchen das zu deaktivieren und dann RAM beobachten.
Schreib hier:
https://github.com/ioBroker/ioBroker.ja … ipt.js#L47
und hier
https://github.com/ioBroker/ioBroker.ja ... pt.js#L151
ein return und beobachte RAm. `
Erledigt. Stop/Start iobroker und Reboot Rechner.
Speicher geht trotzdem erst auf 1,5 GB in Instanz.0 und dann auf 400 MB.
objectChange: function (id, obj) { return; // DEBUG Zeile 47 if (this.regExEnum.test(id)) {
stateChange: function (id, state) { return; // DEBUG Zeile 151 if (id.match(/^messagebox\./) || id.match(/^log\./)) return;
-
> Speicher geht trotzdem erst auf 1,5 GB in Instanz.0 und dann auf 400 MB.
Beim start werden alle Objekte und States einmal gelesen (1,5GB).Dan wird vermutlich der Speicher, der für lesen benötigt war freigegeben (400MB). Dann sollte aber es konstant bleiben.
1.5GB… wie viel Objekte hast du?
Man kann "_id" in objekts.json zählen.
-
Nachtrag:
-
alle Adapter, bis auf admin und javascript.0 deaktiviert.
-
die beiden return in der javascript.js sind eingefügt
Der Speicherverbrauch geht in der einen aktiven Javascript-Instanz .0 trotzdem auf 1,5 GB hoch
-
-
> Speicher geht trotzdem erst auf 1,5 GB in Instanz.0 und dann auf 400 MB.
Beim start werden alle Objekte und States einmal gelesen (1,5GB).Dan wird vermutlich der Speicher, der für lesen benötigt war freigegeben (400MB). Dann sollte aber es konstant bleiben.
1.5GB… wie viel Objekte hast du?
Man kann "_id" in objekts.json zählen. `
3.256 Objekte
Momentan bleibt der Speicherverbrauch bei 1,5 GB für die Instanz .0. (nur admin und javascript.0 aktiv).
Habe eigentlich kaum was laufen gehabt (35 Adapter in der Grundeinrichtung und einige SQL-Monitorpunkte). Ich war ja gerade bei derNeueinrichtung, als es passierte. Alles frisch.
Ja, normalerweise geht der Speicher auf 400 MB runter oder auch mal auf 250 und schwankt dort hin und her. Ich hatte oben einige Beispiele als Grafik drin.
-
Hab den Übeltäter wahrscheinlich gefunden. @Bluefox: Deine Erklärungen waren sehr hilfreich.
Da das System vorher perfekt lief und das Problem anfing, als ich ein Miniänderung an einem Skript vorgenommen habe, hab ich vermutet, dass es sich ggf. um ein Objekt innerhalb javascript.x handeln könnte, was beim Einlesen Probleme macht.
Also habe ich angefangen die Datenpunkte in javascript.x nach und nach zu löschen und jeweils den Adapter neu zu starten.
Dabei bin ich auf einen Zweig in javascript.0. gestossen, der sich in Admin/Objekte nicht aufklappen lies und den Tab im Chrome zum Absturz gebracht hat. Innerhalb dieses Zweigs gibt es neun Datenpunkte, die ich aus den objects.json zum analysieren raus kopiert habe. Es handelt sich dabei die Datenpunkte eines alten Skripts für eine Ereignisliste.
Meine states.json ist über 200 MB groß und lässt sich in meinem JSON-Editor auf dem Mac nicht öffnen, was auch auf ein Problem innerhalb des JSON hinweist.
Ich werde jetzt versuchen, die entsprechenden States innerhalb der states.json mit einem Texteditor raus zu kopieren. Mein Editor kämpft gerade aber auch mit der Datei
Was ggf. Optimierungsmöglichkeiten für den Javascript-Adapter bietet:
-
Die einstellbare Speichergrenze in den Instanzen scheinen nicht zu greifen
-
ggf. kann der Adapter die Objekte prüfen und so ein Speicherproblem dann beim Einlesen verhindern
Danke für Deine Geduld!
Mir war wichtig die Ursache zu finden. Eine Neuinstallation wäre für mich schneller gewesen und hätte mich nicht die letzten zwei Wochen gekostet (der Kampf mit den beiden betroffenen Systemen). Danke noch einmal.
Ich versuche zu den Objekten noch die States zu isolieren und wenn es OK ist, schicke ich Dir die neun Datenpunkte. Vielleicht kannst Du ja was einbauen, was einen Totalabsturz verhindert 8-)
-
-
Hab den Übeltäter wahrscheinlich gefunden. @Bluefox: Deine Erklärungen waren sehr hilfreich.
Da das System vorher perfekt lief und das Problem anfing, als ich ein Miniänderung an einem Skript vorgenommen habe, hab ich vermutet, dass es sich ggf. um ein Objekt innerhalb javascript.x handeln könnte, was beim Einlesen Probleme macht.
Also habe ich angefangen die Datenpunkte in javascript.x nach und nach zu löschen und jeweils den Adapter neu zu starten.
Dabei bin ich auf einen Zweig in javascript.0. gestossen, der sich in Admin/Objekte nicht aufklappen lies und den Tab im Chrome zum Absturz gebracht hat. Innerhalb dieses Zweigs gibt es neun Datenpunkte, die ich aus den objects.json zum analysieren raus kopiert habe. Es handelt sich dabei die Datenpunkte eines alten Skripts für eine Ereignisliste.
Meine states.json ist über 200 MB groß und lässt sich in meinem JSON-Editor auf dem Mac nicht öffnen, was auch auf ein Problem innerhalb des JSON hinweist.
Ich werde jetzt versuchen, die entsprechenden States innerhalb der states.json mit einem Texteditor raus zu kopieren. Mein Editor kämpft gerade aber auch mit der Datei
Was ggf. Optimierungsmöglichkeiten für den Javascript-Adapter bietet:
-
Die einstellbare Speichergrenze in den Instanzen scheinen nicht zu greifen
-
ggf. kann der Adapter die Objekte prüfen und so ein Speicherproblem dann beim Einlesen verhindern
Danke für Deine Geduld!
Mir war wichtig die Ursache zu finden. Eine Neuinstallation wäre für mich schneller gewesen und hätte mich nicht die letzten zwei Wochen gekostet (der Kampf mit den beiden betroffenen Systemen). Danke noch einmal.
Ich versuche zu den Objekten noch die States zu isolieren und wenn es OK ist, schicke ich Dir die neun Datenpunkte. Vielleicht kannst Du ja was einbauen, was einen Totalabsturz verhindert 8-) `
Es ist toll zu hören, dass du weiter gekommen bist.> Die einstellbare Speichergrenze in den Instanzen scheinen nicht zu greifen
Es wird eine Einstellung vorgenommen, die heißt "–max-old-space-size".Es kann sein, dass die nur für 0.10 und 0.12 gültig ist.
Und das habe ich noch gefunden:
"
Keep in mind that --max-old-space-size specifies the heap limit for the v8 JS engine that powers Node.js. This doesn't include all the memory the process might be using, such as buffers (for example, if you load very large images or JSON files). OSX will show you the entire memory usage of the node process in its activity monitor. Use process.memoryUsage() programatically to see heap memory usage."
-
-
Es ist toll zu hören, dass du weiter gekommen bist.
> Die einstellbare Speichergrenze in den Instanzen scheinen nicht zu greifen
Es wird eine Einstellung vorgenommen, die heißt "–max-old-space-size".Es kann sein, dass die nur für 0.10 und 0.12 gültig ist.
Und das habe ich noch gefunden:
"
Keep in mind that --max-old-space-size specifies the heap limit for the v8 JS engine that powers Node.js. This doesn't include all the memory the process might be using, such as buffers (for example, if you load very large images or JSON files). OSX will show you the entire memory usage of the node process in its activity monitor. Use process.memoryUsage() programatically to see heap memory usage." `
very large JSON… passt ja :roll:
Sieht so aus, als könnte man das gar nicht verhindern...
Ich muss noch einen Editor für den Mac finden, der mit der Datei klar kommt. Ein erster Blick heute zeigte, dass das Skript wahrscheinlich ein Fehler hat und als Wert für einen Datenpunkt ein recht langes JSON erzeugt hat.
Ich gebe auf jeden Fall Rückmeldung. Entweder als Fehlerbild, um zukünftiges Unheil zu vermeiden oder man kann ggf. doch was abfangen.
Gruß
Michael
-
Mehrere hundert MB JSON File ist natürlich zu viel, selbst bei tausenden Datenpunkten. Dein Skript hat vermutlich einen Datenpunkt erstellt der alleine einen Großteil der Dateigröße ausmacht. Die meisten Editoren laden die gesamte Datei auf einmal und bekommen das ebensowenig hin wie ioBroker.
Es gibt aber auch Editoren welche die Datei nicht als ganzes laden, auf Anhieb kann ich dir jetzt leider keinen nennen.
-
Mehrere hundert MB JSON File ist natürlich zu viel, selbst bei tausenden Datenpunkten. Dein Skript hat vermutlich einen Datenpunkt erstellt der alleine einen Großteil der Dateigröße ausmacht. Die meisten Editoren laden die gesamte Datei auf einmal und bekommen das ebensowenig hin wie ioBroker.
Es gibt aber auch Editoren welche die Datei nicht als ganzes laden, auf Anhieb kann ich dir jetzt leider keinen nennen. `
Mehrere hundert MB?? na, sind nur zwei mal hundert
Die 3.000 Objekte hat man ganz schnell zusammen. Ausser die Adapter als Grundgerüst, habe ich in der Installation noch gar nicht viel gemacht.
Nach den Editor suche ich gleich.
Wie groß ist den so eine durchschnittliche states.json?
Auf dem pi3 mit meinem Bluetooth Skript sind es nur 40 kB. Schon ein kleiner Unterschied zu den 200 MB. :lol:
P.S.: ja, ein Skript hatte einen Fehler und statt 50 Einträge, nun ja, sagen wir mal… recht viele Einträge erzeugt.
-
Super, dass Du den Fehler hartnäckig eingegrenzt und gefunden hast.
Mit Notepad++ hab ich schon wesentlich größere Dateien geöffnet - ich weiß nicht ob's da ein Pendant für den MAc gibt. Oder magst Du evtl. die kaputte states.json mal hochladen?
Gruß Thilo
-
Auf dem Mac kann man MacVim benutzen. Vim war zwar nie mein Favorit (Bedienung).
Danke für Dein Angebot! Da stehen allerdings ein paar sehr private Daten drin, als dass ich diese ins Netz stellen möchte
Jetzt muss ich mal schauen, ob ich mir nicht noch einen anderen Bock geschossen habe.
Mein SFTP client (Cyberduck) hatte die states.json auch nach dem aktualisieren immer noch mit 207 MB angezeigt, obwohl die Datei in echt nur noch knapp 1,2 MB groß war. Daher habe ich sie gesichert und und dann einfach die states.json und die states.bak gelöscht (vorher iobroker gestoppt).
Die Datei wurde dann wieder erstellt. Interessanterweise haben wohl alle Datenpunkte wieder Ihre Werte. ich dachte eigentlich, dass die letzten Werte in der states.json gespeichert sind.
Daher muss ich nun noch folgendes klären, um das System zu verstehen:
-
sind wirklich alle Werte vorhanden?
-
wenn ja, woher kamen die Werte?
-
habe ich mir jetzt ggf. einen Bock geschossen?
-