NucleusArray to Receptor
This commit is contained in:
parent
f295da9c55
commit
f8aaa4ca80
@ -79,13 +79,13 @@ public class Cluster : Nucleus {
|
|||||||
// Copy nucleus arrays
|
// Copy nucleus arrays
|
||||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||||
Nucleus prefabReceptor = prefabNuclei[nucleusIx];
|
Nucleus prefabReceptor = prefabNuclei[nucleusIx];
|
||||||
if (prefabReceptor is not Nucleus prefabNucleus)
|
if (prefabReceptor is not Receptor prefabNucleus)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (prefabNucleus.array == null || prefabNucleus.array.nuclei == null || prefabNucleus.array.nuclei.Length == 0)
|
if (prefabNucleus.array == null || prefabNucleus.array.nuclei == null || prefabNucleus.array.nuclei.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Nucleus clonedNucleus = clonedNuclei[nucleusIx] as Nucleus;
|
Receptor clonedNucleus = clonedNuclei[nucleusIx] as Receptor;
|
||||||
if (prefabNucleus == prefabNucleus.array.nuclei[0]) {
|
if (prefabNucleus == prefabNucleus.array.nuclei[0]) {
|
||||||
// We clone the array only for the first entry
|
// We clone the array only for the first entry
|
||||||
NucleusArray clonedArray = new(prefabNucleus.array.nuclei.Length, "array");
|
NucleusArray clonedArray = new(prefabNucleus.array.nuclei.Length, "array");
|
||||||
@ -106,7 +106,7 @@ public class Cluster : Nucleus {
|
|||||||
else {
|
else {
|
||||||
// The others will refer to the array created for the first nucleus in the array
|
// The others will refer to the array created for the first nucleus in the array
|
||||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabNucleus.array.nuclei[0]);
|
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabNucleus.array.nuclei[0]);
|
||||||
Nucleus clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Nucleus;
|
Receptor clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Receptor;
|
||||||
clonedNucleus.array = clonedFirstNucleus.array;
|
clonedNucleus.array = clonedFirstNucleus.array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ public class Cluster : Nucleus {
|
|||||||
public override Nucleus Clone(ClusterPrefab prefab) {
|
public override Nucleus Clone(ClusterPrefab prefab) {
|
||||||
//Neuron clone = new(this.cluster, this.name) {
|
//Neuron clone = new(this.cluster, this.name) {
|
||||||
Neuron clone = new(prefab, this.name) {
|
Neuron clone = new(prefab, this.name) {
|
||||||
array = this.array,
|
// array = this.array,
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Synapse synapse in this.synapses) {
|
foreach (Synapse synapse in this.synapses) {
|
||||||
|
|||||||
@ -295,30 +295,30 @@ public class ClusterInspector : Editor {
|
|||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (this.currentNucleus is Receptor receptor1) {
|
||||||
float maxValue = 0;
|
float maxValue = 0;
|
||||||
foreach (Nucleus nucleus in this.currentNucleus.array.nuclei) {
|
foreach (Nucleus nucleus in receptor1.array.nuclei) {
|
||||||
float value = length(nucleus.outputValue);
|
float value = length(nucleus.outputValue);
|
||||||
if (value > maxValue)
|
if (value > maxValue)
|
||||||
maxValue = value;
|
maxValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float spacing = 400f / this.currentNucleus.array.nuclei.Count();
|
float spacing = 400f / receptor1.array.nuclei.Count();
|
||||||
float margin = 10 + spacing / 2;
|
float margin = 10 + spacing / 2;
|
||||||
float xMin = 150 - size;
|
float xMin = 150 - size;
|
||||||
float xMax = 150 + size;
|
float xMax = 150 + size;
|
||||||
float yMin = 10 + margin - size / 2;
|
float yMin = 10 + margin - size / 2;
|
||||||
float yMax = 400 - margin + size;
|
float yMax = 400 - margin + size;
|
||||||
Vector3[] verts = new Vector3[4] {
|
Vector3[] verts = new Vector3[4] {
|
||||||
new(xMin, yMin, 0),
|
new(xMin, yMin, 0),
|
||||||
new(xMax, yMin, 0),
|
new(xMax, yMin, 0),
|
||||||
new(xMax, yMax, 0),
|
new(xMax, yMax, 0),
|
||||||
new(xMin, yMax, 0)
|
new(xMin, yMax, 0)
|
||||||
};
|
};
|
||||||
Handles.color = Color.black;
|
Handles.color = Color.black;
|
||||||
Handles.DrawAAConvexPolygon(verts);
|
Handles.DrawAAConvexPolygon(verts);
|
||||||
int row = 0;
|
int row = 0;
|
||||||
foreach (Nucleus nucleus in this.currentNucleus.array.nuclei) {
|
foreach (Nucleus nucleus in receptor1.array.nuclei) {
|
||||||
Vector3 pos = new(150, margin + row * spacing, 0.0f);
|
Vector3 pos = new(150, margin + row * spacing, 0.0f);
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
// The selected nucleus highlight ring
|
// The selected nucleus highlight ring
|
||||||
@ -357,9 +357,11 @@ public class ClusterInspector : Editor {
|
|||||||
int row = 0;
|
int row = 0;
|
||||||
List<NucleusArray> drawnArrays = new();
|
List<NucleusArray> drawnArrays = new();
|
||||||
foreach (Nucleus receiver in nucleus.receivers) {
|
foreach (Nucleus receiver in nucleus.receivers) {
|
||||||
if (drawnArrays.Contains(receiver.array))
|
if (receiver is Receptor receptor) {
|
||||||
continue;
|
if (drawnArrays.Contains(receptor.array))
|
||||||
drawnArrays.Add(receiver.array);
|
continue;
|
||||||
|
drawnArrays.Add(receptor.array);
|
||||||
|
}
|
||||||
|
|
||||||
Nucleus receiverNucleus = receiver;
|
Nucleus receiverNucleus = receiver;
|
||||||
if (receiverNucleus == null)
|
if (receiverNucleus == null)
|
||||||
@ -383,10 +385,10 @@ public class ClusterInspector : Editor {
|
|||||||
int neuronCount = 0;
|
int neuronCount = 0;
|
||||||
List<NucleusArray> drawnArrays = new();
|
List<NucleusArray> drawnArrays = new();
|
||||||
foreach (Synapse synapse in nucleus.synapses) {
|
foreach (Synapse synapse in nucleus.synapses) {
|
||||||
if (synapse.nucleus is Neuron neuroid) {
|
if (synapse.nucleus is Receptor receptor) {
|
||||||
if (drawnArrays.Contains(neuroid.array))
|
if (drawnArrays.Contains(receptor.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(neuroid.array);
|
drawnArrays.Add(receptor.array);
|
||||||
|
|
||||||
}
|
}
|
||||||
float value = length(synapse.nucleus.outputValue) * synapse.weight;
|
float value = length(synapse.nucleus.outputValue) * synapse.weight;
|
||||||
@ -403,7 +405,7 @@ public class ClusterInspector : Editor {
|
|||||||
int row = 0;
|
int row = 0;
|
||||||
drawnArrays = new();
|
drawnArrays = new();
|
||||||
foreach (Synapse synapse in nucleus.synapses) {
|
foreach (Synapse synapse in nucleus.synapses) {
|
||||||
if (synapse.nucleus is Neuron neuron) {
|
if (synapse.nucleus is Receptor neuron) {
|
||||||
if (drawnArrays.Contains(neuron.array))
|
if (drawnArrays.Contains(neuron.array))
|
||||||
continue;
|
continue;
|
||||||
drawnArrays.Add(neuron.array);
|
drawnArrays.Add(neuron.array);
|
||||||
@ -461,11 +463,13 @@ public class ClusterInspector : Editor {
|
|||||||
fontStyle = FontStyle.Bold,
|
fontStyle = FontStyle.Bold,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (nucleus.array == null || nucleus.array.nuclei == null || nucleus.array.nuclei.Count() == 0)
|
if (nucleus is Receptor receptor1) {
|
||||||
nucleus.array = new NucleusArray(nucleus);
|
if (receptor1.array == null || receptor1.array.nuclei == null || receptor1.array.nuclei.Count() == 0)
|
||||||
|
receptor1.array = new NucleusArray(nucleus);
|
||||||
|
|
||||||
if ((!expandArray || nucleus.array.nuclei.First() != this.currentNucleus) && nucleus.array.nuclei.Count() > 1) {
|
if ((!expandArray || receptor1.array.nuclei.First() != this.currentNucleus) && receptor1.array.nuclei.Count() > 1) {
|
||||||
Handles.Label(labelPosition, nucleus.array.nuclei.Count().ToString(), style);
|
Handles.Label(labelPosition, receptor1.array.nuclei.Count().ToString(), style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nucleus is ReceptorArray receptor) {
|
if (nucleus is ReceptorArray receptor) {
|
||||||
Handles.Label(labelPosition, receptor.instances.Count().ToString(), style);
|
Handles.Label(labelPosition, receptor.instances.Count().ToString(), style);
|
||||||
@ -481,9 +485,9 @@ public class ClusterInspector : Editor {
|
|||||||
// Handles.Label(labelPosition, $"[{arrayIx}]", style);
|
// Handles.Label(labelPosition, $"[{arrayIx}]", style);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if (expandArray && nucleus.array.nuclei.First() == this.currentNucleus) {
|
if (expandArray && nucleus is Receptor receptor2 && receptor2.array.nuclei.First() == this.currentNucleus) {
|
||||||
int arrayIx = 0;
|
int arrayIx = 0;
|
||||||
foreach (Nucleus n in nucleus.array.nuclei) {
|
foreach (Nucleus n in receptor2.array.nuclei) {
|
||||||
if (n == nucleus)
|
if (n == nucleus)
|
||||||
break;
|
break;
|
||||||
arrayIx++;
|
arrayIx++;
|
||||||
@ -672,8 +676,8 @@ public class ClusterInspector : Editor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (synapse.nucleus.array != null && synapse.nucleus.array.nuclei.Length > 1)
|
if (synapse.nucleus is Receptor receptor2 && receptor2.array != null && receptor2.array.nuclei.Length > 1)
|
||||||
array = synapse.nucleus.array;
|
array = receptor2.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
@ -721,8 +725,10 @@ public class ClusterInspector : Editor {
|
|||||||
neuron.curvePreset = newPreset;
|
neuron.curvePreset = newPreset;
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
}
|
}
|
||||||
if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Count() == 0)
|
if (neuron is Receptor receptor2) {
|
||||||
neuron.array = new NucleusArray(neuron);
|
if (receptor2.array == null || receptor2.array.nuclei == null || receptor2.array.nuclei.Count() == 0)
|
||||||
|
receptor2.array = new NucleusArray(neuron);
|
||||||
|
}
|
||||||
|
|
||||||
// if (this.currentNucleus is Receptor receptor1) {
|
// if (this.currentNucleus is Receptor receptor1) {
|
||||||
// EditorGUILayout.BeginHorizontal();
|
// EditorGUILayout.BeginHorizontal();
|
||||||
@ -778,13 +784,20 @@ public class ClusterInspector : Editor {
|
|||||||
Handles.color = Color.yellow;
|
Handles.color = Color.yellow;
|
||||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreach (Nucleus nucleus in this.currentNucleus.array.nuclei) {
|
if (this.currentNucleus is Receptor receptor1) {
|
||||||
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
foreach (Nucleus nucleus in receptor1.array.nuclei) {
|
||||||
|
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
||||||
|
Handles.color = Color.yellow;
|
||||||
|
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
|
||||||
Handles.color = Color.yellow;
|
Handles.color = Color.yellow;
|
||||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
Neuron.cs
14
Neuron.cs
@ -45,12 +45,12 @@ public class Neuron : Nucleus {
|
|||||||
public CurvePresets curvePreset {
|
public CurvePresets curvePreset {
|
||||||
get { return _curvePreset; }
|
get { return _curvePreset; }
|
||||||
set {
|
set {
|
||||||
if (this.array != null && this.array.nuclei != null) {
|
// if (this.array != null && this.array.nuclei != null) {
|
||||||
foreach (Neuron nucleus in this.array.nuclei.Cast<Neuron>()) {
|
// foreach (Neuron nucleus in this.array.nuclei.Cast<Neuron>()) {
|
||||||
nucleus._curvePreset = value;
|
// nucleus._curvePreset = value;
|
||||||
nucleus.curve = GenerateCurve();
|
// nucleus.curve = GenerateCurve();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
_curvePreset = value;
|
_curvePreset = value;
|
||||||
this.curve = GenerateCurve();
|
this.curve = GenerateCurve();
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ public class Neuron : Nucleus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CloneFields(Neuron clone) {
|
protected virtual void CloneFields(Neuron clone) {
|
||||||
clone.array = this.array;
|
// clone.array = this.array;
|
||||||
clone.bias = this.bias;
|
clone.bias = this.bias;
|
||||||
clone.combinator = this.combinator;
|
clone.combinator = this.combinator;
|
||||||
clone.curve = this.curve;
|
clone.curve = this.curve;
|
||||||
|
|||||||
48
Nucleus.cs
48
Nucleus.cs
@ -6,8 +6,8 @@ using static Unity.Mathematics.math;
|
|||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class Nucleus {
|
public abstract class Nucleus {
|
||||||
public string name;
|
public string name;
|
||||||
|
|
||||||
//[Obsolete]
|
//[Obsolete]
|
||||||
public ClusterPrefab cluster { get; set; }
|
public ClusterPrefab cluster { get; set; }
|
||||||
public Cluster parent { get; set; }
|
public Cluster parent { get; set; }
|
||||||
@ -48,7 +48,7 @@ public abstract class Nucleus {
|
|||||||
#region Synapses
|
#region Synapses
|
||||||
|
|
||||||
public Vector3 bias = Vector3.zero;
|
public Vector3 bias = Vector3.zero;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private List<Synapse> _synapses = new();
|
private List<Synapse> _synapses = new();
|
||||||
public List<Synapse> synapses => _synapses;
|
public List<Synapse> synapses => _synapses;
|
||||||
@ -90,35 +90,43 @@ public abstract class Nucleus {
|
|||||||
|
|
||||||
#endregion Receivers
|
#endregion Receivers
|
||||||
|
|
||||||
[SerializeReference]
|
// [SerializeReference]
|
||||||
private NucleusArray _array;
|
// private NucleusArray _array;
|
||||||
public NucleusArray array {
|
// public NucleusArray array {
|
||||||
get { return _array; }
|
// get { return _array; }
|
||||||
set { _array = value; }
|
// set { _array = value; }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#region Update
|
#region Update
|
||||||
|
|
||||||
public abstract void UpdateStateIsolated();
|
public abstract void UpdateStateIsolated();
|
||||||
|
|
||||||
public virtual void UpdateNuclei() {
|
public virtual void UpdateNuclei() {
|
||||||
if (this.array == null || this.array.nuclei == null || this.array.nuclei.Length <= 1)
|
// if (this.array == null || this.array.nuclei == null || this.array.nuclei.Length <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.stale++;
|
// this.stale++;
|
||||||
if (this.stale > staleValueForSleep) {
|
// if (this.stale > staleValueForSleep) {
|
||||||
//Debug.Log($"{this.name} goes to sleep, stale = {this.stale}");
|
// //Debug.Log($"{this.name} goes to sleep, stale = {this.stale}");
|
||||||
_outputValue = Vector3.zero;
|
// _outputValue = Vector3.zero;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||||
this.array.ProcessStimulus(thingId, inputValue, thingName);
|
//this.array.ProcessStimulus(thingId, inputValue, thingName);
|
||||||
|
// this.ProcessStimulus(inputValue);
|
||||||
|
this.stale = 0;
|
||||||
|
this.bias = inputValue;
|
||||||
|
this.parent.UpdateFromNucleus(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
// public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
||||||
this.array.ProcessStimulus(thingId, inputValue, thingName);
|
// // this.array.ProcessStimulus(thingId, inputValue, thingName);
|
||||||
}
|
// // this.ProcessStimulus(inputValue);
|
||||||
|
// this.stale = 0;
|
||||||
|
// this.bias = inputValue;
|
||||||
|
// this.parent.UpdateFromNucleus(this);
|
||||||
|
// }
|
||||||
|
|
||||||
#endregion Update
|
#endregion Update
|
||||||
|
|
||||||
|
|||||||
18
Receptor.cs
18
Receptor.cs
@ -9,23 +9,26 @@ public class Receptor : Neuron {
|
|||||||
|
|
||||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
public override Nucleus ShallowCloneTo(Cluster parent) {
|
||||||
Receptor clone = new(parent, name);
|
Receptor clone = new(parent, name);
|
||||||
|
CloneFields(clone);
|
||||||
|
clone.array = this.array;
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
public override Nucleus Clone(ClusterPrefab prefab) {
|
public override Nucleus Clone(ClusterPrefab prefab) {
|
||||||
Receptor clone = new(prefab, name);
|
Receptor clone = new(prefab, name);
|
||||||
CloneFields(clone);
|
CloneFields(clone);
|
||||||
|
clone.array = this.array;
|
||||||
// Adding receivers will also add synapses to the receivers
|
// Adding receivers will also add synapses to the receivers
|
||||||
foreach (Nucleus receiver in this.receivers)
|
foreach (Nucleus receiver in this.receivers)
|
||||||
clone.AddReceiver(receiver);
|
clone.AddReceiver(receiver);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [SerializeReference]
|
[SerializeReference]
|
||||||
// private NucleusArray _array;
|
private NucleusArray _array;
|
||||||
// public NucleusArray array {
|
public NucleusArray array {
|
||||||
// get { return _array; }
|
get { return _array; }
|
||||||
// set { _array = value; }
|
set { _array = value; }
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void UpdateStateIsolated() {
|
public override void UpdateStateIsolated() {
|
||||||
@ -40,4 +43,7 @@ public class Receptor : Neuron {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||||
|
this.array.ProcessStimulus(thingId, inputValue, thingName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -138,9 +138,9 @@ public class ReceptorArray : Nucleus {
|
|||||||
|
|
||||||
private Dictionary<int, Nucleus> thingReceivers = new();
|
private Dictionary<int, Nucleus> thingReceivers = new();
|
||||||
|
|
||||||
public override void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
// public override void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
||||||
ProcessStimulus(inputValue, thingId, thingName);
|
// ProcessStimulus(inputValue, thingId, thingName);
|
||||||
}
|
// }
|
||||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||||
CleanupReceivers();
|
CleanupReceivers();
|
||||||
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
||||||
|
|||||||
@ -14,8 +14,8 @@ public class SelectorBrain : NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void Update() {
|
protected void Update() {
|
||||||
receptor.ProcessStimulus(0, input1);
|
receptor.ProcessStimulus(input1, 0);
|
||||||
receptor.ProcessStimulus(1, input2);
|
receptor.ProcessStimulus(input2, 1);
|
||||||
output = this.brain.outputValue;
|
output = this.brain.outputValue;
|
||||||
|
|
||||||
this.brain.UpdateNuclei();
|
this.brain.UpdateNuclei();
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public class Selector : Neuron {
|
|||||||
|
|
||||||
public override Nucleus ShallowCloneTo(Cluster newParent) {
|
public override Nucleus ShallowCloneTo(Cluster newParent) {
|
||||||
Selector clone = new(newParent, this.name) {
|
Selector clone = new(newParent, this.name) {
|
||||||
array = this.array,
|
// array = this.array,
|
||||||
curve = this.curve,
|
curve = this.curve,
|
||||||
curvePreset = this.curvePreset,
|
curvePreset = this.curvePreset,
|
||||||
curveMax = this.curveMax,
|
curveMax = this.curveMax,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user