├── README.MD └── src ├── .gitignore ├── BottomUpDDDLatter.sln ├── Domain.Tests ├── Domain.Tests.csproj └── Users │ └── RegisterUserTest.cs ├── Domain ├── Application │ ├── CircleApplicationService.cs │ ├── Models │ │ ├── FullNameModel.cs │ │ ├── UserModel.cs │ │ └── UserSummaryModel.cs │ └── UserApplicationService.cs ├── Domain.csproj ├── Domain │ ├── Circles │ │ ├── Circle.cs │ │ ├── CircleId.cs │ │ ├── ICircleFactory.cs │ │ ├── ICircleNotification.cs │ │ └── ICircleRepository.cs │ └── Users │ │ ├── FullName.cs │ │ ├── IUserFactory.cs │ │ ├── IUserRepository.cs │ │ ├── User.cs │ │ ├── UserId.cs │ │ ├── UserName.cs │ │ └── UserService.cs └── UnitOfWorkSample │ ├── IUnitOfWork.cs │ └── UserApplicationService.cs ├── InMemoryInfrastructure ├── InMemoryInfrastructure.csproj └── Users │ └── InMemoryUserRepository.cs ├── ProductInfrastructure ├── Circles │ ├── CircleDataModel.cs │ ├── CircleNotification.cs │ └── CircleRepository.cs ├── Config.cs ├── DbContexts │ └── BottomUpDddDbContext.cs ├── Models │ └── User.cs ├── ProductInfrastructure.csproj ├── UnitOfWorkSample │ ├── UnitOfWork.cs │ └── UserRepository.cs └── Users │ ├── EFUserRepository.cs │ ├── UserFactory.cs │ └── UserRepository.cs └── WebApplication ├── Controllers ├── HomeController.cs └── UserController.cs ├── Models ├── EditUserViewModel.cs ├── ErrorViewModel.cs ├── RegisterUserViewModel.cs ├── UserDetailViewModel.cs ├── UserSummaryViewModel.cs └── UserViewModel.cs ├── Program.cs ├── Properties └── launchSettings.json ├── Startup.cs ├── Views ├── Home │ ├── About.cshtml │ ├── Contact.cshtml │ └── Index.cshtml ├── Shared │ ├── Error.cshtml │ ├── _Layout.cshtml │ └── _ValidationScriptsPartial.cshtml ├── User │ ├── Delete.cshtml │ ├── Detail.cshtml │ ├── Edit.cshtml │ ├── Index.cshtml │ └── NewUser.cshtml ├── _ViewImports.cshtml └── _ViewStart.cshtml ├── WebApplication.csproj ├── appsettings.Development.json ├── appsettings.json ├── bundleconfig.json └── wwwroot ├── css ├── site.css └── site.min.css ├── favicon.ico ├── images ├── banner1.svg ├── banner2.svg ├── banner3.svg └── banner4.svg ├── js ├── site.js └── site.min.js └── lib ├── bootstrap ├── .bower.json ├── LICENSE └── dist │ ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.css.map │ ├── bootstrap-theme.min.css │ ├── bootstrap-theme.min.css.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ └── bootstrap.min.css.map │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 │ └── js │ ├── bootstrap.js │ ├── bootstrap.min.js │ └── npm.js ├── jquery-validation-unobtrusive ├── .bower.json ├── jquery.validate.unobtrusive.js └── jquery.validate.unobtrusive.min.js ├── jquery-validation ├── .bower.json ├── LICENSE.md └── dist │ ├── additional-methods.js │ ├── additional-methods.min.js │ ├── jquery.validate.js │ └── jquery.validate.min.js └── jquery ├── .bower.json ├── LICENSE.txt └── dist ├── jquery.js ├── jquery.min.js └── jquery.min.map /README.MD: -------------------------------------------------------------------------------- 1 | # ボトムアップドメイン駆動設計後編 2 | ボトムアップドメイン駆動設計の後編用プロジェクトです。 3 | 解説記事: https://nrslib.com/bottomup-ddd-2/ 4 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /src/BottomUpDDDLatter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2015 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Domain", "Domain\Domain.csproj", "{C6391B11-252A-4A70-9637-D1CE2D836761}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductInfrastructure", "ProductInfrastructure\ProductInfrastructure.csproj", "{359BC6A2-BFEA-4C07-92C9-C768FF2D6B84}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Domain.Tests", "Domain.Tests\Domain.Tests.csproj", "{D19F0794-F56B-408A-87C5-A6017D06D36A}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InMemoryInfrastructure", "InMemoryInfrastructure\InMemoryInfrastructure.csproj", "{73FCF21B-49BA-458B-96AE-9D545B6E2983}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApplication", "WebApplication\WebApplication.csproj", "{9FAFE385-7467-404D-B24E-8800A197A67F}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {C6391B11-252A-4A70-9637-D1CE2D836761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {C6391B11-252A-4A70-9637-D1CE2D836761}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {C6391B11-252A-4A70-9637-D1CE2D836761}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {C6391B11-252A-4A70-9637-D1CE2D836761}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {359BC6A2-BFEA-4C07-92C9-C768FF2D6B84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {359BC6A2-BFEA-4C07-92C9-C768FF2D6B84}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {359BC6A2-BFEA-4C07-92C9-C768FF2D6B84}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {359BC6A2-BFEA-4C07-92C9-C768FF2D6B84}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {D19F0794-F56B-408A-87C5-A6017D06D36A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {D19F0794-F56B-408A-87C5-A6017D06D36A}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {D19F0794-F56B-408A-87C5-A6017D06D36A}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {D19F0794-F56B-408A-87C5-A6017D06D36A}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {73FCF21B-49BA-458B-96AE-9D545B6E2983}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {73FCF21B-49BA-458B-96AE-9D545B6E2983}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {73FCF21B-49BA-458B-96AE-9D545B6E2983}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {73FCF21B-49BA-458B-96AE-9D545B6E2983}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {9FAFE385-7467-404D-B24E-8800A197A67F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {9FAFE385-7467-404D-B24E-8800A197A67F}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {9FAFE385-7467-404D-B24E-8800A197A67F}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {9FAFE385-7467-404D-B24E-8800A197A67F}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {0557A76C-83DF-4DCF-B114-69E4E7DE98FC} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /src/Domain.Tests/Domain.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Domain.Tests/Users/RegisterUserTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Domain.Application; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using MySql.Data.MySqlClient; 6 | using ProductInfrastructure.DbContexts; 7 | using ProductInfrastructure.Users; 8 | 9 | namespace Domain.Tests.Users 10 | { 11 | [TestClass] 12 | public class RegisterUserTest 13 | { 14 | [TestMethod] 15 | public void TestUserIsAtomic() { 16 | var factory = new UserFactory(); 17 | var throwedException = false; 18 | try { 19 | Parallel.For(0, 2, _ => { 20 | var context = new BottomUpDddDbContext(); 21 | context.Database.AutoTransactionsEnabled = false; 22 | var repository = new EFUserRepository(context); 23 | var app = new UserApplicationService(factory, repository); 24 | app.RegisterUser("ataro", "taro", "tanaka"); 25 | }); 26 | } catch (AggregateException e) { 27 | throwedException = true; 28 | } 29 | Assert.IsTrue(throwedException); 30 | } 31 | 32 | private MySqlConnection CreateConnection() { 33 | var connection = new MySqlConnection("Database=bottomup_ddd;Data Source=localhost;User id=developer;Password=11111111;SslMode=none;"); 34 | connection.Open(); 35 | return connection; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Domain/Application/CircleApplicationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | using Domain.Domain.Circles; 4 | using Domain.Domain.Users; 5 | 6 | namespace Domain.Application { 7 | public class CircleApplicationService { 8 | private readonly ICircleFactory circleFactory; 9 | private readonly ICircleRepository circleRepository; 10 | private readonly IUserRepository userRepository; 11 | 12 | public CircleApplicationService( 13 | ICircleFactory circleFactory, 14 | ICircleRepository circleRepository, 15 | IUserRepository userRepository 16 | ) { 17 | this.circleFactory = circleFactory; 18 | this.circleRepository = circleRepository; 19 | this.userRepository = userRepository; 20 | } 21 | 22 | public void CreateCircle(string userId, string circleName) { 23 | using (var transaction = new TransactionScope()) { 24 | var ownerId = new UserId(userId); 25 | var owner = userRepository.Find(ownerId); 26 | if (owner == null) { 27 | throw new Exception("owner not found. userId: " + userId); 28 | } 29 | var circle = owner.CreateCircle(circleFactory, circleName); 30 | circleRepository.Save(circle); 31 | transaction.Complete(); 32 | } 33 | } 34 | 35 | public void JoinUser(string circleId, string userId) { 36 | using (var transaction = new TransactionScope()) { 37 | var targetCircleId = new CircleId(circleId); 38 | var targetCircle = circleRepository.Find(targetCircleId); 39 | if (targetCircle == null) { 40 | throw new Exception("circle not found. circleId: " + circleId); 41 | } 42 | 43 | var joinUserId = new UserId(userId); 44 | var joinUser = userRepository.Find(joinUserId); 45 | if (joinUser == null) { 46 | throw new Exception("user not found. userId: " + userId); 47 | } 48 | 49 | targetCircle.Join(joinUser); // targetCircle.Users.Add(joinUser); とは書けなくなりました 50 | circleRepository.Save(targetCircle); 51 | transaction.Complete(); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Domain/Application/Models/FullNameModel.cs: -------------------------------------------------------------------------------- 1 | using Domain.Domain.Users; 2 | 3 | namespace Domain.Application.Models 4 | { 5 | public class FullNameModel 6 | { 7 | public FullNameModel(FullName source) { 8 | FirstName = source.FirstName; 9 | FamilyName = source.FamilyName; 10 | } 11 | 12 | public string FirstName { get; } 13 | public string FamilyName { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Domain/Application/Models/UserModel.cs: -------------------------------------------------------------------------------- 1 | using Domain.Domain.Users; 2 | 3 | namespace Domain.Application.Models 4 | { 5 | public class UserModel 6 | { 7 | public UserModel(User source) { 8 | Id = source.Id.Value; 9 | UserName = source.UserName.Value; 10 | Name = new FullNameModel(source.Name); 11 | } 12 | 13 | public string Id { get; } 14 | public string UserName { get; } 15 | public FullNameModel Name { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Domain/Application/Models/UserSummaryModel.cs: -------------------------------------------------------------------------------- 1 | using Domain.Domain.Users; 2 | 3 | namespace Domain.Application.Models { 4 | public class UserSummaryModel{ 5 | public UserSummaryModel(User source) { 6 | Id = source.Id.Value; 7 | UserName = source.UserName.Value; 8 | } 9 | 10 | public string Id { get; } 11 | public string UserName { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Domain/Application/UserApplicationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Transactions; 5 | using Domain.Application.Models; 6 | using Domain.Domain.Users; 7 | 8 | namespace Domain.Application { 9 | public class UserApplicationService { 10 | private readonly IUserFactory userFactory; 11 | private readonly IUserRepository userRepository; 12 | private readonly UserService userService; 13 | 14 | public UserApplicationService( 15 | IUserFactory userFactory, 16 | IUserRepository userRepository 17 | ) { 18 | this.userFactory = userFactory; 19 | this.userRepository = userRepository; 20 | userService = new UserService(userRepository); 21 | } 22 | 23 | public void RegisterUser(string username, string firstname, string familyname) { 24 | using (var transaction = new TransactionScope()) { 25 | var user = userFactory.CreateUser( 26 | new UserName(username), 27 | new FullName(firstname, familyname) 28 | ); 29 | if (userService.IsDuplicated(user)) { 30 | throw new Exception("重複しています"); 31 | } else { 32 | userRepository.Save(user); 33 | } 34 | transaction.Complete(); 35 | } 36 | } 37 | 38 | public void ChangeUserInfo(string id, string username, string firstname, string familyname) { 39 | var targetId = new UserId(id); 40 | var target = userRepository.Find(targetId); 41 | if (target == null) { 42 | throw new Exception("not found. target id:" + id); 43 | } 44 | 45 | var newUserName = new UserName(username); 46 | target.ChangeUserName(newUserName); 47 | if (userService.IsDuplicated(target)) { 48 | throw new Exception("重複しています"); 49 | } 50 | 51 | var newName = new FullName(firstname, familyname); 52 | target.ChangeName(newName); 53 | userRepository.Save(target); 54 | } 55 | 56 | public void RemoveUser(string id) { 57 | var targetId = new UserId(id); 58 | var target = userRepository.Find(targetId); 59 | if (target == null) { 60 | throw new Exception("not found. target id:" + id); 61 | } 62 | userRepository.Remove(target); 63 | } 64 | 65 | public UserModel GetUserInfo(string id) { 66 | var userId = new UserId(id); 67 | var target = userRepository.Find(userId); 68 | if (target == null) { 69 | return null; 70 | } 71 | 72 | return new UserModel(target); 73 | } 74 | 75 | public List GetUserList() { 76 | var users = userRepository.FindAll(); 77 | return users.Select(x => new UserSummaryModel(x)).ToList(); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/Domain/Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Domain/Domain/Circles/Circle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Domain.Domain.Users; 4 | 5 | namespace Domain.Domain.Circles 6 | { 7 | public class Circle : IEquatable { 8 | private readonly CircleId id; 9 | private string name; 10 | private List users; 11 | 12 | public Circle( 13 | CircleId id, 14 | string name, 15 | List users 16 | ) { 17 | this.id = id; 18 | this.name = name; 19 | this.users = users; 20 | } 21 | 22 | public bool Equals(Circle other) { 23 | if (ReferenceEquals(null, other)) return false; 24 | if (ReferenceEquals(this, other)) return true; 25 | return Equals(id, other.id); 26 | } 27 | 28 | public override bool Equals(object obj) { 29 | if (ReferenceEquals(null, obj)) return false; 30 | if (ReferenceEquals(this, obj)) return true; 31 | if (obj.GetType() != this.GetType()) return false; 32 | return Equals((Circle) obj); 33 | } 34 | 35 | public override int GetHashCode() { 36 | return (id != null ? id.GetHashCode() : 0); 37 | } 38 | 39 | public void Join(User user) { 40 | if (users.Count >= 30) { 41 | throw new Exception("too many members."); 42 | } 43 | users.Add(user.Id); 44 | } 45 | 46 | public void Notify(ICircleNotification note) { 47 | note.Id(id); 48 | note.Name(name); 49 | note.Users(new List(users)); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Domain/Domain/Circles/CircleId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Domain.Domain.Circles 4 | { 5 | public class CircleId: IEquatable { 6 | public CircleId(string value) { 7 | Value = value; 8 | } 9 | 10 | public string Value { get; } 11 | 12 | public bool Equals(CircleId other) { 13 | if (ReferenceEquals(null, other)) return false; 14 | if (ReferenceEquals(this, other)) return true; 15 | return string.Equals(Value, other.Value); 16 | } 17 | 18 | public override bool Equals(object obj) { 19 | if (ReferenceEquals(null, obj)) return false; 20 | if (ReferenceEquals(this, obj)) return true; 21 | if (obj.GetType() != this.GetType()) return false; 22 | return Equals((CircleId) obj); 23 | } 24 | 25 | public override int GetHashCode() { 26 | return (Value != null ? Value.GetHashCode() : 0); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Domain/Domain/Circles/ICircleFactory.cs: -------------------------------------------------------------------------------- 1 | using Domain.Domain.Users; 2 | 3 | namespace Domain.Domain.Circles 4 | { 5 | public interface ICircleFactory { 6 | Circle Create(UserId userId, string name); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Domain/Domain/Circles/ICircleNotification.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Domain.Domain.Users; 3 | 4 | namespace Domain.Domain.Circles 5 | { 6 | public interface ICircleNotification { 7 | void Id(CircleId id); 8 | void Name(string name); 9 | void Users(List users); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Domain/Domain/Circles/ICircleRepository.cs: -------------------------------------------------------------------------------- 1 | namespace Domain.Domain.Circles 2 | { 3 | public interface ICircleRepository { 4 | Circle Find(CircleId id); 5 | void Save(Circle circle); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Domain/Domain/Users/FullName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Domain.Domain.Users 4 | { 5 | public class FullName : IEquatable { 6 | private readonly string firstname; 7 | private readonly string familyname; 8 | 9 | public FullName(string firstname, string familyname) { 10 | this.firstname = firstname; 11 | this.familyname = familyname; 12 | } 13 | 14 | public string FirstName { get { return firstname; } } 15 | public string FamilyName { get { return familyname; } } 16 | 17 | public bool Equals(FullName other) { 18 | if (ReferenceEquals(null, other)) return false; 19 | if (ReferenceEquals(this, other)) return true; 20 | return string.Equals(firstname, other.firstname) && string.Equals(familyname, other.familyname); 21 | } 22 | 23 | public override bool Equals(object obj) { 24 | if (ReferenceEquals(null, obj)) return false; 25 | if (ReferenceEquals(this, obj)) return true; 26 | if (obj.GetType() != this.GetType()) return false; 27 | return Equals((FullName)obj); 28 | } 29 | 30 | public override int GetHashCode() { 31 | unchecked { 32 | return ((firstname != null ? firstname.GetHashCode() : 0) * 397) ^ (familyname != null ? familyname.GetHashCode() : 0); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Domain/Domain/Users/IUserFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Domain.Domain.Users 2 | { 3 | public interface IUserFactory { 4 | User CreateUser(UserName username, FullName fullName); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Domain/Domain/Users/IUserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Domain.Domain.Users { 4 | public interface IUserRepository { 5 | User Find(UserId id); 6 | User Find(UserName name); 7 | IEnumerable FindAll(); 8 | void Save(User user); 9 | void Remove(User user); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Domain/Domain/Users/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Domain.Domain.Circles; 3 | 4 | namespace Domain.Domain.Users { 5 | public class User : IEquatable { 6 | private readonly UserId id; 7 | private UserName userName; 8 | private FullName name; 9 | 10 | public User(UserId id, UserName userName, FullName name) { 11 | this.id = id; 12 | this.userName = userName; 13 | this.name = name; 14 | } 15 | 16 | public UserId Id { 17 | get { return id; } 18 | } 19 | 20 | public UserName UserName { 21 | get { return userName; } 22 | } 23 | 24 | public FullName Name { 25 | get { return name; } 26 | } 27 | 28 | public void ChangeUserName(UserName newName) { 29 | if (newName == null) throw new ArgumentNullException(nameof(newName)); 30 | userName = newName; 31 | } 32 | 33 | public void ChangeName(FullName newName) { 34 | if (newName == null) throw new ArgumentNullException(nameof(newName)); 35 | this.name = newName; 36 | } 37 | 38 | public Circle CreateCircle(ICircleFactory circleFactory, string circleName) { 39 | return circleFactory.Create(id, circleName); 40 | } 41 | 42 | public bool Equals(User other) 43 | { 44 | if (ReferenceEquals(null, other)) return false; 45 | if (ReferenceEquals(this, other)) return true; 46 | return Equals(id, other.id); 47 | } 48 | 49 | public override bool Equals(object obj) 50 | { 51 | if (ReferenceEquals(null, obj)) return false; 52 | if (ReferenceEquals(this, obj)) return true; 53 | if (obj.GetType() != this.GetType()) return false; 54 | return Equals((User) obj); 55 | } 56 | 57 | public override int GetHashCode() 58 | { 59 | return (id != null ? id.GetHashCode() : 0); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/Domain/Domain/Users/UserId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Domain.Domain.Users { 4 | public class UserId : IEquatable { 5 | public UserId(string id) { 6 | Value = id; 7 | } 8 | 9 | public string Value { get; } 10 | 11 | public bool Equals(UserId other) { 12 | if (ReferenceEquals(null, other)) return false; 13 | if (ReferenceEquals(this, other)) return true; 14 | return string.Equals(Value, other.Value); 15 | } 16 | 17 | public override bool Equals(object obj) { 18 | if (ReferenceEquals(null, obj)) return false; 19 | if (ReferenceEquals(this, obj)) return true; 20 | if (obj.GetType() != this.GetType()) return false; 21 | return Equals((UserId) obj); 22 | } 23 | 24 | public override int GetHashCode() { 25 | return (Value != null ? Value.GetHashCode() : 0); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Domain/Domain/Users/UserName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Domain.Domain.Users 4 | { 5 | public class UserName : IEquatable { 6 | private readonly string name; 7 | 8 | public UserName(string name) { 9 | if (string.IsNullOrEmpty(name)) { 10 | throw new ArgumentNullException(nameof(name)); 11 | } 12 | if (name.Length > 50) { 13 | throw new ArgumentOutOfRangeException("It must be 50 characters or less", nameof(name)); 14 | } 15 | this.name = name; 16 | } 17 | 18 | public string Value { get { return name; } } 19 | 20 | public bool Equals(UserName other) { 21 | if (ReferenceEquals(null, other)) return false; 22 | if (ReferenceEquals(this, other)) return true; 23 | return string.Equals(name, other.name); 24 | } 25 | 26 | public override bool Equals(object obj) { 27 | if (ReferenceEquals(null, obj)) return false; 28 | if (ReferenceEquals(this, obj)) return true; 29 | if (obj.GetType() != this.GetType()) return false; 30 | return Equals((UserName) obj); 31 | } 32 | 33 | public override int GetHashCode() { 34 | return (name != null ? name.GetHashCode() : 0); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Domain/Domain/Users/UserService.cs: -------------------------------------------------------------------------------- 1 | namespace Domain.Domain.Users { 2 | public class UserService { 3 | private readonly IUserRepository userRepository; 4 | 5 | public UserService(IUserRepository userRepository) { 6 | this.userRepository = userRepository; 7 | } 8 | 9 | public bool IsDuplicated(User user) { 10 | var name = user.UserName; 11 | var searched = userRepository.Find(name); 12 | 13 | return searched != null; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Domain/UnitOfWorkSample/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Domain.Domain.Users; 3 | 4 | namespace Domain.UnitOfWorkSample 5 | { 6 | public interface IUnitOfWork : IDisposable { 7 | IUserRepository UserRepository { get; } 8 | void Commit(); 9 | void Rollback(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Domain/UnitOfWorkSample/UserApplicationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection.Metadata; 5 | using Domain.Application.Models; 6 | using Domain.Domain.Users; 7 | 8 | namespace Domain.UnitOfWorkSample 9 | { 10 | public class UserApplicationServiceByUow 11 | { 12 | private readonly IUserFactory userFactory; 13 | private readonly IUnitOfWork uow; 14 | private readonly UserService userService; 15 | 16 | public UserApplicationServiceByUow( 17 | IUserFactory userFactory, 18 | IUnitOfWork uow) { 19 | this.userFactory = userFactory; 20 | this.uow = uow; 21 | userService = new UserService(uow.UserRepository); 22 | } 23 | 24 | public void RegisterUser(string username, string firstname, string familyname) { 25 | try { 26 | var user = userFactory.CreateUser( 27 | new UserName(username), 28 | new FullName(firstname, familyname) 29 | ); 30 | if (userService.IsDuplicated(user)) { 31 | throw new Exception("重複しています"); 32 | } else { 33 | uow.UserRepository.Save(user); 34 | } 35 | uow.Commit(); 36 | } catch { 37 | uow.Rollback(); 38 | throw; 39 | } 40 | } 41 | 42 | public void ChangeUserInfo(string id, string username, string firstname, string familyname) { 43 | try { 44 | var targetId = new UserId(id); 45 | var target = uow.UserRepository.Find(targetId); 46 | if (target == null) { 47 | throw new Exception("not found. target id:" + id); 48 | } 49 | var newUserName = new UserName(username); 50 | target.ChangeUserName(newUserName); 51 | var newName = new FullName(firstname, familyname); 52 | target.ChangeName(newName); 53 | uow.UserRepository.Save(target); 54 | uow.Commit(); 55 | } catch { 56 | uow.Rollback(); 57 | throw; 58 | } 59 | } 60 | 61 | public void RemoveUser(string id) { 62 | try { 63 | var targetId = new UserId(id); 64 | var target = uow.UserRepository.Find(targetId); 65 | if (target == null) { 66 | throw new Exception("not found. target id:" + id); 67 | } 68 | uow.UserRepository.Remove(target); 69 | uow.Commit(); 70 | } catch { 71 | uow.Rollback(); 72 | throw; 73 | } 74 | } 75 | 76 | public UserModel GetUserInfo(string id) { 77 | var userId = new UserId(id); 78 | var target = uow.UserRepository.Find(userId); 79 | if (target == null) { 80 | return null; 81 | } 82 | 83 | return new UserModel(target); 84 | } 85 | 86 | public List GetUserList() { 87 | var users = uow.UserRepository.FindAll(); 88 | return users.Select(x => new UserSummaryModel(x)).ToList(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/InMemoryInfrastructure/InMemoryInfrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/InMemoryInfrastructure/Users/InMemoryUserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Domain.Domain.Users; 4 | 5 | namespace InMemoryInfrastructure.Users { 6 | public class InMemoryUserRepository : IUserRepository { 7 | private readonly Dictionary data = new Dictionary(); 8 | 9 | public User Find(UserId id) { 10 | if (data.TryGetValue(id, out var target)) { 11 | return cloneUser(target); 12 | } else { 13 | return null; 14 | } 15 | } 16 | 17 | public User Find(UserName name) { 18 | var target = data.Values.FirstOrDefault(x => x.UserName.Equals(name)); 19 | if (target != null) { 20 | return cloneUser(target); 21 | } else { 22 | return null; 23 | } 24 | } 25 | 26 | public IEnumerable FindAll() { 27 | return data.Values.Select(cloneUser); 28 | } 29 | 30 | public void Save(User user) { 31 | data[user.Id] = user; 32 | } 33 | 34 | public void Remove(User user) { 35 | data.Remove(user.Id); 36 | } 37 | 38 | private User cloneUser(User user) { 39 | return new User(user.Id, user.UserName, user.Name); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/ProductInfrastructure/Circles/CircleDataModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace ProductInfrastructure.Circles 6 | { 7 | public class CircleDataModel 8 | { 9 | public CircleDataModel(string id, string name, List userIds) { 10 | Id = id; 11 | Name = name; 12 | UserIds = userIds; 13 | } 14 | 15 | public string Id { get; } 16 | public string Name { get; } 17 | public List UserIds { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Circles/CircleNotification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Domain.Domain.Circles; 5 | using Domain.Domain.Users; 6 | 7 | namespace ProductInfrastructure.Circles 8 | { 9 | public class CircleNotification : ICircleNotification { 10 | private CircleId id; 11 | private string name; 12 | private List userIds; 13 | 14 | public void Id(CircleId id) { 15 | this.id = id; 16 | } 17 | 18 | public void Name(string name) { 19 | this.name = name; 20 | } 21 | 22 | public void Users(List userIds) { 23 | this.userIds = userIds; 24 | } 25 | 26 | public CircleDataModel Build() { 27 | var ids = userIds.Select(x => x.Value).ToList(); 28 | 29 | return new CircleDataModel( 30 | id.Value, 31 | name, 32 | ids 33 | ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Circles/CircleRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Domain.Domain.Circles; 6 | using Domain.Domain.Users; 7 | using MySql.Data.MySqlClient; 8 | 9 | namespace ProductInfrastructure.Circles 10 | { 11 | public class CircleRepository : ICircleRepository 12 | { 13 | public Circle Find(CircleId id) { 14 | throw new NotImplementedException(); 15 | } 16 | 17 | public void Save(Circle circle) { 18 | using (var con = new MySqlConnection(Config.ConnectionString)) { 19 | con.Open(); 20 | using (var com = con.CreateCommand()) { 21 | var note = new CircleNotification(); 22 | circle.Notify(note); 23 | var data = note.Build(); 24 | 25 | com.CommandText = "UPDATE t_circle SET circle_name = @circle_name, join_members = @join_members WHERE id = @id"; 26 | com.Parameters.Add(new MySqlParameter("@circle_name", data.Name)); 27 | com.Parameters.Add(new MySqlParameter("@id", data.Id)); 28 | com.Parameters.Add(new MySqlParameter("@join_members", string.Join(",", data.UserIds))); // 所属メンバーは中間テーブルにしたほうがいいかも 29 | com.ExecuteNonQuery(); 30 | } 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Config.cs: -------------------------------------------------------------------------------- 1 | namespace ProductInfrastructure 2 | { 3 | class Config { 4 | public const string ConnectionString = "Database=bottomup_ddd;Data Source=localhost;User id=developer;Password=11111111;SslMode=none;"; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/DbContexts/BottomUpDddDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using ProductInfrastructure.Models; 3 | 4 | namespace ProductInfrastructure.DbContexts 5 | { 6 | public class BottomUpDddDbContext : DbContext 7 | { 8 | public DbSet Users { get; set; } 9 | 10 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { 11 | optionsBuilder 12 | .UseMySQL(Config.ConnectionString); 13 | 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Models/User.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace ProductInfrastructure.Models 5 | { 6 | [Table("t_user")] 7 | public class User 8 | { 9 | [StringLength(255)] 10 | public string Id { get; set; } 11 | [StringLength(255)] 12 | public string Username { get; set; } 13 | [StringLength(255)] 14 | public string Firstname { get; set; } 15 | [StringLength(255)] 16 | public string Familyname { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/ProductInfrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/UnitOfWorkSample/UnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Domain.Domain.Users; 3 | using Domain.UnitOfWorkSample; 4 | using MySql.Data.MySqlClient; 5 | 6 | namespace ProductInfrastructure.UnitOfWorkSample { 7 | public class UnitOfWork : IUnitOfWork { 8 | private readonly MySqlConnection con; 9 | private readonly MySqlTransaction transaction; 10 | private bool disposed; 11 | 12 | private UserRepository userRepository; 13 | 14 | public UnitOfWork() { 15 | con = new MySqlConnection(Config.ConnectionString); 16 | con.Open(); 17 | transaction = con.BeginTransaction(); 18 | } 19 | 20 | public IUserRepository UserRepository { 21 | get { 22 | if (userRepository == null) { 23 | userRepository = new UserRepository(con); 24 | } 25 | return userRepository; 26 | } 27 | } 28 | 29 | public void Commit() { 30 | transaction.Commit(); 31 | } 32 | 33 | public void Rollback() { 34 | transaction.Rollback(); 35 | } 36 | 37 | public void Dispose() { 38 | Dispose(true); 39 | GC.SuppressFinalize(this); 40 | } 41 | 42 | protected virtual void Dispose(bool disposing) { 43 | if (!disposed) { 44 | if (disposing) { 45 | transaction.Dispose(); 46 | con.Dispose(); 47 | } 48 | } 49 | disposed = true; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/UnitOfWorkSample/UserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Domain.Domain.Users; 3 | using MySql.Data.MySqlClient; 4 | 5 | namespace ProductInfrastructure.UnitOfWorkSample 6 | { 7 | public class UserRepository : IUserRepository 8 | { 9 | private readonly MySqlConnection con; 10 | 11 | public UserRepository(MySqlConnection con) { 12 | this.con = con; 13 | } 14 | 15 | public User Find(UserId id) { 16 | using (var com = con.CreateCommand()) { 17 | com.CommandText = "SELECT * FROM t_user WHERE id = @id"; 18 | com.Parameters.Add(new MySqlParameter("@id", id.Value)); 19 | var reader = com.ExecuteReader(); 20 | if (reader.Read()) { 21 | var username = reader["username"] as string; 22 | var firstname = reader["firstname"] as string; 23 | var familyname = reader["familyname"] as string; 24 | return new User( 25 | id, 26 | new UserName(username), 27 | new FullName(firstname, familyname) 28 | ); 29 | } else { 30 | return null; 31 | } 32 | } 33 | } 34 | 35 | public User Find(UserName userName) { 36 | using (var com = con.CreateCommand()) { 37 | com.CommandText = "SELECT * FROM t_user WHERE username = @username"; 38 | com.Parameters.Add(new MySqlParameter("@username", userName.Value)); 39 | var reader = com.ExecuteReader(); 40 | if (reader.Read()) { 41 | var id = reader["id"] as string; 42 | var firstname = reader["firstname"] as string; 43 | var familyname = reader["familyname"] as string; 44 | 45 | return new User( 46 | new UserId(id), 47 | userName, 48 | new FullName(firstname, familyname) 49 | ); 50 | } else { 51 | return null; 52 | } 53 | } 54 | } 55 | 56 | public IEnumerable FindAll() { 57 | using (var com = con.CreateCommand()) { 58 | com.CommandText = "SELECT * FROM t_user"; 59 | var reader = com.ExecuteReader(); 60 | var results = new List(); 61 | while (reader.Read()) { 62 | var id = reader["id"] as string; 63 | var firstname = reader["firstname"] as string; 64 | var familyname = reader["familyname"] as string; 65 | var username = reader["username"] as string; 66 | var user = new User( 67 | new UserId(id), 68 | new UserName(username), 69 | new FullName(firstname, familyname) 70 | ); 71 | results.Add(user); 72 | } 73 | return results; 74 | } 75 | } 76 | 77 | public void Save(User user) { 78 | bool isExist; 79 | using (var com = con.CreateCommand()) { 80 | com.CommandText = "SELECT * FROM t_user WHERE id = @id"; 81 | com.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 82 | var reader = com.ExecuteReader(); 83 | isExist = reader.Read(); 84 | } 85 | 86 | using (var command = con.CreateCommand()) { 87 | command.CommandText = isExist 88 | ? "UPDATE t_user SET username = @username, firstname = @firstname, familyname = @familyname WHERE id = @id" 89 | : "INSERT INTO t_user VALUES(@id, @username, @firstname, @familyname)"; 90 | command.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 91 | command.Parameters.Add(new MySqlParameter("@username", user.UserName.Value)); 92 | command.Parameters.Add(new MySqlParameter("@firstname", user.Name.FirstName)); 93 | command.Parameters.Add(new MySqlParameter("@familyname", user.Name.FamilyName)); 94 | command.ExecuteNonQuery(); 95 | } 96 | } 97 | 98 | public void Remove(User user) { 99 | using (var command = con.CreateCommand()) { 100 | command.CommandText = "DELETE FROM t_user WHERE id = @id"; 101 | command.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 102 | command.ExecuteNonQuery(); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Users/EFUserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Domain.Domain.Users; 4 | using ProductInfrastructure.DbContexts; 5 | 6 | namespace ProductInfrastructure.Users 7 | { 8 | public class EFUserRepository : IUserRepository { 9 | private readonly BottomUpDddDbContext dbContext; 10 | 11 | public EFUserRepository(BottomUpDddDbContext dbContext) { 12 | this.dbContext = dbContext; 13 | } 14 | 15 | public User Find(UserId id) { 16 | var target = dbContext.Users 17 | .FirstOrDefault(x => x.Id == id.Value); 18 | if (target != null) { 19 | return convertFrom(target); 20 | } else { 21 | return null; 22 | } 23 | } 24 | 25 | public User Find(UserName name) { 26 | var target = dbContext.Users 27 | .FirstOrDefault(x => x.Username == name.Value); 28 | if (target != null) { 29 | return convertFrom(target); 30 | } else { 31 | return null; 32 | } 33 | } 34 | 35 | public IEnumerable FindAll() { 36 | return dbContext.Users.Select(convertFrom); 37 | } 38 | 39 | public void Save(User user) { 40 | var target = dbContext.Users.FirstOrDefault(x => x.Id == user.Id.Value); 41 | if (target != null) { 42 | target.Id = user.Id.Value; 43 | target.Username = user.UserName.Value; 44 | target.Firstname = user.Name.FirstName; 45 | target.Familyname = user.Name.FamilyName; 46 | } else { 47 | var newUser = new Models.User { 48 | Id = user.Id.Value, 49 | Username = user.UserName.Value, 50 | Firstname = user.Name.FirstName, 51 | Familyname = user.Name.FamilyName 52 | }; 53 | dbContext.Users.Add(newUser); 54 | } 55 | dbContext.SaveChanges(); 56 | } 57 | 58 | public void Remove(User user) { 59 | var target = dbContext.Users.FirstOrDefault(x => x.Id == user.Id.Value); 60 | if (target != null) { 61 | dbContext.Users.Remove(target); 62 | } 63 | dbContext.SaveChanges(true); 64 | } 65 | 66 | private User convertFrom(Models.User source) { 67 | return new User( 68 | new UserId(source.Id), 69 | new UserName(source.Username), 70 | new FullName(source.Firstname, source.Familyname) 71 | ); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Users/UserFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Domain.Domain.Users; 3 | 4 | namespace ProductInfrastructure.Users 5 | { 6 | public class UserFactory : IUserFactory 7 | { 8 | public User CreateUser(UserName username, FullName fullName) { 9 | return new User( 10 | new UserId(Guid.NewGuid().ToString()), 11 | username, 12 | fullName 13 | ); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/ProductInfrastructure/Users/UserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Domain.Domain.Users; 3 | using MySql.Data.MySqlClient; 4 | 5 | namespace ProductInfrastructure.Users { 6 | public class UserRepository : IUserRepository { 7 | public User Find(UserId id) { 8 | using (var con = new MySqlConnection(Config.ConnectionString)) { 9 | con.Open(); 10 | using (var com = con.CreateCommand()) { 11 | com.CommandText = "SELECT * FROM t_user WHERE id = @id"; 12 | com.Parameters.Add(new MySqlParameter("@id", id.Value)); 13 | var reader = com.ExecuteReader(); 14 | if (reader.Read()) { 15 | var username = reader["username"] as string; 16 | var firstname = reader["firstname"] as string; 17 | var familyname = reader["familyname"] as string; 18 | return new User( 19 | id, 20 | new UserName(username), 21 | new FullName(firstname, familyname) 22 | ); 23 | } else { 24 | return null; 25 | } 26 | } 27 | } 28 | } 29 | 30 | public User Find(UserName userName) { 31 | using (var con = new MySqlConnection(Config.ConnectionString)) { 32 | con.Open(); 33 | using (var com = con.CreateCommand()) { 34 | com.CommandText = "SELECT * FROM t_user WHERE username = @username"; 35 | com.Parameters.Add(new MySqlParameter("@username", userName.Value)); 36 | var reader = com.ExecuteReader(); 37 | if (reader.Read()) { 38 | var id = reader["id"] as string; 39 | var firstname = reader["firstname"] as string; 40 | var familyname = reader["familyname"] as string; 41 | 42 | return new User( 43 | new UserId(id), 44 | userName, 45 | new FullName(firstname, familyname) 46 | ); 47 | } else { 48 | return null; 49 | } 50 | } 51 | } 52 | } 53 | 54 | public IEnumerable FindAll() { 55 | using (var con = new MySqlConnection(Config.ConnectionString)) { 56 | con.Open(); 57 | using (var com = con.CreateCommand()) { 58 | com.CommandText = "SELECT * FROM t_user"; 59 | var reader = com.ExecuteReader(); 60 | var results = new List(); 61 | while (reader.Read()) { 62 | var id = reader["id"] as string; 63 | var firstname = reader["firstname"] as string; 64 | var familyname = reader["familyname"] as string; 65 | var username = reader["username"] as string; 66 | var user = new User( 67 | new UserId(id), 68 | new UserName(username), 69 | new FullName(firstname, familyname) 70 | ); 71 | results.Add(user); 72 | } 73 | return results; 74 | } 75 | } 76 | } 77 | 78 | public void Save(User user) { 79 | using (var con = new MySqlConnection(Config.ConnectionString)) { 80 | con.Open(); 81 | 82 | bool isExist; 83 | using (var com = con.CreateCommand()) { 84 | com.CommandText = "SELECT * FROM t_user WHERE id = @id"; 85 | com.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 86 | var reader = com.ExecuteReader(); 87 | isExist = reader.Read(); 88 | } 89 | 90 | using (var command = con.CreateCommand()) { 91 | command.CommandText = isExist 92 | ? "UPDATE t_user SET username = @username, firstname = @firstname, familyname = @familyname WHERE id = @id" 93 | : "INSERT INTO t_user VALUES(@id, @username, @firstname, @familyname)"; 94 | command.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 95 | command.Parameters.Add(new MySqlParameter("@username", user.UserName.Value)); 96 | command.Parameters.Add(new MySqlParameter("@firstname", user.Name.FirstName)); 97 | command.Parameters.Add(new MySqlParameter("@familyname", user.Name.FamilyName)); 98 | command.ExecuteNonQuery(); 99 | } 100 | } 101 | } 102 | 103 | public void Remove(User user) { 104 | using (var con = new MySqlConnection(Config.ConnectionString)) { 105 | con.Open(); 106 | using (var command = con.CreateCommand()) { 107 | command.CommandText = "DELETE FROM t_user WHERE id = @id"; 108 | command.Parameters.Add(new MySqlParameter("@id", user.Id.Value)); 109 | command.ExecuteNonQuery(); 110 | } 111 | } 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /src/WebApplication/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using WebApplication.Models; 8 | 9 | namespace WebApplication.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | public IActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | public IActionResult About() 19 | { 20 | ViewData["Message"] = "Your application description page."; 21 | 22 | return View(); 23 | } 24 | 25 | public IActionResult Contact() 26 | { 27 | ViewData["Message"] = "Your contact page."; 28 | 29 | return View(); 30 | } 31 | 32 | public IActionResult Error() 33 | { 34 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/WebApplication/Controllers/UserController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Domain.Application; 3 | using Microsoft.AspNetCore.Mvc; 4 | using WebApplication.Models; 5 | 6 | namespace WebApplication.Controllers 7 | { 8 | public class UserController : Controller { 9 | private readonly UserApplicationService userService; 10 | 11 | public UserController(UserApplicationService userService) { 12 | this.userService = userService; 13 | } 14 | 15 | public IActionResult Index() { 16 | var users = userService.GetUserList(); 17 | var summaries = users.Select(x => new UserSummaryViewModel { 18 | Id = x.Id, 19 | UserName = x.UserName 20 | }); 21 | 22 | return View(summaries); 23 | } 24 | 25 | public IActionResult NewUser() { 26 | return View(); 27 | } 28 | 29 | [HttpPost] 30 | public IActionResult Register(RegisterUserViewModel model) { 31 | var username = model.UserName; 32 | var firstname = model.FirstName; 33 | var familyname = model.FamilyName; 34 | userService.RegisterUser(username, firstname, familyname); 35 | return Redirect("Index"); 36 | } 37 | 38 | public IActionResult Delete(string id) { 39 | var user = userService.GetUserInfo(id); 40 | var model = new UserDetailViewModel { 41 | Id = user.Id, 42 | UserName = user.UserName, 43 | FirstName = user.Name.FirstName, 44 | FamilyName = user.Name.FamilyName, 45 | }; 46 | return View(model); 47 | } 48 | 49 | [HttpPost] 50 | public IActionResult DeleteUser(string id) { 51 | userService.RemoveUser(id); 52 | return Redirect("Index"); 53 | } 54 | 55 | public IActionResult Detail(string id) { 56 | var user = userService.GetUserInfo(id); 57 | var model = new UserDetailViewModel { 58 | Id = user.Id, 59 | UserName = user.UserName, 60 | FirstName = user.Name.FirstName, 61 | FamilyName = user.Name.FamilyName, 62 | }; 63 | return View(model); 64 | } 65 | 66 | public IActionResult Edit(string id) { 67 | var target = userService.GetUserInfo(id); 68 | var model = new EditUserViewModel { 69 | Id = target.Id, 70 | UserName = target.UserName, 71 | FirstName = target.Name.FirstName, 72 | FamilyName = target.Name.FamilyName, 73 | }; 74 | return View(model); 75 | } 76 | 77 | [HttpPost] 78 | public IActionResult Update(EditUserViewModel model) { 79 | userService.ChangeUserInfo(model.Id, model.UserName, model.FirstName, model.FamilyName); 80 | return Redirect("Detail/" + model.Id); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/WebApplication/Models/EditUserViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace WebApplication.Models 2 | { 3 | public class EditUserViewModel { 4 | public string Id { get; set; } 5 | public string UserName { get; set; } 6 | public string FirstName { get; set; } 7 | public string FamilyName { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WebApplication/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WebApplication.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/WebApplication/Models/RegisterUserViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace WebApplication.Models 2 | { 3 | public class RegisterUserViewModel 4 | { 5 | public string UserName { get; set; } 6 | public string FirstName { get; set; } 7 | public string FamilyName { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WebApplication/Models/UserDetailViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace WebApplication.Models 2 | { 3 | public class UserDetailViewModel 4 | { 5 | public string Id { get; set; } 6 | public string UserName { get; set; } 7 | public string FirstName { get; set; } 8 | public string FamilyName { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/WebApplication/Models/UserSummaryViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace WebApplication.Models 2 | { 3 | public class UserSummaryViewModel 4 | { 5 | public string Id { get; set; } 6 | public string UserName { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/WebApplication/Models/UserViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace WebApplication.Models 2 | { 3 | public class UserViewModel 4 | { 5 | public string Id { get; set; } 6 | public string FirstName { get; set; } 7 | public string FamilyName { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WebApplication/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace WebApplication 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WebApplication/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3336/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:3337/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/WebApplication/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Domain.Application; 6 | using Domain.Domain.Users; 7 | using Domain.UnitOfWorkSample; 8 | using InMemoryInfrastructure.Users; 9 | using Microsoft.AspNetCore.Builder; 10 | using Microsoft.AspNetCore.Hosting; 11 | using Microsoft.Extensions.Configuration; 12 | using Microsoft.Extensions.DependencyInjection; 13 | using MySql.Data.MySqlClient; 14 | using ProductInfrastructure.DbContexts; 15 | using ProductInfrastructure.UnitOfWorkSample; 16 | using ProductInfrastructure.Users; 17 | using UserRepository = ProductInfrastructure.Users.UserRepository; 18 | 19 | namespace WebApplication 20 | { 21 | public class Startup 22 | { 23 | public Startup(IConfiguration configuration) 24 | { 25 | Configuration = configuration; 26 | } 27 | 28 | public IConfiguration Configuration { get; } 29 | 30 | // This method gets called by the runtime. Use this method to add services to the container. 31 | public void ConfigureServices(IServiceCollection services) 32 | { 33 | services.AddMvc(); 34 | 35 | SetupByNormal(services); 36 | 37 | // UnitOfWork で動かしたい場合は↑をコメントにして、↓をコメントアウト 38 | // SetupByUnitOfWork(services); 39 | // UserController で UserApplicationServiceByUow を利用するようにしてください 40 | } 41 | 42 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 44 | { 45 | if (env.IsDevelopment()) 46 | { 47 | app.UseBrowserLink(); 48 | app.UseDeveloperExceptionPage(); 49 | } 50 | else 51 | { 52 | app.UseExceptionHandler("/Home/Error"); 53 | } 54 | 55 | app.UseStaticFiles(); 56 | 57 | app.UseMvc(routes => 58 | { 59 | routes.MapRoute( 60 | name: "default", 61 | template: "{controller=Home}/{action=Index}/{id?}"); 62 | }); 63 | } 64 | 65 | private void SetupByNormal(IServiceCollection services) { 66 | RegisterInMemory(services); 67 | // ↓SQL を利用して動かしたい場合 68 | // RegisterSql(services); 69 | // ↓EntityFramework を利用して動かしたい場合 70 | // RegisterEntityFramework(services); 71 | 72 | services.AddTransient(); 73 | } 74 | 75 | private void RegisterInMemory(IServiceCollection services) { 76 | services.AddSingleton(); 77 | services.AddSingleton(); 78 | } 79 | 80 | private void RegisterSql(IServiceCollection services) { 81 | services.AddSingleton(); 82 | services.AddTransient(); 83 | } 84 | 85 | private void RegisterEntityFramework(IServiceCollection services) { 86 | services.AddSingleton(); 87 | services.AddTransient(provider => { 88 | var context = new BottomUpDddDbContext(); 89 | context.Database.AutoTransactionsEnabled = false; // 自動トランザクションを無効にして Nested transaction にならないようにする 90 | return context; 91 | }); 92 | services.AddDbContext(); 93 | services.AddTransient(); 94 | } 95 | 96 | private void SetupByUnitOfWork(IServiceCollection services) { 97 | services.AddSingleton(); 98 | services.AddTransient(); 99 | services.AddTransient(); 100 | 101 | services.AddTransient(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/WebApplication/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

