This commit is contained in:
backuppc
2025-11-10 14:43:47 +09:00
parent 68745f23bb
commit 6e54633c08
57 changed files with 4432 additions and 1018 deletions

View File

@@ -51,6 +51,8 @@ namespace AGVSimulator.Forms
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.reloadMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.launchMapEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
@@ -65,7 +67,6 @@ namespace AGVSimulator.Forms
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this._toolStrip = new System.Windows.Forms.ToolStrip();
this.openMapToolStripButton = new System.Windows.Forms.ToolStripButton();
this.reloadMapToolStripButton = new System.Windows.Forms.ToolStripButton();
this.launchMapEditorToolStripButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
@@ -79,6 +80,7 @@ namespace AGVSimulator.Forms
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.btPredict = new System.Windows.Forms.ToolStripButton();
this.btMakeMap = new System.Windows.Forms.ToolStripButton();
this._statusStrip = new System.Windows.Forms.StatusStrip();
this._statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this._coordLabel = new System.Windows.Forms.ToolStripStatusLabel();
@@ -109,12 +111,12 @@ namespace AGVSimulator.Forms
this._addAgvButton = new System.Windows.Forms.Button();
this._agvListCombo = new System.Windows.Forms.ComboBox();
this._canvasPanel = new System.Windows.Forms.Panel();
this.lbPredict = new System.Windows.Forms.RichTextBox();
this._agvInfoPanel = new System.Windows.Forms.Panel();
this._pathDebugLabel = new System.Windows.Forms.TextBox();
this._agvInfoTitleLabel = new System.Windows.Forms.Label();
this._liftDirectionLabel = new System.Windows.Forms.Label();
this._motorDirectionLabel = new System.Windows.Forms.Label();
this.lbPredict = new System.Windows.Forms.RichTextBox();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this._menuStrip.SuspendLayout();
this._toolStrip.SuspendLayout();
@@ -145,6 +147,8 @@ namespace AGVSimulator.Forms
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openMapToolStripMenuItem,
this.reloadMapToolStripMenuItem,
this.SToolStripMenuItem,
this.ToolStripMenuItem,
this.toolStripSeparator1,
this.launchMapEditorToolStripMenuItem,
this.toolStripSeparator4,
@@ -169,6 +173,20 @@ namespace AGVSimulator.Forms
this.reloadMapToolStripMenuItem.Text = "맵 다시열기(&R)";
this.reloadMapToolStripMenuItem.Click += new System.EventHandler(this.OnReloadMap_Click);
//
// 맵저장SToolStripMenuItem
//
this.SToolStripMenuItem.Name = "맵저장SToolStripMenuItem";
this.SToolStripMenuItem.Size = new System.Drawing.Size(221, 22);
this.SToolStripMenuItem.Text = "맵 저장(&S)";
this.SToolStripMenuItem.Click += new System.EventHandler(this.SToolStripMenuItem_Click);
//
// 맵다른이름으로저장ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "맵다른이름으로저장ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(221, 22);
this.ToolStripMenuItem.Text = "맵 다른 이름으로 저장";
this.ToolStripMenuItem.Click += new System.EventHandler(this.btMapSaveAs_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
@@ -272,7 +290,6 @@ namespace AGVSimulator.Forms
// _toolStrip
//
this._toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.openMapToolStripButton,
this.reloadMapToolStripButton,
this.launchMapEditorToolStripButton,
this.toolStripSeparator2,
@@ -285,22 +302,14 @@ namespace AGVSimulator.Forms
this.resetZoomToolStripButton,
this.toolStripSeparator5,
this.toolStripButton1,
this.btPredict});
this.btPredict,
this.btMakeMap});
this._toolStrip.Location = new System.Drawing.Point(0, 24);
this._toolStrip.Name = "_toolStrip";
this._toolStrip.Size = new System.Drawing.Size(1034, 25);
this._toolStrip.TabIndex = 1;
this._toolStrip.Text = "toolStrip";
//
// openMapToolStripButton
//
this.openMapToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.openMapToolStripButton.Name = "openMapToolStripButton";
this.openMapToolStripButton.Size = new System.Drawing.Size(51, 22);
this.openMapToolStripButton.Text = "맵 열기";
this.openMapToolStripButton.ToolTipText = "맵 파일을 엽니다";
this.openMapToolStripButton.Click += new System.EventHandler(this.OnOpenMap_Click);
//
// reloadMapToolStripButton
//
this.reloadMapToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
@@ -406,6 +415,15 @@ namespace AGVSimulator.Forms
this.btPredict.Text = "다음 행동 예측";
this.btPredict.Click += new System.EventHandler(this.btPredict_Click);
//
// btMakeMap
//
this.btMakeMap.Image = ((System.Drawing.Image)(resources.GetObject("btMakeMap.Image")));
this.btMakeMap.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btMakeMap.Name = "btMakeMap";
this.btMakeMap.Size = new System.Drawing.Size(63, 22);
this.btMakeMap.Text = "맵기록";
this.btMakeMap.Click += new System.EventHandler(this.btMakeMap_Click);
//
// _statusStrip
//
this._statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -701,6 +719,15 @@ namespace AGVSimulator.Forms
this._canvasPanel.Size = new System.Drawing.Size(801, 560);
this._canvasPanel.TabIndex = 4;
//
// lbPredict
//
this.lbPredict.Dock = System.Windows.Forms.DockStyle.Bottom;
this.lbPredict.Location = new System.Drawing.Point(0, 513);
this.lbPredict.Name = "lbPredict";
this.lbPredict.Size = new System.Drawing.Size(801, 47);
this.lbPredict.TabIndex = 0;
this.lbPredict.Text = "";
//
// _agvInfoPanel
//
this._agvInfoPanel.BackColor = System.Drawing.Color.LightBlue;
@@ -757,15 +784,6 @@ namespace AGVSimulator.Forms
this._motorDirectionLabel.TabIndex = 2;
this._motorDirectionLabel.Text = "모터 방향: -";
//
// lbPredict
//
this.lbPredict.Dock = System.Windows.Forms.DockStyle.Bottom;
this.lbPredict.Location = new System.Drawing.Point(0, 513);
this.lbPredict.Name = "lbPredict";
this.lbPredict.Size = new System.Drawing.Size(801, 47);
this.lbPredict.TabIndex = 0;
this.lbPredict.Text = "";
//
// timer1
//
this.timer1.Interval = 500;
@@ -825,7 +843,6 @@ namespace AGVSimulator.Forms
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
private System.Windows.Forms.ToolStrip _toolStrip;
private System.Windows.Forms.ToolStripButton openMapToolStripButton;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripButton startSimulationToolStripButton;
private System.Windows.Forms.ToolStripButton stopSimulationToolStripButton;
@@ -879,5 +896,8 @@ namespace AGVSimulator.Forms
private System.Windows.Forms.ToolStripButton btPredict;
private System.Windows.Forms.RichTextBox lbPredict;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.ToolStripButton btMakeMap;
private System.Windows.Forms.ToolStripMenuItem SToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem;
}
}

