last works ...

Resolve all XPOI XPivot and XPivotAnalysis Refactoring Side Affects on XFIMA ...
This commit is contained in:
2025-09-23 01:47:54 +03:30
parent bb2aff17a9
commit 11811624d9
6 changed files with 244 additions and 2153 deletions
+2 -3
View File
@@ -239,8 +239,7 @@ class XCPOIDrawer : public XCBase
string prefix = Prefix(); string prefix = Prefix();
ulong chartId = ChartIdentification(); ulong chartId = ChartIdentification();
int window = SubWindowIdentification(); int window = SubWindowIdentification();
to = to = IsSpecifiedValid(to)
IsSpecifedValid(to)
? to ? to
: ((datetime)((int)bar.time) + (PeriodSeconds(bar.period) - 1)); : ((datetime)((int)bar.time) + (PeriodSeconds(bar.period) - 1));
object = new XCOHCLObject(); object = new XCOHCLObject();
@@ -871,7 +870,7 @@ class XCPOIDrawer : public XCBase
object != NULL; object != NULL;
if (!has) if (!has)
{ {
return result; return;
} }
// //
+242 -68
View File
@@ -645,94 +645,91 @@ bool CreateMainPanel()
// edtPositionId.TextAlign(ALIGN_LEFT); // edtPositionId.TextAlign(ALIGN_LEFT);
// } // }
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// //
CButton btnPauseReplay; CButton btnPauseReplay;
bool isVisualTesterPaused = false; bool isVisualTesterPaused = false;
// //
// Initial Btn Pause Play ... // Initial Btn Pause Play ...
int subWindow = 0; int subWindow = 0;
int defaultGap = 5; int defaultGap = 5;
int defaultWidth = 100; int defaultWidth = 100;
int defaultHeight = 30; int defaultHeight = 30;
ulong chartId = eaExpert.eaChartHelper.ChartId(); ulong chartId = eaExpert.eaChartHelper.ChartId();
//
int btnPauseReplayX1 = defaultGap;
int btnPauseReplayX2 = btnPauseReplayX1 + defaultWidth;
int btnPauseReplayY1 = eaExpert.eaChartHelper.Height() - defaultHeight - defaultGap;
int btnPauseReplayY2 = btnPauseReplayY1 + defaultHeight;
//
string btnPauseReplayName = ShortName + "BTN_PAUSE_REPLAY";
//
isInited = btnPauseReplay.Create(
chartId,
btnPauseReplayName,
subWindow,
btnPauseReplayX1,
btnPauseReplayY1,
btnPauseReplayX2,
btnPauseReplayY2 //
);
if (isInited)
{
//
// Apply Style ...
string btnPauseReplayText =
isVisualTesterPaused
? "Play"
: "Pause";
btnPauseReplay.Text(btnPauseReplayText);
btnPauseReplay.Color(clrAzure);
btnPauseReplay.ColorBackground(clrBlack);
}
// //
int btnPauseReplayX1 = defaultGap;
int btnPauseReplayX2 = btnPauseReplayX1 + defaultWidth;
int btnPauseReplayY1 = eaExpert.eaChartHelper.Height() - defaultHeight - defaultGap;
int btnPauseReplayY2 = btnPauseReplayY1 + defaultHeight;
//
string btnPauseReplayName = ShortName + "BTN_PAUSE_REPLAY";
//
isInited = btnPauseReplay.Create(
chartId,
btnPauseReplayName,
subWindow,
btnPauseReplayX1,
btnPauseReplayY1,
btnPauseReplayX2,
btnPauseReplayY2 //
);
if (isInited)
{
// //
// Update btn Pause Replay ... // Apply Style ...
string btnPauseReplayText = string btnPauseReplayText =
isVisualTesterPaused isVisualTesterPaused
? "Play" ? "Play"
: "Pause"; : "Pause";
btnPauseReplay.Text(btnPauseReplayText); btnPauseReplay.Text(btnPauseReplayText);
if (IsRunningeOnTestVisualMode()) btnPauseReplay.Color(clrAzure);
btnPauseReplay.ColorBackground(clrBlack);
}
//
//
// Update btn Pause Replay ...
string btnPauseReplayText =
isVisualTesterPaused
? "Play"
: "Pause";
btnPauseReplay.Text(btnPauseReplayText);
if (IsRunningeOnTestVisualMode())
{
//
btnPauseReplay.Show();
btnPauseReplay.Enable();
}
else
{
//
btnPauseReplay.Hide();
btnPauseReplay.Enable();
}
if (btnPauseReplay.Pressed())
{
//
if (btnPauseReplay.IsEnabled())
{ {
// //
btnPauseReplay.Show(); HandlePauseStrategyTester();
btnPauseReplay.Enable();
}
else
{
//
btnPauseReplay.Hide();
btnPauseReplay.Enable();
}
if (btnPauseReplay.Pressed())
{
//
if (btnPauseReplay.IsEnabled())
{
//
HandlePauseStrategyTester();
//
btnPauseReplayText =
isVisualTesterPaused
? "Play"
: "Pause";
btnPauseReplay.Text(btnPauseReplayText);
}
// //
btnPauseReplay.Pressed(false); btnPauseReplayText =
isVisualTesterPaused
? "Play"
: "Pause";
btnPauseReplay.Text(btnPauseReplayText);
} }
//
btnPauseReplay.Pressed(false);
}
void HandlePauseStrategyTester() void HandlePauseStrategyTester()
{ {
@@ -745,3 +742,180 @@ void HandlePauseStrategyTester()
keybd_event(VK_SPACE, 0, 0, 0); keybd_event(VK_SPACE, 0, 0, 0);
keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0); keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0);
} }
///////////////////////////
/// XFIMA ...
///////////////////////////
//
// ZIGZAG Pattern ...
// if (detectZIGZAGPatterns)
// {
// //
// // Detect Market Analysis ...
// XZigZagAnalysis zAnalysis;
// has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag(
// cBar,
// cBar.period,
// fima2Signaller.fimaHelper,
// zAnalysis,
// 15 //
// );
// if (has)
// {
// //
// Print(ShortName + zAnalysis.GetMessage());
// //
// XCZigZagAnalysisObject *iObj;
// has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysisByPV(
// iObj,
// zAnalysis //
// );
// if (has)
// {
// draws.Add(iObj);
// }
// }
// }
//
// Reading Pivots ...
double iLows[];
double iHighs[];
double lowTo = 0;
double highTo = 0;
double lowFrom = 0;
double highFrom = 0;
datetime lowToTime = NULL;
datetime highToTime = NULL;
datetime lowFromTime = NULL;
datetime highFromTime = NULL;
double lowsSlope = EMPTY_VALUE;
double highsSlope = EMPTY_VALUE;
double lowsIntercept = EMPTY_VALUE;
double highsIntercept = EMPTY_VALUE;
//
int iLoopbackLength = 50;
for (int i = 0; i < iLoopbackLength; i++)
{
//
double iLowPrice = iLow(_Symbol, _Period, i);
double iHighPrice = iHigh(_Symbol, _Period, i);
//
Add(
iLowPrice,
iLows //
);
Add(
iHighPrice,
iHighs //
);
}
has = CalculateLinearRegression(
lowsSlope,
lowsIntercept,
iLows,
0,
0 //
);
if (has)
{
//
lowToTime = GetBarTime(
_Symbol,
_Period,
0 //
);
lowTo = CalculateValueBySlopeIntercept(
lowsSlope,
lowsIntercept,
0 //
);
//
lowFromTime = GetBarTime(
_Symbol,
_Period,
iLoopbackLength //
);
lowFrom = CalculateValueBySlopeIntercept(
lowsSlope,
lowsIntercept,
iLoopbackLength //
);
}
//
has = CalculateLinearRegression(
highsSlope,
highsIntercept,
iHighs,
0,
0 //
);
if (has)
{
//
highToTime = GetBarTime(
_Symbol,
_Period,
0 //
);
highTo = CalculateValueBySlopeIntercept(
highsSlope,
highsIntercept,
0 //
);
//
highFromTime = GetBarTime(
_Symbol,
_Period,
iLoopbackLength //
);
highFrom = CalculateValueBySlopeIntercept(
highsSlope,
highsIntercept,
iLoopbackLength //
);
}
//
// Try to Draw ...
//
// Low ...
CChartObjectTrend *iLowTrend;
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
lowFrom,
lowFromTime,
lowTo,
lowToTime,
iLowTrend,
"LOW_TREMD",
true // Ray Right ...
);
if (has)
{
draws.Add(iLowTrend);
}
//
// High ...
CChartObjectTrend *iHighTrend;
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
highFrom,
highFromTime,
highTo,
highToTime,
iHighTrend,
"HIGH_TREMD",
true // Ray Right ...
);
if (has)
{
draws.Add(iHighTrend);
}
-174
View File
@@ -159,7 +159,6 @@ int eaCTHandler = INVALID_HANDLE; // Candle Timer Handler ...
// //
bool eaIsNewBar; // Check New Bar ... bool eaIsNewBar; // Check New Bar ...
XZigZagAnalysis zigzagAnalysis;
ENUM_X_DIRECTION trendDir = X_DIRECTION_NONE; ENUM_X_DIRECTION trendDir = X_DIRECTION_NONE;
// //
@@ -816,7 +815,6 @@ void DetectPatterns()
// //
// XFIMA Patetrns ... // XFIMA Patetrns ...
bool detectFIMAPatterns = true; bool detectFIMAPatterns = true;
bool detectZIGZAGPatterns = true;
// //
// Checking Momentum Bar ... // Checking Momentum Bar ...
@@ -1145,178 +1143,6 @@ void DetectPatterns()
// Detecting FIMA Patterns ... // Detecting FIMA Patterns ...
if (detectFIMAPatterns) if (detectFIMAPatterns)
{ {
//
// ZIGZAG Pattern ...
// if (detectZIGZAGPatterns)
// {
// //
// // Detect Market Analysis ...
// XZigZagAnalysis zAnalysis;
// has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag(
// cBar,
// cBar.period,
// fima2Signaller.fimaHelper,
// zAnalysis,
// 15 //
// );
// if (has)
// {
// //
// Print(ShortName + zAnalysis.GetMessage());
// //
// XCZigZagAnalysisObject *iObj;
// has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysisByPV(
// iObj,
// zAnalysis //
// );
// if (has)
// {
// draws.Add(iObj);
// }
// }
// }
//
// Reading Pivots ...
double iLows[];
double iHighs[];
double lowTo = 0;
double highTo = 0;
double lowFrom = 0;
double highFrom = 0;
datetime lowToTime = NULL;
datetime highToTime = NULL;
datetime lowFromTime = NULL;
datetime highFromTime = NULL;
double lowsSlope = EMPTY_VALUE;
double highsSlope = EMPTY_VALUE;
double lowsIntercept = EMPTY_VALUE;
double highsIntercept = EMPTY_VALUE;
//
int iLoopbackLength = 50;
for (int i = 0; i < iLoopbackLength; i++)
{
//
double iLowPrice = iLow(_Symbol, _Period, i);
double iHighPrice = iHigh(_Symbol, _Period, i);
//
Add(
iLowPrice,
iLows //
);
Add(
iHighPrice,
iHighs //
);
}
has = CalculateLinearRegression(
lowsSlope,
lowsIntercept,
iLows,
0,
0 //
);
if (has)
{
//
lowToTime = GetBarTime(
_Symbol,
_Period,
0 //
);
lowTo = CalculateValueBySlopeIntercept(
lowsSlope,
lowsIntercept,
0 //
);
//
lowFromTime = GetBarTime(
_Symbol,
_Period,
iLoopbackLength //
);
lowFrom = CalculateValueBySlopeIntercept(
lowsSlope,
lowsIntercept,
iLoopbackLength //
);
}
//
has = CalculateLinearRegression(
highsSlope,
highsIntercept,
iHighs,
0,
0 //
);
if (has)
{
//
highToTime = GetBarTime(
_Symbol,
_Period,
0 //
);
highTo = CalculateValueBySlopeIntercept(
highsSlope,
highsIntercept,
0 //
);
//
highFromTime = GetBarTime(
_Symbol,
_Period,
iLoopbackLength //
);
highFrom = CalculateValueBySlopeIntercept(
highsSlope,
highsIntercept,
iLoopbackLength //
);
}
//
// Try to Draw ...
//
// Low ...
CChartObjectTrend *iLowTrend;
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
lowFrom,
lowFromTime,
lowTo,
lowToTime,
iLowTrend,
"LOW_TREMD",
true // Ray Right ...
);
if (has)
{
draws.Add(iLowTrend);
}
//
// High ...
CChartObjectTrend *iHighTrend;
has = fima2Signaller.fimaPOIDrawer.DrawTrendLine(
highFrom,
highFromTime,
highTo,
highToTime,
iHighTrend,
"HIGH_TREMD",
true // Ray Right ...
);
if (has)
{
draws.Add(iHighTrend);
}
} }
// //
@@ -56,277 +56,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector
// //
// Actions and Tools ... // Actions and Tools ...
/**
* Get Specified Number of Recent ZigZag Points ...
*
* @param bar: XOHCL, Specified Bar for Start ...
* @param fimaHelper: XCXFIMAHelper, instance of XFIMA Helper ...
* @param zigzagPoints: XZigZagPoint, Array of Founded Points ...
* @param numberOfRequiredPivots: int, Specified Number of required ZigZag Points ...
*
* @return ( int )
*/
int GetZigZagPivot(
XOHCL &bar,
XCXFIMAHelper *&fimaHelper,
XZigZagPivot &zigzagPivots[],
int numberOfRequiredPivots = 5 //
)
{
//
int result = 0;
//
// Normalize ...
SpecifiedClean(zigzagPivots);
numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 3);
//
// Validate ...
result = bar.IsValid() &&
bar.symbol == fimaHelper.GetSymbol() &&
bar.period == fimaHelper.GetPeriod();
if (!result)
{
return result;
}
//
// Update Fima Helper ...
int index = bar.Index();
fimaHelper.Update(index);
//
// Start Reading ZigZag Values ...
double iZG = 0;
double iPZG = 0;
int iZGIdx = -1;
int iPZGIdx = -1;
bool has = false;
int start = index;
XZigZagPivot iZGPoint;
datetime iZGTime = NULL;
datetime iPZGTime = NULL;
int lastZGDetected = start;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_ZIGZAG_POINT_TYPE iType = X_ZIGZAG_PIVOT_TYPE_NONE;
while (ArraySize(zigzagPivots) < numberOfRequiredPivots)
{
//
// Reading Last two ZigZag Value ...
//
// Detect Last ZG Value ...
has = GetZigZagValue(lastZGDetected, iZG, iZGIdx, iZGTime, fimaHelper);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Detect Previous ZG Value ...
has = GetZigZagValue(lastZGDetected + 1, iPZG, iPZGIdx, iPZGTime, fimaHelper);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Check Direction ...
iDir =
(iZG > iPZG)
? X_DIRECTION_BULLISH
: (iZG < iPZG)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
// Check Point Type ...
iType =
IsSpecifiedBullish(iDir)
? X_ZIGZAG_PIVOT_TYPE_PEAK
: IsSpecifiedBearish(iDir)
? X_ZIGZAG_PIVOT_TYPE_VALE
: X_ZIGZAG_PIVOT_TYPE_NONE;
has =
IsXValid(iType) &&
HasDirection(iDir);
if (!has)
{
//
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
lastZGDetected++;
//
continue;
}
//
// Initialize ZigZag Point ...
has = iZGPoint.Init(
iZG,
iZGTime,
bar.symbol,
iDir,
bar.period,
iType //
);
if (has)
{
//
iZGPoint.AddIfNotExists(zigzagPivots);
lastZGDetected = iZGIdx + 1;
}
//
// Reset Resources ...
iZG = 0;
iPZG = 0;
iZGIdx = -1;
iPZGIdx = -1;
iZGTime = NULL;
iPZGTime = NULL;
iZGPoint.Clean();
iDir = X_DIRECTION_NONE;
iType = X_ZIGZAG_PIVOT_TYPE_NONE;
//
start++;
}
//
result = ArraySize(zigzagPivots);
//
return result;
}
//
bool AnalyseMarketUsingZigZag(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod,
XCXFIMAHelper *&fimaHelper,
XZigZagAnalysis &analysis,
int numberOfRequiredPivots = 20 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Normalize ...
numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 5);
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = bar.period;
}
//
// Reading XZigZag Points ...
XOHCL iPeriodBar;
result = iPeriodBar.Init(
bar.symbol,
forPeriod,
bar.Index() //
);
if (!result)
{
//
iPeriodBar.Clean();
return result;
}
//
// Reading Required Pivots ...
XZigZagPivot pivots[];
int pivotsCount = GetZigZagPivot(
iPeriodBar,
fimaHelper,
pivots,
numberOfRequiredPivots //
);
result = IsValidSize(pivotsCount);
if (!result)
{
//
analysis.Clean();
iPeriodBar.Clean();
SpecifiedClean(pivots);
}
//
// Initialize Analysis Model ...
result = analysis.Analyse(
bar,
pivots //
);
if (!result)
{
//
analysis.Clean();
iPeriodBar.Clean();
SpecifiedClean(pivots);
}
//
return result;
}
// //
// Tools ... // Tools ...
@@ -349,102 +78,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector
// //
// Tools / Actions ... // Tools / Actions ...
/**
* Read Specified Value of ZigZag ...
*
* @param fromBarIndex: int, Specified Start Bar Index ...
* @param value: double, reference to Hold ZigZag Value ...
* @param index: int, reference to Hold ZigZag Value's Bar Index ...
* @param time: datetime, reference to Hold ZigZag Value's Time ...
* @param maxAllowedLoopback: int, Maximum Allowe Loopback to Detect Specified Point ...
*
* @return ( bool )
*/
bool GetZigZagValue(
int fromBarIndex,
double &value,
int &index,
datetime &time,
XCXFIMAHelper *&fimaHelper,
int maxAllowedLoopback = 100 //
)
{
//
bool result = false;
//
// Normalize ...
fromBarIndex = NormalizeInt(fromBarIndex, 0);
maxAllowedLoopback = NormalizeInt(maxAllowedLoopback, 10, 100);
//
// Prepare ...
value = 0;
index = -1;
time = NULL;
//
// Validate ...
result = fimaHelper != NULL;
if (!result)
{
return result;
}
//
int start = fromBarIndex;
int end = start + maxAllowedLoopback;
while (start < end)
{
//
fimaHelper.Update(start);
//
value = fimaHelper.GetZigZag(start);
result = value > 0 && value != EMPTY_VALUE;
if (result)
{
//
time = GetBarTime(
fimaHelper.GetSymbol(),
fimaHelper.GetPeriod(),
start //
);
//
index = start;
//
break;
}
//
value = 0;
index = -1;
time = NULL;
//
start++;
}
//
result =
value > 0 &&
IsValidIndex(index) &&
value != EMPTY_VALUE &&
IsSpecifiedValid(time);
if (!result)
{
//
value = 0;
index = -1;
time = NULL;
}
//
return result;
}
// //
// Private ... // Private ...
private: private:
@@ -33,179 +33,6 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer
public: public:
// //
/**
* Draw Specified XZigZagMarketStyle on Chart ...
*
* @param object: XCZigZagAnalysisObject, pointer reference to Drawn Object ...
* @param model: XZigZagAnalysis, reference to Model ...
* @param numberOfPivots: int, required number of pivots for Draw Trends ...
* @param rayRight: bool, Ray To Right ...
* @param rayLeft: bool, Ray To Left ...
*
* @return ( bool )
*/
bool DrawZigZagMarketAnalysisByPV(
XCZigZagAnalysisObject *&object,
XZigZagAnalysis &model,
bool rayRight = false,
bool rayLeft = false,
int numberOfPivots = 2 //
)
{
//
bool result = false;
//
// Prepare ...
object = NULL;
//
// Validate ...
result = model.IsValid();
if (!result)
{
return result;
}
//
object = new XCZigZagAnalysisObject();
result = object.CreateByPV(
ChartIdentification(),
SubWindowIdentification(),
model //
);
if (result)
{
//
// Apply Style ...
bool isBullish = model.IsBullish();
//
XPOIStyle style;
if (isBullish)
{
style = defaultBullishStyle;
}
else
{
style = defaultBearishStyle;
}
//
ApplyZigZagMarketAnalysisStyle(
object,
style,
true, // Ray Right ...
false // Ray Left ...
);
}
//
return result;
}
/**
* Draw Specified XZigZagMarketStyle on Chart ...
*
* @param object: XCZigZagAnalysisObject, pointer reference to Drawn Object ...
* @param model: XZigZagAnalysis, reference to Model ...
* @param numberOfPivots: int, required number of pivots for Draw Trends ...
* @param rayRight: bool, Ray To Right ...
* @param rayLeft: bool, Ray To Left ...
*
* @return ( bool )
*/
bool DrawZigZagMarketAnalysisByRecent(
XCZigZagAnalysisObject *&object,
XZigZagAnalysis &model,
bool rayRight = false,
bool rayLeft = false,
int numberOfPivots = 2 //
)
{
//
bool result = false;
//
// Prepare ...
object = NULL;
//
// Validate ...
result = model.IsValid();
if (!result)
{
return result;
}
//
object = new XCZigZagAnalysisObject();
result = object.CreateByRecent(
ChartIdentification(),
SubWindowIdentification(),
model,
numberOfPivots //
);
if (result)
{
//
// Apply Style ...
bool isBullish = model.IsBullish();
//
XPOIStyle style;
if (isBullish)
{
style = defaultBullishStyle;
}
else
{
style = defaultBearishStyle;
}
//
ApplyZigZagMarketAnalysisStyle(
object,
style,
true, // Ray Right ...
false // Ray Left ...
);
}
//
return result;
}
/**
* Apply Specified Style to Object ...
*/
void ApplyZigZagMarketAnalysisStyle(
XCZigZagAnalysisObject *&object,
XPOIStyle &style,
bool rayRight = false,
bool rayLeft = false //
)
{
//
bool has = object != NULL;
if (!has)
{
return;
}
//
object.UpperColor(style.clr);
object.LowerColor(style.clr);
object.UpperWidth(style.width);
object.UpperRayLeft(rayLeft);
object.UpperRayRight(rayRight);
object.LowerWidth(style.width);
object.UpperStyle(style.style);
object.LowerStyle(style.style);
object.LowerRayLeft(rayLeft);
object.LowerRayRight(rayRight);
}
// //
}; };
File diff suppressed because it is too large Load Diff