@ViewData["Title"]

5 |

@ViewData["Message"]

6 | 7 |

Use this area to provide additional information.

8 | -------------------------------------------------------------------------------- /src/WebApplication/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

@ViewData["Title"]

5 |

@ViewData["Message"]

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
18 | -------------------------------------------------------------------------------- /src/WebApplication/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 | @Html.ActionLink( 6 | "Try a DEMO", 7 | "Index", 8 | "User", 9 | new { }, 10 | new { @class = "btn btn-default" } 11 | ) -------------------------------------------------------------------------------- /src/WebApplication/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 22 |

23 | -------------------------------------------------------------------------------- /src/WebApplication/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - WebApplication 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 40 |
41 | @RenderBody() 42 |
43 |
44 |

© 2018 - WebApplication

45 |
46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 66 | 67 | 68 | 69 | @RenderSection("Scripts", required: false) 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/WebApplication/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /src/WebApplication/Views/User/Delete.cshtml: -------------------------------------------------------------------------------- 1 | @model WebApplication.Models.UserDetailViewModel 2 | 3 | @{ 4 | ViewBag.Title = "title"; 5 | Layout = "_Layout"; 6 | } 7 | 8 |

Delete

9 |

Delete

10 |
11 |
12 | ID 13 |
14 |
15 | @Model.Id 16 |
17 |
18 |
19 |
20 | UserName 21 |
22 |
23 | @Model.UserName 24 |
25 |
26 |
27 |
28 | FirstName 29 |
30 |
31 | @Model.FirstName 32 |
33 |
34 |
35 |
36 | FamilyName 37 |
38 |
39 | @Model.FamilyName 40 |
41 |
42 |
43 | @using (Html.BeginForm("DeleteUser", "User")) { 44 | @Html.HiddenFor(model => model.Id) 45 | 46 | } 47 |
48 | @Html.ActionLink("Back", "Index", "User", new { }, new { @class = "btn btn-default" }) 49 |
50 |
-------------------------------------------------------------------------------- /src/WebApplication/Views/User/Detail.cshtml: -------------------------------------------------------------------------------- 1 | @model WebApplication.Models.UserDetailViewModel 2 | 3 | @{ 4 | ViewBag.Title = "title"; 5 | Layout = "_Layout"; 6 | } 7 | 8 |

