├── Assets └── example.png ├── Libraries ├── NDILibDotNet2.dll ├── Processing.NDI.Lib.x64.dll └── Processing.NDI.Lib.x86.dll ├── App.config ├── Properties ├── Settings.settings ├── AssemblyInfo.cs ├── Settings.Designer.cs ├── Resources.Designer.cs └── Resources.resx ├── Whiteboard.csproj.user ├── packages.config ├── App.xaml.cs ├── README.md ├── LICENSE ├── App.xaml ├── Whiteboard.sln ├── WhiteboardCanvas.cs ├── MainWindow.xaml.cs ├── Whiteboard.csproj └── MainWindow.xaml /Assets/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbraad-apps/NDI-Whiteboard/HEAD/Assets/example.png -------------------------------------------------------------------------------- /Libraries/NDILibDotNet2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbraad-apps/NDI-Whiteboard/HEAD/Libraries/NDILibDotNet2.dll -------------------------------------------------------------------------------- /Libraries/Processing.NDI.Lib.x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbraad-apps/NDI-Whiteboard/HEAD/Libraries/Processing.NDI.Lib.x64.dll -------------------------------------------------------------------------------- /Libraries/Processing.NDI.Lib.x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbraad-apps/NDI-Whiteboard/HEAD/Libraries/Processing.NDI.Lib.x86.dll -------------------------------------------------------------------------------- /App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Whiteboard.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ShowAllFiles 5 | 6 | -------------------------------------------------------------------------------- /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace Whiteboard 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using System.Windows; 4 | 5 | [assembly: AssemblyTitle("NDI Whiteboard")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("NDI Whiteboard")] 10 | [assembly: AssemblyCopyright("Copyright © 2018 Gerard Braad ")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly:ThemeInfo( 16 | ResourceDictionaryLocation.None, 17 | ResourceDictionaryLocation.SourceAssembly 18 | )] 19 | [assembly: AssemblyVersion("1.0.0.0")] 20 | [assembly: AssemblyFileVersion("1.0.0.0")] 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NDI Whiteboard 2 | 3 | 4 | Simple Whiteboard application which outputs to NDI endpoint named `Whiteboard`. 5 | Offers basic colors (black, red, blue, yellow, green) and possible backgrounds 6 | (white, chroma [green], alpha [transparent]). 7 | 8 | Needs NDI SDK to function properly 9 | 10 | 11 | ![Example](https://raw.githubusercontent.com/gbraad/NDI-Whiteboard/master/Assets/example.png) 12 | 13 | 14 | Authors 15 | ------- 16 | 17 | | [!["Gerard Braad"](http://gravatar.com/avatar/e466994eea3c2a1672564e45aca844d0.png?s=60)](http://gbraad.nl "Gerard Braad ") | 18 | |---| 19 | | [@gbraad](https://twitter.com/gbraad) | 20 | 21 | 22 | License 23 | ------- 24 | Licensed under the [MIT License](https://opensource.org/licenses/MIT) 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Gerard Braad 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Whiteboard.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Whiteboard.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2027 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Whiteboard", "Whiteboard.csproj", "{AE760191-0372-4792-AC45-8563530B47EC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|x64.ActiveCfg = Debug|x64 21 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|x64.Build.0 = Debug|x64 22 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|x86.ActiveCfg = Debug|x86 23 | {AE760191-0372-4792-AC45-8563530B47EC}.Debug|x86.Build.0 = Debug|x86 24 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|x64.ActiveCfg = Release|x64 27 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|x64.Build.0 = Release|x64 28 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|x86.ActiveCfg = Release|x86 29 | {AE760191-0372-4792-AC45-8563530B47EC}.Release|x86.Build.0 = Release|x86 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {D9FADB72-AC2B-42ED-8AC0-E151F6EF3EDE} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /WhiteboardCanvas.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Controls; 3 | using System.Windows.Ink; 4 | using System.Windows.Input; 5 | using System.Windows.Media; 6 | using System.Windows.Shapes; 7 | using Brushes = System.Windows.Media.Brushes; 8 | using Canvas = System.Windows.Controls.Canvas; 9 | 10 | namespace Whiteboard 11 | { 12 | class WhiteboardCanvas : Canvas 13 | { 14 | 15 | private double brushThickness = 1.0; 16 | private Color brushColor = Colors.Black; 17 | private InkCanvas inkCanvas; 18 | 19 | public WhiteboardCanvas() 20 | { 21 | InitializeComponent(); 22 | } 23 | 24 | private void InitializeComponent() 25 | { 26 | inkCanvas = new InkCanvas(); 27 | inkCanvas.Background = Brushes.Transparent; 28 | SizeChanged += WhiteboardCanvas_SizeChanged; 29 | 30 | inkCanvas.UseCustomCursor = true; 31 | inkCanvas.Cursor = this.Cursor; 32 | 33 | this.Children.Add(inkCanvas); 34 | } 35 | 36 | private void WhiteboardCanvas_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e) 37 | { 38 | // make sure the ink canvas also changes 39 | inkCanvas.Width = this.Width; 40 | inkCanvas.Height = this.Height; 41 | } 42 | 43 | private void setPenAttributes(Color color, double size) 44 | { 45 | DrawingAttributes inkDA = new DrawingAttributes(); 46 | inkDA.Width = size; 47 | inkDA.Height = size; 48 | inkDA.Color = color; 49 | inkCanvas.DefaultDrawingAttributes = inkDA; 50 | } 51 | 52 | public void SetPenColor(Color color) 53 | { 54 | brushColor = color; 55 | setPenAttributes(brushColor, brushThickness); 56 | } 57 | 58 | public void SetPenColor(Brush color) 59 | { 60 | var scb = (SolidColorBrush)color; 61 | SetPenColor(scb.Color); 62 | } 63 | 64 | public void SetPenThickness(double size) 65 | { 66 | brushThickness = size; 67 | setPenAttributes(brushColor, size); 68 | } 69 | 70 | 71 | public void Undo() 72 | { 73 | if (inkCanvas.Strokes.Count > 0) 74 | { 75 | inkCanvas.Strokes.RemoveAt(inkCanvas.Strokes.Count - 1); 76 | } 77 | } 78 | 79 | public void Clear() 80 | { 81 | inkCanvas.Strokes.Clear(); 82 | } 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MahApps.Metro.Controls; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Input; 5 | using System.Windows.Media; 6 | using Brushes = System.Windows.Media.Brushes; 7 | 8 | namespace Whiteboard 9 | { 10 | public partial class MainWindow : MetroWindow 11 | { 12 | 13 | public MainWindow() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | private void MainWindow_KeyDown(object sender, KeyEventArgs e) 19 | { 20 | switch (e.Key) 21 | { 22 | case Key.Z: 23 | if ((System.Windows.Forms.Control.ModifierKeys & System.Windows.Forms.Keys.Control) == System.Windows.Forms.Keys.Control) 24 | theWhiteboard.Undo(); 25 | break; 26 | } 27 | } 28 | 29 | private void Btn_White_Click(object sender, RoutedEventArgs e) 30 | { 31 | theWhiteboard.Background = Brushes.White; 32 | } 33 | private void Btn_Chroma_Click(object sender, RoutedEventArgs e) 34 | { 35 | Button btn = (Button)sender; 36 | theWhiteboard.Background = btn.Foreground; 37 | } 38 | private void Btn_Transparent_Click(object sender, RoutedEventArgs e) 39 | { 40 | theWhiteboard.Background = Brushes.Transparent; 41 | } 42 | 43 | private void Btn_Pen_Click(object sender, RoutedEventArgs e) 44 | { 45 | /* 46 | foreach (UIElement control in DrawSettings.Children) 47 | { 48 | if (control is Border) 49 | { 50 | Border border = control as Border; 51 | border.BorderBrush = Brushes.Transparent; 52 | } 53 | } 54 | */ 55 | 56 | Button btn = (Button)sender; 57 | //btn.BorderBrush = Brushes.Red; 58 | 59 | theWhiteboard.SetPenColor(btn.Foreground); 60 | } 61 | 62 | private void Btn_Delete_Click(object sender, RoutedEventArgs e) 63 | { 64 | theWhiteboard.Clear(); 65 | } 66 | private void Btn_Size1_Click(object sender, RoutedEventArgs e) 67 | { 68 | theWhiteboard.SetPenThickness(1.0); 69 | } 70 | 71 | private void Btn_Size2_Click(object sender, RoutedEventArgs e) 72 | { 73 | theWhiteboard.SetPenThickness(2.0); 74 | } 75 | 76 | private void Btn_Size3_Click(object sender, RoutedEventArgs e) 77 | { 78 | theWhiteboard.SetPenThickness(3.0); 79 | } 80 | 81 | private void Btn_Size4_Click(object sender, RoutedEventArgs e) 82 | { 83 | theWhiteboard.SetPenThickness(4.0); 84 | } 85 | 86 | private void Btn_Size5_Click(object sender, RoutedEventArgs e) 87 | { 88 | theWhiteboard.SetPenThickness(5.0); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Whiteboard.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Whiteboard.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Whiteboard.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AE760191-0372-4792-AC45-8563530B47EC} 8 | WinExe 9 | Properties 10 | Whiteboard 11 | Whiteboard 12 | v4.5.1 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | publish\ 17 | true 18 | Disk 19 | false 20 | Foreground 21 | 7 22 | Days 23 | false 24 | false 25 | true 26 | 0 27 | 1.0.0.%2a 28 | false 29 | false 30 | true 31 | 32 | 33 | true 34 | ..\..\Bin\x64\Debug\ 35 | TRACE;DEBUG 36 | full 37 | x64 38 | prompt 39 | MinimumRecommendedRules.ruleset 40 | true 41 | 42 | 43 | ..\..\Bin\x64\Release\ 44 | TRACE 45 | true 46 | pdbonly 47 | x64 48 | prompt 49 | MinimumRecommendedRules.ruleset 50 | true 51 | 52 | 53 | true 54 | ..\..\Bin\x86\Debug\ 55 | DEBUG;TRACE 56 | full 57 | x86 58 | prompt 59 | MinimumRecommendedRules.ruleset 60 | true 61 | 62 | 63 | ..\..\Bin\x86\Release\ 64 | TRACE 65 | true 66 | pdbonly 67 | x86 68 | prompt 69 | MinimumRecommendedRules.ruleset 70 | true 71 | 72 | 73 | true 74 | ..\..\Bin\AnyCPU\Debug\ 75 | TRACE;DEBUG 76 | full 77 | AnyCPU 78 | prompt 79 | MinimumRecommendedRules.ruleset 80 | false 81 | 82 | 83 | ..\..\Bin\AnyCPU\Release\ 84 | TRACE 85 | true 86 | pdbonly 87 | AnyCPU 88 | prompt 89 | MinimumRecommendedRules.ruleset 90 | false 91 | 92 | 93 | 94 | packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll 95 | 96 | 97 | packages\MahApps.Metro.1.6.5\lib\net45\MahApps.Metro.dll 98 | 99 | 100 | packages\MaterialDesignColors.1.1.3\lib\net45\MaterialDesignColors.dll 101 | 102 | 103 | packages\MaterialDesignThemes.2.4.0.1044\lib\net45\MaterialDesignThemes.Wpf.dll 104 | 105 | 106 | Libraries\NDILibDotNet2.dll 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 4.0 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | MSBuild:Compile 123 | 124 | 125 | 126 | MSBuild:Compile 127 | Designer 128 | 129 | 130 | App.xaml 131 | Code 132 | 133 | 134 | MainWindow.xaml 135 | Code 136 | 137 | 138 | 139 | 140 | Code 141 | 142 | 143 | True 144 | True 145 | Resources.resx 146 | 147 | 148 | True 149 | Settings.settings 150 | True 151 | 152 | 153 | ResXFileCodeGenerator 154 | Resources.Designer.cs 155 | 156 | 157 | 158 | SettingsSingleFileGenerator 159 | Settings.Designer.cs 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | False 169 | Microsoft .NET Framework 4.5.1 %28x86 and x64%29 170 | true 171 | 172 | 173 | False 174 | .NET Framework 3.5 SP1 Client Profile 175 | false 176 | 177 | 178 | False 179 | .NET Framework 3.5 SP1 180 | false 181 | 182 | 183 | 184 | 185 | xcopy "$(ProjectDir)\..\..\..\Bin\x64\*.dll" "$(TargetDir)" /D /Y 186 | xcopy "$(ProjectDir)\..\..\..\Bin\x86\*.dll" "$(TargetDir)" /D /Y 187 | EXIT 0 188 | 189 | 190 | 197 | -------------------------------------------------------------------------------- /MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 38 | 43 | 44 | 45 | 46 | 50 | 51 | 54 | 64 | 65 | 66 | 69 | 79 | 80 | 81 | 84 | 94 | 95 | 96 | 99 | 109 | 110 | 111 | 114 | 124 | 125 | 128 | 138 | 139 | 142 | 152 | 153 | 156 | 166 | 167 | 170 | 180 | 181 | 182 | 185 | 203 | 204 | 205 | 208 | 226 | 227 | 228 | 231 | 249 | 250 | 251 | 254 | 272 | 273 | 274 | 277 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | --------------------------------------------------------------------------------