feature: add CurrentBranch property to ViewModels.Repository

This commit is contained in:
leo 2024-07-24 15:36:26 +08:00
parent f8caeceade
commit 6f317039ab
No known key found for this signature in database
4 changed files with 63 additions and 64 deletions

View file

@ -147,7 +147,7 @@ namespace SourceGit.ViewModels
if (datagrid.SelectedItems.Count != 1) if (datagrid.SelectedItems.Count != 1)
return null; return null;
var current = _repo.Branches.Find(x => x.IsCurrent); var current = _repo.CurrentBranch;
if (current == null) if (current == null)
return null; return null;

View file

@ -68,7 +68,7 @@ namespace SourceGit.ViewModels
public Pull(Repository repo, Models.Branch specifiedRemoteBranch) public Pull(Repository repo, Models.Branch specifiedRemoteBranch)
{ {
_repo = repo; _repo = repo;
_current = repo.Branches.Find(x => x.IsCurrent); _current = repo.CurrentBranch;
if (specifiedRemoteBranch != null) if (specifiedRemoteBranch != null)
{ {

View file

@ -99,6 +99,12 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _branches, value); private set => SetProperty(ref _branches, value);
} }
public Models.Branch CurrentBranch
{
get => _currentBranch;
private set => SetProperty(ref _currentBranch, value);
}
public List<BranchTreeNode> LocalBranchTrees public List<BranchTreeNode> LocalBranchTrees
{ {
get => _localBranchTrees; get => _localBranchTrees;
@ -364,7 +370,7 @@ namespace SourceGit.ViewModels
if (!PopupHost.CanCreatePopup()) if (!PopupHost.CanCreatePopup())
return; return;
if (Remotes.Count == 0) if (_remotes.Count == 0)
{ {
App.RaiseException(_fullpath, "No remotes added to this repository!!!"); App.RaiseException(_fullpath, "No remotes added to this repository!!!");
return; return;
@ -378,7 +384,7 @@ namespace SourceGit.ViewModels
if (!PopupHost.CanCreatePopup()) if (!PopupHost.CanCreatePopup())
return; return;
if (Remotes.Count == 0) if (_remotes.Count == 0)
{ {
App.RaiseException(_fullpath, "No remotes added to this repository!!!"); App.RaiseException(_fullpath, "No remotes added to this repository!!!");
return; return;
@ -392,13 +398,13 @@ namespace SourceGit.ViewModels
if (!PopupHost.CanCreatePopup()) if (!PopupHost.CanCreatePopup())
return; return;
if (Remotes.Count == 0) if (_remotes.Count == 0)
{ {
App.RaiseException(_fullpath, "No remotes added to this repository!!!"); App.RaiseException(_fullpath, "No remotes added to this repository!!!");
return; return;
} }
if (Branches.Find(x => x.IsCurrent) == null) if (_currentBranch == null)
{ {
App.RaiseException(_fullpath, "Can NOT found current branch!!!"); App.RaiseException(_fullpath, "Can NOT found current branch!!!");
return; return;
@ -478,10 +484,10 @@ namespace SourceGit.ViewModels
break; break;
case 2: case 2:
visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, false).Result(); visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, false).Result();
break; break;
case 3: case 3:
visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, true).Result(); visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, true).Result();
break; break;
} }
@ -527,9 +533,8 @@ namespace SourceGit.ViewModels
public void NavigateToCurrentHead() public void NavigateToCurrentHead()
{ {
var cur = Branches.Find(x => x.IsCurrent); if (_currentBranch != null)
if (cur != null) NavigateToCommit(_currentBranch.Head);
NavigateToCommit(cur.Head);
} }
public void UpdateFilter(string filter, bool toggle) public void UpdateFilter(string filter, bool toggle)
@ -607,22 +612,20 @@ namespace SourceGit.ViewModels
public void RefreshBranches() public void RefreshBranches()
{ {
var branches = new Commands.QueryBranches(FullPath).Result(); var branches = new Commands.QueryBranches(_fullpath).Result();
var remotes = new Commands.QueryRemotes(FullPath).Result(); var remotes = new Commands.QueryRemotes(_fullpath).Result();
var builder = BuildBranchTree(branches, remotes); var builder = BuildBranchTree(branches, remotes);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
Remotes = remotes; Remotes = remotes;
Branches = branches; Branches = branches;
CurrentBranch = branches.Find(x => x.IsCurrent);
LocalBranchTrees = builder.Locals; LocalBranchTrees = builder.Locals;
RemoteBranchTrees = builder.Remotes; RemoteBranchTrees = builder.Remotes;
if (_workingCopy != null) if (_workingCopy != null)
{ _workingCopy.CanCommitWithPush = _currentBranch != null && !string.IsNullOrEmpty(_currentBranch.Upstream);
var cur = Branches.Find(x => x.IsCurrent);
_workingCopy.CanCommitWithPush = cur != null && !string.IsNullOrEmpty(cur.Upstream);
}
}); });
} }
@ -647,7 +650,7 @@ namespace SourceGit.ViewModels
public void RefreshTags() public void RefreshTags()
{ {
var tags = new Commands.QueryTags(FullPath).Result(); var tags = new Commands.QueryTags(_fullpath).Result();
foreach (var tag in tags) foreach (var tag in tags)
tag.IsFiltered = _settings.Filters.Contains(tag.Name); tag.IsFiltered = _settings.Filters.Contains(tag.Name);
@ -698,7 +701,7 @@ namespace SourceGit.ViewModels
var canPushCommits = new HashSet<string>(); var canPushCommits = new HashSet<string>();
var canPullCommits = new HashSet<string>(); var canPullCommits = new HashSet<string>();
var currentBranch = Branches.Find(x => x.IsCurrent); var currentBranch = _branches.Find(x => x.IsCurrent);
if (currentBranch != null) if (currentBranch != null)
{ {
foreach (var sha in currentBranch.TrackStatus.Ahead) foreach (var sha in currentBranch.TrackStatus.Ahead)
@ -724,13 +727,13 @@ namespace SourceGit.ViewModels
public void RefreshSubmodules() public void RefreshSubmodules()
{ {
var submodules = new Commands.QuerySubmodules(FullPath).Result(); var submodules = new Commands.QuerySubmodules(_fullpath).Result();
Dispatcher.UIThread.Invoke(() => Submodules = submodules); Dispatcher.UIThread.Invoke(() => Submodules = submodules);
} }
public void RefreshWorkingCopyChanges() public void RefreshWorkingCopyChanges()
{ {
var changes = new Commands.QueryLocalChanges(FullPath, _includeUntracked).Result(); var changes = new Commands.QueryLocalChanges(_fullpath, _includeUntracked).Result();
if (_workingCopy == null) if (_workingCopy == null)
return; return;
@ -774,7 +777,7 @@ namespace SourceGit.ViewModels
public void RefreshStashes() public void RefreshStashes()
{ {
var stashes = new Commands.QueryStashes(FullPath).Result(); var stashes = new Commands.QueryStashes(_fullpath).Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
if (_stashesPage != null) if (_stashesPage != null)
@ -785,15 +788,14 @@ namespace SourceGit.ViewModels
public void CreateNewBranch() public void CreateNewBranch()
{ {
var current = Branches.Find(x => x.IsCurrent); if (_currentBranch == null)
if (current == null)
{ {
App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit."); App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit.");
return; return;
} }
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new CreateBranch(this, current)); PopupHost.ShowPopup(new CreateBranch(this, _currentBranch));
} }
public void CheckoutBranch(Models.Branch branch) public void CheckoutBranch(Models.Branch branch)
@ -820,7 +822,7 @@ namespace SourceGit.ViewModels
} }
else else
{ {
foreach (var b in Branches) foreach (var b in _branches)
{ {
if (b.IsLocal && b.Upstream == branch.FullName) if (b.IsLocal && b.Upstream == branch.FullName)
{ {
@ -843,15 +845,14 @@ namespace SourceGit.ViewModels
public void CreateNewTag() public void CreateNewTag()
{ {
var current = Branches.Find(x => x.IsCurrent); if (_currentBranch == null)
if (current == null)
{ {
App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit."); App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit.");
return; return;
} }
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new CreateTag(this, current)); PopupHost.ShowPopup(new CreateTag(this, _currentBranch));
} }
public void AddRemote() public void AddRemote()
@ -1007,12 +1008,12 @@ namespace SourceGit.ViewModels
var fetch = new MenuItem(); var fetch = new MenuItem();
fetch.Header = App.Text("GitLFS.Fetch"); fetch.Header = App.Text("GitLFS.Fetch");
fetch.Icon = App.CreateMenuIcon("Icons.Fetch"); fetch.Icon = App.CreateMenuIcon("Icons.Fetch");
fetch.IsEnabled = Remotes.Count > 0; fetch.IsEnabled = _remotes.Count > 0;
fetch.Click += (_, e) => fetch.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
{ {
if (Remotes.Count == 1) if (_remotes.Count == 1)
PopupHost.ShowAndStartPopup(new LFSFetch(this)); PopupHost.ShowAndStartPopup(new LFSFetch(this));
else else
PopupHost.ShowPopup(new LFSFetch(this)); PopupHost.ShowPopup(new LFSFetch(this));
@ -1025,12 +1026,12 @@ namespace SourceGit.ViewModels
var pull = new MenuItem(); var pull = new MenuItem();
pull.Header = App.Text("GitLFS.Pull"); pull.Header = App.Text("GitLFS.Pull");
pull.Icon = App.CreateMenuIcon("Icons.Pull"); pull.Icon = App.CreateMenuIcon("Icons.Pull");
pull.IsEnabled = Remotes.Count > 0; pull.IsEnabled = _remotes.Count > 0;
pull.Click += (_, e) => pull.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
{ {
if (Remotes.Count == 1) if (_remotes.Count == 1)
PopupHost.ShowAndStartPopup(new LFSPull(this)); PopupHost.ShowAndStartPopup(new LFSPull(this));
else else
PopupHost.ShowPopup(new LFSPull(this)); PopupHost.ShowPopup(new LFSPull(this));
@ -1043,12 +1044,12 @@ namespace SourceGit.ViewModels
var push = new MenuItem(); var push = new MenuItem();
push.Header = App.Text("GitLFS.Push"); push.Header = App.Text("GitLFS.Push");
push.Icon = App.CreateMenuIcon("Icons.Push"); push.Icon = App.CreateMenuIcon("Icons.Push");
push.IsEnabled = Remotes.Count > 0; push.IsEnabled = _remotes.Count > 0;
push.Click += (_, e) => push.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
{ {
if (Remotes.Count == 1) if (_remotes.Count == 1)
PopupHost.ShowAndStartPopup(new LFSPush(this)); PopupHost.ShowAndStartPopup(new LFSPush(this));
else else
PopupHost.ShowPopup(new LFSPush(this)); PopupHost.ShowPopup(new LFSPush(this));
@ -1074,8 +1075,8 @@ namespace SourceGit.ViewModels
var locks = new MenuItem(); var locks = new MenuItem();
locks.Header = App.Text("GitLFS.Locks"); locks.Header = App.Text("GitLFS.Locks");
locks.Icon = App.CreateMenuIcon("Icons.Lock"); locks.Icon = App.CreateMenuIcon("Icons.Lock");
locks.IsEnabled = Remotes.Count > 0; locks.IsEnabled = _remotes.Count > 0;
if (Remotes.Count == 1) if (_remotes.Count == 1)
{ {
locks.Click += (_, e) => locks.Click += (_, e) =>
{ {
@ -1083,14 +1084,14 @@ namespace SourceGit.ViewModels
if (topLevel == null) if (topLevel == null)
return; return;
var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, Remotes[0].Name) }; var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, _remotes[0].Name) };
dialog.Show(topLevel); dialog.Show(topLevel);
e.Handled = true; e.Handled = true;
}; };
} }
else else
{ {
foreach (var remote in Remotes) foreach (var remote in _remotes)
{ {
var remoteName = remote.Name; var remoteName = remote.Name;
var lockRemote = new MenuItem(); var lockRemote = new MenuItem();
@ -1138,7 +1139,7 @@ namespace SourceGit.ViewModels
var push = new MenuItem(); var push = new MenuItem();
push.Header = new Views.NameHighlightedTextBlock("BranchCM.Push", branch.Name); push.Header = new Views.NameHighlightedTextBlock("BranchCM.Push", branch.Name);
push.Icon = App.CreateMenuIcon("Icons.Push"); push.Icon = App.CreateMenuIcon("Icons.Push");
push.IsEnabled = Remotes.Count > 0; push.IsEnabled = _remotes.Count > 0;
push.Click += (_, e) => push.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
@ -1201,8 +1202,6 @@ namespace SourceGit.ViewModels
} }
else else
{ {
var current = Branches.Find(x => x.IsCurrent);
var checkout = new MenuItem(); var checkout = new MenuItem();
checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name); checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name);
checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Icon = App.CreateMenuIcon("Icons.Check");
@ -1213,7 +1212,7 @@ namespace SourceGit.ViewModels
}; };
menu.Items.Add(checkout); menu.Items.Add(checkout);
var upstream = Branches.Find(x => x.FullName == branch.Upstream); var upstream = _branches.Find(x => x.FullName == branch.Upstream);
if (upstream != null) if (upstream != null)
{ {
var fastForward = new MenuItem(); var fastForward = new MenuItem();
@ -1235,22 +1234,22 @@ namespace SourceGit.ViewModels
menu.Items.Add(push); menu.Items.Add(push);
var merge = new MenuItem(); var merge = new MenuItem();
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, current.Name); merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, _currentBranch.Name);
merge.Icon = App.CreateMenuIcon("Icons.Merge"); merge.Icon = App.CreateMenuIcon("Icons.Merge");
merge.Click += (_, e) => merge.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Merge(this, branch.Name, current.Name)); PopupHost.ShowPopup(new Merge(this, branch.Name, _currentBranch.Name));
e.Handled = true; e.Handled = true;
}; };
var rebase = new MenuItem(); var rebase = new MenuItem();
rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", current.Name, branch.Name); rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, branch.Name);
rebase.Icon = App.CreateMenuIcon("Icons.Rebase"); rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
rebase.Click += (_, e) => rebase.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Rebase(this, current, branch)); PopupHost.ShowPopup(new Rebase(this, _currentBranch, branch));
e.Handled = true; e.Handled = true;
}; };
@ -1268,9 +1267,9 @@ namespace SourceGit.ViewModels
if (_histories != null) if (_histories != null)
{ {
var target = new Commands.QuerySingleCommit(FullPath, branch.Head).Result(); var target = new Commands.QuerySingleCommit(_fullpath, branch.Head).Result();
_histories.AutoSelectedCommit = null; _histories.AutoSelectedCommit = null;
_histories.DetailContext = new RevisionCompare(FullPath, target, null); _histories.DetailContext = new RevisionCompare(_fullpath, target, null);
} }
}; };
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
@ -1353,7 +1352,7 @@ namespace SourceGit.ViewModels
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
var remoteBranches = new List<Models.Branch>(); var remoteBranches = new List<Models.Branch>();
foreach (var b in Branches) foreach (var b in _branches)
{ {
if (!b.IsLocal) if (!b.IsLocal)
remoteBranches.Add(b); remoteBranches.Add(b);
@ -1505,7 +1504,6 @@ namespace SourceGit.ViewModels
public ContextMenu CreateContextMenuForRemoteBranch(Models.Branch branch) public ContextMenu CreateContextMenuForRemoteBranch(Models.Branch branch)
{ {
var menu = new ContextMenu(); var menu = new ContextMenu();
var current = Branches.Find(x => x.IsCurrent);
var name = branch.FriendlyName; var name = branch.FriendlyName;
var checkout = new MenuItem(); var checkout = new MenuItem();
@ -1519,10 +1517,10 @@ namespace SourceGit.ViewModels
menu.Items.Add(checkout); menu.Items.Add(checkout);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
if (current != null) if (_currentBranch != null)
{ {
var pull = new MenuItem(); var pull = new MenuItem();
pull.Header = new Views.NameHighlightedTextBlock("BranchCM.PullInto", name, current.Name); pull.Header = new Views.NameHighlightedTextBlock("BranchCM.PullInto", name, _currentBranch.Name);
pull.Icon = App.CreateMenuIcon("Icons.Pull"); pull.Icon = App.CreateMenuIcon("Icons.Pull");
pull.Click += (_, e) => pull.Click += (_, e) =>
{ {
@ -1532,22 +1530,22 @@ namespace SourceGit.ViewModels
}; };
var merge = new MenuItem(); var merge = new MenuItem();
merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", name, current.Name); merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", name, _currentBranch.Name);
merge.Icon = App.CreateMenuIcon("Icons.Merge"); merge.Icon = App.CreateMenuIcon("Icons.Merge");
merge.Click += (_, e) => merge.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Merge(this, name, current.Name)); PopupHost.ShowPopup(new Merge(this, name, _currentBranch.Name));
e.Handled = true; e.Handled = true;
}; };
var rebase = new MenuItem(); var rebase = new MenuItem();
rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", current.Name, name); rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, name);
rebase.Icon = App.CreateMenuIcon("Icons.Rebase"); rebase.Icon = App.CreateMenuIcon("Icons.Rebase");
rebase.Click += (_, e) => rebase.Click += (_, e) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Rebase(this, current, branch)); PopupHost.ShowPopup(new Rebase(this, _currentBranch, branch));
e.Handled = true; e.Handled = true;
}; };
@ -1569,9 +1567,9 @@ namespace SourceGit.ViewModels
if (_histories != null) if (_histories != null)
{ {
var target = new Commands.QuerySingleCommit(FullPath, branch.Head).Result(); var target = new Commands.QuerySingleCommit(_fullpath, branch.Head).Result();
_histories.AutoSelectedCommit = null; _histories.AutoSelectedCommit = null;
_histories.DetailContext = new RevisionCompare(FullPath, target, null); _histories.DetailContext = new RevisionCompare(_fullpath, target, null);
} }
}; };
menu.Items.Add(compareWithWorktree); menu.Items.Add(compareWithWorktree);
@ -1663,7 +1661,7 @@ namespace SourceGit.ViewModels
var pushTag = new MenuItem(); var pushTag = new MenuItem();
pushTag.Header = new Views.NameHighlightedTextBlock("TagCM.Push", tag.Name); pushTag.Header = new Views.NameHighlightedTextBlock("TagCM.Push", tag.Name);
pushTag.Icon = App.CreateMenuIcon("Icons.Push"); pushTag.Icon = App.CreateMenuIcon("Icons.Push");
pushTag.IsEnabled = Remotes.Count > 0; pushTag.IsEnabled = _remotes.Count > 0;
pushTag.Click += (_, ev) => pushTag.Click += (_, ev) =>
{ {
if (PopupHost.CanCreatePopup()) if (PopupHost.CanCreatePopup())
@ -1813,14 +1811,14 @@ namespace SourceGit.ViewModels
private MenuItem CreateMenuItemToCompareBranches(Models.Branch branch) private MenuItem CreateMenuItemToCompareBranches(Models.Branch branch)
{ {
if (Branches.Count == 1) if (_branches.Count == 1)
return null; return null;
var compare = new MenuItem(); var compare = new MenuItem();
compare.Header = App.Text("BranchCM.CompareWithBranch"); compare.Header = App.Text("BranchCM.CompareWithBranch");
compare.Icon = App.CreateMenuIcon("Icons.Compare"); compare.Icon = App.CreateMenuIcon("Icons.Compare");
foreach (var b in Branches) foreach (var b in _branches)
{ {
if (b.FullName != branch.FullName) if (b.FullName != branch.FullName)
{ {
@ -1836,7 +1834,7 @@ namespace SourceGit.ViewModels
var wnd = new Views.BranchCompare() var wnd = new Views.BranchCompare()
{ {
DataContext = new BranchCompare(FullPath, branch, dup) DataContext = new BranchCompare(_fullpath, branch, dup)
}; };
wnd.Show(topLevel); wnd.Show(topLevel);
@ -1922,6 +1920,7 @@ namespace SourceGit.ViewModels
private List<Models.Remote> _remotes = new List<Models.Remote>(); private List<Models.Remote> _remotes = new List<Models.Remote>();
private List<Models.Branch> _branches = new List<Models.Branch>(); private List<Models.Branch> _branches = new List<Models.Branch>();
private Models.Branch _currentBranch = null;
private List<BranchTreeNode> _localBranchTrees = new List<BranchTreeNode>(); private List<BranchTreeNode> _localBranchTrees = new List<BranchTreeNode>();
private List<BranchTreeNode> _remoteBranchTrees = new List<BranchTreeNode>(); private List<BranchTreeNode> _remoteBranchTrees = new List<BranchTreeNode>();
private List<Models.Worktree> _worktrees = new List<Models.Worktree>(); private List<Models.Worktree> _worktrees = new List<Models.Worktree>();

View file

@ -90,7 +90,7 @@ namespace SourceGit.ViewModels
{ {
if (SetProperty(ref _useAmend, value) && value) if (SetProperty(ref _useAmend, value) && value)
{ {
var currentBranch = _repo.Branches.Find(x => x.IsCurrent); var currentBranch = _repo.CurrentBranch;
if (currentBranch == null) if (currentBranch == null)
{ {
App.RaiseException(_repo.FullPath, "No commits to amend!!!"); App.RaiseException(_repo.FullPath, "No commits to amend!!!");