├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md └── UmbracoAdminReset ├── UmbracoAdminReset.sln └── UmbracoAdminReset ├── Controllers └── UserActionsController.cs ├── Properties └── AssemblyInfo.cs ├── TypeExtensions └── StringExtensions.cs ├── UmbracoAdminReset.csproj ├── app.config └── packages.config /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Note: VisualStudio gitignore rules may also be relevant 2 | 3 | # Ignore unimportant folders generated by Umbraco 4 | **/App_Data/ClientDependency/ 5 | **/App_Data/ExamineIndexes/ 6 | **/App_Data/Logs/ 7 | **/App_Data/[Pp]review/ 8 | **/App_Data/TEMP/ 9 | Cached/ 10 | 11 | # Ignore Umbraco content cache file 12 | **/App_Data/umbraco.config 13 | 14 | # Don't ignore Umbraco packages (VisualStudio.gitignore mistakes this for a NuGet packages folder) 15 | # Make sure to include details from VisualStudio.gitignore BEFORE this 16 | !**/App_Data/[Pp]ackages/ 17 | !**/[Uu]mbraco/[Dd]eveloper/[Pp]ackages 18 | /UmbracoAdminReset/UmbracoAdminReset/obj 19 | /UmbracoAdminReset/UmbracoAdminReset/bin 20 | /UmbracoAdminReset/packages 21 | /UmbracoAdminReset/UmbracoAdminReset/App_Data/NuGetBackup 22 | /UmbracoAdminReset/.vs 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Richard Soeteman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Umbraco admin reset 2 | Simple project that allows reset of the admin user(user 0 by default) by adding the UmbracoAdminReset.dll to the ~/bin folder of your Umbraco installation and request the url **/umbraco/adminreset/useractions/reset**. Handy when you inherit a site and didn't receive the credentials or when everything else fails. 3 | 4 | The username will be reset to **Admin** and password to **Admin1234!** by default 5 | 6 | When the password is reset it will make sure the admin user is unlocked and will delete the dll afterwards so you can login and change the credentials yourself. 7 | 8 | If you are concerned about security, you can use the following parameters to change the defaults 9 | 10 | /umbraco/adminreset/useractions/reset?userId=[id of the user]&userName=[new username]&userPassword=[new password] 11 | 12 | The DLL will make sure the Membership provider is allow to change passwords and reset the username and password. The DLL will make sure the admin user is unlocked and will delete itself afterwards so you can login and change the credentials yourself. 13 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UmbracoAdminReset", "UmbracoAdminReset\UmbracoAdminReset.csproj", "{4973FC05-0C95-4665-AC4E-8CEED3201FF8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4973FC05-0C95-4665-AC4E-8CEED3201FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4973FC05-0C95-4665-AC4E-8CEED3201FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4973FC05-0C95-4665-AC4E-8CEED3201FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4973FC05-0C95-4665-AC4E-8CEED3201FF8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/Controllers/UserActionsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net.Http; 4 | using System.Net.Http.Headers; 5 | using System.Web; 6 | using System.Web.Http; 7 | using System.Xml; 8 | using umbraco.IO; 9 | using Umbraco.Core.Logging; 10 | using Umbraco.Web.Mvc; 11 | using Umbraco.Web.WebApi; 12 | 13 | namespace UmbracoAdminReset.Controllers 14 | { 15 | [PluginController("adminreset")] 16 | public class UserActionsController :UmbracoApiController 17 | { 18 | [HttpGet] 19 | public HttpResponseMessage Reset(int userId = 0, string userName = "Admin", string userPassword = "Admin1234!") 20 | { 21 | try 22 | { 23 | var user = ApplicationContext.Services.UserService.GetUserById(userId); 24 | if (user != null) 25 | { 26 | //Make sure the provider supports change password 27 | ForceAllowChangePassword(); 28 | 29 | user.Username = userName; 30 | user.IsApproved = true; 31 | user.IsLockedOut = false; 32 | 33 | //Save changes 34 | ApplicationContext.Services.UserService.Save(user); 35 | 36 | //Change password 37 | ApplicationContext.Services.UserService.SavePassword(user,userPassword); 38 | } 39 | 40 | //Delete this dll 41 | var fileName = IOHelper.MapPath("~/bin/UmbracoAdminReset.dll"); 42 | File.Delete(fileName); 43 | } 44 | catch (Exception ex) 45 | { 46 | LogHelper.Error("Error during password reset", ex); 47 | } 48 | 49 | var response = new HttpResponseMessage 50 | { 51 | Content = new StringContent("