Detail

9 |
10 |
11 | ID 12 |
13 |
14 | @Model.Id 15 |
16 |
17 |
18 |
19 | UserName 20 |
21 |
22 | @Model.UserName 23 |
24 |
25 |
26 |
27 | FirstName 28 |
29 |
30 | @Model.FirstName 31 |
32 |
33 |
34 |
35 | FamilyName 36 |
37 |
38 | @Model.FamilyName 39 |
40 |
41 |
42 |
43 | @Html.ActionLink("Edit", "Edit", "User", new { id = Model.Id }, new { @class = "btn btn-primary" }) 44 |
45 |
46 | @Html.ActionLink("Back", "Index", "User", new { }, new { @class = "btn btn-default" }) 47 |
48 |
-------------------------------------------------------------------------------- /src/WebApplication/Views/User/Edit.cshtml: -------------------------------------------------------------------------------- 1 | @model WebApplication.Models.EditUserViewModel 2 | 3 | @{ 4 | ViewBag.Title = "title"; 5 | Layout = "_Layout"; 6 | } 7 | 8 | 9 |

Edit

10 | @using (Html.BeginForm("Update", "User")) { 11 |
12 |
13 | UserName 14 |
15 |
16 | @Html.TextBoxFor(model => model.UserName) 17 |
18 |
19 |
20 |
21 | FirstName 22 |
23 |
24 | @Html.TextBoxFor(model => model.FirstName) 25 |
26 |
27 |
28 |
29 | FamilyName 30 |
31 |
32 | @Html.TextBoxFor(model => model.FamilyName) 33 |
34 |
35 | @Html.HiddenFor(model => model.Id) 36 | 37 | } -------------------------------------------------------------------------------- /src/WebApplication/Views/User/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Collections.Generic.IEnumerable 2 | 3 | @{ 4 | ViewBag.Title = "title"; 5 | Layout = "_Layout"; 6 | } 7 | 8 |

