a1331212cb
Self-hosted Minecraft modpack distribution + administration system.
- launcher/ Avalonia 12 desktop client; single-file win-x64 publish.
Microsoft auth via XboxAuthNet, manifest+SHA-1 mod sync,
portable install path, sidecar settings.
- server/ brass-sigil-server daemon (.NET 8, linux-x64). Wraps the
MC subprocess, embedded Kestrel admin panel with cookie
auth + rate limiting, RCON bridge, scheduled backups,
BlueMap CLI integration with player markers + skin proxy,
friend-side whitelist request flow, world wipe with seed
selection (keep current / random / custom).
- pack/ pack.lock.json (Modrinth + manual CurseForge entries),
data-only tweak source under tweaks/, build outputs in
overrides/ (gitignored).
- scripts/ Build-Pack / Build-Tweaks / Update-Pack / Check-Updates
plus Deploy-Brass.ps1 unified one-shot deploy with
version-bump pre-flight and daemon-state detection.
396 lines
24 KiB
XML
396 lines
24 KiB
XML
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="600"
|
|
x:Class="ModpackLauncher.MainWindow"
|
|
Title="Modpack Launcher"
|
|
Width="900" Height="640"
|
|
MinWidth="720" MinHeight="540"
|
|
Background="Transparent"
|
|
TransparencyLevelHint="Transparent"
|
|
WindowDecorations="None"
|
|
Icon="/Assets/icon.png"
|
|
WindowStartupLocation="CenterScreen">
|
|
|
|
<Window.Resources>
|
|
<!-- Palette: dark navy base + brass trim + cyan magic accent -->
|
|
|
|
<!-- Brass gradient (lit from top, polished) -->
|
|
<LinearGradientBrush x:Key="BrassTrim" StartPoint="0%,0%" EndPoint="0%,100%">
|
|
<GradientStop Offset="0" Color="#F5D88A" />
|
|
<GradientStop Offset="0.35" Color="#E8B95C" />
|
|
<GradientStop Offset="0.65" Color="#A37A2E" />
|
|
<GradientStop Offset="1" Color="#5C4519" />
|
|
</LinearGradientBrush>
|
|
<LinearGradientBrush x:Key="BrassFill" StartPoint="0%,0%" EndPoint="0%,100%">
|
|
<GradientStop Offset="0" Color="#F5D88A" />
|
|
<GradientStop Offset="0.5" Color="#D4A24C" />
|
|
<GradientStop Offset="1" Color="#8C6829" />
|
|
</LinearGradientBrush>
|
|
<LinearGradientBrush x:Key="BrassFillHover" StartPoint="0%,0%" EndPoint="0%,100%">
|
|
<GradientStop Offset="0" Color="#FBE3A0" />
|
|
<GradientStop Offset="0.5" Color="#E8B95C" />
|
|
<GradientStop Offset="1" Color="#A37A2E" />
|
|
</LinearGradientBrush>
|
|
|
|
<!-- Rivet (radial gradient, lit from upper-left) -->
|
|
<RadialGradientBrush x:Key="RivetFill" Center="35%,35%" GradientOrigin="35%,35%" RadiusX="0.55" RadiusY="0.55">
|
|
<GradientStop Offset="0" Color="#F8DC95" />
|
|
<GradientStop Offset="0.5" Color="#C99843" />
|
|
<GradientStop Offset="1" Color="#3F2E10" />
|
|
</RadialGradientBrush>
|
|
|
|
<!-- Card fill (deep navy gradient) -->
|
|
<LinearGradientBrush x:Key="CardFill" StartPoint="0%,0%" EndPoint="0%,100%">
|
|
<GradientStop Offset="0" Color="#13192A" />
|
|
<GradientStop Offset="1" Color="#0A0F1A" />
|
|
</LinearGradientBrush>
|
|
|
|
<!-- Title bar metallic -->
|
|
<LinearGradientBrush x:Key="TitleBarFill" StartPoint="0%,0%" EndPoint="0%,100%">
|
|
<GradientStop Offset="0" Color="#0F1626" />
|
|
<GradientStop Offset="1" Color="#070B16" />
|
|
</LinearGradientBrush>
|
|
|
|
<!-- Magic cyan glow (radial) -->
|
|
<RadialGradientBrush x:Key="MagicGlow" Center="50%,50%" GradientOrigin="50%,50%" RadiusX="0.8" RadiusY="0.8">
|
|
<GradientStop Offset="0" Color="#605DD4E8" />
|
|
<GradientStop Offset="0.5" Color="#205DD4E8" />
|
|
<GradientStop Offset="1" Color="#005DD4E8" />
|
|
</RadialGradientBrush>
|
|
|
|
<!-- Tileable noise overlay -->
|
|
<ImageBrush x:Key="NoiseBrush" Source="/Assets/noise.png"
|
|
TileMode="Tile" Stretch="None"
|
|
DestinationRect="0,0,128,128" />
|
|
</Window.Resources>
|
|
|
|
<Window.Styles>
|
|
<!-- Reusable "brass panel" with metal trim + corner rivets -->
|
|
<Style Selector="ContentControl.brass-panel">
|
|
<Setter Property="Padding" Value="20" />
|
|
<Setter Property="Template">
|
|
<ControlTemplate>
|
|
<Grid>
|
|
<!-- Outer brass trim -->
|
|
<Border BorderBrush="{StaticResource BrassTrim}" BorderThickness="2" CornerRadius="6"
|
|
Background="{StaticResource CardFill}">
|
|
<ContentPresenter Content="{TemplateBinding Content}"
|
|
Margin="{TemplateBinding Padding}" />
|
|
</Border>
|
|
<!-- Corner rivets -->
|
|
<Ellipse Width="6" Height="6" HorizontalAlignment="Left" VerticalAlignment="Top"
|
|
Margin="6" Fill="{StaticResource RivetFill}" />
|
|
<Ellipse Width="6" Height="6" HorizontalAlignment="Right" VerticalAlignment="Top"
|
|
Margin="6" Fill="{StaticResource RivetFill}" />
|
|
<Ellipse Width="6" Height="6" HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
|
Margin="6" Fill="{StaticResource RivetFill}" />
|
|
<Ellipse Width="6" Height="6" HorizontalAlignment="Right" VerticalAlignment="Bottom"
|
|
Margin="6" Fill="{StaticResource RivetFill}" />
|
|
</Grid>
|
|
</ControlTemplate>
|
|
</Setter>
|
|
</Style>
|
|
|
|
<!-- Primary button: brass gradient + cyan magic hover glow -->
|
|
<Style Selector="Button.primary">
|
|
<Setter Property="Background" Value="{StaticResource BrassFill}" />
|
|
<Setter Property="Foreground" Value="#1A140F" />
|
|
<Setter Property="Padding" Value="26 12" />
|
|
<Setter Property="FontSize" Value="16" />
|
|
<Setter Property="FontWeight" Value="Bold" />
|
|
<Setter Property="CornerRadius" Value="6" />
|
|
<Setter Property="BorderBrush" Value="#5C4519" />
|
|
<Setter Property="BorderThickness" Value="1" />
|
|
</Style>
|
|
<Style Selector="Button.primary:pointerover /template/ ContentPresenter">
|
|
<Setter Property="Background" Value="{StaticResource BrassFillHover}" />
|
|
</Style>
|
|
<Style Selector="Button.primary:disabled /template/ ContentPresenter">
|
|
<Setter Property="Background" Value="#3A2D1E" />
|
|
<Setter Property="Foreground" Value="#6B5F4A" />
|
|
</Style>
|
|
|
|
<!-- Secondary button -->
|
|
<Style Selector="Button.secondary">
|
|
<Setter Property="Background" Value="#1B233A" />
|
|
<Setter Property="Foreground" Value="#E8DFC8" />
|
|
<Setter Property="Padding" Value="14 8" />
|
|
<Setter Property="CornerRadius" Value="4" />
|
|
<Setter Property="BorderBrush" Value="#A37A2E" />
|
|
<Setter Property="BorderThickness" Value="1" />
|
|
</Style>
|
|
<Style Selector="Button.secondary:pointerover /template/ ContentPresenter">
|
|
<Setter Property="Background" Value="#26314D" />
|
|
<Setter Property="BorderBrush" Value="#E8B95C" />
|
|
</Style>
|
|
|
|
<Style Selector="TextBlock.h1">
|
|
<Setter Property="FontSize" Value="22" />
|
|
<Setter Property="FontWeight" Value="SemiBold" />
|
|
<Setter Property="Foreground" Value="#E8DFC8" />
|
|
</Style>
|
|
<Style Selector="TextBlock.muted">
|
|
<Setter Property="Foreground" Value="#7A8497" />
|
|
<Setter Property="FontSize" Value="13" />
|
|
</Style>
|
|
|
|
<!-- Brass progress bar -->
|
|
<Style Selector="ProgressBar.brass">
|
|
<Setter Property="Foreground" Value="{StaticResource BrassFill}" />
|
|
<Setter Property="Background" Value="#0A0F1A" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource BrassTrim}" />
|
|
<Setter Property="BorderThickness" Value="1" />
|
|
</Style>
|
|
|
|
<!-- Custom title bar caption buttons -->
|
|
<Style Selector="Button.caption">
|
|
<Setter Property="Background" Value="Transparent" />
|
|
<Setter Property="Width" Value="46" />
|
|
<Setter Property="Height" Value="36" />
|
|
<Setter Property="CornerRadius" Value="0" />
|
|
<Setter Property="Padding" Value="0" />
|
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
|
<Setter Property="VerticalContentAlignment" Value="Center" />
|
|
</Style>
|
|
<Style Selector="Button.caption:pointerover /template/ ContentPresenter">
|
|
<Setter Property="Background" Value="#1B233A" />
|
|
</Style>
|
|
<Style Selector="Button.caption Path">
|
|
<Setter Property="Stroke" Value="#A37A2E" />
|
|
<Setter Property="StrokeThickness" Value="1" />
|
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
|
<Setter Property="VerticalAlignment" Value="Center" />
|
|
</Style>
|
|
<Style Selector="Button.caption:pointerover Path">
|
|
<Setter Property="Stroke" Value="#F5D88A" />
|
|
</Style>
|
|
<Style Selector="Button.caption-close">
|
|
<Setter Property="Background" Value="Transparent" />
|
|
<Setter Property="Width" Value="46" />
|
|
<Setter Property="Height" Value="36" />
|
|
<Setter Property="CornerRadius" Value="0" />
|
|
<Setter Property="Padding" Value="0" />
|
|
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
|
<Setter Property="VerticalContentAlignment" Value="Center" />
|
|
</Style>
|
|
<Style Selector="Button.caption-close:pointerover /template/ ContentPresenter">
|
|
<Setter Property="Background" Value="#B94228" />
|
|
</Style>
|
|
<Style Selector="Button.caption-close Path">
|
|
<Setter Property="Stroke" Value="#A37A2E" />
|
|
<Setter Property="StrokeThickness" Value="1" />
|
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
|
<Setter Property="VerticalAlignment" Value="Center" />
|
|
</Style>
|
|
<Style Selector="Button.caption-close:pointerover Path">
|
|
<Setter Property="Stroke" Value="#F5D88A" />
|
|
</Style>
|
|
</Window.Styles>
|
|
|
|
<!-- Outermost: main brass-bordered window + slide-out info panel (separate column, OUTSIDE the window) -->
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="Auto" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Border Grid.Column="0" Name="RootBorder" CornerRadius="10"
|
|
Background="{StaticResource BrassTrim}"
|
|
ClipToBounds="True">
|
|
<Border CornerRadius="8" Background="#0B1220" Margin="2" ClipToBounds="True">
|
|
<Panel Background="{StaticResource NoiseBrush}">
|
|
<Grid RowDefinitions="36,1,*">
|
|
|
|
<!-- Title bar -->
|
|
<Grid Grid.Row="0" Name="TitleBar" Background="{StaticResource TitleBarFill}"
|
|
PointerPressed="OnTitleBarPressed">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="Auto" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Magic glow halo behind icon + title text -->
|
|
<Grid Grid.Column="0" Margin="10 0 0 0" VerticalAlignment="Center" IsHitTestVisible="False">
|
|
<Ellipse Width="36" Height="36" HorizontalAlignment="Left"
|
|
Margin="-8 0 0 0" Fill="{StaticResource MagicGlow}" />
|
|
<StackPanel Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
|
|
<Image Source="/Assets/icon.png" Width="22" Height="22"
|
|
RenderOptions.BitmapInterpolationMode="HighQuality" />
|
|
<TextBlock Name="TitleText" Text="Brass & Sigil Launcher"
|
|
Foreground="#F5D88A" FontSize="12" FontWeight="SemiBold"
|
|
VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Stretch">
|
|
<Button Classes="caption" Click="OnRefreshClick" ToolTip.Tip="Check for updates">
|
|
<Path Width="11" Height="11"
|
|
Data="M 9,1.5 A 4,4 0 1 0 10.5,5 M 9,1.5 V 4 H 6.5" />
|
|
</Button>
|
|
<Button Classes="caption" Click="OnInfoClick" ToolTip.Tip="Pack info">
|
|
<Path Width="11" Height="11"
|
|
Data="M 5.5,0.5 A 5,5 0 1 1 5.499,0.5 Z M 5.5,4 V 9 M 5.5,2 V 2.5" />
|
|
</Button>
|
|
<Button Classes="caption" Click="OnMinimizeClick" ToolTip.Tip="Minimize">
|
|
<Path Width="10" Height="10" Data="M 0,5 H 10" />
|
|
</Button>
|
|
<Button Classes="caption-close" Click="OnCloseClick" ToolTip.Tip="Close">
|
|
<Path Width="10" Height="10" Data="M 0,0 L 10,10 M 10,0 L 0,10" />
|
|
</Button>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<!-- Brass divider hairline (own row so hover backgrounds can't paint over it) -->
|
|
<Border Grid.Row="1" Background="{StaticResource BrassTrim}" IsHitTestVisible="False" />
|
|
|
|
<!-- Main content -->
|
|
<Grid Grid.Row="2" RowDefinitions="Auto,Auto,*,Auto" Margin="14">
|
|
|
|
<!-- Update-available banner (hidden until manifest reports a newer launcherVersion) -->
|
|
<Border Name="UpdateBanner" Grid.Row="0" IsVisible="False"
|
|
Background="#13192A" BorderBrush="#D4A24C" BorderThickness="1"
|
|
CornerRadius="6" Padding="12 10" Margin="0 0 0 12">
|
|
<Grid ColumnDefinitions="Auto,*,Auto" VerticalAlignment="Center">
|
|
<TextBlock Grid.Column="0" Text="ⓘ" FontSize="16"
|
|
Foreground="#E8B95C" VerticalAlignment="Center" Margin="0 0 10 0" />
|
|
<TextBlock Grid.Column="1" Name="UpdateBannerText" VerticalAlignment="Center"
|
|
Foreground="#E8DFC8" FontSize="13" TextWrapping="Wrap"
|
|
Text="A newer launcher is available." />
|
|
<Button Grid.Column="2" Name="UpdateBannerDownloadButton"
|
|
Classes="secondary" Content="Download"
|
|
Click="OnUpdateBannerDownloadClick" />
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- Header card -->
|
|
<ContentControl Grid.Row="1" Classes="brass-panel" Margin="0 0 0 14">
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<StackPanel Grid.Column="0" Orientation="Vertical" Spacing="4">
|
|
<TextBlock Name="PackNameText" Classes="h1" Text="Modpack" />
|
|
<TextBlock Name="PackVersionText" Classes="muted" Text="No pack synced yet" />
|
|
</StackPanel>
|
|
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center" Spacing="10">
|
|
<TextBlock Name="UserText" Classes="muted" Text="Not signed in" VerticalAlignment="Center" />
|
|
<TextBlock Name="WhitelistStatusText" Classes="muted" Text="" IsVisible="False"
|
|
VerticalAlignment="Center" FontStyle="Italic" />
|
|
<Button Name="RequestAccessButton" Classes="secondary" Content="Request access"
|
|
Click="OnRequestAccessClick" IsVisible="False"
|
|
ToolTip.Tip="Send the server admin a request to whitelist your account." />
|
|
<Button Name="LoginButton" Classes="secondary" Content="Sign in" Click="OnLoginClick" />
|
|
<Button Name="LogoutButton" Classes="secondary" Content="Sign out"
|
|
Click="OnLogoutClick" IsVisible="False" />
|
|
</StackPanel>
|
|
</Grid>
|
|
</ContentControl>
|
|
|
|
<!-- Action + log -->
|
|
<Grid Grid.Row="2" RowDefinitions="Auto,*">
|
|
<ContentControl Grid.Row="0" Classes="brass-panel" Margin="0 0 0 14">
|
|
<StackPanel Spacing="14">
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<StackPanel Grid.Column="0" VerticalAlignment="Center" Spacing="2">
|
|
<TextBlock Name="StatusText" Classes="h1" Text="Ready" />
|
|
<TextBlock Name="StatusSubtext" Classes="muted"
|
|
Text="Click Play to sync the pack and launch Minecraft." />
|
|
</StackPanel>
|
|
<!-- Play button with subtle cyan glow halo behind -->
|
|
<Grid Grid.Column="1" Width="180" Height="48">
|
|
<Ellipse HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Width="200" Height="80" Fill="{StaticResource MagicGlow}"
|
|
Opacity="0.45" IsHitTestVisible="False" />
|
|
<Button Name="PlayButton" Classes="primary" Content="Play"
|
|
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
|
Click="OnPlayClick" />
|
|
</Grid>
|
|
</Grid>
|
|
<ProgressBar Name="ProgressBar" Classes="brass" Height="8"
|
|
Minimum="0" Maximum="100" Value="0" CornerRadius="4" />
|
|
</StackPanel>
|
|
</ContentControl>
|
|
|
|
<ContentControl Grid.Row="1" Classes="brass-panel">
|
|
<Grid RowDefinitions="Auto,*">
|
|
<Grid Grid.Row="0" ColumnDefinitions="*,Auto" Margin="0 0 0 8">
|
|
<TextBlock Grid.Column="0" Classes="h1" Text="Log" FontSize="14" />
|
|
<Button Grid.Column="1" Classes="secondary" Content="Open install folder"
|
|
Click="OnOpenFolderClick" />
|
|
</Grid>
|
|
<Border Grid.Row="1" Background="#070B16" CornerRadius="4" Padding="10"
|
|
BorderBrush="#1B233A" BorderThickness="1">
|
|
<ScrollViewer Name="LogScroll" VerticalScrollBarVisibility="Auto">
|
|
<TextBlock Name="LogText" FontFamily="Cascadia Mono, Consolas, monospace"
|
|
FontSize="12" Foreground="#B7C0D6" TextWrapping="Wrap" />
|
|
</ScrollViewer>
|
|
</Border>
|
|
</Grid>
|
|
</ContentControl>
|
|
</Grid>
|
|
|
|
<!-- Footer / settings -->
|
|
<ContentControl Grid.Row="3" Classes="brass-panel" Margin="0 14 0 0">
|
|
<StackPanel Spacing="10">
|
|
<!-- RAM allocation -->
|
|
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
|
|
<TextBlock Grid.Column="0" Text="RAM" VerticalAlignment="Center" Classes="muted" />
|
|
<NumericUpDown Grid.Column="1" Name="RamBox" Margin="10 0 10 0" Width="140"
|
|
Minimum="2048" Maximum="65536" Increment="1024" FormatString="0" />
|
|
<TextBlock Grid.Column="2" Text="MB" VerticalAlignment="Center" Classes="muted" Margin="0 0 10 0" />
|
|
<TextBlock Grid.Column="3" Name="RamWarningText" VerticalAlignment="Center"
|
|
FontSize="11" TextWrapping="Wrap" />
|
|
</Grid>
|
|
<!-- Install location -->
|
|
<Grid ColumnDefinitions="Auto,*,Auto">
|
|
<TextBlock Grid.Column="0" Text="Install location" VerticalAlignment="Center" Classes="muted" />
|
|
<TextBlock Grid.Column="1" Name="InstallDirText" VerticalAlignment="Center" Margin="10 0 10 0"
|
|
TextTrimming="CharacterEllipsis" Foreground="#B7C0D6" FontSize="12" />
|
|
<Button Grid.Column="2" Classes="secondary" Content="Change..." Click="OnChangeInstallDirClick" />
|
|
</Grid>
|
|
<TextBlock Foreground="#5C6478" FontSize="10" TextWrapping="Wrap" HorizontalAlignment="Center"
|
|
Text="NOT AN OFFICIAL MINECRAFT PRODUCT. NOT APPROVED BY OR ASSOCIATED WITH MOJANG OR MICROSOFT." />
|
|
</StackPanel>
|
|
</ContentControl>
|
|
</Grid>
|
|
|
|
</Grid>
|
|
</Panel>
|
|
</Border>
|
|
</Border>
|
|
|
|
<!-- Slide-out container: starts at Width=0 so the Auto column contributes nothing.
|
|
InfoPanel inside has fixed Width=320; HorizontalAlignment=Right + ClipToBounds=True
|
|
on the container makes the panel "slide in" from the right as the container grows.
|
|
Window.Width is animated in lock-step with InfoPanelContainer.Width so the main
|
|
content (RootBorder, in the Star column) keeps its current width throughout.
|
|
Vertically: outer Grid is single-row (full window height) so this Border
|
|
stretches naturally; the inner ScrollViewer inherits it via its Auto,*
|
|
Grid row. No code-behind height management needed. -->
|
|
<Border Grid.Column="1" Name="InfoPanelContainer" Width="0"
|
|
ClipToBounds="True">
|
|
<Border Name="InfoPanel" HorizontalAlignment="Right" Width="320" Margin="14 0 0 0"
|
|
CornerRadius="10" Background="{StaticResource BrassTrim}"
|
|
ClipToBounds="True">
|
|
<Border CornerRadius="8" Background="#0F1622" Margin="2" ClipToBounds="True">
|
|
<Grid RowDefinitions="Auto,*">
|
|
<Grid Grid.Row="0" ColumnDefinitions="*,Auto" Margin="14 12 8 8">
|
|
<TextBlock Grid.Column="0" Classes="h1" Text="Pack info" FontSize="14"
|
|
VerticalAlignment="Center" />
|
|
<Button Grid.Column="1" Classes="caption" Click="OnInfoClick" ToolTip.Tip="Close"
|
|
Width="32" Height="28">
|
|
<Path Width="9" Height="9" Data="M 0,0 L 9,9 M 9,0 L 0,9" />
|
|
</Button>
|
|
</Grid>
|
|
<ScrollViewer Grid.Row="1" Name="InfoScrollViewer"
|
|
Padding="14 0 14 40"
|
|
VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Disabled">
|
|
<StackPanel Name="InfoPanelContent" Spacing="14" Margin="0 0 0 8" />
|
|
</ScrollViewer>
|
|
</Grid>
|
|
</Border>
|
|
</Border>
|
|
</Border>
|
|
</Grid>
|
|
</Window>
|