View File

@@ -35,6 +35,13 @@ namespace AGVSimulator.Forms
private string _currentMapFilePath;
private bool _isTargetCalcMode; // 타겟계산 모드 상태
// 맵 스캔 모드 관련
private bool _isMapScanMode; // 맵 스캔 모드 상태
private DateTime _lastNodeAddTime; // 마지막 노드 추가 시간
private MapNode _lastScannedNode; // 마지막으로 스캔된 노드
private int _scanNodeCounter; // 스캔 노드 카운터
private AgvDirection _lastScanDirection; // 마지막 스캔 방향
// UI Controls - Designer에서 생성됨
#endregion
@@ -238,7 +245,8 @@ namespace AGVSimulator.Forms
UpdateAGVComboBox();
UpdateUI();
_statusLabel.Text = $"{agvId} 추가됨";
_statusLabel.Text = $"{agvId} 추가됨";
_simulatorCanvas.FitToNodes();
}
private void OnRemoveAGV_Click(object sender, EventArgs e)
@@ -508,6 +516,165 @@ namespace AGVSimulator.Forms
return closestNode;
}
/// <summary>
/// 방향을 기호로 변환
/// </summary>
private string GetDirectionSymbol(AgvDirection direction)
{
switch (direction)
{
case AgvDirection.Forward: return "→";
case AgvDirection.Backward: return "←";
case AgvDirection.Left: return "↺";
case AgvDirection.Right: return "↻";
default: return "-";
}
}
/// <summary>
/// 맵 스캔 모드에서 RFID로부터 노드 생성
/// </summary>
private void CreateNodeFromRfidScan(string rfidId, VirtualAGV selectedAGV)
{
try
{
// 현재 선택된 방향 확인 (최상단에서 먼저 확인)
var directionItem = _directionCombo.SelectedItem as DirectionItem;
var currentDirection = directionItem?.Direction ?? AgvDirection.Forward;
// 중복 RFID 확인
var existingNode = _mapNodes?.FirstOrDefault(n => n.RfidId.Equals(rfidId, StringComparison.OrdinalIgnoreCase));
if (existingNode != null)
{
// 이미 존재하는 노드로 이동
Program.WriteLine($"[맵 스캔] RFID '{rfidId}'는 이미 존재합니다 (노드: {existingNode.NodeId})");
// 기존 노드로 AGV 위치 설정
_simulatorCanvas.SetAGVPosition(selectedAGV.AgvId, existingNode, currentDirection);
selectedAGV.SetPosition(existingNode, currentDirection);
_lastScannedNode = existingNode;
_lastNodeAddTime = DateTime.Now;
_lastScanDirection = currentDirection; // 방향 업데이트
_statusLabel.Text = $"기존 노드로 이동: {existingNode.NodeId} [{GetDirectionSymbol(currentDirection)}]";
_rfidTextBox.Text = "";
return;
}
// 새 노드 생성 위치 계산
int newX = 100; // 기본 시작 X 위치
int newY = 300; // 기본 시작 Y 위치
if (_lastScannedNode != null)
{
// 시간차 기반 X축 거리 계산
var timeDiff = (DateTime.Now - _lastNodeAddTime).TotalSeconds;
// 10초당 10px, 최소 50px, 최대 100px
int distanceX = Math.Max(50, Math.Min(100, (int)(timeDiff * 10)));
// 방향 전환 확인
bool directionChanged = (_lastScanDirection != currentDirection);
if (directionChanged)
{
// 방향이 바뀌면 Y축을 50px 증가시켜서 겹치지 않게 함
newY = _lastScannedNode.Position.Y + 50;
newX = _lastScannedNode.Position.X; // X는 같은 위치에서 시작
Program.WriteLine($"[맵 스캔] 방향 전환: {_lastScanDirection} → {currentDirection}, Y축 +50px");
}
else
{
// 방향이 같으면 Y축 유지
newY = _lastScannedNode.Position.Y;
// 모터 방향에 따라 X축 증가/감소
if (currentDirection == AgvDirection.Forward)
{
// 전진: X축 증가
newX = _lastScannedNode.Position.X + distanceX;
Program.WriteLine($"[맵 스캔] 전진 모드: X축 +{distanceX}px");
}
else if (currentDirection == AgvDirection.Backward)
{
// 후진: X축 감소
newX = _lastScannedNode.Position.X - distanceX;
Program.WriteLine($"[맵 스캔] 후진 모드: X축 -{distanceX}px");
}
else
{
// 그 외(회전 등): 기본적으로 전진 방향 사용
newX = _lastScannedNode.Position.X + distanceX;
Program.WriteLine($"[맵 스캔] 기타 방향({currentDirection}): X축 +{distanceX}px");
}
}
Program.WriteLine($"[맵 스캔] 시간차: {timeDiff:F1}초 → 거리: {distanceX}px");
}
// 새 노드 생성
var newNodeId = $"{_scanNodeCounter:D3}";
var newNode = new MapNode
{
NodeId = newNodeId,
RfidId = rfidId,
Position = new Point(newX, newY),
Type = NodeType.Normal,
IsActive = true,
Name = $"N{_scanNodeCounter}"
};
// 맵에 추가
if (_mapNodes == null)
_mapNodes = new List<MapNode>();
_mapNodes.Add(newNode);
// 이전 노드와 연결 생성
if (_lastScannedNode != null)
{
// 양방향 연결 (ConnectedNodes에 추가 - JSON 저장됨)
_lastScannedNode.AddConnection(newNode.NodeId);
newNode.AddConnection(_lastScannedNode.NodeId);
Program.WriteLine($"[맵 스캔] 연결 생성: {_lastScannedNode.NodeId} ↔ {newNode.NodeId}");
}
// AGV 위치 설정
_simulatorCanvas.SetAGVPosition(selectedAGV.AgvId, newNode, currentDirection);
selectedAGV.SetPosition(newNode, currentDirection);
// 캔버스 업데이트
_simulatorCanvas.Nodes = _mapNodes;
// 화면을 새 노드 위치로 이동
_simulatorCanvas.PanToNode(newNode.NodeId);
_simulatorCanvas.Invalidate();
// 상태 업데이트
_lastScannedNode = newNode;
_lastNodeAddTime = DateTime.Now;
_lastScanDirection = currentDirection; // 현재 방향 저장
_scanNodeCounter++;
// UI 업데이트
UpdateNodeComboBoxes();
_statusLabel.Text = $"노드 생성: {newNode.NodeId} (RFID: {rfidId}) [{GetDirectionSymbol(currentDirection)}] - 총 {_mapNodes.Count}개";
_rfidTextBox.Text = "";
Program.WriteLine($"[맵 스캔] 노드 생성 완료: {newNode.NodeId} (RFID: {rfidId}) at ({newX}, {newY}), 방향: {currentDirection}");
}
catch (Exception ex)
{
MessageBox.Show($"노드 생성 중 오류 발생:\n{ex.Message}", "오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
Program.WriteLine($"[맵 스캔 오류] {ex.Message}");
}
}
private void OnSetPosition_Click(object sender, EventArgs e)
{
SetAGVPositionByRfid();
@@ -561,6 +728,19 @@ namespace AGVSimulator.Forms
MessageBox.Show("RFID 값을 입력해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 선택된 방향 확인
var selectedDirectionItem = _directionCombo.SelectedItem as DirectionItem;
var selectedDirection = selectedDirectionItem?.Direction ?? AgvDirection.Forward;
// 맵 스캔 모드일 때: 노드 자동 생성
if (_isMapScanMode)
{
CreateNodeFromRfidScan(rfidId, selectedAGV);
this._simulatorCanvas.FitToNodes();
return;
}
// RFID에 해당하는 노드 직접 찾기
var targetNode = _mapNodes?.FirstOrDefault(n => n.RfidId.Equals(rfidId, StringComparison.OrdinalIgnoreCase));
@@ -571,10 +751,7 @@ namespace AGVSimulator.Forms
return;
}
// 선택된 방향 확인
var selectedDirectionItem = _directionCombo.SelectedItem as DirectionItem;
var selectedDirection = selectedDirectionItem?.Direction ?? AgvDirection.Forward;
//이전위치와 동일한지 체크한다.
if (selectedAGV.CurrentNodeId == targetNode.NodeId && selectedAGV.CurrentDirection == selectedDirection)
{
@@ -1625,6 +1802,184 @@ namespace AGVSimulator.Forms
var command = agv.Predict();
this.lbPredict.Text = $"Motor:{command.Motor},Magnet:{command.Magnet},Speed:{command.Speed} : {command.Reason}";
}
private void btMakeMap_Click(object sender, EventArgs e)
{
if (!_isMapScanMode)
{
// 스캔 모드 시작
var result = MessageBox.Show(
"맵 스캔 모드를 시작합니다.\n\n" +
"RFID를 입력하면 자동으로 맵 노드가 생성되고\n" +
"이전 노드와 연결됩니다.\n\n" +
"기존 맵 데이터를 삭제하고 시작하시겠습니까?\n\n" +
"예: 새 맵 시작\n" +
"아니오: 기존 맵에 추가",
"맵 스캔 모드",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
{
// 기존 맵 데이터 삭제
_mapNodes?.Clear();
_mapNodes = new List<MapNode>();
_simulatorCanvas.Nodes = _mapNodes;
_currentMapFilePath = string.Empty;
UpdateNodeComboBoxes();
_statusLabel.Text = "맵 초기화 완료 - 스캔 모드 시작";
}
// 스캔 모드 활성화
_isMapScanMode = true;
_lastNodeAddTime = DateTime.Now;
_lastScannedNode = null;
_scanNodeCounter = 1;
_lastScanDirection = AgvDirection.Forward; // 기본 방향은 전진
btMakeMap.Text = "스캔 중지";
btMakeMap.BackColor = Color.LightCoral;
_statusLabel.Text = "맵 스캔 모드: RFID를 입력하여 노드를 생성하세요";
Program.WriteLine("[맵 스캔] 스캔 모드 시작");
}
else
{
// 스캔 모드 종료
_isMapScanMode = false;
btMakeMap.Text = "맵 생성";
btMakeMap.BackColor = SystemColors.Control;
_statusLabel.Text = $"맵 스캔 완료 - {_mapNodes?.Count ?? 0}개 노드 생성됨";
Program.WriteLine($"[맵 스캔] 스캔 모드 종료 - 총 {_mapNodes?.Count ?? 0}개 노드");
// 맵 저장 권장
if (_mapNodes != null && _mapNodes.Count > 0)
{
var saveResult = MessageBox.Show(
$"맵 스캔이 완료되었습니다.\n\n" +
$"생성된 노드: {_mapNodes.Count}개\n\n" +
"맵을 저장하시겠습니까?",
"맵 저장",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (saveResult == DialogResult.Yes)
{
btMapSaveAs_Click(sender, e);
}
}
}
}
/// <summary>
/// 맵 데이터를 파일에 저장 (MapLoader 공통 저장 로직 사용)
/// </summary>
private void SaveMapToFile(string filePath)
{
try
{
// MapLoader의 표준 저장 메서드 사용 (AGVMapEditor와 동일한 형식)
bool success = MapLoader.SaveMapToFile(filePath, _mapNodes);
if (success)
{
Program.WriteLine($"[맵 저장] 파일 저장 완료: {filePath} ({_mapNodes.Count}개 노드)");
}
else
{
throw new InvalidOperationException("맵 저장에 실패했습니다.");
}
}
catch (Exception ex)
{
Program.WriteLine($"[맵 저장 오류] {ex.Message}");
throw;
}
}
private void btMapSaveAs_Click(object sender, EventArgs e)
{
// 맵 데이터 확인
if (_mapNodes == null || _mapNodes.Count == 0)
{
MessageBox.Show("저장할 맵 데이터가 없습니다.", "알림",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
using (var saveDialog = new SaveFileDialog())
{
saveDialog.Filter = "AGV Map Files (*.agvmap)|*.agvmap|모든 파일 (*.*)|*.*";
saveDialog.Title = "맵 파일 저장";
saveDialog.DefaultExt = "agvmap";
// 현재 파일이 있으면 기본 파일명으로 설정
if (!string.IsNullOrEmpty(_currentMapFilePath))
{
saveDialog.FileName = Path.GetFileName(_currentMapFilePath);
saveDialog.InitialDirectory = Path.GetDirectoryName(_currentMapFilePath);
}
else
{
// 기본 파일명: 날짜_시간 형식
saveDialog.FileName = $"ScanMap_{DateTime.Now:yyyyMMdd_HHmmss}.agvmap";
}
if (saveDialog.ShowDialog() == DialogResult.OK)
{
try
{
SaveMapToFile(saveDialog.FileName);
_currentMapFilePath = saveDialog.FileName;
// 설정에 마지막 맵 파일 경로 저장
_config.LastMapFilePath = _currentMapFilePath;
if (_config.AutoSave)
{
_config.Save();
}
_statusLabel.Text = $"맵 저장 완료: {Path.GetFileName(_currentMapFilePath)}";
MessageBox.Show($"맵이 저장되었습니다.\n\n파일: {_currentMapFilePath}", "저장 완료",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"맵 저장 중 오류 발생:\n{ex.Message}", "저장 오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void SToolStripMenuItem_Click(object sender, EventArgs e)
{
// 현재 맵 파일 경로가 있는 경우 해당 파일에 저장
if (string.IsNullOrEmpty(_currentMapFilePath))
{
// 경로가 없으면 다른 이름으로 저장 다이얼로그 표시
btMapSaveAs_Click(sender, e);
return;
}
try
{
SaveMapToFile(_currentMapFilePath);
_statusLabel.Text = $"맵 저장 완료: {Path.GetFileName(_currentMapFilePath)}";
MessageBox.Show($"맵이 저장되었습니다.\n\n파일: {_currentMapFilePath}", "저장 완료",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"맵 저장 중 오류 발생:\n{ex.Message}", "저장 오류",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>

View File

@@ -152,6 +152,21 @@
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<data name="btMakeMap.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="_statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">