private void SetListCommandBindings() { if (ListGameItems == null) { return; } var swapStartInput = mainModel.AppSettings.Fullscreen.SwapStartDetailsAction; ListGameItems.InputBindings.Clear(); ListGameItems.InputBindings.Add(new KeyBinding() { Command = mainModel.OpenGameMenuCommand, Key = swapStartInput ? Key.A : Key.X }); ListGameItems.InputBindings.Add(new KeyBinding() { Command = mainModel.ToggleGameDetailsCommand, Key = swapStartInput ? Key.X : Key.A }); ListGameItems.InputBindings.Add(new KeyBinding() { Command = mainModel.ActivateSelectedCommand, Key = Key.Enter }); ListGameItems.InputBindings.Add(new XInputBinding(mainModel.OpenGameMenuCommand, XInputButton.Start)); ListGameItems.InputBindings.Add(new XInputBinding(mainModel.ToggleGameDetailsCommand, swapStartInput ? XInputButton.X : XInputButton.A)); ListGameItems.InputBindings.Add(new XInputBinding(mainModel.ActivateSelectedCommand, swapStartInput ? XInputButton.A : XInputButton.X)); ButtonPlay?.SetResourceReference(ButtonEx.InputHintProperty, swapStartInput ? "ButtonPromptA" : "ButtonPromptX"); ButtonInstall?.SetResourceReference(ButtonEx.InputHintProperty, swapStartInput ? "ButtonPromptA" : "ButtonPromptX"); ButtonDetails?.SetResourceReference(ButtonEx.InputHintProperty, swapStartInput ? "ButtonPromptX" : "ButtonPromptA"); }
private void AssignFilter(string title, string partId, GameField field, string bindBased) { var button = new ButtonEx(); button.SetResourceReference(ButtonBase.ContentProperty, title); button.SetResourceReference(ButtonBase.StyleProperty, "FilterPanelNagivationButton"); button.Command = mainModel.LoadSubFilterCommand; button.CommandParameter = field; BindingTools.SetBinding( button, ButtonBase.TagProperty, mainModel.AppSettings.Fullscreen.FilterSettings, $"{bindBased}.{nameof(FilterItemProperites.IsSet)}"); ItemsHost.Items.Add(button); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); if (Template == null) { return; } ViewHost = Template.FindName("PART_ViewHost", this) as FrameworkElement; if (ViewHost != null) { BindingTools.SetBinding(ViewHost, FocusBahaviors.FocusBindingProperty, mainModel, nameof(mainModel.GameStatusVisible)); } PanelActionButtons = Template.FindName("PART_PanelActionButtons", this) as Panel; if (PanelActionButtons != null) { var buttonClose = new ButtonEx(); buttonClose.Content = ResourceProvider.GetString(LOC.CloseLabel); buttonClose.SetResourceReference(ButtonEx.StyleProperty, "ButtonGameStatusAction"); buttonClose.Command = mainModel.CloseGameStatusCommand; PanelActionButtons.Children.Add(buttonClose); } TextStatus = Template.FindName("PART_TextStatus", this) as TextBlock; if (TextStatus != null) { BindingTools.SetBinding(TextStatus, TextBlock.TextProperty, mainModel, nameof(mainModel.GameStatusText)); } ImageCover = Template.FindName("PART_ImageCover", this) as Image; if (ImageCover != null) { var sourceBinding = new PriorityBinding(); sourceBinding.Bindings.Add(new Binding() { Path = new PropertyPath(nameof(GamesCollectionViewEntry.CoverImageObject)), Converter = new NullToDependencyPropertyUnsetConverter() }); sourceBinding.Bindings.Add(new Binding() { Path = new PropertyPath(nameof(GamesCollectionViewEntry.DefaultCoverImageObject)), Converter = new NullToDependencyPropertyUnsetConverter() }); BindingOperations.SetBinding(ImageCover, Image.SourceProperty, sourceBinding); } }
private void AssignFilter(GameField field, string bindBased, string text) { var button = new ButtonEx(); button.Content = ResourceProvider.GetString(text); button.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelNagivationButton"); button.Command = mainModel.LoadSubFilterCommand; button.CommandParameter = field; BindingTools.SetBinding( button, ButtonBase.TagProperty, mainModel.AppSettings.Fullscreen.FilterSettings, $"{bindBased}.{nameof(FilterItemProperites.IsSet)}"); PanelItemsHost.Children.Add(button); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); if (Template == null) { return; } PanelItemsHost = Template.FindName("PART_PanelItemsHost", this) as Panel; if (PanelItemsHost != null) { PanelItemsHost.Focusable = false; PanelItemsHost.InputBindings.Add(new KeyBinding(mainModel.ToggleFiltersCommand, new KeyGesture(Key.Back))); PanelItemsHost.InputBindings.Add(new KeyBinding(mainModel.ToggleFiltersCommand, new KeyGesture(Key.Escape))); PanelItemsHost.InputBindings.Add(new XInputBinding(mainModel.ToggleFiltersCommand, XInputButton.B)); } var ButtonClear = new ButtonEx(); ButtonClear.Command = mainModel.ClearFiltersCommand; ButtonClear.Content = ResourceProvider.GetString(LOC.ClearLabel); ButtonClear.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelButtonEx"); PanelItemsHost.Children.Add(ButtonClear); BindingTools.SetBinding(ButtonClear, FocusBahaviors.FocusBindingProperty, mainModel, nameof(mainModel.FilterPanelVisible)); AssignBoolFilter(nameof(FilterSettings.IsInstalled), LOC.GameIsInstalledTitle); AssignBoolFilter(nameof(FilterSettings.IsUnInstalled), LOC.GameIsUnInstalledTitle); AssignBoolFilter(nameof(FilterSettings.Favorite), LOC.GameFavoriteTitle); AssignBoolFilter(nameof(FilterSettings.Hidden), LOC.GameHiddenTitle); AssignBoolFilter(nameof(FilterSettings.UseAndFilteringStyle), LOC.UseFilterStyleAndTitle); AssignFilter(GameField.PluginId, nameof(FilterSettings.Library), LOC.Library); AssignFilter(GameField.Platforms, nameof(FilterSettings.Platform), LOC.PlatformTitle); AssignFilter(GameField.Categories, nameof(FilterSettings.Category), LOC.CategoryLabel); var ButtonAdditional = new ButtonEx(); ButtonAdditional.Command = mainModel.OpenAdditionalFiltersCommand; ButtonAdditional.Content = ResourceProvider.GetString(LOC.AditionalFilters); ButtonAdditional.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelNagivationButton"); BindingTools.SetBinding( ButtonAdditional, ButtonBase.TagProperty, mainModel.AppSettings.Fullscreen.FilterSettings, nameof(FullscreenFilterSettings.IsSubAdditionalFilterActive)); PanelItemsHost.Children.Add(ButtonAdditional); var desc = new TextBlock(); desc.Text = ResourceProvider.GetString(LOC.MenuSortByTitle); desc.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelText"); PanelItemsHost.Children.Add(desc); var SelectSortBy = new ComboBoxEx(); SelectSortBy.SetResourceReference(ComboBoxEx.StyleProperty, "FilterPanelComboBoxEx"); SelectSortBy.ItemsSource = ItemsSource.GetEnumSources(typeof(SortOrder)); SelectSortBy.DisplayMemberPath = nameof(ItemsSource.EnumItem.Name); SelectSortBy.SelectedValuePath = nameof(ItemsSource.EnumItem.Value); BindingTools.SetBinding( SelectSortBy, Selector.SelectedValueProperty, mainModel.AppSettings.Fullscreen.ViewSettings, nameof(FullscreenViewSettings.SortingOrder), BindingMode.TwoWay, UpdateSourceTrigger.PropertyChanged); PanelItemsHost.Children.Add(SelectSortBy); var SelectSortDirection = new ComboBoxEx(); SelectSortDirection.SetResourceReference(ComboBoxEx.StyleProperty, "FilterPanelComboBoxEx"); SelectSortDirection.ItemsSource = ItemsSource.GetEnumSources(typeof(SortOrderDirection)); SelectSortDirection.DisplayMemberPath = nameof(ItemsSource.EnumItem.Name); SelectSortDirection.SelectedValuePath = nameof(ItemsSource.EnumItem.Value); BindingTools.SetBinding( SelectSortDirection, Selector.SelectedValueProperty, mainModel.AppSettings.Fullscreen.ViewSettings, nameof(FullscreenViewSettings.SortingOrderDirection), BindingMode.TwoWay, UpdateSourceTrigger.PropertyChanged); PanelItemsHost.Children.Add(SelectSortDirection); desc = new TextBlock(); desc.Text = ResourceProvider.GetString(LOC.SettingsTopPanelFilterPresetsItem); desc.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelText"); PanelItemsHost.Children.Add(desc); var ComboFilterPresets = new ComboBoxEx(); ComboFilterPresets.SetResourceReference(ComboBoxEx.StyleProperty, "FilterPanelComboBoxEx"); BindingTools.SetBinding(ComboFilterPresets, ComboBox.ItemsSourceProperty, mainModel, nameof(mainModel.SortedFilterPresets)); BindingTools.SetBinding(ComboFilterPresets, ComboBox.SelectedItemProperty, mainModel, nameof(mainModel.ActiveFilterPreset), mode: BindingMode.TwoWay); ComboFilterPresets.DisplayMemberPath = nameof(FilterPreset.Name); PanelItemsHost.Children.Add(ComboFilterPresets); var ButtonSaveFilter = new ButtonEx(); BindingTools.SetBinding(ButtonSaveFilter, ButtonBase.CommandProperty, mainModel, nameof(mainModel.AddFilterPresetCommand)); ButtonSaveFilter.SetResourceReference(ButtonEx.ContentTemplateProperty, "FilterPanelAddPresetTemplate"); ButtonSaveFilter.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelFilterPresetActionButton"); var ButtonRenameFilter = new ButtonEx(); BindingTools.SetBinding(ButtonRenameFilter, ButtonBase.CommandProperty, mainModel, nameof(mainModel.RenameFilterPresetCommand)); BindingTools.SetBinding(ButtonRenameFilter, ButtonBase.CommandParameterProperty, mainModel, nameof(mainModel.ActiveFilterPreset)); ButtonRenameFilter.SetResourceReference(ButtonEx.ContentTemplateProperty, "FilterPanelRenamePresetTemplate"); ButtonRenameFilter.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelFilterPresetActionButton"); var ButtonDeleteFilter = new ButtonEx(); BindingTools.SetBinding(ButtonDeleteFilter, ButtonBase.CommandProperty, mainModel, nameof(mainModel.RemoveFilterPresetCommand)); BindingTools.SetBinding(ButtonDeleteFilter, ButtonBase.CommandParameterProperty, mainModel, nameof(mainModel.ActiveFilterPreset)); ButtonDeleteFilter.SetResourceReference(ButtonEx.ContentTemplateProperty, "FilterPanelRemovePresetTemplate"); ButtonDeleteFilter.SetResourceReference(ButtonEx.StyleProperty, "FilterPanelFilterPresetActionButton"); var filterButtonGrid = new UniformGrid { Columns = 3 }; filterButtonGrid.Children.Add(ButtonSaveFilter); filterButtonGrid.Children.Add(ButtonRenameFilter); filterButtonGrid.Children.Add(ButtonDeleteFilter); PanelItemsHost.Children.Add(filterButtonGrid); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); if (Template != null) { ViewHost = Template.FindName("PART_ViewHost", this) as FrameworkElement; if (ViewHost != null) { ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.OpenMainMenuCommand, Key = Key.F1 }); ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.PrevFilterViewCommand, Key = Key.F2 }); ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.NextFilterViewCommand, Key = Key.F3 }); ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.OpenSearchCommand, Key = Key.Y }); ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.ToggleFiltersCommand, Key = Key.F }); ViewHost.InputBindings.Add(new KeyBinding() { Command = mainModel.SwitchToDesktopCommand, Key = Key.F11 }); ViewHost.InputBindings.Add(new XInputBinding(mainModel.PrevFilterViewCommand, XInputButton.LeftShoulder)); ViewHost.InputBindings.Add(new XInputBinding(mainModel.NextFilterViewCommand, XInputButton.RightShoulder)); ViewHost.InputBindings.Add(new XInputBinding(mainModel.OpenSearchCommand, XInputButton.Y)); ViewHost.InputBindings.Add(new XInputBinding(mainModel.ToggleFiltersCommand, XInputButton.RightStick)); ViewHost.InputBindings.Add(new XInputBinding(mainModel.OpenMainMenuCommand, XInputButton.Back)); } MainHost = Template.FindName("PART_MainHost", this) as FrameworkElement; if (MainHost != null) { BindingTools.SetBinding(MainHost, FrameworkElement.WidthProperty, mainModel, nameof(FullscreenAppViewModel.ViewportWidth)); BindingTools.SetBinding(MainHost, FrameworkElement.HeightProperty, mainModel, nameof(FullscreenAppViewModel.ViewportHeight)); } AssignButtonWithCommand(ref ButtonProgramUpdate, "PART_ButtonProgramUpdate", mainModel.OpenUpdatesCommand); AssignButtonWithCommand(ref ButtonMainMenu, "PART_ButtonMainMenu", mainModel.OpenMainMenuCommand); AssignButtonWithCommand(ref ButtonNotifications, "PART_ButtonNotifications", mainModel.OpenNotificationsMenuCommand); if (ButtonProgramUpdate != null) { BindingTools.SetBinding(ButtonProgramUpdate, Button.VisibilityProperty, mainModel, nameof(mainModel.UpdatesAvailable), converter: new Converters.BooleanToVisibilityConverter()); } ImageBackground = Template.FindName("PART_ImageBackground", this) as FadeImage; if (ImageBackground != null) { SetBackgroundBinding(); SetBackgroundEffect(); } TextClock = Template.FindName("PART_TextClock", this) as TextBlock; if (TextClock != null) { BindingTools.SetBinding(TextClock, TextBlock.TextProperty, mainModel.CurrentTime, nameof(ObservableTime.Time)); BindingTools.SetBinding( TextClock, TextBlock.VisibilityProperty, mainModel.AppSettings.Fullscreen, nameof(FullscreenSettings.ShowClock), converter: new Converters.BooleanToVisibilityConverter()); } TextBatteryPercentage = Template.FindName("PART_TextBatteryPercentage", this) as TextBlock; if (TextBatteryPercentage != null) { BindingTools.SetBinding(TextBatteryPercentage, TextBlock.TextProperty, mainModel.PowerStatus, nameof(ObservablePowerStatus.PercentCharge), stringFormat: "{0}%"); BindingTools.SetBinding(TextBatteryPercentage, TextBlock.VisibilityProperty, mainModel.AppSettings.Fullscreen, nameof(FullscreenSettings.ShowBatteryPercentage), converter: new Converters.BooleanToVisibilityConverter()); } ElemBatteryStatus = Template.FindName("PART_ElemBatteryStatus", this) as FrameworkElement; if (ElemBatteryStatus != null) { BindingTools.SetBinding( ElemBatteryStatus, TextBlock.VisibilityProperty, mainModel.AppSettings.Fullscreen, nameof(FullscreenSettings.ShowBattery), converter: new Converters.BooleanToVisibilityConverter()); } TextProgressTooltip = Template.FindName("PART_TextProgressTooltip", this) as TextBlock; if (TextProgressTooltip != null) { BindingTools.SetBinding(TextProgressTooltip, TextBlock.TextProperty, mainModel, nameof(FullscreenAppViewModel.ProgressStatus)); BindingTools.SetBinding(TextProgressTooltip, TextBlock.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.ProgressActive), converter: new Converters.BooleanToVisibilityConverter()); } ElemProgressIndicator = Template.FindName("PART_ElemProgressIndicator", this) as FrameworkElement; if (ElemProgressIndicator != null) { BindingTools.SetBinding(ElemProgressIndicator, ToggleButton.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.ProgressActive), converter: new Converters.BooleanToVisibilityConverter()); } ElemExtraFilterActive = Template.FindName("PART_ElemExtraFilterActive", this) as FrameworkElement; if (ElemExtraFilterActive != null) { BindingTools.SetBinding(ElemExtraFilterActive, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.IsExtraFilterActive), converter: new Converters.BooleanToVisibilityConverter()); } ElemSearchActive = Template.FindName("PART_ElemSearchActive", this) as FrameworkElement; if (ElemSearchActive != null) { BindingTools.SetBinding(ElemSearchActive, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.IsSearchActive), converter: new Converters.BooleanToVisibilityConverter()); } ListGameItems = Template.FindName("PART_ListGameItems", this) as ListBox; if (ListGameItems != null) { XNamespace pns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; ListGameItems.ItemsPanel = Xaml.FromString <ItemsPanelTemplate>(new XDocument( new XElement(pns + nameof(ItemsPanelTemplate), new XElement(pns + nameof(FullscreenTilePanel), new XAttribute(nameof(FullscreenTilePanel.Rows), "{Settings Fullscreen.Rows}"), new XAttribute(nameof(FullscreenTilePanel.Columns), "{Settings Fullscreen.Columns}"), new XAttribute(nameof(FullscreenTilePanel.UseHorizontalLayout), "{Settings Fullscreen.HorizontalLayout}"), new XAttribute(nameof(FullscreenTilePanel.ItemAspectRatio), "{Settings CoverAspectRatio}"), new XAttribute(nameof(FullscreenTilePanel.ItemSpacing), "{Settings FullscreenItemSpacing}"))) ).ToString()); ListGameItems.ItemTemplate = Xaml.FromString <DataTemplate>(new XDocument( new XElement(pns + nameof(DataTemplate), new XElement(pns + nameof(GameListItem), new XAttribute(nameof(GameListItem.Style), "{StaticResource ListGameItemTemplate}"))) ).ToString()); ListGameItems.SetResourceReference(ListBoxEx.ItemContainerStyleProperty, "ListGameItemStyle"); BindingTools.SetBinding(ListGameItems, ListBox.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.GameListVisible), converter: new Converters.BooleanToVisibilityConverter()); BindingTools.SetBinding(ListGameItems, ListBox.SelectedItemProperty, mainModel, nameof(FullscreenAppViewModel.SelectedGame), BindingMode.TwoWay); BindingTools.SetBinding(ListGameItems, ListBox.ItemsSourceProperty, mainModel, $"{nameof(FullscreenAppViewModel.GamesView)}.{nameof(FullscreenCollectionView.CollectionView)}"); BindingTools.SetBinding(ListGameItems, FocusBahaviors.FocusBindingProperty, mainModel, nameof(mainModel.GameListFocused)); } AssignButtonWithCommand(ref ButtonInstall, "PART_ButtonInstall", mainModel.ActivateSelectedCommand); if (ButtonInstall != null) { BindingTools.SetBinding( ButtonInstall, ButtonBase.VisibilityProperty, mainModel, $"{nameof(FullscreenAppViewModel.SelectedGame)}.{nameof(GamesCollectionViewEntry.IsInstalled)}", converter: new InvertedBooleanToVisibilityConverter(), fallBackValue: Visibility.Collapsed); } AssignButtonWithCommand(ref ButtonPlay, "PART_ButtonPlay", mainModel.ActivateSelectedCommand); if (ButtonPlay != null) { ButtonPlay.Command = mainModel.ActivateSelectedCommand; BindingTools.SetBinding( ButtonPlay, ButtonBase.VisibilityProperty, mainModel, $"{nameof(FullscreenAppViewModel.SelectedGame)}.{nameof(GamesCollectionViewEntry.IsInstalled)}", converter: new Converters.BooleanToVisibilityConverter(), fallBackValue: Visibility.Collapsed); } AssignButtonWithCommand(ref ButtonDetails, "PART_ButtonDetails", mainModel.ToggleGameDetailsCommand); if (ButtonDetails != null) { BindingTools.SetBinding( ButtonDetails, ButtonBase.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.GameDetailsButtonVisible), converter: new Converters.BooleanToVisibilityConverter()); } AssignButtonWithCommand(ref ButtonGameOptions, "PART_ButtonGameOptions", mainModel.OpenGameMenuCommand); if (ButtonGameOptions != null) { BindingTools.SetBinding( ButtonGameOptions, ButtonBase.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.GameDetailsButtonVisible), converter: new Converters.BooleanToVisibilityConverter()); ButtonGameOptions.SetResourceReference(ButtonEx.InputHintProperty, "ButtonPromptStart"); } AssignButtonWithCommand(ref ButtonSearch, "PART_ButtonSearch", mainModel.OpenSearchCommand); ButtonSearch?.SetResourceReference(ButtonEx.InputHintProperty, "ButtonPromptY"); AssignButtonWithCommand(ref ButtonFilter, "PART_ButtonFilter", mainModel.ToggleFiltersCommand); ButtonFilter?.SetResourceReference(ButtonEx.InputHintProperty, "ButtonPromptRS"); ElemFilters = Template.FindName("PART_ElemFilters", this) as FrameworkElement; if (ElemFilters != null) { BindingTools.SetBinding(ElemFilters, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.FilterPanelVisible), converter: new Converters.BooleanToVisibilityConverter()); } ElemFiltersAdditional = Template.FindName("PART_ElemFiltersAdditional", this) as FrameworkElement; if (ElemFiltersAdditional != null) { BindingTools.SetBinding(ElemFiltersAdditional, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.FilterAdditionalPanelVisible), converter: new Converters.BooleanToVisibilityConverter()); } ContentFilterItems = Template.FindName("PART_ContentFilterItems", this) as ContentControl; if (ContentFilterItems != null) { BindingTools.SetBinding(ContentFilterItems, ContentControl.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.SubFilterVisible), converter: new Converters.BooleanToVisibilityConverter()); BindingTools.SetBinding(ContentFilterItems, ContentControl.ContentProperty, mainModel, nameof(FullscreenAppViewModel.SubFilterControl)); } ElemGameDetails = Template.FindName("PART_ElemGameDetails", this) as FrameworkElement; if (ElemGameDetails != null) { BindingTools.SetBinding(ElemGameDetails, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.GameDetailsVisible), converter: new Converters.BooleanToVisibilityConverter()); BindingTools.SetBinding(ElemGameDetails, FrameworkElement.DataContextProperty, mainModel, nameof(FullscreenAppViewModel.SelectedGame)); } ElemGameStatus = Template.FindName("PART_ElemGameStatus", this) as FrameworkElement; if (ElemGameStatus != null) { BindingTools.SetBinding(ElemGameStatus, FrameworkElement.VisibilityProperty, mainModel, nameof(FullscreenAppViewModel.GameStatusVisible), converter: new Converters.BooleanToVisibilityConverter()); BindingTools.SetBinding(ElemGameStatus, FrameworkElement.DataContextProperty, mainModel, nameof(FullscreenAppViewModel.SelectedGame)); } SetListCommandBindings(); ControlTemplateTools.InitializePluginControls( mainModel.Extensions, Template, this, ApplicationMode.Fullscreen, mainModel, $"{nameof(FullscreenAppViewModel.SelectedGameDetails)}.{nameof(GameDetailsViewModel.Game)}.{nameof(GameDetailsViewModel.Game.Game)}"); } }