Index

9 |
10 | @Html.ActionLink( 11 | "New User", 12 | "NewUser", 13 | "User", 14 | new {}, 15 | new {@class = "btn btn-primary" } 16 | ) 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | @foreach (var summary in Model) { 30 | 31 | 32 | 33 | 34 | 35 | 36 | } 37 | 38 |
IDUserName
@summary.Id@summary.UserName@Html.ActionLink("Detail", "Detail", "User", new { id = summary.Id }, new { @class = "btn btn-default" })@Html.ActionLink("Delete", "Delete", "User", new { id = summary.Id }, new { @class = "btn btn-default" })
39 |
40 | -------------------------------------------------------------------------------- /src/WebApplication/Views/User/NewUser.cshtml: -------------------------------------------------------------------------------- 1 | @model WebApplication.Models.RegisterUserViewModel 2 | 3 | @{ 4 | ViewBag.Title = "title"; 5 | Layout = "_Layout"; 6 | } 7 | 8 |

New User

9 | @using (Html.BeginForm("Register","User")) { 10 |
11 |
12 | UserName 13 |
14 |
15 | @Html.TextBoxFor(model => model.UserName) 16 |
17 |
18 |
19 |
20 | FirstName 21 |
22 |
23 | @Html.TextBoxFor(model => model.FirstName) 24 |
25 |
26 |
27 |
28 | FamilyName 29 |
30 |
31 | @Html.TextBoxFor(model => model.FamilyName) 32 |
33 |
34 | 35 | } -------------------------------------------------------------------------------- /src/WebApplication/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using WebApplication 2 | @using WebApplication.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /src/WebApplication/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /src/WebApplication/WebApplication.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/WebApplication/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/WebApplication/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/WebApplication/bundleconfig.json: -------------------------------------------------------------------------------- 1 | // Configure bundling and minification for the project. 2 | // More info at https://go.microsoft.com/fwlink/?LinkId=808241 3 | [ 4 | { 5 | "outputFileName": "wwwroot/css/site.min.css", 6 | // An array of relative input file paths. Globbing patterns supported 7 | "inputFiles": [ 8 | "wwwroot/css/site.css" 9 | ] 10 | }, 11 | { 12 | "outputFileName": "wwwroot/js/site.min.js", 13 | "inputFiles": [ 14 | "wwwroot/js/site.js" 15 | ], 16 | // Optionally specify minification options 17 | "minify": { 18 | "enabled": true, 19 | "renameLocals": true 20 | }, 21 | // Optionally generate .map file 22 | "sourceMap": false 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Wrapping element */ 7 | /* Set some basic padding to keep content from hitting the edges */ 8 | .body-content { 9 | padding-left: 15px; 10 | padding-right: 15px; 11 | } 12 | 13 | /* Carousel */ 14 | .carousel-caption p { 15 | font-size: 20px; 16 | line-height: 1.4; 17 | } 18 | 19 | /* Make .svg files in the carousel display properly in older browsers */ 20 | .carousel-inner .item img[src$=".svg"] { 21 | width: 100%; 22 | } 23 | 24 | /* QR code generator */ 25 | #qrCode { 26 | margin: 15px; 27 | } 28 | 29 | /* Hide/rearrange for smaller screens */ 30 | @media screen and (max-width: 767px) { 31 | /* Hide captions */ 32 | .carousel-caption { 33 | display: none; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | banner3b -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/images/banner4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your JavaScript code. 2 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} 6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */ -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nrslib/BottomUpDDDTheLaterPart/c8d6c081041030f2ad2584750c971857686b3bf6/src/WebApplication/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "version": "3.2.6", 4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", 6 | "main": [ 7 | "jquery.validate.unobtrusive.js" 8 | ], 9 | "ignore": [ 10 | "**/.*", 11 | "*.json", 12 | "*.md", 13 | "*.txt", 14 | "gulpfile.js" 15 | ], 16 | "keywords": [ 17 | "jquery", 18 | "asp.net", 19 | "mvc", 20 | "validation", 21 | "unobtrusive" 22 | ], 23 | "authors": [ 24 | "Microsoft" 25 | ], 26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" 30 | }, 31 | "dependencies": { 32 | "jquery-validation": ">=1.8", 33 | "jquery": ">=1.8" 34 | }, 35 | "_release": "3.2.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.2.6", 39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" 40 | }, 41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", 42 | "_target": "3.2.6", 43 | "_originalSource": "jquery-validation-unobtrusive" 44 | } -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | /*! 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | 6 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ 7 | /*global document: false, jQuery: false */ 8 | 9 | (function ($) { 10 | var $jQval = $.validator, 11 | adapters, 12 | data_validation = "unobtrusiveValidation"; 13 | 14 | function setValidationValues(options, ruleName, value) { 15 | options.rules[ruleName] = value; 16 | if (options.message) { 17 | options.messages[ruleName] = options.message; 18 | } 19 | } 20 | 21 | function splitAndTrim(value) { 22 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 23 | } 24 | 25 | function escapeAttributeValue(value) { 26 | // As mentioned on http://api.jquery.com/category/selectors/ 27 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 28 | } 29 | 30 | function getModelPrefix(fieldName) { 31 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 32 | } 33 | 34 | function appendModelPrefix(value, prefix) { 35 | if (value.indexOf("*.") === 0) { 36 | value = value.replace("*.", prefix); 37 | } 38 | return value; 39 | } 40 | 41 | function onError(error, inputElement) { // 'this' is the form element 42 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 43 | replaceAttrValue = container.attr("data-valmsg-replace"), 44 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 45 | 46 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 47 | error.data("unobtrusiveContainer", container); 48 | 49 | if (replace) { 50 | container.empty(); 51 | error.removeClass("input-validation-error").appendTo(container); 52 | } 53 | else { 54 | error.hide(); 55 | } 56 | } 57 | 58 | function onErrors(event, validator) { // 'this' is the form element 59 | var container = $(this).find("[data-valmsg-summary=true]"), 60 | list = container.find("ul"); 61 | 62 | if (list && list.length && validator.errorList.length) { 63 | list.empty(); 64 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 65 | 66 | $.each(validator.errorList, function () { 67 | $("
  • ").html(this.message).appendTo(list); 68 | }); 69 | } 70 | } 71 | 72 | function onSuccess(error) { // 'this' is the form element 73 | var container = error.data("unobtrusiveContainer"); 74 | 75 | if (container) { 76 | var replaceAttrValue = container.attr("data-valmsg-replace"), 77 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 78 | 79 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 80 | error.removeData("unobtrusiveContainer"); 81 | 82 | if (replace) { 83 | container.empty(); 84 | } 85 | } 86 | } 87 | 88 | function onReset(event) { // 'this' is the form element 89 | var $form = $(this), 90 | key = '__jquery_unobtrusive_validation_form_reset'; 91 | if ($form.data(key)) { 92 | return; 93 | } 94 | // Set a flag that indicates we're currently resetting the form. 95 | $form.data(key, true); 96 | try { 97 | $form.data("validator").resetForm(); 98 | } finally { 99 | $form.removeData(key); 100 | } 101 | 102 | $form.find(".validation-summary-errors") 103 | .addClass("validation-summary-valid") 104 | .removeClass("validation-summary-errors"); 105 | $form.find(".field-validation-error") 106 | .addClass("field-validation-valid") 107 | .removeClass("field-validation-error") 108 | .removeData("unobtrusiveContainer") 109 | .find(">*") // If we were using valmsg-replace, get the underlying error 110 | .removeData("unobtrusiveContainer"); 111 | } 112 | 113 | function validationInfo(form) { 114 | var $form = $(form), 115 | result = $form.data(data_validation), 116 | onResetProxy = $.proxy(onReset, form), 117 | defaultOptions = $jQval.unobtrusive.options || {}, 118 | execInContext = function (name, args) { 119 | var func = defaultOptions[name]; 120 | func && $.isFunction(func) && func.apply(form, args); 121 | } 122 | 123 | if (!result) { 124 | result = { 125 | options: { // options structure passed to jQuery Validate's validate() method 126 | errorClass: defaultOptions.errorClass || "input-validation-error", 127 | errorElement: defaultOptions.errorElement || "span", 128 | errorPlacement: function () { 129 | onError.apply(form, arguments); 130 | execInContext("errorPlacement", arguments); 131 | }, 132 | invalidHandler: function () { 133 | onErrors.apply(form, arguments); 134 | execInContext("invalidHandler", arguments); 135 | }, 136 | messages: {}, 137 | rules: {}, 138 | success: function () { 139 | onSuccess.apply(form, arguments); 140 | execInContext("success", arguments); 141 | } 142 | }, 143 | attachValidation: function () { 144 | $form 145 | .off("reset." + data_validation, onResetProxy) 146 | .on("reset." + data_validation, onResetProxy) 147 | .validate(this.options); 148 | }, 149 | validate: function () { // a validation function that is called by unobtrusive Ajax 150 | $form.validate(); 151 | return $form.valid(); 152 | } 153 | }; 154 | $form.data(data_validation, result); 155 | } 156 | 157 | return result; 158 | } 159 | 160 | $jQval.unobtrusive = { 161 | adapters: [], 162 | 163 | parseElement: function (element, skipAttach) { 164 | /// 165 | /// Parses a single HTML element for unobtrusive validation attributes. 166 | /// 167 | /// The HTML element to be parsed. 168 | /// [Optional] true to skip attaching the 169 | /// validation to the form. If parsing just this single element, you should specify true. 170 | /// If parsing several elements, you should specify false, and manually attach the validation 171 | /// to the form when you are finished. The default is false. 172 | var $element = $(element), 173 | form = $element.parents("form")[0], 174 | valInfo, rules, messages; 175 | 176 | if (!form) { // Cannot do client-side validation without a form 177 | return; 178 | } 179 | 180 | valInfo = validationInfo(form); 181 | valInfo.options.rules[element.name] = rules = {}; 182 | valInfo.options.messages[element.name] = messages = {}; 183 | 184 | $.each(this.adapters, function () { 185 | var prefix = "data-val-" + this.name, 186 | message = $element.attr(prefix), 187 | paramValues = {}; 188 | 189 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 190 | prefix += "-"; 191 | 192 | $.each(this.params, function () { 193 | paramValues[this] = $element.attr(prefix + this); 194 | }); 195 | 196 | this.adapt({ 197 | element: element, 198 | form: form, 199 | message: message, 200 | params: paramValues, 201 | rules: rules, 202 | messages: messages 203 | }); 204 | } 205 | }); 206 | 207 | $.extend(rules, { "__dummy__": true }); 208 | 209 | if (!skipAttach) { 210 | valInfo.attachValidation(); 211 | } 212 | }, 213 | 214 | parse: function (selector) { 215 | /// 216 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 217 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 218 | /// attribute values. 219 | /// 220 | /// Any valid jQuery selector. 221 | 222 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one 223 | // element with data-val=true 224 | var $selector = $(selector), 225 | $forms = $selector.parents() 226 | .addBack() 227 | .filter("form") 228 | .add($selector.find("form")) 229 | .has("[data-val=true]"); 230 | 231 | $selector.find("[data-val=true]").each(function () { 232 | $jQval.unobtrusive.parseElement(this, true); 233 | }); 234 | 235 | $forms.each(function () { 236 | var info = validationInfo(this); 237 | if (info) { 238 | info.attachValidation(); 239 | } 240 | }); 241 | } 242 | }; 243 | 244 | adapters = $jQval.unobtrusive.adapters; 245 | 246 | adapters.add = function (adapterName, params, fn) { 247 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 248 | /// The name of the adapter to be added. This matches the name used 249 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 250 | /// [Optional] An array of parameter names (strings) that will 251 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 252 | /// mmmm is the parameter name). 253 | /// The function to call, which adapts the values from the HTML 254 | /// attributes into jQuery Validate rules and/or messages. 255 | /// 256 | if (!fn) { // Called with no params, just a function 257 | fn = params; 258 | params = []; 259 | } 260 | this.push({ name: adapterName, params: params, adapt: fn }); 261 | return this; 262 | }; 263 | 264 | adapters.addBool = function (adapterName, ruleName) { 265 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 266 | /// the jQuery Validate validation rule has no parameter values. 267 | /// The name of the adapter to be added. This matches the name used 268 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 269 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 270 | /// of adapterName will be used instead. 271 | /// 272 | return this.add(adapterName, function (options) { 273 | setValidationValues(options, ruleName || adapterName, true); 274 | }); 275 | }; 276 | 277 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 278 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 279 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 280 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 281 | /// The name of the adapter to be added. This matches the name used 282 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 283 | /// The name of the jQuery Validate rule to be used when you only 284 | /// have a minimum value. 285 | /// The name of the jQuery Validate rule to be used when you only 286 | /// have a maximum value. 287 | /// The name of the jQuery Validate rule to be used when you 288 | /// have both a minimum and maximum value. 289 | /// [Optional] The name of the HTML attribute that 290 | /// contains the minimum value. The default is "min". 291 | /// [Optional] The name of the HTML attribute that 292 | /// contains the maximum value. The default is "max". 293 | /// 294 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 295 | var min = options.params.min, 296 | max = options.params.max; 297 | 298 | if (min && max) { 299 | setValidationValues(options, minMaxRuleName, [min, max]); 300 | } 301 | else if (min) { 302 | setValidationValues(options, minRuleName, min); 303 | } 304 | else if (max) { 305 | setValidationValues(options, maxRuleName, max); 306 | } 307 | }); 308 | }; 309 | 310 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 311 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 312 | /// the jQuery Validate validation rule has a single value. 313 | /// The name of the adapter to be added. This matches the name used 314 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 315 | /// [Optional] The name of the HTML attribute that contains the value. 316 | /// The default is "val". 317 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 318 | /// of adapterName will be used instead. 319 | /// 320 | return this.add(adapterName, [attribute || "val"], function (options) { 321 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 322 | }); 323 | }; 324 | 325 | $jQval.addMethod("__dummy__", function (value, element, params) { 326 | return true; 327 | }); 328 | 329 | $jQval.addMethod("regex", function (value, element, params) { 330 | var match; 331 | if (this.optional(element)) { 332 | return true; 333 | } 334 | 335 | match = new RegExp(params).exec(value); 336 | return (match && (match.index === 0) && (match[0].length === value.length)); 337 | }); 338 | 339 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 340 | var match; 341 | if (nonalphamin) { 342 | match = value.match(/\W/g); 343 | match = match && match.length >= nonalphamin; 344 | } 345 | return match; 346 | }); 347 | 348 | if ($jQval.methods.extension) { 349 | adapters.addSingleVal("accept", "mimtype"); 350 | adapters.addSingleVal("extension", "extension"); 351 | } else { 352 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 353 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 354 | // validating the extension, and ignore mime-type validations as they are not supported. 355 | adapters.addSingleVal("extension", "extension", "accept"); 356 | } 357 | 358 | adapters.addSingleVal("regex", "pattern"); 359 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 360 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 361 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); 362 | adapters.add("equalto", ["other"], function (options) { 363 | var prefix = getModelPrefix(options.element.name), 364 | other = options.params.other, 365 | fullOtherName = appendModelPrefix(other, prefix), 366 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 367 | 368 | setValidationValues(options, "equalTo", element); 369 | }); 370 | adapters.add("required", function (options) { 371 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 372 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 373 | setValidationValues(options, "required", true); 374 | } 375 | }); 376 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 377 | var value = { 378 | url: options.params.url, 379 | type: options.params.type || "GET", 380 | data: {} 381 | }, 382 | prefix = getModelPrefix(options.element.name); 383 | 384 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 385 | var paramName = appendModelPrefix(fieldName, prefix); 386 | value.data[paramName] = function () { 387 | var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); 388 | // For checkboxes and radio buttons, only pick up values from checked fields. 389 | if (field.is(":checkbox")) { 390 | return field.filter(":checked").val() || field.filter(":hidden").val() || ''; 391 | } 392 | else if (field.is(":radio")) { 393 | return field.filter(":checked").val() || ''; 394 | } 395 | return field.val(); 396 | }; 397 | }); 398 | 399 | setValidationValues(options, "remote", value); 400 | }); 401 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 402 | if (options.params.min) { 403 | setValidationValues(options, "minlength", options.params.min); 404 | } 405 | if (options.params.nonalphamin) { 406 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 407 | } 408 | if (options.params.regex) { 409 | setValidationValues(options, "regex", options.params.regex); 410 | } 411 | }); 412 | 413 | $(function () { 414 | $jQval.unobtrusive.parse(document); 415 | }); 416 | }(jQuery)); -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | !function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery); -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "http://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jzaefferer/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.14.0", 31 | "_release": "1.14.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.14.0", 35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" 36 | }, 37 | "_source": "git://github.com/jzaefferer/jquery-validation.git", 38 | "_target": ">=1.8", 39 | "_originalSource": "jquery-validation" 40 | } -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery-validation/dist/additional-methods.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.14.0 - 6/30/2015 2 | * http://jqueryvalidation.org/ 3 | * Copyright (c) 2015 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g="string"==typeof d?d.replace(/\s/g,"").replace(/,/g,"|"):"image/*",h=this.optional(c);if(h)return h;if("file"===a(c).attr("type")&&(g=g.replace(/\*/g,".*"),c.files&&c.files.length))for(e=0;ec;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a)},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a){"use strict";var b,c,d,e,f,g,h=[];if(a=a.toUpperCase(),!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)"))return!1;for(d=0;9>d;d++)h[d]=parseInt(a.charAt(d),10);for(c=h[2]+h[4]+h[6],e=1;8>e;e+=2)f=(2*h[e]).toString(),g=f.charAt(1),c+=parseInt(f.charAt(0),10)+(""===g?0:parseInt(g,10));return/^[ABCDEFGHJNPQRSUVW]{1}/.test(a)?(c+="",b=10-parseInt(c.charAt(c.length-1),10),a+=b,h[8].toString()===String.fromCharCode(64+b)||h[8].toString()===a.charAt(a.length-1)):!1},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return(10===c||11===c)&&(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;9>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;10>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:128&d?!0:!1},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=e?!0:c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d?!0:!1):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="";if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):/^[XYZ]{1}/.test(a)?a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23):!1:!1},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):/^[KLM]{1}/.test(a)?a[8]===String.fromCharCode(64):!1:!1},"Please specify a valid NIF number."),jQuery.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=e||"undefined"==typeof c.caseSensitive?!1:c.caseSensitive,g=e||"undefined"==typeof c.includeTerritories?!1:c.includeTerritories,h=e||"undefined"==typeof c.includeMilitary?!1:c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;17>b;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,d=d.concat(c.errorList)}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b===this.lastElement)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors();var b,c=this.elements().removeData("previousValue").removeAttr("aria-invalid");if(this.settings.unhighlight)for(b=0;c[b];b++)this.settings.unhighlight.call(this,c[b],this.settings.errorClass,"");else c.removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?this.findByName(b.name).filter(":checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\]|\$)/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.off(".validate-equalTo").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})}); -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "2.2.0", 16 | "_release": "2.2.0", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "2.2.0", 20 | "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5" 21 | }, 22 | "_source": "git://github.com/jquery/jquery-dist.git", 23 | "_target": "2.2.0", 24 | "_originalSource": "jquery" 25 | } -------------------------------------------------------------------------------- /src/WebApplication/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | --------------------------------------------------------------------------------