Password is reset

And dll is removed from the /bin folder

") 52 | }; 53 | response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); 54 | return response; 55 | } 56 | 57 | private void ForceAllowChangePassword() 58 | { 59 | try 60 | { 61 | //Create a new xml document 62 | XmlDocument document = new XmlDocument(); 63 | 64 | //Keep current indentions format 65 | document.PreserveWhitespace = true; 66 | 67 | //Load the web.config file into the xml document 68 | var webconfigFile = HttpContext.Current.Server.MapPath("~/web.config"); 69 | document.Load(webconfigFile); 70 | var userMembershipNode = 71 | document.SelectSingleNode( 72 | "//configuration/system.web/membership/providers/add[@name='UsersMembershipProvider']"); 73 | if (userMembershipNode == null) return; 74 | var att = userMembershipNode.Attributes["allowManuallyChangingPassword"]; 75 | if (att == null) 76 | { 77 | att = document.CreateAttribute("allowManuallyChangingPassword"); 78 | userMembershipNode.Attributes.Append(att); 79 | } 80 | if (!att.Value.Equals("true")) 81 | { 82 | att.Value = "true"; 83 | } 84 | 85 | document.Save(webconfigFile); 86 | } 87 | catch (Exception ex) 88 | { 89 | LogHelper.Error("Error during allowManuallyChangingPassword",ex); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UmbracoAdminReset")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UmbracoAdminReset")] 13 | [assembly: AssemblyCopyright("Copyright © 2015-2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6c9ded8d-c075-4b3e-af38-c50c93ccf0ac")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.4.0.0")] 36 | [assembly: AssemblyFileVersion("1.4.0.0")] 37 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/TypeExtensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace UmbracoAdminReset.TypeExtensions 8 | { 9 | public static class StringExtensions 10 | { 11 | public static int ToInt(this string s) 12 | { 13 | int.TryParse(s, out int i); 14 | return i; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/UmbracoAdminReset.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4973FC05-0C95-4665-AC4E-8CEED3201FF8} 8 | Library 9 | Properties 10 | UmbracoAdminReset 11 | UmbracoAdminReset 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll 35 | True 36 | 37 | 38 | ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll 39 | True 40 | 41 | 42 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\businesslogic.dll 43 | True 44 | 45 | 46 | ..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll 47 | True 48 | 49 | 50 | ..\packages\ClientDependency-Mvc5.1.8.0.0\lib\net45\ClientDependency.Core.Mvc.dll 51 | True 52 | 53 | 54 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\cms.dll 55 | True 56 | 57 | 58 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\controls.dll 59 | True 60 | 61 | 62 | ..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll 63 | True 64 | 65 | 66 | ..\packages\Examine.0.1.85\lib\net45\Examine.dll 67 | True 68 | 69 | 70 | ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll 71 | True 72 | 73 | 74 | ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll 75 | True 76 | 77 | 78 | ..\packages\ImageProcessor.2.5.3\lib\net45\ImageProcessor.dll 79 | True 80 | 81 | 82 | ..\packages\ImageProcessor.Web.4.8.3\lib\net45\ImageProcessor.Web.dll 83 | True 84 | 85 | 86 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\interfaces.dll 87 | True 88 | 89 | 90 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\log4net.dll 91 | True 92 | 93 | 94 | ..\packages\Log4Net.Async.2.0.4\lib\net40\Log4Net.Async.dll 95 | True 96 | 97 | 98 | ..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll 99 | True 100 | 101 | 102 | ..\packages\Markdown.1.14.7\lib\net45\MarkdownSharp.dll 103 | True 104 | 105 | 106 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\Microsoft.ApplicationBlocks.Data.dll 107 | True 108 | 109 | 110 | ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll 111 | True 112 | 113 | 114 | ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll 115 | True 116 | 117 | 118 | ..\packages\Microsoft.AspNet.SignalR.Core.2.2.1\lib\net45\Microsoft.AspNet.SignalR.Core.dll 119 | True 120 | 121 | 122 | ..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.1\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll 123 | True 124 | 125 | 126 | ..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll 127 | True 128 | 129 | 130 | ..\packages\Microsoft.Owin.Host.SystemWeb.3.1.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll 131 | True 132 | 133 | 134 | ..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll 135 | True 136 | 137 | 138 | ..\packages\Microsoft.Owin.Security.Cookies.3.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll 139 | True 140 | 141 | 142 | ..\packages\Microsoft.Owin.Security.OAuth.3.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll 143 | True 144 | 145 | 146 | ..\packages\Microsoft.AspNet.WebHelpers.3.2.3\lib\net45\Microsoft.Web.Helpers.dll 147 | True 148 | 149 | 150 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 151 | True 152 | 153 | 154 | ..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll 155 | True 156 | 157 | 158 | ..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll 159 | True 160 | 161 | 162 | ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll 163 | True 164 | 165 | 166 | ..\packages\Owin.1.0\lib\net40\Owin.dll 167 | True 168 | 169 | 170 | ..\packages\semver.1.1.2\lib\net45\Semver.dll 171 | True 172 | 173 | 174 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\SQLCE4Umbraco.dll 175 | True 176 | 177 | 178 | 179 | 180 | 181 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\System.Data.SqlServerCe.dll 182 | True 183 | 184 | 185 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\System.Data.SqlServerCe.Entity.dll 186 | True 187 | 188 | 189 | 190 | ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll 191 | True 192 | 193 | 194 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll 195 | True 196 | 197 | 198 | ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll 199 | True 200 | 201 | 202 | 203 | ..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll 204 | True 205 | 206 | 207 | 208 | 209 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll 210 | True 211 | 212 | 213 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll 214 | True 215 | 216 | 217 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll 218 | True 219 | 220 | 221 | ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll 222 | True 223 | 224 | 225 | ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll 226 | True 227 | 228 | 229 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll 230 | True 231 | 232 | 233 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll 234 | True 235 | 236 | 237 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll 238 | True 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\TidyNet.dll 247 | True 248 | 249 | 250 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\umbraco.dll 251 | True 252 | 253 | 254 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\Umbraco.Core.dll 255 | True 256 | 257 | 258 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\umbraco.DataLayer.dll 259 | True 260 | 261 | 262 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\umbraco.editorControls.dll 263 | True 264 | 265 | 266 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\umbraco.MacroEngines.dll 267 | True 268 | 269 | 270 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\umbraco.providers.dll 271 | True 272 | 273 | 274 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\Umbraco.Web.UI.dll 275 | True 276 | 277 | 278 | ..\packages\UmbracoCms.Core.7.7.1\lib\net45\UmbracoExamine.dll 279 | True 280 | 281 | 282 | ..\packages\Microsoft.AspNet.WebPages.Data.3.2.3\lib\net45\WebMatrix.Data.dll 283 | True 284 | 285 | 286 | ..\packages\Microsoft.AspNet.WebPages.WebData.3.2.3\lib\net45\WebMatrix.WebData.dll 287 | True 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 313 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /UmbracoAdminReset/UmbracoAdminReset/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | --------------------------------------------------------------------------------