From e52b4cd47b027b65d1b49b6d5332dc9bab19c4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 14:20:29 +0100 Subject: [PATCH 001/338] Added configuration from json file --- .../Configuration/ClientDataConfiguration.cs | 13 ++ .../Constants/ConfigurationConsts.cs | 4 + .../Configuration/Identity/Claim.cs | 13 ++ .../Configuration/Identity/Role.cs | 10 ++ .../Configuration/Identity/User.cs | 13 ++ .../Interfaces/IClientDataConfiguration.cs | 12 ++ .../Interfaces/IRootConfiguration.cs | 2 + .../Interfaces/IUserDataConfiguration.cs | 11 ++ .../Configuration/RootConfiguration.cs | 13 +- .../Configuration/UserDataConfiguration.cs | 12 ++ .../Helpers/DbMigrationHelpers.cs | 100 ++++++++---- .../Helpers/StartupHelpers.cs | 2 + .../appsettings.json | 154 +++++++++++++++++- 13 files changed, 311 insertions(+), 48 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Role.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/User.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs new file mode 100644 index 000000000..0ed877735 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs @@ -0,0 +1,13 @@ +using IdentityServer4.Models; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration +{ + public class ClientDataConfiguration : IClientDataConfiguration + { + public List Clients { get; set; } = new List(); + public List IdentityResources { get; set; } = new List(); + public List ApiResources { get; set; } = new List(); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs index 984a75912..885b085d9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs @@ -15,5 +15,9 @@ public class ConfigurationConsts public const string ResourcesPath = "Resources"; public const string AdminConfigurationKey = "AdminConfiguration"; + + public const string ClientDataConfigurationKey = "ClientData"; + + public const string UserDataConfigurationKey = "UserData"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs new file mode 100644 index 000000000..8bb9d41e5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Identity +{ + public class Claim + { + public string Type { get; set; } + public string Value { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Role.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Role.cs new file mode 100644 index 000000000..c4757232e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Role.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Identity +{ + public class Role + { + public string Name { get; set; } + public List Claims { get; set; } = new List(); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/User.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/User.cs new file mode 100644 index 000000000..5d71184bd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/User.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Identity +{ + public class User + { + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } + public List Claims { get; set; } = new List(); + public List Roles { get; set; } = new List(); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs new file mode 100644 index 000000000..e5a0274bb --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs @@ -0,0 +1,12 @@ +using IdentityServer4.Models; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces +{ + public interface IClientDataConfiguration + { + List Clients { get; set; } + List IdentityResources { get; set; } + List ApiResources { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs index 190fe5366..150d684f8 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs @@ -3,5 +3,7 @@ public interface IRootConfiguration { IAdminConfiguration AdminConfiguration { get; } + IUserDataConfiguration UserDataConfiguration { get; } + IClientDataConfiguration ClientDataConfiguration { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs new file mode 100644 index 000000000..36d2018e1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs @@ -0,0 +1,11 @@ +using Skoruba.IdentityServer4.Admin.Configuration.Identity; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces +{ + public interface IUserDataConfiguration + { + List Roles { get; set; } + List Users { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs index a659c55ff..2924ae275 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; namespace Skoruba.IdentityServer4.Admin.Configuration @@ -10,10 +6,15 @@ namespace Skoruba.IdentityServer4.Admin.Configuration public class RootConfiguration : IRootConfiguration { public IAdminConfiguration AdminConfiguration { get; set; } + public IUserDataConfiguration UserDataConfiguration { get; set; } + public IClientDataConfiguration ClientDataConfiguration { get; set; } - public RootConfiguration(IOptions adminConfiguration) + public RootConfiguration(IOptions adminConfiguration, IOptions clientConfiguration, + IOptions userConfiguration) { AdminConfiguration = adminConfiguration.Value; + UserDataConfiguration = userConfiguration.Value; + ClientDataConfiguration = clientConfiguration.Value; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs new file mode 100644 index 000000000..d14143d80 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs @@ -0,0 +1,12 @@ +using Skoruba.IdentityServer4.Admin.Configuration.Identity; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration +{ + public class UserDataConfiguration : IUserDataConfiguration + { + public List Roles { get; set; } + public List Users { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 2b06acb83..0173a3ecf 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using IdentityModel; using IdentityServer4.EntityFramework.Mappers; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; @@ -80,8 +81,8 @@ public static async Task EnsureSeedData( var roleManager = scope.ServiceProvider.GetRequiredService>(); var rootConfiguration = scope.ServiceProvider.GetRequiredService(); - await EnsureSeedIdentityServerData(context, rootConfiguration.AdminConfiguration); - await EnsureSeedIdentityData(userManager, roleManager); + await EnsureSeedIdentityServerData(context, rootConfiguration.AdminConfiguration, rootConfiguration.ClientDataConfiguration); + await EnsureSeedIdentityData(userManager, roleManager, rootConfiguration.UserDataConfiguration); } } @@ -89,69 +90,98 @@ public static async Task EnsureSeedData( /// Generate default admin user / role /// private static async Task EnsureSeedIdentityData(UserManager userManager, - RoleManager roleManager) + RoleManager roleManager, IUserDataConfiguration userDataConfiguration) where TUser : IdentityUser, new() where TRole : IdentityRole, new() { - // Create admin role - if (!await roleManager.RoleExistsAsync(AuthorizationConsts.AdministrationRole)) - { - var role = new TRole { Name = AuthorizationConsts.AdministrationRole }; - - await roleManager.CreateAsync(role); + if (! await roleManager.Roles.AnyAsync()) { + // adding roles from seed + foreach (var r in userDataConfiguration.Roles) + { + if (! await roleManager.RoleExistsAsync(r.Name)) + { + var role = new TRole + { + Name = r.Name + }; + + var res = await roleManager.CreateAsync(role); + + if (res.Succeeded) + { + foreach (var c in r.Claims) + { + await roleManager.AddClaimAsync(role, new System.Security.Claims.Claim(c.Type, c.Value)); + } + } + } + } } - // Create admin user - if (await userManager.FindByNameAsync(Users.AdminUserName) != null) return; - - var user = new TUser - { - UserName = Users.AdminUserName, - Email = Users.AdminEmail, - EmailConfirmed = true - }; - - var result = await userManager.CreateAsync(user, Users.AdminPassword); - - if (result.Succeeded) + if (!await userManager.Users.AnyAsync()) { - await userManager.AddToRoleAsync(user, AuthorizationConsts.AdministrationRole); + // adding users from seed + foreach (var u in userDataConfiguration.Users) + { + var us = new TUser + { + UserName = u.Username, + Email = u.Email, + EmailConfirmed = true + }; + + var res = await userManager.CreateAsync(us, u.Password); + if (res.Succeeded) + { + foreach (var c in u.Claims) + { + await userManager.AddClaimAsync(us, new System.Security.Claims.Claim(c.Type, c.Value)); + } + + foreach (var r in u.Roles) + { + await userManager.AddToRoleAsync(us, r); + } + } + } } } /// /// Generate default clients, identity and api resources /// - private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IAdminConfiguration adminConfiguration) + private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IAdminConfiguration adminConfiguration, IClientDataConfiguration clientDataConfiguration) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext { - if (!context.Clients.Any()) + if (!context.IdentityResources.Any()) { - foreach (var client in Clients.GetAdminClient(adminConfiguration).ToList()) + foreach (var resource in clientDataConfiguration.IdentityResources) { - await context.Clients.AddAsync(client.ToEntity()); + await context.IdentityResources.AddAsync(resource.ToEntity()); } await context.SaveChangesAsync(); } - if (!context.IdentityResources.Any()) + if (!context.ApiResources.Any()) { - var identityResources = ClientResources.GetIdentityResources().ToList(); - - foreach (var resource in identityResources) + foreach (var resource in clientDataConfiguration.ApiResources) { - await context.IdentityResources.AddAsync(resource.ToEntity()); + await context.ApiResources.AddAsync(resource.ToEntity()); } await context.SaveChangesAsync(); } - if (!context.ApiResources.Any()) + if (!context.Clients.Any()) { - foreach (var resource in ClientResources.GetApiResources().ToList()) + foreach (var client in clientDataConfiguration.Clients) { - await context.ApiResources.AddAsync(resource.ToEntity()); + foreach (var secret in client.ClientSecrets) + { + secret.Value = secret.Value.ToSha256(); + } + await context.Clients.AddAsync(client.ToEntity()); } await context.SaveChangesAsync(); diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 958b397cd..4f75563a4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -478,6 +478,8 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect services.AddOptions(); services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); + services.Configure(configuration.GetSection(ConfigurationConsts.UserDataConfigurationKey)); + services.Configure(configuration.GetSection(ConfigurationConsts.ClientDataConfigurationKey)); services.TryAddSingleton(); diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index c1b74714b..e80e53f63 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -1,10 +1,10 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" - }, + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, "AdminConfiguration": { "IdentityAdminBaseUrl": "http://localhost:9000", "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", @@ -37,7 +37,7 @@ { "Name": "MSSqlServer", "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "connectionString": "Data Source=NORDIC-WALKING;Initial Catalog=IdentityAdmin;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", "tableName": "Log", "columnOptionsSection": { "addStandardColumns": [ "LogEvent" ], @@ -46,5 +46,145 @@ } } ] + }, + "UserData": { + "Roles": [ + { + "Name": "SkorubaIdentityAdminAdministrator" + } + ], + "Users": [ + { + "Username": "administrator", + "Password": "Pa$$word123", + "Email": "admin@example.com", + "Roles": [ + "SkorubaIdentityAdminAdministrator" + ], + "Claims": [ + { + "Type": "name", + "Value": "Administrator" + } + ] + } + ] + }, + "ClientData": { + "IdentityResources": [ + { + "Name": "roles", + "Enabled": true, + "DisplayName": "Roles", + "UserClaims": [ + "role" + ] + }, + { + "Name": "openid", + "Enabled": true, + "Required": true, + "DisplayName": "Your user identifier", + "UserClaims": [ + "sub" + ] + }, + { + "Name": "profile", + "Enabled": true, + "DisplayName": "User profile", + "Description": "Your user profile information (first name, last name, etc.)", + "Emphasize": true, + "UserClaims": [ + "name", + "family_name", + "given_name", + "middle_name", + "nickname", + "preferred_username", + "profile", + "picture", + "website", + "gender", + "birthdate", + "zoneinfo", + "locale", + "updated_at" + ] + }, + { + "Name": "email", + "Enabled": true, + "DisplayName": "Your email address", + "Emphasize": true, + "UserClaims": [ + "email", + "email_verified" + ] + }, + { + "Name": "address", + "Enabled": true, + "DisplayName": "Your address", + "Emphasize": true, + "UserClaims": [ + "address" + ] + } + ], + "ApiResources": [ + { + "Name": "api1", + "DisplayName" : "Some API 1" + }, + { + "Name": "api2", + "UserClaims": [ + "name", + "email" + ], + "Scopes": [ + { + "Name": "api2.full_access", + "DisplayName": "Full access to API 2" + }, + { + "Name": "api2.read_only", + "DisplayName": "Read only access to API 2" + } + ] + } + ], + "Clients": [ + { + "ClientId": "skoruba_identity_admin", + "ClientName": "skoruba_identity_admin", + "ClientUri": "http://localhost:9000", + "AllowedGrantTypes": [ + "hybrid" + ], + "ClientSecrets": [ + { + "Value": "skoruba_admin_client_secret" + } + ], + "RedirectUris": [ + "http://localhost:9000/signin-oidc" + ], + "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", + "PostLogoutRedirectUris": [ + "http://localhost:9000/signout-callback-oidc" + ], + "AllowedCorsOrigins": [ + "http://localhost:9000" + ], + "AllowedScopes": [ + "openid", + "email", + "profile", + "roles" + ] + } + ] } } \ No newline at end of file From a3100d279d6ffeb68ba7dde1ac435cb7c297522c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 14:29:43 +0100 Subject: [PATCH 002/338] Added hashing secret for api resources --- .../Helpers/DbMigrationHelpers.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 0173a3ecf..bf98b6dd9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -167,6 +167,11 @@ private static async Task EnsureSeedIdentityServerData { foreach (var resource in clientDataConfiguration.ApiResources) { + foreach (var s in resource.ApiSecrets) + { + s.Value = s.Value.ToSha256(); + } + await context.ApiResources.AddAsync(resource.ToEntity()); } From c7df0e87b9db11cc46d49c375ca247a3f21e0254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 14:37:14 +0100 Subject: [PATCH 003/338] Removed no longer required hardcoded configuration --- .../Configuration/IdentityServer/Clients.cs | 318 ------------------ .../Configuration/IdentityServer/Resources.cs | 70 ---- .../Helpers/DbMigrationHelpers.cs | 4 - 3 files changed, 392 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Clients.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Resources.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Clients.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Clients.cs deleted file mode 100644 index e0f8888e1..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Clients.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System.Collections.Generic; -using IdentityModel; -using IdentityServer4; -using IdentityServer4.Models; -using Skoruba.IdentityServer4.Admin.Configuration.Constants; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; - -namespace Skoruba.IdentityServer4.Admin.Configuration.IdentityServer - -{ - public class Clients - { - - public static IEnumerable GetAdminClient(IAdminConfiguration adminConfiguration) - { - - return new List - { - - /////////////////////////////////////////// - // Skoruba.IdentityServer4.Admin Client - ////////////////////////////////////////// - new Client - { - - ClientId =adminConfiguration.ClientId, - ClientName =adminConfiguration.ClientId, - ClientUri = adminConfiguration.IdentityAdminBaseUrl, - - AllowedGrantTypes = GrantTypes.Hybrid, - - ClientSecrets = new List - { - new Secret(adminConfiguration.ClientSecret.ToSha256()) - }, - - RedirectUris = { $"{adminConfiguration.IdentityAdminBaseUrl}/signin-oidc"}, - FrontChannelLogoutUri = $"{adminConfiguration.IdentityAdminBaseUrl}/signout-oidc", - PostLogoutRedirectUris = { $"{adminConfiguration.IdentityAdminBaseUrl}/signout-callback-oidc"}, - AllowedCorsOrigins = { adminConfiguration.IdentityAdminBaseUrl }, - - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Profile, - IdentityServerConstants.StandardScopes.Email, - "roles" - } - }, - - }; - - } - - - public static IEnumerable Get() - { - return new List - { - /////////////////////////////////////////// - // Console Client Credentials Flow Sample - ////////////////////////////////////////// - new Client - { - ClientId = "client", - ClientSecrets = - { - new Secret("secret".Sha256()) - }, - - AllowedGrantTypes = GrantTypes.ClientCredentials, - AllowedScopes = { "api1", "api2.read_only" } - }, - - /////////////////////////////////////////// - // Console Client Credentials Flow with client JWT assertion - ////////////////////////////////////////// - new Client - { - ClientId = "client.jwt", - ClientSecrets = - { - new Secret - { - Type = IdentityServerConstants.SecretTypes.X509CertificateBase64, - Value = "MIIDATCCAe2gAwIBAgIQoHUYAquk9rBJcq8W+F0FAzAJBgUrDgMCHQUAMBIxEDAOBgNVBAMTB0RldlJvb3QwHhcNMTAwMTIwMjMwMDAwWhcNMjAwMTIwMjMwMDAwWjARMQ8wDQYDVQQDEwZDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSaY4x1eXqjHF1iXQcF3pbFrIbmNw19w/IdOQxbavmuPbhY7jX0IORu/GQiHjmhqWt8F4G7KGLhXLC1j7rXdDmxXRyVJBZBTEaSYukuX7zGeUXscdpgODLQVay/0hUGz54aDZPAhtBHaYbog+yH10sCXgV1Mxtzx3dGelA6pPwiAmXwFxjJ1HGsS/hdbt+vgXhdlzud3ZSfyI/TJAnFeKxsmbJUyqMfoBl1zFKG4MOvgHhBjekp+r8gYNGknMYu9JDFr1ue0wylaw9UwG8ZXAkYmYbn2wN/CpJl3gJgX42/9g87uLvtVAmz5L+rZQTlS1ibv54ScR2lcRpGQiQav/LAgMBAAGjXDBaMBMGA1UdJQQMMAoGCCsGAQUFBwMCMEMGA1UdAQQ8MDqAENIWANpX5DZ3bX3WvoDfy0GhFDASMRAwDgYDVQQDEwdEZXZSb290ghAsWTt7E82DjU1E1p427Qj2MAkGBSsOAwIdBQADggEBADLje0qbqGVPaZHINLn+WSM2czZk0b5NG80btp7arjgDYoWBIe2TSOkkApTRhLPfmZTsaiI3Ro/64q+Dk3z3Kt7w+grHqu5nYhsn7xQFAQUf3y2KcJnRdIEk0jrLM4vgIzYdXsoC6YO+9QnlkNqcN36Y8IpSVSTda6gRKvGXiAhu42e2Qey/WNMFOL+YzMXGt/nDHL/qRKsuXBOarIb++43DV3YnxGTx22llhOnPpuZ9/gnNY7KLjODaiEciKhaKqt/b57mTEz4jTF4kIg6BP03MUfDXeVlM1Qf1jB43G2QQ19n5lUiqTpmQkcfLfyci2uBZ8BkOhXr3Vk9HIk/xBXQ=" - } - }, - - AllowedGrantTypes = GrantTypes.ClientCredentials, - AllowedScopes = { "api1", "api2.read_only" } - }, - - /////////////////////////////////////////// - // Custom Grant Sample - ////////////////////////////////////////// - new Client - { - ClientId = "client.custom", - ClientSecrets = - { - new Secret("secret".Sha256()) - }, - - AllowedScopes = { "api1", "api2.read_only" } - }, - - /////////////////////////////////////////// - // Console Resource Owner Flow Sample - ////////////////////////////////////////// - new Client - { - ClientId = "roclient", - ClientSecrets = - { - new Secret("secret".Sha256()) - }, - - AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, - - AllowOfflineAccess = true, - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - "custom.profile", - "api1", "api2.read_only" - } - }, - - /////////////////////////////////////////// - // Console Public Resource Owner Flow Sample - ////////////////////////////////////////// - new Client - { - ClientId = "roclient.public", - RequireClientSecret = false, - - AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, - - AllowOfflineAccess = true, - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" - } - }, - - /////////////////////////////////////////// - // Console Hybrid with PKCE Sample - ////////////////////////////////////////// - new Client - { - ClientId = "console.hybrid.pkce", - ClientName = "Console Hybrid with PKCE Sample", - RequireClientSecret = false, - - AllowedGrantTypes = GrantTypes.Hybrid, - RequirePkce = true, - - RedirectUris = { "http://127.0.0.1:7890/" }, - - AllowOfflineAccess = true, - - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Profile, - IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only", - }, - }, - - /////////////////////////////////////////// - // Introspection Client Sample - ////////////////////////////////////////// - new Client - { - ClientId = "roclient.reference", - ClientSecrets = - { - new Secret("secret".Sha256()) - }, - - AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, - AllowedScopes = { "api1", "api2.read_only" }, - - AccessTokenType = AccessTokenType.Reference - }, - - /////////////////////////////////////////// - // MVC Implicit Flow Samples - ////////////////////////////////////////// - new Client - { - - ClientId = "mvc.implicit", - ClientName = "MVC Implicit", - ClientUri = "http://identityserver.io", - - AllowedGrantTypes = GrantTypes.Implicit, - AllowAccessTokensViaBrowser = true, - - RedirectUris = { "http://localhost:44077/signin-oidc" }, - FrontChannelLogoutUri = "http://localhost:44077/signout-oidc", - PostLogoutRedirectUris = { "http://localhost:44077/signout-callback-oidc" }, - - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Profile, - IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" - }, - }, - - /////////////////////////////////////////// - // MVC Manual Implicit Flow Sample - ////////////////////////////////////////// - new Client - { - ClientId = "mvc.manual", - ClientName = "MVC Manual", - ClientUri = "http://identityserver.io", - - AllowedGrantTypes = GrantTypes.Implicit, - RedirectUris = { "http://localhost:44077/home/callback" }, - FrontChannelLogoutUri = "http://localhost:44077/signout-oidc", - PostLogoutRedirectUris = { "http://localhost:44077/" }, - - AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId }, - }, - - /////////////////////////////////////////// - // MVC Hybrid Flow Samples - ////////////////////////////////////////// - new Client - { - ClientId = "mvc.hybrid", - ClientName = "MVC Hybrid", - ClientUri = "http://identityserver.io", - - ClientSecrets = - { - new Secret("secret".Sha256()) - }, - - AllowedGrantTypes = GrantTypes.Hybrid, - AllowAccessTokensViaBrowser = false, - - RedirectUris = { "http://localhost:21402/signin-oidc" }, - FrontChannelLogoutUri = "http://localhost:21402/signout-oidc", - PostLogoutRedirectUris = { "http://localhost:21402/signout-callback-oidc" }, - - AllowOfflineAccess = true, - - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Profile, - IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only", - }, - }, - - /////////////////////////////////////////// - // JS OAuth 2.0 Sample - ////////////////////////////////////////// - new Client - { - ClientId = "js_oauth", - ClientName = "JavaScript OAuth 2.0 Client", - ClientUri = "http://identityserver.io", - - AllowedGrantTypes = GrantTypes.Implicit, - AllowAccessTokensViaBrowser = true, - - RedirectUris = { "http://localhost:28895/index.html" }, - AllowedScopes = { "api1", "api2.read_only" }, - }, - - /////////////////////////////////////////// - // JS OIDC Sample - ////////////////////////////////////////// - new Client - { - ClientId = "js_oidc", - ClientName = "JavaScript OIDC Client", - ClientUri = "http://identityserver.io", - - AllowedGrantTypes = GrantTypes.Implicit, - AllowAccessTokensViaBrowser = true, - RequireClientSecret = false, - AccessTokenType = AccessTokenType.Reference, - - RedirectUris = - { - "http://localhost:7017/index.html", - "http://localhost:7017/callback.html", - "http://localhost:7017/silent.html", - "http://localhost:7017/popup.html", - }, - - PostLogoutRedirectUris = { "http://localhost:7017/index.html" }, - AllowedCorsOrigins = { "http://localhost:7017" }, - - AllowedScopes = - { - IdentityServerConstants.StandardScopes.OpenId, - IdentityServerConstants.StandardScopes.Profile, - IdentityServerConstants.StandardScopes.Email, - "api1", "api2.read_only" - }, - }, - }; - } - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Resources.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Resources.cs deleted file mode 100644 index b33603dc5..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Resources.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Collections.Generic; -using IdentityModel; -using IdentityServer4.Models; - -namespace Skoruba.IdentityServer4.Admin.Configuration.IdentityServer -{ - public class ClientResources - { - public static IEnumerable GetIdentityResources() - { - return new[] - { - // some standard scopes from the OIDC spec - new IdentityResources.OpenId(), - new IdentityResources.Profile(), - new IdentityResources.Email(), - - // custom identity resource with some consolidated claims - new IdentityResource("custom.profile", new[] { JwtClaimTypes.Name, JwtClaimTypes.Email, "location" }), - - // add additional identity resource - new IdentityResource("roles", "Roles", new[] { "role" }) - }; - } - - public static IEnumerable GetApiResources() - { - return new[] - { - // simple version with ctor - new ApiResource("api1", "Some API 1") - { - // this is needed for introspection when using reference tokens - ApiSecrets = { new Secret("secret".Sha256()) } - }, - - // expanded version if more control is needed - new ApiResource - { - Name = "api2", - - ApiSecrets = - { - new Secret("secret".Sha256()) - }, - - UserClaims = - { - JwtClaimTypes.Name, - JwtClaimTypes.Email - }, - - Scopes = - { - new Scope() - { - Name = "api2.full_access", - DisplayName = "Full access to API 2", - }, - new Scope - { - Name = "api2.read_only", - DisplayName = "Read only access to API 2" - } - } - } - }; - } - } -} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index bf98b6dd9..15ed3cd4f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -5,12 +5,8 @@ using IdentityServer4.EntityFramework.Mappers; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; -using Skoruba.IdentityServer4.Admin.Configuration.Constants; -using Skoruba.IdentityServer4.Admin.Configuration.Identity; -using Skoruba.IdentityServer4.Admin.Configuration.IdentityServer; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; From daa616c3621b0f74cc687efb5ecdde12e8d4c588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 14:56:43 +0100 Subject: [PATCH 004/338] Removed unnecessary info from codebase that is already in appsettings.json --- .../Configuration/AdminConfiguration.cs | 14 +++++++------- .../Constants/AuthenticationConsts.cs | 14 ++------------ .../Helpers/DbMigrationHelpers.cs | 4 ++-- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index e1ee4a057..4331017bb 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -5,15 +5,15 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { public class AdminConfiguration : IAdminConfiguration { - public string IdentityAdminBaseUrl { get; set; } = "http://localhost:9000"; + public string IdentityAdminBaseUrl { get; set; } - public string IdentityAdminRedirectUri { get; set; } = "http://localhost:9000/signin-oidc"; + public string IdentityAdminRedirectUri { get; set; } - public string IdentityServerBaseUrl { get; set; } = "http://localhost:5000"; - public string ClientId { get; set; } = AuthenticationConsts.OidcClientId; - public string[] Scopes { get; set; } = AuthenticationConsts.Scopes.ToArray(); - public string ClientSecret { get; set; } = AuthenticationConsts.OidcClientSecret; - public string OidcResponseType { get; set; } = AuthenticationConsts.OidcResponseType; + public string IdentityServerBaseUrl { get; set; } + public string ClientId { get; set; } + public string[] Scopes { get; set; } + public string ClientSecret { get; set; } + public string OidcResponseType { get; set; } = AuthenticationConsts.OidcAuthenticationScheme; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs index 26b1e4e08..588a02873 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs @@ -1,22 +1,12 @@ -using System.Collections.Generic; - -namespace Skoruba.IdentityServer4.Admin.Configuration.Constants +namespace Skoruba.IdentityServer4.Admin.Configuration.Constants { public class AuthenticationConsts { public const string IdentityAdminCookieName = "IdentityServerAdmin"; public const string UserNameClaimType = "name"; public const string SignInScheme = "Cookies"; - public const string OidcClientId = "skoruba_identity_admin"; - public const string OidcClientSecret = "skoruba_admin_client_secret"; - public const string OidcAuthenticationScheme = "oidc"; - public const string OidcResponseType = "code id_token"; - public static List Scopes = new List { ScopeOpenId, ScopeProfile, ScopeEmail, ScopeRoles }; - public const string ScopeOpenId = "openid"; - public const string ScopeProfile = "profile"; - public const string ScopeEmail = "email"; - public const string ScopeRoles = "roles"; + public const string OidcAuthenticationScheme = "oidc"; public const string RoleClaim = "role"; diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 15ed3cd4f..642fa345e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -77,7 +77,7 @@ public static async Task EnsureSeedData( var roleManager = scope.ServiceProvider.GetRequiredService>(); var rootConfiguration = scope.ServiceProvider.GetRequiredService(); - await EnsureSeedIdentityServerData(context, rootConfiguration.AdminConfiguration, rootConfiguration.ClientDataConfiguration); + await EnsureSeedIdentityServerData(context, rootConfiguration.ClientDataConfiguration); await EnsureSeedIdentityData(userManager, roleManager, rootConfiguration.UserDataConfiguration); } } @@ -146,7 +146,7 @@ private static async Task EnsureSeedIdentityData(UserManager /// Generate default clients, identity and api resources /// - private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IAdminConfiguration adminConfiguration, IClientDataConfiguration clientDataConfiguration) + private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IClientDataConfiguration clientDataConfiguration) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext { if (!context.IdentityResources.Any()) From d26ebada6bfce8744e4c21e035b1e079f19b2d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 15:31:52 +0100 Subject: [PATCH 005/338] The name of default role is now configurable --- .../Configuration/AdminConfiguration.cs | 2 +- .../Configuration/Constants/AuthorizationConsts.cs | 1 - .../Configuration/Interfaces/IAdminConfiguration.cs | 2 ++ .../Configuration/Interfaces/IClientDataConfiguration.cs | 6 +++--- .../Configuration/Interfaces/IUserDataConfiguration.cs | 4 ++-- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 4 ++-- .../Middlewares/AuthenticatedTestRequestMiddleware.cs | 1 + src/Skoruba.IdentityServer4.Admin/Startup.cs | 2 +- src/Skoruba.IdentityServer4.Admin/appsettings.json | 3 ++- .../Common/HttpClientExtensions.cs | 2 +- 10 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index 4331017bb..1a3d525c1 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -14,7 +14,7 @@ public class AdminConfiguration : IAdminConfiguration public string[] Scopes { get; set; } public string ClientSecret { get; set; } public string OidcResponseType { get; set; } = AuthenticationConsts.OidcAuthenticationScheme; - + public string AdministrationRole { get; set; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthorizationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthorizationConsts.cs index 823cf2a9d..e66cc84fd 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthorizationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthorizationConsts.cs @@ -3,6 +3,5 @@ public class AuthorizationConsts { public const string AdministrationPolicy = "RequireAdministratorRole"; - public const string AdministrationRole = "SkorubaIdentityAdminAdministrator"; } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs index 97d5b0436..59fdcefcb 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs @@ -11,5 +11,7 @@ public interface IAdminConfiguration string ClientSecret { get; } string OidcResponseType { get; } string[] Scopes { get; } + + string AdministrationRole { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs index e5a0274bb..ec0785fb7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs @@ -5,8 +5,8 @@ namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { public interface IClientDataConfiguration { - List Clients { get; set; } - List IdentityResources { get; set; } - List ApiResources { get; set; } + List Clients { get; } + List IdentityResources { get; } + List ApiResources { get; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs index 36d2018e1..901e86721 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs @@ -5,7 +5,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { public interface IUserDataConfiguration { - List Roles { get; set; } - List Users { get; set; } + List Roles { get; } + List Users { get; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 4f75563a4..6599f6396 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -291,12 +291,12 @@ public static void AddDbContexts /// - public static void AddAuthorizationPolicies(this IServiceCollection services) + public static void AddAuthorizationPolicies(this IServiceCollection services, IRootConfiguration rootConfiguration) { services.AddAuthorization(options => { options.AddPolicy(AuthorizationConsts.AdministrationPolicy, - policy => policy.RequireRole(AuthorizationConsts.AdministrationRole)); + policy => policy.RequireRole(rootConfiguration.AdminConfiguration.AdministrationRole)); }); } diff --git a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs index 654060372..65f529221 100644 --- a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs +++ b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs @@ -14,6 +14,7 @@ public class AuthenticatedTestRequestMiddleware public const string TestUserId = "UserId"; public const string TestUserName = "UserName"; public const string TestUserRoles = "UserRoles"; + public const string TestAdministrationRole = "SkorubaIdentityAdminAdministrator"; public AuthenticatedTestRequestMiddleware(RequestDelegate next) { diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 9207f6388..5b39f1dce 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -76,7 +76,7 @@ public void ConfigureServices(IServiceCollection services) RoleClaimsDto>(); // Add authorization policies for MVC - services.AddAuthorizationPolicies(); + services.AddAuthorizationPolicies(rootConfiguration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index e80e53f63..2b2f873a6 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -17,7 +17,8 @@ "profile", "email", "roles" - ] + ], + "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, "Serilog": { "MinimumLevel": { diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs index 92ed63eaa..832548ee5 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs @@ -10,7 +10,7 @@ public static void SetAdminClaimsViaHeaders(this HttpClient client) { client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserId}", "1"); client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserName}", "test"); - client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserRoles}", AuthorizationConsts.AdministrationRole); + client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserRoles}", AuthenticatedTestRequestMiddleware.TestAdministrationRole); } } From aba54d1ede44850afc78a43a39e4bfd881742b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 15:34:00 +0100 Subject: [PATCH 006/338] Removed unused constant field --- .../Configuration/Constants/AuthenticationConsts.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs index 588a02873..312b5f468 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs @@ -3,7 +3,6 @@ public class AuthenticationConsts { public const string IdentityAdminCookieName = "IdentityServerAdmin"; - public const string UserNameClaimType = "name"; public const string SignInScheme = "Cookies"; public const string OidcAuthenticationScheme = "oidc"; From 03d12497f7199ca5ba24f753f216c3fe233ca8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 27 Mar 2019 15:52:15 +0100 Subject: [PATCH 007/338] Also adjustible admin role in STS --- .../Configuration/Identity/Claim.cs | 7 +------ .../Configuration/AdminConfiguration.cs | 3 ++- .../Configuration/Constants/AddressClaimConstants.cs | 7 +------ .../Configuration/Constants/AuthorizationConsts.cs | 1 - .../Configuration/Intefaces/IAdminConfiguration.cs | 1 + .../Helpers/StartupHelpers.cs | 5 +++-- src/Skoruba.IdentityServer4.STS.Identity/Startup.cs | 4 +++- src/Skoruba.IdentityServer4.STS.Identity/appsettings.json | 7 ++++--- 8 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs index 8bb9d41e5..0336d4ae9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Claim.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Skoruba.IdentityServer4.Admin.Configuration.Identity +namespace Skoruba.IdentityServer4.Admin.Configuration.Identity { public class Claim { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs index fa1c26181..e2943bd55 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs @@ -4,6 +4,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.Configuration { public class AdminConfiguration : IAdminConfiguration { - public string IdentityAdminBaseUrl { get; set; } = "http://localhost:9000"; + public string IdentityAdminBaseUrl { get; set; } + public string AdministrationRole { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AddressClaimConstants.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AddressClaimConstants.cs index f20769253..a2f0f6e28 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AddressClaimConstants.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AddressClaimConstants.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Constants +namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Constants { public static class AddressClaimConstants { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AuthorizationConsts.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AuthorizationConsts.cs index dc5c69b1f..eef49070b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AuthorizationConsts.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/AuthorizationConsts.cs @@ -3,6 +3,5 @@ public class AuthorizationConsts { public const string AdministrationPolicy = "RequireAdministratorRole"; - public const string AdministrationRole = "SkorubaIdentityAdminAdministrator"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs index 4bcf9dec8..caf9a144b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs @@ -3,5 +3,6 @@ public interface IAdminConfiguration { string IdentityAdminBaseUrl { get; } + string AdministrationRole { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 2301fd899..74946ccc0 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -424,12 +424,13 @@ public static void AddLogging(this IApplicationBuilder app, ILoggerFactory logge /// Add authorization policies /// /// - public static void AddAuthorizationPolicies(this IServiceCollection services) + public static void AddAuthorizationPolicies(this IServiceCollection services, + IRootConfiguration rootConfiguration) { services.AddAuthorization(options => { options.AddPolicy(AuthorizationConsts.AdministrationPolicy, - policy => policy.RequireRole(AuthorizationConsts.AdministrationRole)); + policy => policy.RequireRole(rootConfiguration.AdminConfiguration.AdministrationRole)); }); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index a138daf30..50e2c4e79 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using Skoruba.IdentityServer4.Admin.EntityFramework.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Entities.Identity; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; using Skoruba.IdentityServer4.STS.Identity.Helpers; namespace Skoruba.IdentityServer4.STS.Identity @@ -52,7 +53,8 @@ public void ConfigureServices(IServiceCollection services) services.AddMvcWithLocalization(); // Add authorization policies for MVC - services.AddAuthorizationPolicies(); + var rootConfiguration = services.BuildServiceProvider().GetService(); + services.AddAuthorizationPolicies(rootConfiguration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 590e9fdc8..443843b33 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -66,7 +66,8 @@ "LoginConfiguration": { "ResolutionPolicy": "Username" }, - "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000" - } + "AdminConfiguration": { + "IdentityAdminBaseUrl": "http://localhost:9000", + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + } } \ No newline at end of file From 51042b75f3f5d25e9aaa62d583318a76e129c7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 17 Apr 2019 22:07:05 +0200 Subject: [PATCH 008/338] Minor update allowing for seeding users without passwords attached --- .../Helpers/DbMigrationHelpers.cs | 6 ++- .../appsettings.json | 37 ++++--------------- .../appsettings.json | 4 +- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 642fa345e..d7911ff40 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -126,7 +126,11 @@ private static async Task EnsureSeedIdentityData(UserManager", "OidcResponseType": "code id_token", "Scopes": [ "openid", @@ -18,7 +18,7 @@ "email", "roles" ], - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + "AdministrationRole": "Global Administrator" }, "Serilog": { "MinimumLevel": { @@ -51,7 +51,7 @@ "UserData": { "Roles": [ { - "Name": "SkorubaIdentityAdminAdministrator" + "Name": "Global Administrator" } ], "Users": [ @@ -60,7 +60,7 @@ "Password": "Pa$$word123", "Email": "admin@example.com", "Roles": [ - "SkorubaIdentityAdminAdministrator" + "Global Administrator" ], "Claims": [ { @@ -134,39 +134,18 @@ } ], "ApiResources": [ - { - "Name": "api1", - "DisplayName" : "Some API 1" - }, - { - "Name": "api2", - "UserClaims": [ - "name", - "email" - ], - "Scopes": [ - { - "Name": "api2.full_access", - "DisplayName": "Full access to API 2" - }, - { - "Name": "api2.read_only", - "DisplayName": "Read only access to API 2" - } - ] - } ], "Clients": [ { - "ClientId": "skoruba_identity_admin", - "ClientName": "skoruba_identity_admin", + "ClientId": "sybilla_identity_admin", + "ClientName": "sybilla_identity_admin", "ClientUri": "http://localhost:9000", "AllowedGrantTypes": [ "hybrid" ], "ClientSecrets": [ { - "Value": "skoruba_admin_client_secret" + "Value": "" } ], "RedirectUris": [ diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 443843b33..07e4c0bc3 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -64,10 +64,10 @@ "Password": "" }, "LoginConfiguration": { - "ResolutionPolicy": "Username" + "ResolutionPolicy": "Email" }, "AdminConfiguration": { "IdentityAdminBaseUrl": "http://localhost:9000", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + "AdministrationRole": "Global Administrator " } } \ No newline at end of file From 9a7ca0d414a783a4382542048d97bcdc6bd21294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 17 Apr 2019 22:34:57 +0200 Subject: [PATCH 009/338] Simplified integration tests --- src/Skoruba.IdentityServer4.Admin/Program.cs | 7 ++-- .../Common/TestFixture.cs | 40 ------------------- .../Common/WebApplicationFactoryExtensions.cs | 24 +++++++++++ ...ntityServer4.Admin.IntegrationTests.csproj | 1 + .../Tests/ConfigurationControllerTests.cs | 7 ++-- .../Tests/GrantControllerTests.cs | 7 ++-- .../Tests/HomeControllerTests.cs | 7 ++-- .../Tests/IdentityControllerTests.cs | 7 ++-- .../Tests/LogControllerTests.cs | 7 ++-- .../Common/TestFixture.cs | 40 ------------------- .../Common/WebApplicationFactoryExtensions.cs | 26 ++++++++++++ ...rver4.STS.Identity.IntegrationTests.csproj | 1 + .../Tests/AccountControllerTests.cs | 7 ++-- .../Tests/DiagnosticsControllerTests.cs | 7 ++-- .../Tests/GrantsControllerTests.cs | 7 ++-- .../Tests/HomeControllerTests.cs | 7 ++-- .../Tests/IdentityServerTests.cs | 7 ++-- .../Tests/ManageControllerTests.cs | 7 ++-- 18 files changed, 99 insertions(+), 117 deletions(-) delete mode 100644 tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/TestFixture.cs create mode 100644 tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs delete mode 100644 tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/TestFixture.cs create mode 100644 tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index b72b21317..d87e6e982 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -18,7 +18,7 @@ public static async Task Main(string[] args) var seed = args.Any(x => x == SeedArgs); if (seed) args = args.Except(new[] { SeedArgs }).ToArray(); - var host = BuildWebHost(args); + var host = CreateWebHostBuilder(args).Build(); // Uncomment this to seed upon startup, alternatively pass in `dotnet run /seed` to seed using CLI // await DbMigrationHelpers.EnsureSeedData(host); @@ -30,11 +30,10 @@ public static async Task Main(string[] args) host.Run(); } - public static IWebHost BuildWebHost(string[] args) => + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseKestrel(c => c.AddServerHeader = false) .UseStartup() - .UseSerilog() - .Build(); + .UseSerilog(); } } \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/TestFixture.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/TestFixture.cs deleted file mode 100644 index 3cc834cd0..000000000 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/TestFixture.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.TestHost; - -namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Common -{ - public class TestFixture : IDisposable - { - private readonly TestServer _testServer; - - public HttpClient Client { get; } - - public TestFixture() - { - var builder = new WebHostBuilder() - .UseContentRoot(GetContentRootPath()) - .UseEnvironment(EnvironmentName.Staging) - .UseStartup(); - - _testServer = new TestServer(builder); - Client = _testServer.CreateClient(); - } - - private string GetContentRootPath() - { - var testProjectPath = AppContext.BaseDirectory; - const string relativePathToWebProject = @"../../../../../src/Skoruba.IdentityServer4.Admin/"; - - return Path.Combine(testProjectPath, relativePathToWebProject); - } - - public void Dispose() - { - Client.Dispose(); - _testServer.Dispose(); - } - } -} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs new file mode 100644 index 000000000..76ad9fe6b --- /dev/null +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -0,0 +1,24 @@ +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; + +namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Common +{ + public static class WebApplicationFactoryExtensions + { + public static HttpClient SetupClient(this WebApplicationFactory fixture) + { + var options = new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false + }; + + return fixture.WithWebHostBuilder( + builder => builder + .UseEnvironment(EnvironmentName.Staging) + .ConfigureTestServices(services => { }) + ).CreateClient(options); + } + } +} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj index f67d01e34..74883d67a 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj @@ -13,6 +13,7 @@ runtime; build; native; contentfiles; analyzers + diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs index 6abb32b71..e6c3dcd0c 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class ConfigurationControllerTests : IClassFixture + public class ConfigurationControllerTests : IClassFixture> { private readonly HttpClient _client; - public ConfigurationControllerTests(TestFixture fixture) + public ConfigurationControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs index ce00b9e1f..c89e9f2ba 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class GrantControllerTests : IClassFixture + public class GrantControllerTests : IClassFixture> { private readonly HttpClient _client; - public GrantControllerTests(TestFixture fixture) + public GrantControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs index 7d7d48ecd..da33a23d1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class HomeControllerTests : IClassFixture + public class HomeControllerTests : IClassFixture> { private readonly HttpClient _client; - public HomeControllerTests(TestFixture fixture) + public HomeControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs index 0ee7dd83d..04e7dc219 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class IdentityControllerTests : IClassFixture + public class IdentityControllerTests : IClassFixture> { private readonly HttpClient _client; - public IdentityControllerTests(TestFixture fixture) + public IdentityControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs index df5422c1e..373464bff 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class LogControllerTests : IClassFixture + public class LogControllerTests : IClassFixture> { private readonly HttpClient _client; - public LogControllerTests(TestFixture fixture) + public LogControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/TestFixture.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/TestFixture.cs deleted file mode 100644 index f7ace86a3..000000000 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/TestFixture.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.TestHost; - -namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common -{ - public class TestFixture : IDisposable - { - private readonly TestServer _testServer; - - public HttpClient Client { get; } - - public TestFixture() - { - var builder = new WebHostBuilder() - .UseContentRoot(GetContentRootPath()) - .UseEnvironment(EnvironmentName.Staging) - .UseStartup(); - - _testServer = new TestServer(builder); - Client = _testServer.CreateClient(); - } - - private string GetContentRootPath() - { - var testProjectPath = AppContext.BaseDirectory; - const string relativePathToWebProject = @"../../../../../src/Skoruba.IdentityServer4.STS.Identity/"; - - return Path.Combine(testProjectPath, relativePathToWebProject); - } - - public void Dispose() - { - Client.Dispose(); - _testServer.Dispose(); - } - } -} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs new file mode 100644 index 000000000..9b962e782 --- /dev/null +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; + +namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common +{ + public static class WebApplicationFactoryExtensions + { + public static HttpClient SetupClient(this WebApplicationFactory fixture) + { + var options = new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false + }; + + return fixture.WithWebHostBuilder( + builder => builder + .UseEnvironment(EnvironmentName.Staging) + .ConfigureTestServices(services => { }) + ).CreateClient(options); + } + } +} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj index 2b4c67b05..79886eb54 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj @@ -11,6 +11,7 @@ + diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs index 55ef4eac9..1653485b2 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs @@ -6,19 +6,20 @@ using System.Threading.Tasks; using FluentAssertions; using HtmlAgilityPack; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class AccountControllerTests : IClassFixture + public class AccountControllerTests : IClassFixture> { private readonly HttpClient _client; - public AccountControllerTests(TestFixture fixture) + public AccountControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs index 9d514ed49..4d46d437e 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs @@ -2,18 +2,19 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class DiagnosticsControllerTests : IClassFixture + public class DiagnosticsControllerTests : IClassFixture> { private readonly HttpClient _client; - public DiagnosticsControllerTests(TestFixture fixture) + public DiagnosticsControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs index 5877cad47..0126ffb70 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class GrantsControllerTests : IClassFixture + public class GrantsControllerTests : IClassFixture> { private readonly HttpClient _client; - public GrantsControllerTests(TestFixture fixture) + public GrantsControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs index 80bff894d..db00a321d 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs @@ -2,18 +2,19 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class HomeControllerTests : IClassFixture + public class HomeControllerTests : IClassFixture> { private readonly HttpClient _client; - public HomeControllerTests(TestFixture fixture) + public HomeControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs index 766571c49..a4a5d12e4 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs @@ -2,18 +2,19 @@ using System.Threading.Tasks; using FluentAssertions; using IdentityModel.Client; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class IdentityServerTests : IClassFixture + public class IdentityServerTests : IClassFixture> { private readonly HttpClient _client; - public IdentityServerTests(TestFixture fixture) + public IdentityServerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs index aa30c9828..ba95638c6 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs @@ -2,19 +2,20 @@ using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class ManageControllerTests : IClassFixture + public class ManageControllerTests : IClassFixture> { private readonly HttpClient _client; - public ManageControllerTests(TestFixture fixture) + public ManageControllerTests(WebApplicationFactory factory) { - _client = fixture.Client; + _client = factory.SetupClient(); } [Fact] From 01f79c60367724ab55ba00539abd105ef4e5a6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Wed, 17 Apr 2019 22:07:05 +0200 Subject: [PATCH 010/338] Minor update allowing for seeding users without passwords attached --- .../Helpers/DbMigrationHelpers.cs | 6 ++- .../appsettings.json | 37 ++++--------------- .../appsettings.json | 4 +- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 642fa345e..d7911ff40 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -126,7 +126,11 @@ private static async Task EnsureSeedIdentityData(UserManager", "OidcResponseType": "code id_token", "Scopes": [ "openid", @@ -18,7 +18,7 @@ "email", "roles" ], - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + "AdministrationRole": "Global Administrator" }, "Serilog": { "MinimumLevel": { @@ -51,7 +51,7 @@ "UserData": { "Roles": [ { - "Name": "SkorubaIdentityAdminAdministrator" + "Name": "Global Administrator" } ], "Users": [ @@ -60,7 +60,7 @@ "Password": "Pa$$word123", "Email": "admin@example.com", "Roles": [ - "SkorubaIdentityAdminAdministrator" + "Global Administrator" ], "Claims": [ { @@ -134,39 +134,18 @@ } ], "ApiResources": [ - { - "Name": "api1", - "DisplayName" : "Some API 1" - }, - { - "Name": "api2", - "UserClaims": [ - "name", - "email" - ], - "Scopes": [ - { - "Name": "api2.full_access", - "DisplayName": "Full access to API 2" - }, - { - "Name": "api2.read_only", - "DisplayName": "Read only access to API 2" - } - ] - } ], "Clients": [ { - "ClientId": "skoruba_identity_admin", - "ClientName": "skoruba_identity_admin", + "ClientId": "sybilla_identity_admin", + "ClientName": "sybilla_identity_admin", "ClientUri": "http://localhost:9000", "AllowedGrantTypes": [ "hybrid" ], "ClientSecrets": [ { - "Value": "skoruba_admin_client_secret" + "Value": "" } ], "RedirectUris": [ diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 443843b33..07e4c0bc3 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -64,10 +64,10 @@ "Password": "" }, "LoginConfiguration": { - "ResolutionPolicy": "Username" + "ResolutionPolicy": "Email" }, "AdminConfiguration": { "IdentityAdminBaseUrl": "http://localhost:9000", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + "AdministrationRole": "Global Administrator " } } \ No newline at end of file From 9c89779a0d7ba9b1b2cd50639c6c1b6f1a059eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Thu, 18 Apr 2019 00:48:32 +0200 Subject: [PATCH 011/338] Simplified integration tests for admin server --- .../AuthenticatedTestRequestMiddleware.cs | 47 +++---------------- .../Common/HttpClientExtensions.cs | 18 +++++-- 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs index 654060372..9e9971f09 100644 --- a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs +++ b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -9,12 +9,7 @@ namespace Skoruba.IdentityServer4.Admin.Middlewares public class AuthenticatedTestRequestMiddleware { private readonly RequestDelegate _next; - - public const string TestUserPrefixHeader = "TestUser"; - public const string TestUserId = "UserId"; - public const string TestUserName = "UserName"; - public const string TestUserRoles = "UserRoles"; - + public static readonly string TestAuthorizationHeader = "FakeAuthorization"; public AuthenticatedTestRequestMiddleware(RequestDelegate next) { _next = next; @@ -22,46 +17,16 @@ public AuthenticatedTestRequestMiddleware(RequestDelegate next) public async Task Invoke(HttpContext context) { - if (context.Request.Headers.Keys.Contains($"{TestUserPrefixHeader}-{TestUserName}")) + if (context.Request.Headers.Keys.Contains(TestAuthorizationHeader)) { - var name = - context.Request.Headers[$"{TestUserPrefixHeader}-{TestUserName}"].First(); - - var id = - context.Request.Headers.Keys.Contains($"{TestUserPrefixHeader}-{TestUserId}") - ? context.Request.Headers[$"{TestUserPrefixHeader}-{TestUserId}"].First() : string.Empty; - - var claims = new List - { - new Claim(ClaimTypes.Name, name), - new Claim(ClaimTypes.NameIdentifier, id), - }; - - AddRoles(context, claims); - - var claimsIdentity = new ClaimsIdentity(claims, "Cookies"); - + var token = context.Request.Headers[TestAuthorizationHeader].Single(); + var jwt = new JwtSecurityToken(token); + var claimsIdentity = new ClaimsIdentity(jwt.Claims, "Cookies"); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); context.User = claimsPrincipal; } await _next(context); } - - private void AddRoles(HttpContext context, List claims) - { - var roles = context.Request.Headers.Keys.Contains($"{TestUserPrefixHeader}-{TestUserRoles}") - ? context.Request.Headers[$"{TestUserPrefixHeader}-{TestUserRoles}"].First() - : string.Empty; - - var rolesList = new List(); - - if (!string.IsNullOrEmpty(roles)) - { - rolesList.AddRange(roles.Split(',')); - } - - claims.AddRange(rolesList.Select(role => new Claim(ClaimTypes.Role, role))); - } } } \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs index 92ed63eaa..7b577bdd1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs @@ -1,4 +1,6 @@ -using System.Net.Http; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; +using System.Security.Claims; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Middlewares; @@ -8,10 +10,16 @@ public static class HttpClientExtensions { public static void SetAdminClaimsViaHeaders(this HttpClient client) { - client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserId}", "1"); - client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserName}", "test"); - client.DefaultRequestHeaders.Add($"{AuthenticatedTestRequestMiddleware.TestUserPrefixHeader}-{AuthenticatedTestRequestMiddleware.TestUserRoles}", AuthorizationConsts.AdministrationRole); - } + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, "1"), + new Claim(ClaimTypes.Name, "test"), + new Claim(ClaimTypes.Role, AuthorizationConsts.AdministrationRole) + }; + var token = new JwtSecurityToken(claims: claims); + var t = new JwtSecurityTokenHandler().WriteToken(token); + client.DefaultRequestHeaders.Add(AuthenticatedTestRequestMiddleware.TestAuthorizationHeader, t); + } } } From 3327d3186d0c1e8d7ea81f252c16548b98d0ea43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Drza=C5=82?= Date: Sat, 1 Jun 2019 22:01:53 +0200 Subject: [PATCH 012/338] Fixed importing client claims --- .../Configuration/ClientDataConfiguration.cs | 2 +- .../Configuration/Identity/Client.cs | 9 +++++++++ .../Configuration/Interfaces/IClientDataConfiguration.cs | 2 +- .../Helpers/DbMigrationHelpers.cs | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs index 0ed877735..314179c68 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs @@ -6,7 +6,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { public class ClientDataConfiguration : IClientDataConfiguration { - public List Clients { get; set; } = new List(); + public List Clients { get; set; } = new List(); public List IdentityResources { get; set; } = new List(); public List ApiResources { get; set; } = new List(); } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs new file mode 100644 index 000000000..8525f0513 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Identity +{ + public class Client: global::IdentityServer4.Models.Client + { + public List ClientClaims { get; set; } = new List(); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs index ec0785fb7..610bd9e32 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs @@ -5,7 +5,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { public interface IClientDataConfiguration { - List Clients { get; } + List Clients { get; } List IdentityResources { get; } List ApiResources { get; } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index d7911ff40..152cdccd6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -186,6 +186,11 @@ private static async Task EnsureSeedIdentityServerData { secret.Value = secret.Value.ToSha256(); } + + client.Claims = client.ClientClaims + .Select(c => new System.Security.Claims.Claim(c.Type, c.Value)) + .ToList(); + await context.Clients.AddAsync(client.ToEntity()); } From c7b984a08f877fe698359236a3a3b433f6b2b986 Mon Sep 17 00:00:00 2001 From: Sebastian Gingter Date: Thu, 27 Jun 2019 13:43:39 +0200 Subject: [PATCH 013/338] Fixed writing accesses that bypass manager classes --- .../Repositories/IdentityRepository.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs index a38813cb3..c7210e95f 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs @@ -284,18 +284,20 @@ public virtual async Task CreateRoleClaimsAsync(TRoleClaim claim public virtual async Task DeleteUserClaimsAsync(string userId, int claimId) { + var user = await UserManager.FindByIdAsync(userId).ConfigureAwait(false);; var userClaim = await DbContext.Set().Where(x => x.Id == claimId).SingleOrDefaultAsync(); - DbContext.UserClaims.Remove(userClaim); + await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue)).ConfigureAwait(false); return await AutoSaveChangesAsync(); } public virtual async Task DeleteRoleClaimsAsync(string roleId, int claimId) { + var role = await RoleManager.FindByIdAsync(roleId).ConfigureAwait(false); var roleClaim = await DbContext.Set().Where(x => x.Id == claimId).SingleOrDefaultAsync(); - DbContext.Set().Remove(roleClaim); + await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue)).ConfigureAwait(false); return await AutoSaveChangesAsync(); } From 8a1cf8e39d83ccc384757793e57f9fa177e43bfc Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Wed, 17 Jul 2019 12:05:03 +0200 Subject: [PATCH 014/338] Update _Layout.cshtml Now in the logged out view the Logout button is replaced by the Login button. --- .../Views/Shared/_Layout.cshtml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml index 2c9afaf9b..2c83d3917 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml @@ -41,9 +41,8 @@ From df22e05f5557dc1f404c533ff41f4150c0146a41 Mon Sep 17 00:00:00 2001 From: Carl Quirion Date: Wed, 14 Aug 2019 11:23:56 -0400 Subject: [PATCH 136/338] Add language support to DatePicker --- .../Scripts/App/components/DatePicker.js | 41 ++++++++++++++++++- src/Skoruba.IdentityServer4.Admin/gulpfile.js | 5 +++ .../wwwroot/dist/js/bundle.min.js | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js index 097f5b243..868d0460d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js @@ -1,11 +1,48 @@ -$(function() { +$(function () { var adminDatePicker = { + getCookie: function getCookie(cname) { + var name = cname + '='; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1); + } + if (c.indexOf(name) === 0) { + return c.substring(name.length, c.length); + } + } + return ''; + }, + getUiCultureFromAspNetCoreCultureCookie: function () { + var cookieValue = decodeURIComponent(this.getCookie('.AspNetCore.Culture')); + if (cookieValue === null || cookieValue === '') return null; + var parameters = cookieValue.split('|'); + for (var i = 0; i < parameters.length; i++) { + if (parameters[i].indexOf('=') !== -1) { + var p = parameters[i].split('='); + if (p[0] === 'uic') { + return p[1]; + } + } + } + return null; + }, + getLanguage: function () { + //Defaults to en if no UiCulture found. + var language = this.getUiCultureFromAspNetCoreCultureCookie() || 'en'; + // bootstrap DatePicker supports Taiwanese chinese as well as Mainland. + // Defaults to Mainland as we currently have no way of specifying variants. + if (language === 'zh') language = 'zh-CN'; + return language; + }, initDatePickers: function () { $('.datepicker').datepicker({ autoclose: true, - todayHighlight: true + todayHighlight: true, + language: getLanguage() }); } diff --git a/src/Skoruba.IdentityServer4.Admin/gulpfile.js b/src/Skoruba.IdentityServer4.Admin/gulpfile.js index 43fe75177..9be522d23 100644 --- a/src/Skoruba.IdentityServer4.Admin/gulpfile.js +++ b/src/Skoruba.IdentityServer4.Admin/gulpfile.js @@ -27,6 +27,11 @@ function processScripts() { './node_modules/moment/min/moment.min.js', './node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.js', './node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fa.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fr.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.ru.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.sv.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.zh-CN.min.js', './Scripts/App/components/Menu.js', './Scripts/App/components/Picker.es5.js', './Scripts/App/components/Theme.js', diff --git a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js index 0eccbf27d..4d4921b80 100644 --- a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js +++ b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js @@ -1 +1 @@ -if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,E=le(),S=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Ee(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Se(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Se(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(St+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=Et,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(E.settings.themes[e]=t),delete E.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[E.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(E.settings,e);E.vars.preempted=!0,E.vars.dataAttr=d.dataAttr||E.setup.dataAttr,c.renderer=d.renderer?d.renderer:E.setup.renderer,-1===E.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=E.setup.supportsSVG?"svg":E.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(E.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(E.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},E={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(E.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){E.vars.cache.themeKeys=E.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=E.vars.cache.themeKeys[0|Math.random()*E.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?E.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return S.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!S.a.Lb(e,S.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return S.onError?function(){try{return e.apply(this,arguments)}catch(e){throw S.onError&&S.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(S.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw S.onError&&S.onError(e),e},0)},H:function(t,e,n){var i=S.a.zc(n);if(n=u[e],S.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),S.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==S.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),S.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return S.N(e)?e():e},$b:function(e){return S.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],S.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=S.a.c(t);null!==n&&n!==hna||(n="");var i=S.h.firstChild(e);!i||3!=i.nodeType||S.h.nextSibling(i)?S.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,S.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=S.a.c(e),t=S.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n",""],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=S.a.W<=8,S.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=S.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=S.a.la(o.lastChild.childNodes)}return n},S.a.Ld=function(e,t){var n=S.a.ta(e,t);return n.length&&n[0].parentElement||S.a.Xb(n)},S.a.dc=function(e,t){if(S.a.Sb(e),null!==(t=S.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=S.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return S.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return S.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&S.eb(n,i,t)})}}),S.b("__tr_ambtns",S.ic.ld),function(){S.B={},S.B.D=function(e){if(this.D=e){var t=S.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},S.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?S.a.dc(this.D,t):this.D[e]=t};var t=S.a.g.Z()+"_";S.B.D.prototype.data=function(e){if(1===arguments.length)return S.a.g.get(this.D,t+e);S.a.g.set(this.D,t+e,arguments[1])};var i=S.a.g.Z();S.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=S.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=S.a.Ld(t,e.ownerDocument),this.text(""),S.a.g.set(e,i,{jb:n,hd:!0})),n}S.a.g.set(e,i,{jb:arguments[0]})},S.B.ia=function(e){this.D=e},S.B.ia.prototype=new S.B.D,S.B.ia.prototype.constructor=S.B.ia,S.B.ia.prototype.text=function(){if(0==arguments.length){var e=S.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}S.a.g.set(this.D,i,{jc:arguments[0]})},S.b("templateSources",S.B),S.b("templateSources.domElement",S.B.D),S.b("templateSources.anonymousTemplate",S.B.ia)}(),function(){function i(e,t,n){var i;for(t=S.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=S.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=S.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),S.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.aa.bd(e,[t])}),S.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])E("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(E("").append(E("").addClass("prev").attr("data-action","previous").append(E("").addClass(this._options.icons.previous))).append(E("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(E("").addClass("next").attr("data-action","next").append(E("").addClass(this._options.icons.next)))),t=E("").append(E("").append(E("").attr("colspan",this._options.calendarWeeks?"8":"7")));return[E("
    ").addClass("datepicker-days").append(E("").addClass("table table-sm").append(e).append(E(""))),E("
    ").addClass("datepicker-months").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-years").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-decades").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},S.prototype._getTimePickerMainTemplate=function(){var e=E(""),t=E(""),n=E("");return this._isEnabled("h")&&(e.append(E("").append(S("").append(S("").append(S("
    ").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(E("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(E("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(E("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(E("").addClass("separator")),t.append(E("").append(E("").addClass("separator"))),E("
    ").addClass("timepicker-picker").append(E("").addClass("table-condensed").append([e,t,n]))},S.prototype._getTimePickerTemplate=function(){var e=E("
    ").addClass("timepicker-hours").append(E("
    ").addClass("table-condensed")),t=E("
    ").addClass("timepicker-minutes").append(E("
    ").addClass("table-condensed")),n=E("
    ").addClass("timepicker-seconds").append(E("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},S.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(E("
    ").append(E("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(E("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(E("").addClass(n))))}return this._options.buttons.showClear&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(E("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(E("").addClass(this._options.icons.close)))),0===e.length?"":E("").addClass("table-condensed").append(E("").append(E("").append(e)))},S.prototype._getTemplate=function(){var e=E("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=E("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=E("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=E("
      ").addClass("list-unstyled"),r=E("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(E("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},S.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=E(window).height()+E(window).scrollTop()&&t.widget.height()+t._element.outerHeight()E(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===E(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},S.prototype._fillDow=function(){var e=E("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(E(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},S.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=E("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},S.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=E("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=E(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},S.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=E("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=E(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},S.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},S.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(E(e.currentTarget).is(".disabled"))return!1;switch(t=t||E(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=E(e.target).closest("tbody").find("span").index(E(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(E(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(E(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();E(e.target).is(".old")&&l.subtract(1,"M"),E(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(E(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=E(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(E(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},S.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=E(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),E(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},S.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),E(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",E.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},S.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},S.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},S.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},S.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},S.prototype.widgetPositioning=function(e){if(0===arguments.length)return E.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},S.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=E(e)),null!==e&&"string"!=typeof e&&!(e instanceof E))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},S._jQueryHandleThis=function(e,t,n){var i=E(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&E.extend({},T.Default,t),i||(i=new S(E(e),t),E(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},S._jQueryInterface=function(e,t){return 1===this.length?S._jQueryHandleThis(this[0],e,t):this.each(function(){S._jQueryHandleThis(this,e,t)})},C=S,E(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(E(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),E.fn[T.NAME]=C._jQueryInterface,E.fn[T.NAME].Constructor=C,E.fn[T.NAME].noConflict=function(){return E.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=E(t)).length||n.data(T.DATA_KEY)||E.extend({},n.data(),E(this).data()),n}function S(e,t){a(this,S);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(S,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&S.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){S.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=S(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=S(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=S.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==S.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==S.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=S.isFunction(S.uniqueSort)?S.uniqueSort(y):S.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(S.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=S(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=S(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=S(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){S.data(e,"datepicker",this),this.element=S(e),this.inputs=S.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(S(this.inputs),t).on("changeDate",S.proxy(this.dateUpdated,this)),this.pickers=S.map(this.inputs,function(e){return S.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=S.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=S.map(this.dates,function(e){return e.valueOf()});S.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){S.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=S.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=S.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(S.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){S.map(this.pickers,function(e){e.destroy()}),S(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=S.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=S(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=S(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return S.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(S.extend({},c,i,n).language),a=S.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(S.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=S(v).filter(function(e,t){return-1!==S.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(E("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},S.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(E("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},S.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||E(this).addClass("disabled")})},S.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},S.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},S.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},S.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=E("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",S.fn.datepicker.DPGlobal=I,S.fn.datepicker.noConflict=function(){return S.fn.datepicker=i,this},S.fn.datepicker.version="1.9.0",S.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},S(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=S(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),S(function(){r.call(S('[data-provide="datepicker-inline"]'))})});var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0})})()}); \ No newline at end of file +if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(E("").append(E("").append(E("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0,language:getLanguage()})})()}); \ No newline at end of file From af7ed0805f1079b378bd459365ca3dbedc8a314c Mon Sep 17 00:00:00 2001 From: Carl Quirion Date: Wed, 14 Aug 2019 11:23:56 -0400 Subject: [PATCH 137/338] Add language support to DatePicker --- .../Scripts/App/components/DatePicker.js | 41 ++++++++++++++++++- src/Skoruba.IdentityServer4.Admin/gulpfile.js | 5 +++ .../wwwroot/dist/js/bundle.min.js | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js index 097f5b243..868d0460d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js @@ -1,11 +1,48 @@ -$(function() { +$(function () { var adminDatePicker = { + getCookie: function getCookie(cname) { + var name = cname + '='; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1); + } + if (c.indexOf(name) === 0) { + return c.substring(name.length, c.length); + } + } + return ''; + }, + getUiCultureFromAspNetCoreCultureCookie: function () { + var cookieValue = decodeURIComponent(this.getCookie('.AspNetCore.Culture')); + if (cookieValue === null || cookieValue === '') return null; + var parameters = cookieValue.split('|'); + for (var i = 0; i < parameters.length; i++) { + if (parameters[i].indexOf('=') !== -1) { + var p = parameters[i].split('='); + if (p[0] === 'uic') { + return p[1]; + } + } + } + return null; + }, + getLanguage: function () { + //Defaults to en if no UiCulture found. + var language = this.getUiCultureFromAspNetCoreCultureCookie() || 'en'; + // bootstrap DatePicker supports Taiwanese chinese as well as Mainland. + // Defaults to Mainland as we currently have no way of specifying variants. + if (language === 'zh') language = 'zh-CN'; + return language; + }, initDatePickers: function () { $('.datepicker').datepicker({ autoclose: true, - todayHighlight: true + todayHighlight: true, + language: getLanguage() }); } diff --git a/src/Skoruba.IdentityServer4.Admin/gulpfile.js b/src/Skoruba.IdentityServer4.Admin/gulpfile.js index 43fe75177..9be522d23 100644 --- a/src/Skoruba.IdentityServer4.Admin/gulpfile.js +++ b/src/Skoruba.IdentityServer4.Admin/gulpfile.js @@ -27,6 +27,11 @@ function processScripts() { './node_modules/moment/min/moment.min.js', './node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.js', './node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fa.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fr.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.ru.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.sv.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.zh-CN.min.js', './Scripts/App/components/Menu.js', './Scripts/App/components/Picker.es5.js', './Scripts/App/components/Theme.js', diff --git a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js index 0eccbf27d..4d4921b80 100644 --- a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js +++ b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js @@ -1 +1 @@ -if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,E=le(),S=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Ee(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Se(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Se(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(St+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=Et,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(E.settings.themes[e]=t),delete E.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[E.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(E.settings,e);E.vars.preempted=!0,E.vars.dataAttr=d.dataAttr||E.setup.dataAttr,c.renderer=d.renderer?d.renderer:E.setup.renderer,-1===E.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=E.setup.supportsSVG?"svg":E.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(E.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(E.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},E={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(E.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){E.vars.cache.themeKeys=E.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=E.vars.cache.themeKeys[0|Math.random()*E.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?E.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return S.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!S.a.Lb(e,S.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return S.onError?function(){try{return e.apply(this,arguments)}catch(e){throw S.onError&&S.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(S.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw S.onError&&S.onError(e),e},0)},H:function(t,e,n){var i=S.a.zc(n);if(n=u[e],S.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),S.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==S.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),S.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return S.N(e)?e():e},$b:function(e){return S.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],S.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=S.a.c(t);null!==n&&n!==hna||(n="");var i=S.h.firstChild(e);!i||3!=i.nodeType||S.h.nextSibling(i)?S.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,S.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=S.a.c(e),t=S.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=S.a.W<=8,S.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=S.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=S.a.la(o.lastChild.childNodes)}return n},S.a.Ld=function(e,t){var n=S.a.ta(e,t);return n.length&&n[0].parentElement||S.a.Xb(n)},S.a.dc=function(e,t){if(S.a.Sb(e),null!==(t=S.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=S.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return S.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return S.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&S.eb(n,i,t)})}}),S.b("__tr_ambtns",S.ic.ld),function(){S.B={},S.B.D=function(e){if(this.D=e){var t=S.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},S.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?S.a.dc(this.D,t):this.D[e]=t};var t=S.a.g.Z()+"_";S.B.D.prototype.data=function(e){if(1===arguments.length)return S.a.g.get(this.D,t+e);S.a.g.set(this.D,t+e,arguments[1])};var i=S.a.g.Z();S.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=S.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=S.a.Ld(t,e.ownerDocument),this.text(""),S.a.g.set(e,i,{jb:n,hd:!0})),n}S.a.g.set(e,i,{jb:arguments[0]})},S.B.ia=function(e){this.D=e},S.B.ia.prototype=new S.B.D,S.B.ia.prototype.constructor=S.B.ia,S.B.ia.prototype.text=function(){if(0==arguments.length){var e=S.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}S.a.g.set(this.D,i,{jc:arguments[0]})},S.b("templateSources",S.B),S.b("templateSources.domElement",S.B.D),S.b("templateSources.anonymousTemplate",S.B.ia)}(),function(){function i(e,t,n){var i;for(t=S.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=S.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=S.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),S.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.aa.bd(e,[t])}),S.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])E("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(E("
    ").addClass("prev").attr("data-action","previous").append(E("").addClass(this._options.icons.previous))).append(E("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(E("").addClass("next").attr("data-action","next").append(E("").addClass(this._options.icons.next)))),t=E("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[E("
    ").addClass("datepicker-days").append(E("").addClass("table table-sm").append(e).append(E(""))),E("
    ").addClass("datepicker-months").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-years").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-decades").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},S.prototype._getTimePickerMainTemplate=function(){var e=E(""),t=E(""),n=E("");return this._isEnabled("h")&&(e.append(E("").append(S("").append(S("").append(S("
    ").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(E("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(E("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(E("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(E("").addClass("separator")),t.append(E("").append(E("").addClass("separator"))),E("
    ").addClass("timepicker-picker").append(E("").addClass("table-condensed").append([e,t,n]))},S.prototype._getTimePickerTemplate=function(){var e=E("
    ").addClass("timepicker-hours").append(E("
    ").addClass("table-condensed")),t=E("
    ").addClass("timepicker-minutes").append(E("
    ").addClass("table-condensed")),n=E("
    ").addClass("timepicker-seconds").append(E("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},S.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(E("
    ").append(E("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(E("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(E("").addClass(n))))}return this._options.buttons.showClear&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(E("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(E("").addClass(this._options.icons.close)))),0===e.length?"":E("").addClass("table-condensed").append(E("").append(E("").append(e)))},S.prototype._getTemplate=function(){var e=E("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=E("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=E("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=E("
      ").addClass("list-unstyled"),r=E("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(E("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},S.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=E(window).height()+E(window).scrollTop()&&t.widget.height()+t._element.outerHeight()E(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===E(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},S.prototype._fillDow=function(){var e=E("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(E(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},S.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=E("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},S.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=E("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=E(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},S.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=E("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=E(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},S.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},S.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(E(e.currentTarget).is(".disabled"))return!1;switch(t=t||E(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=E(e.target).closest("tbody").find("span").index(E(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(E(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(E(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();E(e.target).is(".old")&&l.subtract(1,"M"),E(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(E(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=E(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(E(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},S.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=E(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),E(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},S.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),E(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",E.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},S.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},S.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},S.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},S.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},S.prototype.widgetPositioning=function(e){if(0===arguments.length)return E.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},S.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=E(e)),null!==e&&"string"!=typeof e&&!(e instanceof E))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},S._jQueryHandleThis=function(e,t,n){var i=E(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&E.extend({},T.Default,t),i||(i=new S(E(e),t),E(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},S._jQueryInterface=function(e,t){return 1===this.length?S._jQueryHandleThis(this[0],e,t):this.each(function(){S._jQueryHandleThis(this,e,t)})},C=S,E(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(E(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),E.fn[T.NAME]=C._jQueryInterface,E.fn[T.NAME].Constructor=C,E.fn[T.NAME].noConflict=function(){return E.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=E(t)).length||n.data(T.DATA_KEY)||E.extend({},n.data(),E(this).data()),n}function S(e,t){a(this,S);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(S,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&S.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){S.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=S(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=S(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=S.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==S.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==S.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=S.isFunction(S.uniqueSort)?S.uniqueSort(y):S.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(S.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=S(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=S(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=S(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){S.data(e,"datepicker",this),this.element=S(e),this.inputs=S.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(S(this.inputs),t).on("changeDate",S.proxy(this.dateUpdated,this)),this.pickers=S.map(this.inputs,function(e){return S.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=S.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=S.map(this.dates,function(e){return e.valueOf()});S.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){S.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=S.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=S.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(S.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){S.map(this.pickers,function(e){e.destroy()}),S(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=S.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=S(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=S(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return S.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(S.extend({},c,i,n).language),a=S.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(S.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=S(v).filter(function(e,t){return-1!==S.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(E("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},S.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(E("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},S.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||E(this).addClass("disabled")})},S.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},S.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},S.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},S.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=E("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",S.fn.datepicker.DPGlobal=I,S.fn.datepicker.noConflict=function(){return S.fn.datepicker=i,this},S.fn.datepicker.version="1.9.0",S.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},S(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=S(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),S(function(){r.call(S('[data-provide="datepicker-inline"]'))})});var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0})})()}); \ No newline at end of file +if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(S("").append(S("").append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0,language:getLanguage()})})()}); \ No newline at end of file From 99709747becfef9112ace79837976c9db9ed3866 Mon Sep 17 00:00:00 2001 From: gzinger Date: Fri, 16 Aug 2019 17:38:04 -0400 Subject: [PATCH 138/338] added GetUserRoleClaimsAsync to the admin API --- .../Controllers/UsersController.cs | 14 +++++++++-- .../Services/IdentityService.cs | 17 ++++++++++--- .../Services/Interfaces/IIdentityService.cs | 4 +++- .../Repositories/IdentityRepository.cs | 24 ++++++++++++++++--- .../Interfaces/IIdentityRepository.cs | 5 +++- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index 44c0be89b..ee1c5c46b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Api.Dtos.Roles; using Skoruba.IdentityServer4.Admin.Api.Dtos.Users; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Helpers.Localization; @@ -202,6 +203,15 @@ public async Task PostChangePassword([FromBody]UserChangePassword await _identityService.UserChangePasswordAsync(userChangePasswordDto); return Ok(); - } - } + } + + [HttpGet("{id}/RoleClaims")] + public async Task>> PostChangePassword(TUserDtoKey id, string claimSearchText, int page = 1, int pageSize = 10) + { + var roleClaimsDto = await _identityService.GetUserRoleClaimsAsync(id.ToString(), claimSearchText, page, pageSize); + var roleClaimsApiDto = _mapper.Map>(roleClaimsDto); + + return Ok(roleClaimsApiDto); + } + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs index 8ed96768b..f97836fec 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs @@ -364,9 +364,20 @@ public virtual async Task GetRoleClaimsAsync(string roleId, int roleClaimDtos.RoleName = roleDto.Name; return roleClaimDtos; - } - - public virtual async Task GetRoleClaimAsync(string roleId, int claimId) + } + + public virtual async Task GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10) + { + var userExists = await IdentityRepository.ExistsUserAsync(userId); + if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description); + + var identityRoleClaims = await IdentityRepository.GetUserRoleClaimsAsync(userId, claimSearchText, page, pageSize); + var roleClaimDtos = Mapper.Map(identityRoleClaims); + + return roleClaimDtos; + } + + public virtual async Task GetRoleClaimAsync(string roleId, int claimId) { var roleExists = await IdentityRepository.ExistsRoleAsync(roleId); if (!roleExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description); diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/Interfaces/IIdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/Interfaces/IIdentityService.cs index 22817ad78..9418463f0 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/Interfaces/IIdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/Interfaces/IIdentityService.cs @@ -85,7 +85,9 @@ Task GetUserClaimsAsync(string userId, int page = 1, Task GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10); - Task GetRoleClaimAsync(string roleId, int claimId); + Task GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10); + + Task GetRoleClaimAsync(string roleId, int claimId); Task DeleteRoleClaimsAsync(TRoleClaimsDto role); diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs index a38813cb3..41411c781 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs @@ -252,9 +252,27 @@ public virtual async Task> GetRoleClaimsAsync(string roleI pagedList.PageSize = pageSize; return pagedList; - } - - public virtual Task GetUserClaimAsync(string userId, int claimId) + } + + public virtual async Task> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10) + { + var id = ConvertUserKeyFromString(userId); + Expression> searchCondition = x => x.ClaimType.Contains(claimSearchText); + var claimsQ = DbContext.Set().Where(x => x.UserId.Equals(id)) + .Join(DbContext.Set().WhereIf(!string.IsNullOrEmpty(claimSearchText), searchCondition), ur => ur.RoleId, rc => rc.RoleId, (ur, rc) => rc); + + var claims= await claimsQ.PageBy(x => x.Id, page, pageSize) + .ToListAsync(); + + var pagedList = new PagedList(); + pagedList.Data.AddRange(claims); + pagedList.TotalCount = await claimsQ.CountAsync(); + pagedList.PageSize = pageSize; + + return pagedList; + } + + public virtual Task GetUserClaimAsync(string userId, int claimId) { var userIdConverted = ConvertUserKeyFromString(userId); diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/Interfaces/IIdentityRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/Interfaces/IIdentityRepository.cs index d3e6af8c8..9433fa331 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/Interfaces/IIdentityRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/Interfaces/IIdentityRepository.cs @@ -68,7 +68,10 @@ public interface IIdentityRepository> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10); - Task GetRoleClaimAsync(string roleId, int claimId); + Task> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10); + + + Task GetRoleClaimAsync(string roleId, int claimId); Task DeleteRoleClaimsAsync(string roleId, int claimId); From 47675328846da13a9ab381aacc17329ff430a42f Mon Sep 17 00:00:00 2001 From: Aegide <43409914+Aegide@users.noreply.github.com> Date: Fri, 23 Aug 2019 10:44:07 +0200 Subject: [PATCH 139/338] Delete web.config Unrelated file to this translation --- src/Skoruba.IdentityServer4.Admin/web.config | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin/web.config diff --git a/src/Skoruba.IdentityServer4.Admin/web.config b/src/Skoruba.IdentityServer4.Admin/web.config deleted file mode 100644 index b56a4065f..000000000 --- a/src/Skoruba.IdentityServer4.Admin/web.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file From 7b5f4278cac5d757b089c7e904125c10baaac3c2 Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 11:01:26 +0200 Subject: [PATCH 140/338] restore web.config (dev state) --- src/Skoruba.IdentityServer4.Admin/web.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/web.config b/src/Skoruba.IdentityServer4.Admin/web.config index b56a4065f..3d49211e5 100644 --- a/src/Skoruba.IdentityServer4.Admin/web.config +++ b/src/Skoruba.IdentityServer4.Admin/web.config @@ -5,7 +5,7 @@ --> - + From c0c073640fc5ad32f3fa9a1a6935d9481df6b5dd Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 11:05:48 +0200 Subject: [PATCH 141/338] Restoration of web.config (dev state) --- src/Skoruba.IdentityServer4.Admin/web.config | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Skoruba.IdentityServer4.Admin/web.config diff --git a/src/Skoruba.IdentityServer4.Admin/web.config b/src/Skoruba.IdentityServer4.Admin/web.config new file mode 100644 index 000000000..3d49211e5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/web.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file From b04624dec50f891ef742b5d746ad10b324644f95 Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 11:10:21 +0200 Subject: [PATCH 142/338] Restore package-lock.json (dev state) --- .../package-lock.json | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/package-lock.json b/src/Skoruba.IdentityServer4.STS.Identity/package-lock.json index 460ac6f94..8ceb2fdcf 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/package-lock.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/package-lock.json @@ -1359,7 +1359,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1402,7 +1403,8 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", @@ -1413,7 +1415,8 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1530,7 +1533,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1542,6 +1546,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1571,6 +1576,7 @@ "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1589,6 +1595,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1689,6 +1696,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1774,7 +1782,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1810,6 +1819,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1829,6 +1839,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1872,12 +1883,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, From d93e690fde8eca819d97736fec9247fd0ce06cff Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 15:56:43 +0200 Subject: [PATCH 143/338] Update Signout capital D --- .../Resources/Views/Shared/_Layout.fr.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx index b23f4e878..8cd884165 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx @@ -151,7 +151,7 @@ Réglages - déconnexion + Déconnexion Skoruba IdentityServer4 From fb22c9dd68ef2e073c0ffc11fc2da80c9e715e68 Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 16:01:56 +0200 Subject: [PATCH 144/338] Update "grant" => "octroi" --- .../Resources/Controllers/GrantController.fr.resx | 4 ++-- .../Resources/Services/PersistedGrantService.fr.resx | 4 ++-- .../Views/Configuration/Client/Section/Label.fr.resx | 10 +++++----- .../Resources/Views/Configuration/ClientClone.fr.resx | 2 +- .../Resources/Views/Grants/Index.fr.resx | 2 +- .../Resources/Views/Home/Index.fr.resx | 3 ++- .../Resources/Views/Shared/_Layout.fr.resx | 3 ++- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fr.resx index b01c12377..fe4db2b72 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fr.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Persisted Grant supprimé avec succès ! + Octroi persistant supprimé avec succès ! - Persisted Grants supprimés avec succès ! + Octrois persistants supprimés avec succès ! Succès diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fr.resx index 1aae2a5b5..b4d78fe36 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fr.resx @@ -118,9 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Persisted Grant avec l'ID {0} n'existe pas + Consentement avec l'ID {0} n'existe pas - Persisted Grant pour ce subject d'ID {0} n'existe pas + Consentement pour ce subject d'ID {0} n'existe pas \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fr.resx index d0c8aabe5..bdbeb9b9c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fr.resx @@ -273,11 +273,11 @@ OneTime, la gestion des refresh token sera mise à jour lors de la régénérati Exiger le consentement - Indique si les clients qui utilisent un grant type basé sur un code d'autorisation doivent envoyer une proof key. + Indique si les clients qui utilisent un type d'octroi basé sur un code d'autorisation doivent envoyer une proof key. basé ? - Nécessite Pkce + Nécessite PKCE Sliding, Durée de vie du refresh token en secondes. La valeur par défaut est 1296000 secondes / 15 jours. @@ -298,14 +298,14 @@ OneTime, la gestion des refresh token sera mise à jour lors de la régénérati utilisé par l'implémentations par défaut - Origines Cors autorisées + Origines CORS autorisées - Indique les types de grant que le client est autorisé à utiliser. Utilisez la class GrantTypes pour les combinaisons courantes. Liste des grants par défaut: Grant Implicite - (implicit), Client Credentials Grant - (client_credentials), Authorization Code Grant - (authorization_code), Grant hybride - (hybrid), Resource Owner Password Credentials Grant - (password) + Indique les types d'octroi que le client peut utiliser. Utilisez la class GrantTypes pour les combinaisons courantes. Liste des octroi par défaut: Octroi implicite - (implicit), Octroi par identifiants - (client_credentials), Octroi par code - (authorization_code), Octroi hybride - (hybrid), Resource Owner Password Credentials Grant - (password) Indique les types de grant que le client est autorisé à utiliser. Utilisez la classe GrantTypes pour les combinaisons courantes. Liste des grants par défaut : Grant implicite - (implicit), Grant relative aux justificatifs d'identité du client - (justificatifs d'identité du client), Grant relatif aux codes d'autorisations - (code autorisation), Grant hybride - (hybride), Grant relatif aux justificatifs du propriétaire des ressources - (mot de passe) - Types de grants autorisés + Types d'octroi autorisés Par défaut, un client n'a accès à aucune ressource - indiquez les ressources accessibles en ajoutant les noms de scopes correspondants. diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fr.resx index 8dc9e0b1f..85e47a181 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fr.resx @@ -133,7 +133,7 @@ Origines Cors Client - Types Grant Client + Types d'octroi Client Restrictions IdP Client diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fr.resx index 8a4ccd5a0..f0901ecd6 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fr.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - API Grants + Octrois API Créé : diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx index 7a98b6724..0ed6c61f1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx @@ -127,7 +127,8 @@ Discovery Document - Persisted Grants + Consentements + Octrois persistants. Explicit mistake for clarity échantillons disponibles diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx index 8cd884165..41c9d943b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx @@ -133,7 +133,8 @@ © 2019 - Grants + Consentements + Octrois. Explicit mistake for clarity Mes données personnelles From 9e21e75ee11661fad1ba0f9efd85e4b0895a8709 Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 16:09:55 +0200 Subject: [PATCH 145/338] Update 2FA 2FA =>A2F --- .../Views/Identity/User/Section/Label.fr.resx | 4 ++-- .../Controllers/ManageController.fr.resx | 18 +++++++++--------- .../Resources/Views/Manage/Disable2fa.fr.resx | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx index d173e6171..fa780f8b2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx @@ -219,10 +219,10 @@ Clé du fournisseur - Facteur deux activé pour l'utilisateur + A2F activé - Facteur deux activé pour l'utilisateur + Authentification à deux facteurs (A2F) activée pour l'utilisateur Nom d'utilisateur diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fr.resx index 959d62790..ed67250a8 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fr.resx @@ -133,7 +133,7 @@ L'utilisateur avec l'ID '{0}' s'est supprimé. - Impossible de générer des codes de récupération pour l'utilisateur avec l'ID {0} car 2FA n'est pas activé. + Impossible de générer des codes de récupération pour l'utilisateur avec l'ID {0} car A2F n'est pas activé. Code @@ -142,10 +142,10 @@ Une erreur inattendue s'est produite lors de la suppression de l'utilisateur avec l'ID {0}. - Une erreur inattendue s'est produite en désactivant 2FA pour l'utilisateur avec l'ID {0}. + Une erreur inattendue s'est produite en désactivant A2F pour l'utilisateur avec l'ID {0}. - Impossible de générer des codes de récupération pour l'utilisateur car 2FA n'est pas activé. + Impossible de générer des codes de récupération pour l'utilisateur car A2F n'est pas activé. Une erreur inattendue s'est produite lors du chargement des informations de connexion externe de l'utilisateur avec l'ID {0}. @@ -184,21 +184,21 @@ Votre profil a été mis à jour - L'utilisateur avec l'ID {0} a désactivé 2fa. + L'utilisateur avec l'ID {0} a désactivé A2F. - Le navigateur actuel a été oublié. Lorsque vous vous reconnectez à partir de ce navigateur, vous serez invité à entrer votre code 2fa. + Le navigateur actuel a été oublié. Lorsque vous vous reconnectez à partir de ce navigateur, vous serez invité à entrer votre code A2F. L'utilisateur avec l'ID {0} a réinitialisé sa clé d'application d'authentification. - L'utilisateur avec ID {0} a activé 2FA avec une application d'authentification. - L'utilisateur avec l'ID {0} a activé 2FA avec une application d'authentification. + L'utilisateur avec ID {0} a activé A2F avec une application d'authentification. + L'utilisateur avec l'ID {0} a activé A2F avec une application d'authentification. - L'utilisateur avec ID {0} a généré de nouveaux codes de récupération 2FA. - L'utilisateur avec l'ID {0} a généré de nouveaux codes de récupération 2FA. + L'utilisateur avec ID {0} a généré de nouveaux codes de récupération A2F. + L'utilisateur avec l'ID {0} a généré de nouveaux codes de récupération A2F. Impossible de charger l'utilisateur avec ID {0}. diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx index d8e37403d..43af48711 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx @@ -118,18 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Désactiver 2FA + Désactiver A2F - Désactiver 2FA ne change pas les clés utilisées dans les applications d'authentification. Si vous souhaitez changer la clé utilisée dans une application d'authentification, vous devez + Désactiver A2F ne change pas les clés utilisées dans les applications d'authentification. Si vous souhaitez changer la clé utilisée dans une application d'authentification, vous devez réinitialiser vos clés d'authentification - Cette action désactive uniquement 2FA. + Cette action désactive uniquement A2F. - Désactiver l'authentification à deux facteurs (2FA) + Désactiver l'authentification à deux facteurs (A2F) \ No newline at end of file From cdf9eb2728f8a1c5a294f164affa3d08bf8f5d60 Mon Sep 17 00:00:00 2001 From: Aegide Date: Fri, 23 Aug 2019 16:31:50 +0200 Subject: [PATCH 146/338] Update UserName --- .../Views/Identity/User/Section/Label.fr.resx | 18 +++++++++++------- .../Resources/Views/Identity/Users.fr.resx | 3 ++- .../Resources/Views/Account/Login.fr.resx | 3 ++- .../Resources/Views/Account/Register.fr.resx | 3 ++- .../Resources/Views/Manage/Index.fr.resx | 3 ++- .../Resources/Views/Manage/SetPassword.fr.resx | 2 +- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx index fa780f8b2..e87f6d36e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx @@ -157,17 +157,19 @@ Mot de passe - Nom d'utilisateur + Identifiant + Nom d'utilisateur - Nom d'utilisateur + Identifiant + Nom d'utilisateur - Email de l'utilisateur validé + Email de l'utilisateur confirmé Email validé de l'utilisateur - Email de l'utilisateur validé + Email de l'utilisateur confirmé Email validé de l'utilisateur @@ -198,7 +200,7 @@ Numéro de téléphone de l'utilisateur - Numéro de téléphone de l'utilisateur + Numéro de téléphone Fournisseur d'accès @@ -225,10 +227,12 @@ Authentification à deux facteurs (A2F) activée pour l'utilisateur - Nom d'utilisateur + Identifiant + Nom Utilisateur - Nom d'utilisateur + Identifiant + Nom Utilisateur diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fr.resx index f171f95b6..3e0ea891f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fr.resx @@ -133,6 +133,7 @@ ID Utilisateur - Nom Utilisateur + Identifiant + Nom Utilisateur \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fr.resx index b8af5743d..7a5e7df8e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fr.resx @@ -156,6 +156,7 @@ Connexion - Nom d'utilisateur + Identifiant + Nom d'utilisateur \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fr.resx index 1c04f865b..bfed0e681 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fr.resx @@ -137,6 +137,7 @@ S'inscrire - Nom d'utilisateur + Identifiant + Nom d'utilisateur \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fr.resx index 28b81bd88..93e4a1ad7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fr.resx @@ -154,7 +154,8 @@ Profil - Nom d'utilisateur + Identifiant + Nom d'utilisateur URL du site diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx index 0a5712ce3..1cdb80a8e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx @@ -122,7 +122,7 @@ Confirmer (le) mot de passe - Vous n'avez pas de nom d'utilisateur/mot de passe local pour ce site. Ajoutez un compte local pour pouvoir vous connecter sans connexion externe. + Vous n'avez pas d'identifiant/mot de passe local pour ce site. Ajoutez un compte local pour pouvoir vous connecter sans connexion externe. Nouveau mot de passe From 1e7c3543e067de472f4412d63532bd942caebd76 Mon Sep 17 00:00:00 2001 From: Aegide Date: Mon, 26 Aug 2019 11:30:34 +0200 Subject: [PATCH 147/338] Update Identity section Implicit informations were deleted from the labels, but are kept in the info tooltip --- .../Views/Identity/User/Section/Label.fr.resx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx index e87f6d36e..9ba4373bf 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fr.resx @@ -137,10 +137,10 @@ Type (du) Claim, Type (de) Claim - Nombre d'échecs d'accès des utilisateurs + Nombre d'échecs d'accès de l'utilisateur - Nombre d'échecs d'accès des utilisateurs + Nombre d'échecs d'accès Confirmer mot de passe @@ -169,7 +169,7 @@ Email validé de l'utilisateur - Email de l'utilisateur confirmé + Email confirmé Email validé de l'utilisateur @@ -182,19 +182,19 @@ Verrouillage utilisateur activé - Verrouillage utilisateur activé + Verrouillage Fin du verrouillage de l'utilisateur - Fin du verrouillage de l'utilisateur + Fin du verrouillage - Numéro de téléphone de l'utilisateur Validé + Numéro de téléphone de l'utilisateur Confirmé - Numéro de téléphone de l'utilisateur Validé + Numéro de téléphone confirmé Numéro de téléphone de l'utilisateur @@ -221,10 +221,10 @@ Clé du fournisseur - A2F activé + Authentification à deux facteurs (A2F) activée pour l'utilisateur - Authentification à deux facteurs (A2F) activée pour l'utilisateur + A2F Identifiant From 08b3d5cc2018f6ea09259e6ea42cf6e0582b8eed Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 16 Sep 2019 12:15:00 +0200 Subject: [PATCH 148/338] Fix datepicker and language support --- .../Scripts/App/components/DatePicker.js | 4 ++-- .../wwwroot/dist/js/bundle.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js index 868d0460d..071212432 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/components/DatePicker.js @@ -32,7 +32,7 @@ }, getLanguage: function () { //Defaults to en if no UiCulture found. - var language = this.getUiCultureFromAspNetCoreCultureCookie() || 'en'; + var language = adminDatePicker.getUiCultureFromAspNetCoreCultureCookie() || 'en'; // bootstrap DatePicker supports Taiwanese chinese as well as Mainland. // Defaults to Mainland as we currently have no way of specifying variants. if (language === 'zh') language = 'zh-CN'; @@ -42,7 +42,7 @@ $('.datepicker').datepicker({ autoclose: true, todayHighlight: true, - language: getLanguage() + language: adminDatePicker.getLanguage() }); } diff --git a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js index 4d4921b80..199b4217d 100644 --- a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js +++ b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js @@ -1 +1 @@ -if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(S("").append(S("").append(S("").append(S("").append(S("").append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0,language:getLanguage()})})()}); \ No newline at end of file +if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S(" - @foreach (var client in Model.Logs) + @foreach (var log in Model.Logs) { - - + + - + - - + + } From 44aa9046c08548027937658b32f67b745ee591b1 Mon Sep 17 00:00:00 2001 From: Andrew Godfroy Date: Wed, 30 Oct 2019 22:53:07 -0400 Subject: [PATCH 191/338] Update Configure-Azure-Deploy.md I ran into this issue when deploying to Azure. The solution is written inside of #108 #issuecomment-538904975 https://github.com/skoruba/IdentityServer4.Admin/issues/108#issuecomment-538904975 Adding to documentation to solve an hour of frusturation for people following the tutorial --- docs/Configure-Azure-Deploy.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/Configure-Azure-Deploy.md b/docs/Configure-Azure-Deploy.md index 791812ac1..a6df0fd8e 100644 --- a/docs/Configure-Azure-Deploy.md +++ b/docs/Configure-Azure-Deploy.md @@ -69,6 +69,13 @@ While we're at it we can allow only https traffic to our STS and admin: ![Always https](Images/https_always.PNG) +Then head to "Application Settings" section within your Azure App Service and create a new Application setting with the following parameters: + +``` +Name: WEBSITE_LOAD_CERTIFICATES +Value: * +``` + Last step before deploy - we need to update `src/Skoruba.IdentityServer4.STS.Identity/appsettings.json` and modify following lines: ```json From 17dc8a2ff9da1a223a490d8e2d29e4c45af660e5 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Fri, 1 Nov 2019 13:20:27 +0100 Subject: [PATCH 192/338] Add javascripts for audit logging and update js file for error logging. --- .../Scripts/App/pages/AuditLog.js | 54 +++++++++++++ .../Scripts/App/pages/ErrorsLog.es5.js | 48 ------------ .../Scripts/App/pages/ErrorsLog.es5.min.js | 1 - .../Scripts/App/pages/ErrorsLog.js | 75 +++++++++++-------- .../Views/Log/AuditLog.cshtml | 64 ++++++++++------ .../Views/Shared/_Layout.cshtml | 12 ++- src/Skoruba.IdentityServer4.Admin/gulpfile.js | 3 +- .../wwwroot/dist/js/bundle.min.js | 2 +- 8 files changed, 151 insertions(+), 108 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js delete mode 100644 src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.js delete mode 100644 src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.min.js diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js new file mode 100644 index 000000000..6360e89b3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js @@ -0,0 +1,54 @@ +var auditLog = { + + createJsonTree: function(json) { + var result; + + try { + result = JSONTree.create(JSON.parse(json)); + } catch (e) { + result = JSONTree.create(json); + } + + return result; + }, + + initJsonTrees: function() { + $(".json-tree").each(function () { + + var json = $(this).data("json-tree"); + var result = auditLog.createJsonTree(json); + + $(this).html(result); + }); + }, + + eventHandlers: function() { + $(".audit-subject-button").click(function () { + var subjectId = $(this).data("subject-identifier"); + var subjectType = $(this).data("subject-type"); + var json = $(this).data("subject-additional-data"); + + $(".audit-modal-title").html(subjectId + " (" + subjectType + ")"); + $(".audit-modal-value").html(auditLog.createJsonTree(json)); + $(".audit-modal").modal("show"); + }); + + $(".audit-action-button").click(function () { + var json = $(this).data("action"); + $(".audit-modal-title").html(""); + $(".audit-modal-value").html(auditLog.createJsonTree(json)); + $(".audit-modal").modal("show"); + }); + }, + + init: function() { + + $(function() { + auditLog.eventHandlers(); + auditLog.initJsonTrees(); + }); + + } +}; + +auditLog.init(); \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.js deleted file mode 100644 index 178e69863..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -$(function () { - - $(".error-log-delete-button").click(function () { - - $(".error-log-form").validate(); - - if ($(".error-log-form").validate().form()) { - - $("#deleteLogsModal").modal("show"); - return false; - } else { - $(this).submit(); - return false; - } - }); - - $(".row-error-detail>td").each(function () { - - var json = $(this).data("error-json"); - var result; - - try { - result = JSONTree.create(JSON.parse(json)); - } catch (e) { - result = JSONTree.create(json); - } - - $(this).html(result); - }); - - $(".btn-error-detail").click(function (e) { - - e.preventDefault(); - - var errorId = $(this).data("error-id"); - - if ($(".row-error-detail[data-error-id=" + errorId + "]").is(":visible")) { - $(".row-error-detail[data-error-id=" + errorId + "]").addClass('d-none'); - } else { - $(".row-error-detail[data-error-id=" + errorId + "]").removeClass('d-none'); - } - - return false; - }); -}); - diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.min.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.min.js deleted file mode 100644 index 4c2248093..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.es5.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?($("#deleteLogsModal").modal("show"),!1):($(this).submit(),!1)});$(".row-error-detail>td").each(function(){var t=$(this).data("error-json"),n;try{n=JSONTree.create(JSON.parse(t))}catch(i){n=JSONTree.create(t)}$(this).html(n)});$(".btn-error-detail").click(function(n){n.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}); \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.js index 1453bbfcf..08689fd8a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/ErrorsLog.js @@ -1,46 +1,57 @@ -$(function () { +var errorLog = { - $(".error-log-delete-button").click(function() { + eventHandlers: function () { + $(".error-log-delete-button").click(function () { - $(".error-log-form").validate(); + $(".error-log-form").validate(); - if ($(".error-log-form").validate().form()) { + if ($(".error-log-form").validate().form()) { - $("#deleteLogsModal").modal("show"); - return false; - } else { - $(this).submit(); - return false; - } - }); + $("#deleteLogsModal").modal("show"); + return false; + } else { + $(this).submit(); + return false; + } + }); + + $(".row-error-detail>td").each(function () { - $(".row-error-detail>td").each(function () { + var json = $(this).data("error-json"); + var result; - const json = $(this).data("error-json"); - var result; + try { + result = JSONTree.create(JSON.parse(json)); + } catch (e) { + result = JSONTree.create(json); + } - try { - result = JSONTree.create(JSON.parse(json)); - } catch (e) { - result = JSONTree.create(json); - } + $(this).html(result); + }); - $(this).html(result); - }); + $(".btn-error-detail").click(function (e) { - $(".btn-error-detail").click(function (e) { + e.preventDefault(); - e.preventDefault(); + var errorId = $(this).data("error-id"); + + if ($(".row-error-detail[data-error-id=" + errorId + "]").is(":visible")) { + $(".row-error-detail[data-error-id=" + errorId + "]").addClass('d-none'); + } else { + $(".row-error-detail[data-error-id=" + errorId + "]").removeClass('d-none'); + } + + return false; + }); + }, - var errorId = $(this).data("error-id"); + init: function () { + $(function () { - if ($(`.row-error-detail[data-error-id=${errorId}]`).is(":visible")) { - $(`.row-error-detail[data-error-id=${errorId}]`).addClass('d-none'); - } else { - $(`.row-error-detail[data-error-id=${errorId}]`).removeClass('d-none'); - } + errorLog.eventHandlers(); + }); + } - return false; - }); +}; -}); \ No newline at end of file +errorLog.init(); diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml index 7e72d90e0..a2b5d4e28 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml @@ -5,7 +5,7 @@ ViewData["Title"] = "Audit Log"; } -

    @ViewData["Title"]

    +

    @ViewData["Title"]

    @@ -20,37 +20,28 @@
    + - - - - + - @foreach (var auditLog in Model.Logs) { - - - - - - - - - + + + + + + - - + + - + } @@ -63,4 +54,31 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "AuditLog", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search })
    - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Shared/_Layout.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Shared/_Layout.cshtml index 7d65748e2..945e2631b 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Shared/_Layout.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Shared/_Layout.cshtml @@ -56,8 +56,16 @@ - @Localizer["TitleLogs"] - + + @if (User.Identity.IsAuthenticated) { diff --git a/src/Skoruba.IdentityServer4.Admin/gulpfile.js b/src/Skoruba.IdentityServer4.Admin/gulpfile.js index 9be522d23..56614aa00 100644 --- a/src/Skoruba.IdentityServer4.Admin/gulpfile.js +++ b/src/Skoruba.IdentityServer4.Admin/gulpfile.js @@ -38,7 +38,8 @@ function processScripts() { './Scripts/App/helpers/FormMvcHelpers.js', './Scripts/App/helpers/jsontree.min.js', './Scripts/App/helpers/DateTimeHelpers.js', - './Scripts/App/pages/ErrorsLog.es5.js', + './Scripts/App/pages/ErrorsLog.js', + './Scripts/App/pages/AuditLog.js', './Scripts/App/pages/Secrets.js', './Scripts/App/components/DatePicker.js' ]) diff --git a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js index 199b4217d..fe0d9990b 100644 --- a/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js +++ b/src/Skoruba.IdentityServer4.Admin/wwwroot/dist/js/bundle.min.js @@ -1 +1 @@ -if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i Date: Mon, 16 Sep 2019 12:32:13 +0200 Subject: [PATCH 149/338] Update libraries to latest version. --- .../Skoruba.IdentityServer4.Admin.Api.csproj | 2 +- .../Skoruba.IdentityServer4.Admin.csproj | 10 +++++----- .../Skoruba.IdentityServer4.STS.Identity.csproj | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index d5b28925e..bb25052ce 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index b5bd2339a..cdbd636f7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -9,14 +9,14 @@ - - + + - + - - + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 614344cae..108a933ba 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -6,15 +6,15 @@ - + - - + + - - - + + + From acec16526922a8e951034c04110429df2c6b9197 Mon Sep 17 00:00:00 2001 From: Chris Szabo Date: Sat, 28 Sep 2019 10:33:25 -0400 Subject: [PATCH 150/338] docker support --- .dockerignore | 25 ++++++ Skoruba.IdentityServer4.Admin.sln | 8 +- docker-compose.dcproj | 18 +++++ docker-compose.override.yml | 25 ++++++ docker-compose.yml | 80 +++++++++++++++++++ .../Configuration/AdminApiConfiguration.cs | 1 + .../Dockerfile | 26 ++++++ .../Helpers/StartupHelpers.cs | 2 +- .../Properties/launchSettings.json | 59 ++++++++------ .../Skoruba.IdentityServer4.Admin.Api.csproj | 4 + .../appsettings.json | 11 +-- .../Configuration/AdminConfiguration.cs | 2 +- .../Interfaces/IAdminConfiguration.cs | 1 + src/Skoruba.IdentityServer4.Admin/Dockerfile | 27 +++++++ .../Helpers/StartupHelpers.cs | 2 +- .../Properties/launchSettings.json | 56 +++++++------ .../Skoruba.IdentityServer4.Admin.csproj | 4 + .../appsettings.json | 35 ++++---- .../Dockerfile | 24 ++++++ .../Properties/launchSettings.json | 53 ++++++------ ...koruba.IdentityServer4.STS.Identity.csproj | 4 + 21 files changed, 368 insertions(+), 99 deletions(-) create mode 100644 .dockerignore create mode 100644 docker-compose.dcproj create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Dockerfile create mode 100644 src/Skoruba.IdentityServer4.Admin/Dockerfile create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..3729ff0cd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/Skoruba.IdentityServer4.Admin.sln b/Skoruba.IdentityServer4.Admin.sln index 897a573c2..9ca903f33 100644 --- a/Skoruba.IdentityServer4.Admin.sln +++ b/Skoruba.IdentityServer4.Admin.sln @@ -33,7 +33,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Adm EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.EntityFramework.Shared", "src\Skoruba.IdentityServer4.Admin.EntityFramework.Shared\Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj", "{E18F8C70-7448-4039-9D78-1369D7F498EF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.Extensions", "src\Skoruba.IdentityServer4.Admin.EntityFramework.Extensions\Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj", "{2DD3CB7D-462E-4039-B684-81B1E88C7C6A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.EntityFramework.Extensions", "src\Skoruba.IdentityServer4.Admin.EntityFramework.Extensions\Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj", "{2DD3CB7D-462E-4039-B684-81B1E88C7C6A}" +EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{F817047F-018D-4F93-BDA5-58602073B634}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -93,6 +95,10 @@ Global {2DD3CB7D-462E-4039-B684-81B1E88C7C6A}.Debug|Any CPU.Build.0 = Debug|Any CPU {2DD3CB7D-462E-4039-B684-81B1E88C7C6A}.Release|Any CPU.ActiveCfg = Release|Any CPU {2DD3CB7D-462E-4039-B684-81B1E88C7C6A}.Release|Any CPU.Build.0 = Release|Any CPU + {F817047F-018D-4F93-BDA5-58602073B634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F817047F-018D-4F93-BDA5-58602073B634}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F817047F-018D-4F93-BDA5-58602073B634}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F817047F-018D-4F93-BDA5-58602073B634}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/docker-compose.dcproj b/docker-compose.dcproj new file mode 100644 index 000000000..4e83043c0 --- /dev/null +++ b/docker-compose.dcproj @@ -0,0 +1,18 @@ + + + + 2.1 + Linux + f817047f-018d-4f93-bda5-58602073b634 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + skoruba.identityserver4.admin + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 000000000..2e5f63e8d --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,25 @@ +version: '3.4' + +services: + skoruba.identityserver4.admin: + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "80" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + skoruba.identityserver4.admin.api: + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "80" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + + skoruba.identityserver4.sts.identity: + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "80" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..6545efa6f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,80 @@ +version: '3.4' + +services: + skoruba.identityserver4.admin: + image: ${DOCKER_REGISTRY-}skorubaidentityserver4admin + ports: + - 9000:80 + build: + context: . + dockerfile: src/Skoruba.IdentityServer4.Admin/Dockerfile + container_name: skoruba-identityserver4-admin + environment: + - ASPNETCORE_ENVIRONMENT=Development + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "AdminConfiguration:IdentityAdminBaseUrl=http://127.0.0.1.xip.io:9000" + - "AdminConfiguration:IdentityAdminRedirectUri=http://127.0.0.1.xip.io:9000/signin-oidc" + - "AdminConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io" + - "AdminConfiguration:IdentityRequireHttpsMetadata=false" + command: dotnet Skoruba.IdentityServer4.Admin.dll /seed + depends_on: + - db + - skoruba.identityserver4.sts.identity + + skoruba.identityserver4.admin.api: + image: ${DOCKER_REGISTRY-}skorubaidentityserver4adminapi + build: + context: . + dockerfile: src/Skoruba.IdentityServer4.Admin.Api/Dockerfile + ports: + - 5000:80 + environment: + - "AdminApiConfiguration:IdentityRequireHttpsMetadata=false" + - "AdminApiConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io:5000" + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + container_name: skoruba-identityserver4-admin-api + + skoruba.identityserver4.sts.identity: + image: ${DOCKER_REGISTRY-}skorubaidentityserver4stsidentity + ports: + - 80:80 + build: + context: . + dockerfile: src/Skoruba.IdentityServer4.STS.Identity/Dockerfile + container_name: skoruba-identityserver4-sts-identity + environment: + - ASPNETCORE_ENVIRONMENT=Development + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "AdminConfiguration:IdentityAdminBaseUrl=http://127.0.0.1.xip.io:9000" + depends_on: + - db + networks: + default: + aliases: + - 127.0.0.1.xip.io + db: + image: "mcr.microsoft.com/mssql/server" + ports: + - 1433 + container_name: skoruba-identityserver4-db + environment: + SA_PASSWORD: "Password_123" + ACCEPT_EULA: "Y" + volumes: + - dbdata:/var/opt/mssql + +volumes: + dbdata: + driver: local + +networks: + default: + driver: bridge \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs index d6eb104d1..262c7c39c 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs @@ -9,5 +9,6 @@ public class AdminApiConfiguration public string OidcSwaggerUIClientId { get; set; } = AuthorizationConsts.OidcSwaggerUIClientId; public string OidcApiName { get; set; } = AuthorizationConsts.OidcApiName; + public bool IdentityRequireHttpsMetadata { get; set; } = true; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile new file mode 100644 index 000000000..d19b39113 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile @@ -0,0 +1,26 @@ +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +WORKDIR /src +COPY ["src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj", "src/Skoruba.IdentityServer4.Admin.Api/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/"] +RUN dotnet restore "src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj" +COPY . . +WORKDIR "/src/src/Skoruba.IdentityServer4.Admin.Api" +RUN dotnet build "Skoruba.IdentityServer4.Admin.Api.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Skoruba.IdentityServer4.Admin.Api.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Skoruba.IdentityServer4.Admin.Api.dll"] diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 1ea3cfe7e..28bf41465 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -136,7 +136,7 @@ public static void AddApiAuthentication(this I #if DEBUG options.RequireHttpsMetadata = false; #else - options.RequireHttpsMetadata = true; + options.RequireHttpsMetadata = adminApiConfiguration.IdentityRequireHttpsMetadata; #endif }); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Properties/launchSettings.json b/src/Skoruba.IdentityServer4.Admin.Api/Properties/launchSettings.json index 836e740a0..6a533cabf 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Properties/launchSettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/Properties/launchSettings.json @@ -1,30 +1,37 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:5001", - "sslPort": 0 - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5001", + "sslPort": 0 + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Skoruba.IdentityServer4.Admin.Api": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5002" }, - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Skoruba.IdentityServer4.Admin.Api": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:5002" - } + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": {}, + "httpPort": 10000 } + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index bb25052ce..653c67d98 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -4,6 +4,9 @@ netcoreapp2.2 InProcess 1cc472a2-4e4b-48ce-846b-5219f71fc643 + ..\..\docker-compose.dcproj + Linux + ..\.. @@ -11,6 +14,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 631dbf529..3cca5dc29 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -5,9 +5,10 @@ "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, - "AdminApiConfiguration": { - "IdentityServerBaseUrl": "http://localhost:5000", - "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "OidcApiName": "skoruba_identity_admin_api" - } + "AdminApiConfiguration": { + "IdentityServerBaseUrl": "http://localhost:5000", + "IdentityRequireHttpsMetadata": true, + "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", + "OidcApiName": "skoruba_identity_admin_api" + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index a4c6263e4..42c6af40c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -18,7 +18,7 @@ public class AdminConfiguration : IAdminConfiguration public string ClientSecret { get; set; } = AuthenticationConsts.OidcClientSecret; public string OidcResponseType { get; set; } = AuthenticationConsts.OidcResponseType; - + public bool IdentityRequireHttpsMetadata { get; set; } = true; } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs index 803c73433..01398ffa3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs @@ -12,5 +12,6 @@ public interface IAdminConfiguration string IdentityAdminApiSwaggerUIClientId { get; } string IdentityAdminApiSwaggerUIRedirectUrl { get; } string IdentityAdminApiScope { get; } + bool IdentityRequireHttpsMetadata { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Dockerfile b/src/Skoruba.IdentityServer4.Admin/Dockerfile new file mode 100644 index 000000000..92d6b6658 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Dockerfile @@ -0,0 +1,27 @@ +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +WORKDIR /src +COPY ["src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj", "src/Skoruba.IdentityServer4.Admin/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/"] +COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/"] +RUN dotnet restore "src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj" +COPY . . +WORKDIR "/src/src/Skoruba.IdentityServer4.Admin" +RUN dotnet build "Skoruba.IdentityServer4.Admin.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Skoruba.IdentityServer4.Admin.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true +ENTRYPOINT ["dotnet", "Skoruba.IdentityServer4.Admin.dll"] diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 36d6e0a2a..4e1e858c0 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -443,7 +443,7 @@ public static void AddAuthenticationServicesnetcoreapp2.2 latest 8fe260ca-ef4c-4fa3-9364-029146f8d339 + ..\..\docker-compose.dcproj + Linux + ..\.. @@ -13,6 +16,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 5f46e3b94..36b88301b 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -5,23 +5,24 @@ "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, - "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000", - "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", - "IdentityServerBaseUrl": "http://localhost:5000", - "ClientId": "skoruba_identity_admin", - "ClientSecret": "skoruba_admin_client_secret", - "OidcResponseType": "code id_token", - "Scopes": [ - "openid", - "profile", - "email", - "roles" - ], - "IdentityAdminApiSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "IdentityAdminApiSwaggerUIRedirectUrl": "http://localhost:5001/swagger/oauth2-redirect.html", - "IdentityAdminApiScope": "skoruba_identity_admin_api" - }, + "AdminConfiguration": { + "IdentityAdminBaseUrl": "http://localhost:9000", + "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", + "IdentityServerBaseUrl": "http://localhost:5000", + "ClientId": "skoruba_identity_admin", + "ClientSecret": "skoruba_admin_client_secret", + "OidcResponseType": "code id_token", + "Scopes": [ + "openid", + "profile", + "email", + "roles" + ], + "IdentityAdminApiSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", + "IdentityAdminApiSwaggerUIRedirectUrl": "http://localhost:5001/swagger/oauth2-redirect.html", + "IdentityAdminApiScope": "skoruba_identity_admin_api", + "IdentityRequireHttpsMetadata": true + }, "Serilog": { "MinimumLevel": { "Default": "Error", diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile new file mode 100644 index 000000000..28fa50bf5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile @@ -0,0 +1,24 @@ +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +WORKDIR /src +COPY ["src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj", "src/Skoruba.IdentityServer4.STS.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/"] +COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/"] +RUN dotnet restore "src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj" +COPY . . +WORKDIR "/src/src/Skoruba.IdentityServer4.STS.Identity" +RUN dotnet build "Skoruba.IdentityServer4.STS.Identity.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Skoruba.IdentityServer4.STS.Identity.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true +ENTRYPOINT ["dotnet", "Skoruba.IdentityServer4.STS.Identity.dll"] diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Properties/launchSettings.json b/src/Skoruba.IdentityServer4.STS.Identity/Properties/launchSettings.json index 6b7a7780b..5e1540730 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Properties/launchSettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/Properties/launchSettings.json @@ -1,27 +1,34 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:5000", - "sslPort": 0 - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5000", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Skoruba.IdentityServer4.AspNetIdentity": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Skoruba.IdentityServer4.AspNetIdentity": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:5001;http://localhost:5000" - } + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "environmentVariables": {}, + "httpPort": 10000 } + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 108a933ba..9b143eae0 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -3,6 +3,9 @@ netcoreapp2.2 9c91d295-54c5-4d09-9bd6-fa56fb74011b + ..\..\docker-compose.dcproj + Linux + ..\.. @@ -11,6 +14,7 @@ + From a361c0ee5820fc92d1e0ed704fa6cf6790e335ac Mon Sep 17 00:00:00 2001 From: Chris Szabo Date: Sun, 29 Sep 2019 08:36:54 -0400 Subject: [PATCH 151/338] Added variable for database password --- docker-compose.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6545efa6f..240d80cd0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,10 +11,10 @@ services: container_name: skoruba-identityserver4-admin environment: - ASPNETCORE_ENVIRONMENT=Development - - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "AdminConfiguration:IdentityAdminBaseUrl=http://127.0.0.1.xip.io:9000" - "AdminConfiguration:IdentityAdminRedirectUri=http://127.0.0.1.xip.io:9000/signin-oidc" - "AdminConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io" @@ -34,10 +34,10 @@ services: environment: - "AdminApiConfiguration:IdentityRequireHttpsMetadata=false" - "AdminApiConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io:5000" - - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" container_name: skoruba-identityserver4-admin-api skoruba.identityserver4.sts.identity: @@ -50,9 +50,9 @@ services: container_name: skoruba-identityserver4-sts-identity environment: - ASPNETCORE_ENVIRONMENT=Development - - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" - - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=Password_123;MultipleActiveResultSets=true" + - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "AdminConfiguration:IdentityAdminBaseUrl=http://127.0.0.1.xip.io:9000" depends_on: - db @@ -66,7 +66,7 @@ services: - 1433 container_name: skoruba-identityserver4-db environment: - SA_PASSWORD: "Password_123" + SA_PASSWORD: "${DB_PASSWORD:-Password_123}" ACCEPT_EULA: "Y" volumes: - dbdata:/var/opt/mssql From ba6d5a212ccb08be926bae59fe6cc253563ab1be Mon Sep 17 00:00:00 2001 From: DrQS Date: Wed, 2 Oct 2019 18:05:32 -0300 Subject: [PATCH 152/338] Add Spanish (es) Localization --- .../Helpers/StartupHelpers.cs | 3 +- .../ConfigurationController.es.resx | 189 +++++++ .../Controllers/GrantController.es.resx | 129 +++++ .../Controllers/IdentityController.es.resx | 159 ++++++ .../Services/ApiResourceService.es.resx | 150 ++++++ .../Resources/Services/ClientService.es.resx | 138 ++++++ .../Services/IdentityResourceService.es.resx | 135 +++++ .../Services/IdentityService.es.resx | 180 +++++++ .../Services/PersistedGrantService.es.resx | 126 +++++ .../Views/Account/AccessDenied.es.resx | 129 +++++ .../Resources/Views/ClientClone.es.resx | 162 ++++++ .../Views/Configuration/ApiResource.es.resx | 165 +++++++ .../ApiResource/Section/Label.es.resx | 192 ++++++++ .../Configuration/ApiResourceDelete.es.resx | 132 +++++ .../ApiResourceProperties.es.resx | 147 ++++++ .../ApiResourcePropertyDelete.es.resx | 135 +++++ .../Views/Configuration/ApiResources.es.resx | 135 +++++ .../Configuration/ApiScopeDelete.es.resx | 135 +++++ .../Views/Configuration/ApiScopes.es.resx | 165 +++++++ .../Configuration/ApiSecretDelete.es.resx | 135 +++++ .../Views/Configuration/ApiSecrets.es.resx | 162 ++++++ .../Views/Configuration/Client.es.resx | 129 +++++ .../Client/Section/ActionButtons.es.resx | 129 +++++ .../Client/Section/Authentication.es.resx | 144 ++++++ .../Client/Section/Basics.es.resx | 150 ++++++ .../Client/Section/Consent.es.resx | 123 +++++ .../Client/Section/DeviceFlow.es.resx | 123 +++++ .../Client/Section/Label.es.resx | 462 ++++++++++++++++++ .../Configuration/Client/Section/Name.es.resx | 164 +++++++ .../Client/Section/Token.es.resx | 147 ++++++ .../Configuration/Client/Settings.es.resx | 141 ++++++ .../Configuration/ClientClaimDelete.es.resx | 135 +++++ .../Views/Configuration/ClientClaims.es.resx | 171 +++++++ .../Views/Configuration/ClientClone.es.resx | 162 ++++++ .../Views/Configuration/ClientDelete.es.resx | 129 +++++ .../Configuration/ClientProperties.es.resx | 147 ++++++ .../ClientPropertyDelete.es.resx | 135 +++++ .../Configuration/ClientSecretDelete.es.resx | 135 +++++ .../Views/Configuration/ClientSecrets.es.resx | 162 ++++++ .../Views/Configuration/Clients.es.resx | 135 +++++ .../Configuration/IdentityResource.es.resx | 159 ++++++ .../IdentityResource/Section/Label.es.resx | 186 +++++++ .../IdentityResourceDelete.es.resx | 132 +++++ .../IdentityResourceProperties.es.resx | 147 ++++++ .../IdentityResourcePropertyDelete.es.resx | 135 +++++ .../Configuration/IdentityResources.es.resx | 132 +++++ .../Views/Grant/PersistedGrant.es.resx | 156 ++++++ .../Views/Grant/PersistedGrantDelete.es.resx | 144 ++++++ .../Views/Grant/PersistedGrants.es.resx | 132 +++++ .../Resources/Views/Home/Index.es.resx | 147 ++++++ .../Resources/Views/Identity/Role.es.resx | 138 ++++++ .../Views/Identity/Role/Section/Label.es.resx | 138 ++++++ .../Views/Identity/RoleClaims.es.resx | 168 +++++++ .../Views/Identity/RoleClaimsDelete.es.resx | 135 +++++ .../Views/Identity/RoleDelete.es.resx | 129 +++++ .../Views/Identity/RoleUsers.es.resx | 141 ++++++ .../Resources/Views/Identity/Roles.es.resx | 135 +++++ .../Views/Identity/User/Section/Label.es.resx | 234 +++++++++ .../Views/Identity/UserChangePassword.es.resx | 132 +++++ .../Views/Identity/UserClaims.es.resx | 168 +++++++ .../Views/Identity/UserClaimsDelete.es.resx | 135 +++++ .../Views/Identity/UserDelete.es.resx | 129 +++++ .../Views/Identity/UserProfile.es.resx | 147 ++++++ .../Views/Identity/UserProviders.es.resx | 138 ++++++ .../Identity/UserProvidersDelete.es.resx | 135 +++++ .../Views/Identity/UserRoles.es.resx | 141 ++++++ .../Views/Identity/UserRolesDelete.es.resx | 135 +++++ .../Resources/Views/Identity/Users.es.resx | 138 ++++++ .../Resources/Views/Log/ErrorsLog.es.resx | 150 ++++++ .../Views/Shared/Common/ErrorPage.es.resx | 123 +++++ .../Views/Shared/Common/Pager.es.resx | 126 +++++ .../Views/Shared/Common/Search.es.resx | 126 +++++ .../Shared/Common/SelectLanguage.es.resx | 123 +++++ .../IdentityServerLink/Default.es.resx | 123 +++++ .../Resources/Views/Shared/_Layout.es.resx | 162 ++++++ .../Helpers/StartupHelpers.cs | 3 +- .../Controllers/AccountController.es.resx | 151 ++++++ .../Controllers/ManageController.es.resx | 208 ++++++++ .../Views/Account/ConfirmEmail.es.resx | 126 +++++ .../Account/ExternalLoginConfirmation.es.resx | 140 ++++++ .../Account/ExternalLoginFailure.es.resx | 126 +++++ .../Views/Account/ForgotPassword.es.resx | 132 +++++ .../ForgotPasswordConfirmation.es.resx | 126 +++++ .../Resources/Views/Account/Lockout.es.resx | 126 +++++ .../Resources/Views/Account/LoggedOut.es.resx | 135 +++++ .../Resources/Views/Account/Login.es.resx | 159 ++++++ .../Views/Account/LoginWith2fa.es.resx | 141 ++++++ .../Account/LoginWithRecoveryCode.es.resx | 133 +++++ .../Resources/Views/Account/Logout.es.resx | 129 +++++ .../Resources/Views/Account/Register.es.resx | 141 ++++++ .../Views/Account/RegisterFailure.es.resx | 126 +++++ .../Views/Account/ResetPassword.es.resx | 138 ++++++ .../Account/ResetPasswordConfirmation.es.resx | 129 +++++ .../Resources/Views/Consent/Index.es.resx | 141 ++++++ .../Resources/Views/Device/Success.es.resx | 126 +++++ .../Views/Device/UserCodeCapture.es.resx | 129 +++++ .../Views/Device/UserCodeConfirmation.es.resx | 144 ++++++ .../Resources/Views/Diagnostics/Index.es.resx | 132 +++++ .../Resources/Views/Grants/Index.es.resx | 144 ++++++ .../Resources/Views/Home/Index.es.resx | 156 ++++++ .../Views/Manage/ChangePassword.es.resx | 135 +++++ .../Views/Manage/DeletePersonalData.es.resx | 132 +++++ .../Resources/Views/Manage/Disable2fa.es.resx | 135 +++++ .../Views/Manage/DownloadPersonalData.es.resx | 123 +++++ .../Views/Manage/EnableAuthenticator.es.resx | 148 ++++++ .../Views/Manage/ExternalLogins.es.resx | 132 +++++ .../Manage/GenerateRecoveryCodes.es.resx | 138 ++++++ .../Resources/Views/Manage/Index.es.resx | 162 ++++++ .../Views/Manage/LinkLoginFailure.es.resx | 126 +++++ .../Views/Manage/PersonalData.es.resx | 135 +++++ .../Views/Manage/ResetAuthenticator.es.resx | 138 ++++++ .../Views/Manage/SetPassword.es.resx | 138 ++++++ .../Views/Manage/ShowRecoveryCodes.es.resx | 129 +++++ .../Manage/TwoFactorAuthentication.es.resx | 171 +++++++ .../Shared/Common/SelectLanguage.es.resx | 123 +++++ .../IdentityServerAdminLink/Default.es.resx | 123 +++++ .../Resources/Views/Shared/Error.es.resx | 129 +++++ .../Resources/Views/Shared/Redirect.es.resx | 126 +++++ .../Resources/Views/Shared/_Layout.es.resx | 164 +++++++ .../Views/Shared/_ScopeListItem.es.resx | 123 +++++ .../Views/Shared/_ValidationSummary.es.resx | 123 +++++ 121 files changed, 17237 insertions(+), 2 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.es.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 36d6e0a2a..8181c9f0a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -371,7 +371,8 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) new CultureInfo("fr"), new CultureInfo("ru"), new CultureInfo("sv"), - new CultureInfo("zh") + new CultureInfo("zh"), + new CultureInfo("es") }; opts.DefaultRequestCulture = new RequestCulture("en"); diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.es.resx new file mode 100644 index 000000000..1359bc156 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.es.resx @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ¡El recurso de API {0} fue guardado con éxito! + + + ¡La propiedad de recurso de API {0} para el recurso de API {1} fue guardada con éxito! + + + ¡El alcance de API {0} fue guardado con éxito! + + + ¡El secreto de API fue creado con éxito! + + + ¡El cliente {0} fue creado con éxito! + + + ¡La reclamación de cliente {0} para el cliente {1} fue guardada con éxito! + + + ¡La propiedad de cliente {0} para el cliente {1} fue guardada con éxito! + + + ¡El secreto de cliente para el client {0} fue guardado con éxito! + + + ¡El recurso de identidad {0} fue guardado con éxito! + + + ¡La propiedad de recurso de identidad {0} para el recurso de API {1} fue guardada con éxito! + + + ¡El cliente {0} fue clonado con éxito! + + + ¡El cliente fue eliminado con éxito! + + + ¡El recurso de API Api eliminado con éxito! + + + ¡La propiedad de recurso de API fue eliminada con éxito! + + + ¡El alcance de API fue eliminada con éxito! + + + ¡El secreto de API fue eliminado con éxito! + + + ¡La reclamación de cliente fue eliminada con éxito! + + + ¡La propiedad de cliente fue eliminada con éxito! + + + ¡El secreto de cliente fue eliminado con éxito! + + + ¡El recurso de identidad fue eliminado con éxito! + + + ¡La propiedad de recurso de identidad fue eliminada con éxito! + + + Éxito + + + ¡El cliente {0} fue actualizado con éxito! + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.es.resx new file mode 100644 index 000000000..de5d5fabe --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ¡La concesión persistida fue eliminada con éxito! + + + ¡Las concesiones persistidas fueron eliminadas con éxito! + + + Éxito + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.es.resx new file mode 100644 index 000000000..ea6352f23 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.es.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ¡El rol {0} fue guardado con éxito! + + + ¡La reclamación {0} - {1} fue guardada con éxito! + + + ¡El usuario {0} fue guardado con éxito! + + + ¡La reclamación {0} - {1} fue guardada con éxito! + + + ¡El rol fue guardado con éxito! + + + ¡El rol fue eliminado con éxito! + + + ¡La reclamación fue eliminada con éxito! + + + ¡El usuario fue eliminado con éxito! + + + ¡La reclamación fue eliminada con éxito! + + + ¡El proveedor de usuario fue eliminado con éxito! + + + ¡El rol fue eliminado con éxito! + + + Éxito + + + La nueva contraseña fue cambiada con éxito! + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.es.resx new file mode 100644 index 000000000..6855e5b7a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.es.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El recurso de API con ID {0} no existe + + + El recurso de API ya existe + + + El recurso de API ({0}) ya existe + + + La propiedad de recurso de API con ID {0} no existe + + + La propiedad de recurso de API ya existe + + + La propiedad de recurso de API con llave ({0}) ya existe + + + El alcance de API con ID {0} no existe + + + El alcance de API ya existe + + + El alcance de API ({0}) ya existe + + + El secreto de API con ID {0} no existe + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.es.resx new file mode 100644 index 000000000..bb4219ce3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + La reclamación de cliente con ID {0} no existe + + + El cliente con ID {0} no existe + + + El cliente ya existe + + + La ID de cliente ({0}) ya existe + + + La propiedad de cliente con ID {0} no existe + + + El secreto de cliente con ID {0} no existe + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.es.resx new file mode 100644 index 000000000..346dbfdc8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El recurso de identidad {0} ya existe + + + El recurso de identidad {0} ya existe + + + La propiedad de recurso de identidad con ID {0} no existe + + + La propiedad de recurso de identidad ya existe + + + La propiedad de recurso de identidad con llave ({0}) ya existe + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.es.resx new file mode 100644 index 000000000..fb745fc19 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.es.resx @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + + + La reclamación de rol con ID {0} no existe + + + La creación de las reclamaciones de rol fallaron + + + La eliminación de las reclamaciones de rol fallaron + + + La creación del rol fallo + + + La eliminación del rol fallo + + + El rol con ID {0} no existe + + + La actualización del rol fallo + + + El cambio de contraseña del usuario fallo + + + La reclamación de usuario con ID {0} no existe + + + La creación de las reclamaciones de usuario fallaron + + + La eliminación de las reclamaciones de usuario fallaron + + + La creación del usuario fallo + + + La eliminación del usuario fallo + + + El usuario con ID {0} no existe + + + La eliminación del proveedor de usuario fallo + + + El proveedor de usuario con ID {0} no existe + + + La creación del rol de usuario fallo + + + La eliminación del rol de usuario fallo + + + La actualización del usuario fallo + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.es.resx new file mode 100644 index 000000000..b02d87c2f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + La concesión persistida con ID {0} no existe + + + La concesión persistida para este ID de sujeto {0} no existe + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.es.resx new file mode 100644 index 000000000..dd1c761af --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cerrar sesión + + + ¡Acceso denegado! + + + Volver a IdentityServer + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx new file mode 100644 index 000000000..e76d438dd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clonar cliente + + + Los secretos de cliente no seran clonados. + + + Info: + + + Reclamaciones del cliente + + + Origenes CORS del cliente + + + Tipos de concesión del cliente + + + Restricciones de proveedores de identidad del cliente + + + URIs de redirección post cierre de sesión del cliente + + + Propiedades del cliente + + + URIs de redirección del cliente + + + Alcances del cliente + + + Clientes + + + Clonar cliente + + + Cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.es.resx new file mode 100644 index 000000000..96b308216 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.es.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar recurso de API + + + Administrar propiedades de recurso de API + + + Administrar alcances de API + + + Administrar secretos de API + + + Guardar recurso de API + + + Recursos de API + + + Recurso de API + + + Recurso de API + + + Elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.es.resx new file mode 100644 index 000000000..3d8763b2c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.es.resx @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Este valor puede ser usado, por ejemplo, en la pantalla de consentimiento. + + + Descripción + + + Este valor puede ser usado, por ejemplo, en la pantalla de consentimiento. + + + Nombre en pantalla + + + Indica si este recurso esta habilitado y puede ser solicitado. Habilitado por defecto. + + + Habilitado + + + Expiración + + + Expiración + + + El nombre unico de la API. Este valor es usado para la autenticación con instrospección y puede ser agregado a la audiencia de la token de acceso de salida. + + + Nombre + + + Diccionario que mantiene cualquier valor especifico del recurso según sea necesario. + + + Propiedades + + + Llave + + + Llave + + + Valor + + + Valor + + + Una API debe por lo menos tener un alcance. Cada alcance puede tener diferentes opciones. + + + Alcances + + + Descripción + + + Descripción + + + El secreto de API es usado por el punto final de instrospección. La API puede autenticar con instrospección usando el nombre y secreto de API. + + + Secretos + + + Lista de tipos de reclamación de usuario asociadas que deberian ser incluidas en la token de acceso. + + + Reclamaciones de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.es.resx new file mode 100644 index 000000000..f03362d3f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar recurso de API + + + Recursos de API + + + Eliminar recurso de API + + + Eliminar recurso de API + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.es.resx new file mode 100644 index 000000000..962a67fd7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar propiedad de recurso de API + + + Propiedades de recurso de API + + + Recursos de API + + + Propiedades de recurso de API + + + Propiedades de recurso de API + + + Propiedad de recurso de API + + + Eliminar + + + Llave + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.es.resx new file mode 100644 index 000000000..fbb7152df --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar propiedad de recurso de API + + + Propiedades de recurso de API + + + Recursos de API + + + Eliminar propiedad de recurso de API + + + Eliminar propiedad de recurso de API + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.es.resx new file mode 100644 index 000000000..8838890e1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar recurso de API + + + Recursos de API + + + Recursos de API + + + Editar + + + Nombre + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.es.resx new file mode 100644 index 000000000..ff8d54f97 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar alcance de API + + + Recursos de API + + + Alcances de API + + + Eliminar alcance de API + + + Eliminar alcance de API + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.es.resx new file mode 100644 index 000000000..ada0a2ad7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.es.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Guardar alcance de API + + + Recursos de API + + + Alcances de API + + + Alcances de API + + + Alcance de API + + + elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + + Editar + + + Eliminar + + + Nombre + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.es.resx new file mode 100644 index 000000000..4ec1253dd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar secreto de API + + + Recursos de API + + + Secretos de API + + + Eliminar secreto de API + + + Eliminar secreto de API + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.es.resx new file mode 100644 index 000000000..c85e047ec --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar secreto de API + + + HashType solo sera aplicable para el tipo SharedSecret. + + + Info: + + + Recursos de API + + + Secretos de API + + + Secretos de API + + + Secreto de API + + + Secretos de API + + + Eliminar + + + Creado + + + Descripción + + + Expiración + + + Tipo + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.es.resx new file mode 100644 index 000000000..291b48da3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clientes + + + Cliente + + + Cliente - + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.es.resx new file mode 100644 index 000000000..b24ec35bd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clonar cliente + + + Eliminar cliente + + + Guardar cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.es.resx new file mode 100644 index 000000000..704aee133 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autenticación/Cierre de sesión + + + elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.es.resx new file mode 100644 index 000000000..6d7da38d4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.es.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Administrar propiedades de cliente + + + Administrar secretos de cliente + + + Básico + + + Elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultado de la busqueda: (has clic en un elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.es.resx new file mode 100644 index 000000000..f4eb1ab7a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Pantalla de consentimiento + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.es.resx new file mode 100644 index 000000000..65ab4d8da --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Flujo de dispositivo + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.es.resx new file mode 100644 index 000000000..4df82a381 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.es.resx @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El tiempo de vida máximo de una token de refresco en segundos. 2592000 segundos / 30 dias por defecto. + + + Tiempo de vida absoluto de la token de refresco + + + El tiempo de vida de la token de acceso en segundos. 3600 segundos / 1 hora por defecto. + + + Tiempo de vida de la token de acceso + + + Especifica si la token de acceso es una token de referencia o una token JWT autocontenida. JWT por defecto. + + + Tipo de token de acceso + + + Especifica si este cliente le es permitido recivir tokens de acceso via navegador. Esto es util para reforzar flujos que permite multiple tipos de respuesta (Por ejemplo, impidiendo a un cliente de flujo hibrido que se supone que usa el código id_token para agregar el tipo de respuesta de token y por ende dejando escapar la token al navegador). + + + Permitir token de acceso via navegador + + + Especifica si este cliente puede solicitar tokens de refresco (solicitando el alcance offline_access). + + + Permitir acceso sin conexión + + + Especifica si los clientes usando PKCE pueden usar el desafio de código de texto plano. No recomendado. Deshabilitado por defecto + + + Permitir PKCE en texto plano + + + Especifica si el usuario puede escojer almacenar las deciciones de consentimiento. Habilitado por defecto. + + + Permitir recordar censentimiento + + + + + + Siempre incluye reclamaciones de usuario en IdToken + + + Si esta establecido, las reclamaciones de cliente seran enviadas en cada flujo. En caso contrario, solo para el flujo de credenciales de cliente. Deshabilitado por defecto. + + + Siempre enviar reclamaciones de cliente + + + El tiempo de vida del codigo de autorización en segundos. 300 segundos / 5 minutos por defecto. + + + Tiempo de vida del código de autorización + + + ID unica del cliente + + + ID del cliente + + + Nombre en pantalla del cliente. Usado en las pantallas de inicio de sesión y consentieminto. + + + Nombre del cliente + + + URI hacia más información acerca del cliente. Usado en la pantalla de consentimiento. + + + URI del cliente + + + Especifica si el cliente esta habilitado. Habilitado por defecto. + + + Habilitado + + + Especifica si el cliente puede usar cuentas locales o solo proveedores de identidad externos. Habilitado por defecto. + + + Habilitar el inicio de sesión local + + + Tiempo de vida de la token de indentidad en segundos. 300 seconds / 5 minutes por defecto. + + + Tiempo de vida del token de identidad + + + Especifica si las tokens de acceso JWT deberian tener una ID unica integrada (via la reclamación JTI). + + + Incluir la ID del JWT + + + URI del logo del cliente (usado en la pantalla de consentimiento). + + + URI del logo + + + Absoluta: La token de refresco expirara en un punto fijo en el tiempo (especificado por AbsoluteRefreshTokenLifetime). + +Corrediza: Cuando se este refrescando la token, el tiempo de vida de la token de refresco sera renovado (especificado por SlidingRefreshTokenLifetime). El tiempo de vida no excederá a AbsoluteRefreshTokenLifetime. + + + Expiración de la token de refresco + + + ReUse: El tirador de la token de refresco se mantendra igual cuando se refresquen tokens. + +OneTime: El tirador de la token de refresco sera actualizada cuando se refresquen tokens. + + + Uso de la token de refresco + + + ReUse: El tirador de la token de refresco se mantendra igual cuando se refresquen tokens. + +OneTime: El tirador de la token de refresco sera actualizada cuando se refresquen tokens. + + + Uso de la token de refresco + + + Especifica si este cliente necesita un secreto para solicitar tokens desde un punto final de token. Habilitado por defecto. + + + Requiere secreto de cliente + + + Especifica si una pantalla de consentimiento es necesaria. Habilitado por defecto. + + + Requiere consentimiento + + + Especifica si los clientes usando un tipo de concesión basado en código de autorización debe enviar una llave de evidencia + + + Requiere PKCE + + + Tiempo de vida corredizo de una token de refresco en segundos. 1296000 segundos / 15 dias por defecto. + + + Tiempo de vida corredizo de la token de refresco + + + Obtiene o establece un valor indicando si la token de acceso (y sus reclamaciones) deberian ser actualizadas en una petición de token de refresco. + + + Actualizar las reclamaciones de la token de acceso al refrescar + + + Si es especificado, puede ser usado por las implementaciones de servicio politicas de CORS por defecto (In-Memory y EF) para construir una politica de CORS para clientes de JavaScript. + + + Origenes CORS permitidos + + + Especifica los tipos de concesiones el cliente tiene permitido usar. Usa la clase GrantTypes para combinaciones comunes. Lista de concesiones por defecto: Concesión implicita - (implicit), Concesión de credenciales de cliente - (client_credentials), Concesión de codigo de autorización - (authorization_code), Concesión híbrida - (hybrid), Concesió de credenciales de contraseña del propietario del recurso - (password) + + + Tipos de concesión permitidas + + + Por defecto un cliente no tiene acceso a ningun recurso - especifica los recursos permitidos añadiendo los nombres de alcance correspondientes. + + + Alcances permitidos + + + Permite establecer reclamaciones para el cliente (seran incluidas en el token de acceso). + + + Reclamaciones + + + Lista de secretos de cliente - credenciales para acceder al punto final del token. + + + Secretos del cliente + + + Especifica cuales proveedores de identidad externos pueden ser usados con este cliente (puede usarse todos los proveedores de identidad externos si la lista esta vacia). Vacio por defecto. + + + Restricciones de proveedor de identidad + + + Especifica URIs a las que se puede redireccionar despues de un cierre de sesión. + + + URIs de redirección despues del cierre de sesión + + + Especifica las URIs permitidas a la que es posible entregar tokens o códigos de authorización. + + + URIs de redirección + + + + + + Tipo de reclamación + + + + + + Valor de reclamación + + + + + + Tipo de secreto + + + + + + Valor del secreto + + + + + + Tipo de hash + + + Nombre del rol normalizado. + + + Nombre normalizado + + + Especifica si la ID de sesión del usuario deberia ser enviada en la petición a la BackChannelLogoutUri. Habilitado por defecto. + + + Requiere canal trasero de cierre de sesión + + + Especifica la URI de cierre de sesión en el cliente para el cierre de sesión vía canal trasero basadas en HTTP. Ve la especificación del canal trasero de OIDC para más detalles. + + + URI del canal trasero de cierre de sesión + + + Si es establecido, las reclamaciones de client usaran este prefijo. "client_" por defecto. La intencion es hacer que estas no entren en conflicto demanera accidental con las reclamaciones de usuario. + + + Prefijo de reclamaciones de cliente + + + Descripción de cliente + + + Descripción + + + Especifica si la ID de sesión del usuario deberia ser enviada a la FrontChannelLogoutUri. Habilitado por defecto. + + + Requiere canal frontal de cierre de sesión + + + Especifica la URI de cierre de sesión en el cliente para el cierre de sesión via canal frontal basado en HTTP. Ve la especificación del canal frontal de OIDC para más detalles. + + + URI del canal frontal de cierre de sesión + + + Valor de la sal usada en la generación de subjectId por sabido para usuarios de este cliente. + + + Sal del sujeto por sabido + + + Diccionario para mantener cualquier valor personalizado especifico de cliente según sea necesario. + + + Propiedades + + + Llave + + + Llave + + + Valor + + + Valor + + + El protocolo OpenID Connect por defecto. + + + Tipo de protocolo + + + La duración máxima (en segundos) desde la ultima vez que el usuario se autentico. Nulo por defecto. + + + Tiempo de vida del SSO del usuario + + + Tiempo de vida del código de dispositivo en segundos. 300 segundos / 5 minutos por defecto. + + + Tiempo de vida del código de despositivo + + + Especifica el tipo de código de usuario a usar por el cliente. De lo contrario utiliza default. + + + Tipo de código de usuario + + + Expiración + + + Expiración + + + Descripción + + + Descripción + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.es.resx new file mode 100644 index 000000000..8ea0f3a20 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.es.resx @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Nombre + + + Flujo de codigo de autorización con PKCE + + + TV y aplicaciones de dispositivos con métodos de entrada limitados + + + Flujo de dispositivo + + + Vacio - Por defecto + + + Flujo hibrido + + + Flujo implicito + + + Máquina/Robot + + + Aplicaciones nativas - Móvil/Escritorio + + + Flujo de dueño de recurso y credenciales de cliente + + + Aplicación de una página - Javascript + + + Applicación Web - Del lado del servidor + + + Applicación Web - Del lado del servidor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.es.resx new file mode 100644 index 000000000..2e70cd16d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Administra reclamaciones de cliente + + + Token + + + Elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.es.resx new file mode 100644 index 000000000..16c67d3f3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autenticación/Cierre de sesión + + + Básico + + + Pantalla de consentimiento + + + Flujo de dispositivo + + + Nombre + + + Token + + + Configuración + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.es.resx new file mode 100644 index 000000000..b1b1520f4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar reclamación de cliente + + + Reclamaciones de cliente + + + Clientes + + + Eliminar reclamación de cliente + + + Eliminar reclamación de cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.es.resx new file mode 100644 index 000000000..c78a1d43d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.es.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar reclamación de cliente + + + Reclamaciones de cliente + + + Clientes + + + Reclamaciones de cliente + + + Reclamación de cliente + + + Reclamaciones de cliente + + + elemento ya seleccionado + + + Elemento no seleccionado + + + El tipo es requerido + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + + Eliminar + + + Tipo + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.es.resx new file mode 100644 index 000000000..d8f9c0ff9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clonar cliente + + + Los secretos del cliente no seran clonados. + + + Info: + + + Reclamaciones del cliente + + + Origenes CORS del cliente + + + Tipos de concesión del cliente + + + Restricciones de proveedor de identidad del cliente + + + URIs de redirección despues del cierre de sesión del cliente + + + Propiedades del cliente + + + URIs de redirección del cliente + + + Alcances del cliente + + + Clientes + + + Clonar cliente + + + Cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.es.resx new file mode 100644 index 000000000..e8ec24d82 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar cliente + + + Clientes + + + Eliminar cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.es.resx new file mode 100644 index 000000000..85de8069b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar propiedad de cliente + + + Propiedades del cliente + + + Clientes + + + Propiedades del cliente + + + Propiedades del cliente + + + Propiedad del cliente + + + Eliminar + + + Llave + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.es.resx new file mode 100644 index 000000000..66d59a65c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar propiedad del cliente + + + Propiedades del cliente + + + Clientes + + + Eliminar propiedad del cliente + + + Eliminar propiedad del cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.es.resx new file mode 100644 index 000000000..a5a1b3905 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar secreto del cliente + + + Clientes + + + Secretos del cliente + + + Eliminar secreto del cliente + + + Eliminar secreto del cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.es.resx new file mode 100644 index 000000000..28189e80c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar secreto de cliente + + + HashType será aplicable solo para el tipo SharedSecret. + + + Info: + + + Clientes + + + Secretos del cliente + + + Secretos del cliente + + + Secretos del cliente + + + Secreto del cliente + + + Eliminar + + + Tipo + + + Valor + + + Creado + + + Descripción + + + Expiración + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.es.resx new file mode 100644 index 000000000..f300e1f3d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar cliente + + + Clientes + + + Editar + + + ID del cliente + + + Nombre del cliente + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.es.resx new file mode 100644 index 000000000..57be22cb4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.es.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar recurso de identidad + + + Administrar propiedades del recurso de identidad + + + Guardar recurso de identidad + + + Recursos de identidad + + + Recurso de identidad + + + Recurso de identidad + + + elemento ya seleccionado + + + No hay elementos seleccionados + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.es.resx new file mode 100644 index 000000000..5e7ed0981 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.es.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Este valor puede ser usado, por ejemplo, en la pantalla de consentimiento. + + + Descripción + + + Este valor puede ser usado, por ejemplo, en la pantalla de consentimiento. + + + Nombre en pantalla + + + Especifica si la pantalla de consentimiento enfatizará este alcance (si es que la pantalla de consentimiento implementa la caracteristica). Usa esta opción para alcances delicadas o importantes. Deshabilitado por defecto. + + + Enfatizar + + + Indica si el recurso esta habilitado y puede ser solicitado. Habilitado por defecto. + + + Habilitado + + + El nombre unico del recurso de identidad. Este es el valor que un cliente puede usar para el parametro de alcance en la petición de autorización. + + + Nombre + + + Diccionario que mantiene cualquier valor especifico personalizado de recurso de identidad cuando se necesite. + + + Propiedades + + + Llave + + + Llave + + + Valor + + + Valor + + + Especifica si el usuario puede desmarcar el alcance en la pantalla de consentimiento (si la pantalla de consentimiento implementa la funcionalidad). Deshabilitado por defecto. + + + Requerido + + + Especifica si el alcance aparece en el documento de descubrimiento. Habilitado por defecto. + + + Mostrar en documento de descrubrimiento + + + Lista de tipos de reclamación de usuario asociadas que deberian ser incluidas en la token de identidad. + + + Reclamaciones de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.es.resx new file mode 100644 index 000000000..27161c239 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar recurso de identidad + + + Recursos de identidad + + + Eliminar recurso de identidad + + + Eliminar recurso de identidad + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.es.resx new file mode 100644 index 000000000..0fcc13c1c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar propiedad de recurso de identidad + + + Propiedades de recurso de identidad + + + Recursos de identidad + + + Propiedades del recurso de identidad + + + Propiedades del recurso de identidad + + + Propiedad del recurso de identidad + + + Eliminar + + + Llave + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.es.resx new file mode 100644 index 000000000..fda98d2c0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar propiedad del recurso de identidad + + + Propiedades del recurso de identidad + + + Recursos de identidad + + + Eliminar propiedad del recurso de identidad + + + Eliminar propiedad del recurso de identidad + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.es.resx new file mode 100644 index 000000000..323f99d9c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar recurso de identidad + + + Recursos de identidad + + + Editar + + + Nombre + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.es.resx new file mode 100644 index 000000000..5ccc68e57 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.es.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar todo + + + ¿Estas seguro? Las concesiones persistidas para esta sujeto seran eliminadas. + + + No - cerrar + + + Advertencia + + + Si - eliminar + + + Cencesiones persistidas + + + Concesión persistida + + + Cliente + + + Data + + + Expiración + + + ID del sujeto + + + Tipo + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.es.resx new file mode 100644 index 000000000..3c1ee2558 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar concesión persistida + + + Concesiones persistidas + + + Eliminar concesión persistida + + + Cliente + + + Data + + + Expiración + + + ID del sujeto + + + Tipo + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.es.resx new file mode 100644 index 000000000..86412801f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Concesiones persistidas + + + Detalle + + + ID del sujeto + + + Nombre del sujeto + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.es.resx new file mode 100644 index 000000000..0e0d416f4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Recursos de API + + + Clientes + + + Recursos de identidad + + + Administrar + + + Concesiones persistidas + + + Roles + + + Usuarios + + + La herramienta de administración para IdentityServer4 y Asp.Net Core Identity + + + Skoruba IdentityServer4 Admin + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.es.resx new file mode 100644 index 000000000..273661d47 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar reclamaciones de rol + + + Eliminar rol + + + Usuarios + + + Guardar rol + + + Roles + + + Rol + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.es.resx new file mode 100644 index 000000000..01e8a8005 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nombre del rol + + + Nombre del rol + + + + + + Tipo de reclamación + + + + + + Valor de la reclamación + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.es.resx new file mode 100644 index 000000000..f0161864d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.es.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar reclamación de rol + + + Roles + + + Reclamaciones de rol + + + Reclamaciones de rol + + + Reclamación + + + elemento ya seleccionado + + + No hay elementos seleccionados + + + El elemento es requerido + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + + Eliminar + + + Tipo + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.es.resx new file mode 100644 index 000000000..9acb66f6d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar reclamación de rol + + + Reclamaciones de rol + + + Roles + + + Eliminar reclamación de rol + + + Eliminar reclamación de rol + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.es.resx new file mode 100644 index 000000000..101fc4ab9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar rol + + + Roles + + + Eliminar rol + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.es.resx new file mode 100644 index 000000000..b7cf5c64e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Buscar + + + E-mail + + + Buscar + + + Roles + + + Rol de usuarios + + + ID de usuario + + + Nombre de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.es.resx new file mode 100644 index 000000000..aae2d9277 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar rol + + + Roles + + + Editar + + + Usuarios + + + Nombre + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.es.resx new file mode 100644 index 000000000..991ddb7ef --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.es.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nombre del rol + + + Nombre del rol + + + Rol + + + Rol + + + + + + Tipo de reclamación + + + Numero de intentos fallidos de acceso del usuario + + + Numero de intentos fallidos de acceso del usuario + + + Confirmar contraseña + + + Confirmar contraseña + + + Contraseña + + + Contraseña + + + Nombre de usuario + + + Nombre de usuario + + + E-mail de usuario confirmado + + + E-mail de usuario confirmado + + + E-mail + + + E-mail + + + Bloqueo de usuario habilitado + + + Bloqueo de usuario habilitado + + + Fin del bloqueo de usuario + + + Fin del bloqueo de usuario + + + Número de telefono de usuario confirmado + + + Número de telefono de usuario confirmado + + + Número de telefono de usuario + + + Número de telefono de usuario + + + Proveedor de inicio de sesión + + + Proveedor de inicio de sesión + + + Nombre en pantalla + + + Nombre en pantalla + + + Proveedor de llave + + + Proveedor de llave + + + User Two Factor habilitado + + + User Two Factor habilitado + + + Nombre de usuario + + + Nombre de usuario + + + + + + Valor de reclamación + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.es.resx new file mode 100644 index 000000000..e00e3e20c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cambiar contraseña + + + Usuarios + + + Cambiar contraseña de usuario + + + Cambiar contraseña + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.es.resx new file mode 100644 index 000000000..c2ef343c6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.es.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar reclamación de usuario + + + Usuarios + + + Reclamaciones de usuario + + + Reclamaciones de usuario + + + Reclamación de usuario + + + elemento ya seleccionado + + + No hay elementos selccionados + + + El tipo es requerido + + + Ingresa dos o más caracteres + + + Resultados de la busqueda: (haz clic en el elemento para seleccionarlo) + + + Elementos seleccionados: + + + más + + + Elementos sugeridos: + + + Eliminar + + + Tipo + + + Valor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.es.resx new file mode 100644 index 000000000..2c6eb52b2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar reclamación de usuario + + + Reclamaciones de usuario + + + Usuarios + + + Eliminar reclamación de usuario + + + Eliminar reclamación de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.es.resx new file mode 100644 index 000000000..d41d8de73 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar usuario + + + Usuarios + + + Eliminar usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.es.resx new file mode 100644 index 000000000..1d8e70a46 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.es.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cambiar contraseña + + + Eliminar usuario + + + Administrar reclamaciones de usuario + + + Administrar proveedores de usuarios externos + + + Administrar roles de usuario + + + Guardar usuario + + + Usuarios + + + Usuario + + + Usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.es.resx new file mode 100644 index 000000000..3414b8511 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Usuarios + + + Proveedores de usuarios + + + Eliminar + + + Proveedor de inicio de sesión + + + Nombre en pantalla del proveedor + + + Llave del proveedor + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.es.resx new file mode 100644 index 000000000..ba5434cd1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar proveedor de usuarios + + + Proveedores de usuarios + + + Usuarios + + + Eliminar proveedor de usuarios + + + Eliminar proveedor de usuarios + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.es.resx new file mode 100644 index 000000000..569283f1d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar rol + + + Eliminar + + + Usuarios + + + Nombre + + + Rol de usuario + + + Roles de usuario + + + Roles + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.es.resx new file mode 100644 index 000000000..26f9dc182 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar rol + + + Roles de usuario + + + Usuarios + + + Eliminar rol + + + Rol de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.es.resx new file mode 100644 index 000000000..446c01650 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agregar usuario + + + Editar + + + E-mail + + + Usuarios + + + ID de usuario + + + Nombre de usuario + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.es.resx new file mode 100644 index 000000000..046c5a3f2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.es.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar registros antes del + + + ¿Estas seguro? + + + No - cerrar + + + Advertencia + + + Si - eliminar + + + Registros + + + Nivel + + + Registrado + + + Mensaje + + + Mostrar detalle + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.es.resx new file mode 100644 index 000000000..6db742534 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.es.resx new file mode 100644 index 000000000..582ee28f1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Primero + + + Ultimo + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.es.resx new file mode 100644 index 000000000..1c96e0411 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Buscar + + + Buscar + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.es.resx new file mode 100644 index 000000000..b9817cc6a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Idioma: + + diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.es.resx new file mode 100644 index 000000000..27ad81e9d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.es.resx new file mode 100644 index 000000000..adf60684b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + &copy; 2019 + + + Skoruba IdentityServer4 Admin + + + Recursos de API + + + Clientes + + + Recursos de identidad + + + Cerrar sesión + + + Concesiones persistidas + + + Roles + + + Usuarios + + + Menú + + + Skoruba IdentityServer4 Admin + + + Clientes/Recursos + + + Registros + + + Usuarios/Roles + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 273124f29..af87d2875 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -67,7 +67,8 @@ public static void AddMvcWithLocalization(this IServiceCollection s new CultureInfo("fr"), new CultureInfo("ru"), new CultureInfo("sv"), - new CultureInfo("zh") + new CultureInfo("zh"), + new CultureInfo("es") }; opts.DefaultRequestCulture = new RequestCulture("en"); diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.es.resx new file mode 100644 index 000000000..4761c4faf --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.es.resx @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Por favor, confirma tu cuenta haciento <a href='{0}'>clic aquí</a>. + + + Confirma tu e-mail + + + El usuario no existe o no ha confirmado su cuenta + + + Error de proveedor externo: {0} + + + Código de autenticador invalido. + + + El código de recuperación ingresado es invalido. + + + Por favor, cambia tu contraseña haciendo <a href='{0}'>clic aquí</a>. + + + Restablecer contraseña + + + Fue imposible cargar el usuario de autenticación en dos pasos. + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.es.resx new file mode 100644 index 000000000..685d9ba7b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.es.resx @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El usuario con ID '{0}' pregunto por su información personal. + + + Tu aplicación autenticadora fue verificada. + + + Por favor, confirma tu cuenta haciendo <a href='{0}'>clic aquí</a> + . + + + Confirma tu e-mail + + + El usuario con ID '{0}' se eliminó a si mismo. + + + No se pueden generar los codigos de recuperación para el usuario con ID {0} porque no tienen la autenticación en dos pasos habilitada. + + + Código + + + Ocurrio un error inesperado al tratar de eliminar el usuario con ID {0}. + + + Ocurrio un error inesperado al tratar de deshabilitar autenticación en dos pasos para el usuario con ID {0}. + + + No se pudieron generar los codigos de recuperación para el usuario ya que no tiene la autenticación en dos pasos habilitada. + + + Ocurrio un error inesperado al cargar la información externa de inicio de sesión para el usuario con ID {0}. + + + Ocurrio un error inesperado al remover el inicio de sesión externo para el usuario con ID {0}. + + + Ocurrio un error inesperado al configurar el e-mail para el usuario con ID {0}. + + + Ocurrio un error inesperado al configurar el número de telefono para el usuario con ID {0}. + + + El inicio de sesión externo fue agregado. + + + El inicio de sesión externo fue quitado. + + + El código de verificación es inválido. + + + Tu contraseña ha sido cambiada. + + + El usuario {0} cambió su contraseña con éxito. + + + La contraseña no es correcta. + + + Tu contraseña ha sido establecida. + + + Tu perfil ha sido actualizado. + + + El usuario con ID {0} ha desabilitado la autenticación en dos pasos. + + + El navegador actual ha sido olvidado. Cuando te autentifiques denuevo desde este navegador se te preguntara con tu código de autenticación en dos pasos. + + + El usuario con ID {0} ha restablecido su llave de app de autenticación. + + + El usuario con ID {0} ha habilitado la autenticación en dos pasos con una app autenticadora. + + + El usuario con ID {0} ha generado nuevos códigos de recuperación de autenticación en dos pasos. + + + No es posible cargar el usuario con ID {0}. + + + E-mail de verificación enviado. Por favor, revisa tu bandeja de entrada. + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx new file mode 100644 index 000000000..ff2587e80 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gracias por confirmar tu e-mail. + + + Confirmar e-mail + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx new file mode 100644 index 000000000..9255de959 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Email + + + Te has autentificado de manera exitosa con {0}. + Por favor, ingresa una dirección de correo electrónico para este sitio debajo y has clic en el boton Register para terminar de + iniciar sesión. + + + Regístrate + + + Asocia tu {0} cuenta. + + + Regístrate + + + Nombre de usuario + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx new file mode 100644 index 000000000..e1cb7a3ce --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + La autentificación con el servicio no fue exitosa. + + + Fallo de inicio de sesión + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx new file mode 100644 index 000000000..0e6846c00 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Enviar + + + Ingresa tu e-mail. + + + ¿Olvidaste tu contraseña? + + + E-mail + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx new file mode 100644 index 000000000..11babf008 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Por favor, revisa tu e-mail para restablecer tu contraseña. + + + Confirmación de contraseña olvidada + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.es.resx new file mode 100644 index 000000000..55d62692f --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Esta cuenta ha sido bloqueado. Por favor, intentelo nuevamente más tarde. + + + Bloqueado + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.es.resx new file mode 100644 index 000000000..b3dbf454d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clic + + + aquí + + + para volver a la + + + Tu sesión ha sido cerrada + + + Sesión cerrada + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.es.resx new file mode 100644 index 000000000..25efaa08e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.es.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cancelar + + + E-mail + + + Inicio de sesión externo + + + Olvidé mi contraseña + + + Petición de inicio de sesión inválido + + + Inicio de sesión local + + + Inicio de sesión + + + No hay esquemas de inicio de sesión configurados para este cliente. + + + Contraseña + + + Registrarse + + + Recordar inicio de sesión + + + Iniciar sesión + + + Nombre de usuario + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx new file mode 100644 index 000000000..429311a73 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código autenticador + + + Tu inicio de sesión esta protegido con una app autenticadora. Ingresa tu código autenticador debajo. + + + Iniciar sesión + + + Inicia sesión con un código de recuperación + + + ¿No tienes acceso a tu dispositivo autenticador? Puedes + + + Recordar esta máquina + + + Autentificación en dos pasos + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx new file mode 100644 index 000000000..fcdaa6d76 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código de recuperación + + + Has podido iniciar sesión con un código de recuperación. Este inicio de sesión no sera recordado hasta que proveas + un código de aplicación autenticadora al iniciar sesión o deshabilita la autenticación en dos pasos e inicia sesión nuevamente. + + + Iniciar sesión + + + Verificación del código de recuperación + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.es.resx new file mode 100644 index 000000000..203945250 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ¿Quisieras cerrar la sesión de IdentityServer? + + + Cerrar sesión + + + Si + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.es.resx new file mode 100644 index 000000000..8b1c44a6b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registrarse + + + Confirmar contraseña + + + E-mail + + + Contraseña + + + Crea una nueva cuenta. + + + Registrarse + + + Nombre de usuario + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx new file mode 100644 index 000000000..4265b6397 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El registro de cuentas esta deshabilitado. + + + Problema de registro + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.es.resx new file mode 100644 index 000000000..0d9048cb9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + E-mail + + + Contraseña + + + Restablecer + + + Restablece tu contraseña. + + + Restablecer contraseña + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx new file mode 100644 index 000000000..1386c9b33 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tu contraseña ha sido restablecida. Por favor, + + + has clic aquí para iniciar sesión + + + Confirmación de restablecimiento de contraseña + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.es.resx new file mode 100644 index 000000000..498d7eb22 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Acceso ha aplicación + + + No, no permitir + + + Información personal + + + Recordar mi decisión + + + está pidiendo su permiso + + + Deselecciona los permisos que no quieras otorgar. + + + Si, permitir + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.es.resx new file mode 100644 index 000000000..eef603d9e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Éxito + + + Has autorizado este dispositivo de forma exitosa + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx new file mode 100644 index 000000000..7f3a0e85a --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Por favor, ingresa el código que se muestra en tu dispositivo + + + Enviar + + + Código de usuario + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx new file mode 100644 index 000000000..effb2396e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Acceso a aplicación + + + Por favor, confirma que la petición de autorización tiene el código: + + + No, no permitir + + + Información personal + + + Recuerda mi decisión + + + esta preguntado por tu permiso + + + Desmarca los permisos que no quires otorgar. + + + Si, permitir + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.es.resx new file mode 100644 index 000000000..9cdf0eaea --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Reclamaciones + + + Clientes + + + Propiedades + + + Cookie de autentificación + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.es.resx new file mode 100644 index 000000000..b1499349c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Concesiones de API + + + Creado: + + + Expira: + + + Concesiones de identidad + + + No has dado acceso a ninguna aplicación + + + Revocar acceso + + + Debajo hay una lista de aplicaciones a las que has dado acceso y los nombres de los recursos a los que tienen acceso. + + + Acceso de aplicaciones cliente + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx new file mode 100644 index 000000000..7fe1515f5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autentificación en dos pasos + + + Cambiar contraseña + + + Documento de descubrimiento + + + Concesiones persistidas + + + ejemplos listos para usar + + + repositorio con el codigo fuente + + + Aquí hay enlaces al + + + Inicio de sesión + + + Mi información personal + + + Mi perfil + + + Bienvenido a Skoruba IdentityServer4 + + + Skoruba IdentityServer4 + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx new file mode 100644 index 000000000..337bcae33 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + Nueva contraseña + + + Contraseña actual + + + Cambiar contraseña + + + Cambiar contraseña + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx new file mode 100644 index 000000000..a6c36b4f9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Al eliminar estos datos estaras eliminado tu cuenta de manera permanente. No es posible deshacer esta acción. + + + Eliminar datos y cerrar mi cuenta + + + Contraseña + + + Eliminar datos personales + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx new file mode 100644 index 000000000..7a99766a3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Deshabilitar la autenticación en dos pasos + + + Deshabilitar la autenticación en dos pasos no cambia las llaves usadas en la app autenticadora. Si deseas cambiar la llave usada en la app autenticadora debes + + + restablecer las llaves de tu autenticador + + + Esta acción solo deshabilita la autenticación en dos pasos. + + + Deshabilita la autentificación en dos pasos + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx new file mode 100644 index 000000000..7707a45f0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Descarga tus datos + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx new file mode 100644 index 000000000..c72a4d26f --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código de verificación + + + Descarga una app autenticadora de dos pasos como Microsoft Authenticator para + + + Google Authenticator para + + + Una vez hayas escaneado el codigo QR o hayas ingresado la llave arriva, tu app autenticadora de dos pasos podra proveerte + con un código unico. Ingresa el código en la caja de confirmación. + + + Escanea el código QR o ingresa esta llave + + + en tu app autenticadora de dos pasos. Los espacios y las mayusculas no importan. + + + Para usar una app autenticadora sigue los siguientes pasos: + + + Configurar app autenticadora + + + Verificar + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx new file mode 100644 index 000000000..c3fda7202 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Quitar + + + Inicios de sesión registrados + + + Administra tus inicios de sesión externos + + + Agrega otro servicio de inicio de sesión. + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx new file mode 100644 index 000000000..ac0962bae --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Genera códigos de recuperación + + + Generar nuevos códigos de verificación no cambia las llaves usadas en la apps autenticadoras. Si deseas cambiar la llave usada en la app autenticadora deberias + + + Si pierdes tu dispositivo y no tienes el código de recuperación perderas el acceso a tu cuenta. + + + Restablece tus llaves autenticadoras. + + + Guarda estos códigos en un lugar seguro. + + + Genera códigos de recuperación para la autenticación en dos pasos + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.es.resx new file mode 100644 index 000000000..e13838ef5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + País + + + E-mail + + + Ciudad + + + Nombre completo + + + Número de telefono + + + Código postal + + + URL de perfil + + + Región + + + Guardar + + + Enviar e-mail de verificación + + + Dirección + + + Perfil + + + Nombre de usuario + + + Url de sitio web + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx new file mode 100644 index 000000000..e0a477e41 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Inicio de sesión con servicio no exitoso. + + + Falló el inicio de sesión + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.es.resx new file mode 100644 index 000000000..660caa335 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar + + + Descargar + + + Tu cuenta contiene datos personales que nos has entregado. Esta página te permite descargar o eliminar estos datos. + + + Datos personales + + + Eliminar estos datos eliminara permanentemente tu cuenta. No es posible deshacer esta acción. + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx new file mode 100644 index 000000000..d1656dd21 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Este proceso deshabilitará la autenticación en dos pasos hasta que verifiques tu app autenticadora. + Si no completas la configuración de tu app autenticadora podrias perder el acceso a tu cuenta. + + + Restablecer llave autenticadora + + + Si restableces tu llave autenticadora tu app autenticadora podria no funcionar hasta que la configures. + + + Resetear llave autenticadora + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.es.resx new file mode 100644 index 000000000..82b0799ac --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + No tienes un usuario/contraseña local para este sitio. Agrega una cuenta local para poder ingresar sin un inicio de sesión externo. + + + Nueva contraseña + + + Establecer contraseña + + + Establece tu contraseña + + + Establecer contraseña + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx new file mode 100644 index 000000000..2b7b28752 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Si pierdes tu dispositivo y no tienes acceso a tus códigos de recuperación perderas el acceso a tu cuenta. + + + Guarda estos códigos en un lugar seguro. + + + Códigos de recuperación + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx new file mode 100644 index 000000000..df05aef2c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agrega una app autenticadora + + + App autenticadora + + + Antes de poder ingresar con un código de recuperación + + + Desabilitar la autenticación en dos pasos + + + Olvidar este navegador + + + genera un nuevo conjunto de códigos de recuperación + + + No te quedan códigos de recuperación + + + te queda un código de recuperación + + + códigos de recuperación + + + Restablecer app autenticadora + + + Restablecer códigos de recuperación + + + Configurar app autenticadora + + + Autentificación en dos pasos + + + Puedes generar un nuevo conjunto de códigos de recuperación + + + Tienes + + + Debes + + + Deberias + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx new file mode 100644 index 000000000..2628fbe14 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Idiomas: + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx new file mode 100644 index 000000000..bb5c28976 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer Admin + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.es.resx new file mode 100644 index 000000000..caca1746b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Perdón, hubo un error + + + ID de petición: + + + Error + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.es.resx new file mode 100644 index 000000000..06d1ce8f6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Una vez completado, puedes cerrar esta pestaña + + + Estas siendo redireccionado a la aplicación. + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx new file mode 100644 index 000000000..9cfc0b9fe --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Autentificación en dos pasos + + + Cambiar contraseña + + + Mis inicios de sesión externos + + + Skoruba IdentityServer4 + + + © 2019 + + + Concesiones + + + Mis datos personales + + + Mi perfil + + + Menú + + + IdentityServer4 + + + Configuración + + + Cerrar sesión + + + Skoruba IdentityServer4 + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx new file mode 100644 index 000000000..d35884f57 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (requerido) + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx new file mode 100644 index 000000000..71f62ac84 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + + \ No newline at end of file From 1e2599c140247dc9db22db73b116c9608cf96d0d Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 10:14:29 +0200 Subject: [PATCH 153/338] Update AdminConfiguration --- .../Configuration/AdminConfiguration.cs | 10 ++++------ .../Configuration/Interfaces/IAdminConfiguration.cs | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index da51eeb29..1958b0ea8 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -10,17 +10,15 @@ public class AdminConfiguration : IAdminConfiguration public string IdentityAdminRedirectUri { get; set; } public string[] Scopes { get; set; } - public string IdentityAdminApiSwaggerUIClientId { get; } = AuthenticationConsts.IdentityAdminApiSwaggerClientId; - public string IdentityAdminApiSwaggerUIRedirectUrl { get; } = "http://localhost:5001/swagger/oauth2-redirect.html"; - public string IdentityAdminApiScope { get; } = AuthenticationConsts.IdentityAdminApiScope; + public string IdentityAdminApiSwaggerUIClientId { get; } + public string IdentityAdminApiSwaggerUIRedirectUrl { get; } + public string IdentityAdminApiScope { get; } + public string AdministrationRole { get; } public string IdentityServerBaseUrl { get; set; } public string ClientId { get; set; } - public string[] Scopes { get; set; } public string ClientSecret { get; set; } public string OidcResponseType { get; set; } = AuthenticationConsts.OidcAuthenticationScheme; - public string AdministrationRole { get; set; } - } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs index 803c73433..1dabb5278 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs @@ -12,5 +12,6 @@ public interface IAdminConfiguration string IdentityAdminApiSwaggerUIClientId { get; } string IdentityAdminApiSwaggerUIRedirectUrl { get; } string IdentityAdminApiScope { get; } + string AdministrationRole { get; } } } \ No newline at end of file From 859988aa8ca421efe6806df7f4f68dd22d238bdf Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 11:55:49 +0200 Subject: [PATCH 154/338] Remove secrets from constants; Polish AdminConfiguration; Add client for swagger api; --- .../Configuration/AdminConfiguration.cs | 15 +- .../Configuration/ClientDataConfiguration.cs | 3 +- .../Constants/AuthenticationConsts.cs | 6 - .../Configuration/Identity/Client.cs | 9 - .../Configuration/Identity/Users.cs | 9 - .../Configuration/IdentityServer/Client.cs | 10 + .../Interfaces/IAdminConfiguration.cs | 4 - .../Interfaces/IClientDataConfiguration.cs | 3 +- .../appsettings.json | 303 +++++++++--------- 9 files changed, 174 insertions(+), 188 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Users.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Client.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index 1958b0ea8..74e29b178 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -1,24 +1,15 @@ -using Skoruba.IdentityServer4.Admin.Configuration.Constants; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; namespace Skoruba.IdentityServer4.Admin.Configuration { public class AdminConfiguration : IAdminConfiguration { - public string IdentityAdminBaseUrl { get; set; } - public string IdentityAdminRedirectUri { get; set; } public string[] Scopes { get; set; } - - public string IdentityAdminApiSwaggerUIClientId { get; } - public string IdentityAdminApiSwaggerUIRedirectUrl { get; } - public string IdentityAdminApiScope { get; } - public string AdministrationRole { get; } - - + public string AdministrationRole { get; set; } public string IdentityServerBaseUrl { get; set; } public string ClientId { get; set; } public string ClientSecret { get; set; } - public string OidcResponseType { get; set; } = AuthenticationConsts.OidcAuthenticationScheme; + public string OidcResponseType { get; set; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs index 314179c68..8b44a238b 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs @@ -1,12 +1,13 @@ using IdentityServer4.Models; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using System.Collections.Generic; +using Client = Skoruba.IdentityServer4.Admin.Configuration.IdentityServer.Client; namespace Skoruba.IdentityServer4.Admin.Configuration { public class ClientDataConfiguration : IClientDataConfiguration { - public List Clients { get; set; } = new List(); + public List Clients { get; set; } = new List(); public List IdentityResources { get; set; } = new List(); public List ApiResources { get; set; } = new List(); } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs index 65eb4ac55..f0a62bf46 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs @@ -4,14 +4,8 @@ public class AuthenticationConsts { public const string IdentityAdminCookieName = "IdentityServerAdmin"; public const string SignInScheme = "Cookies"; - public const string OidcAuthenticationScheme = "oidc"; - public const string IdentityAdminApiScope = "skoruba_identity_admin_api"; - - public const string RoleClaim = "role"; - public const string AccountLoginPage = "Account/Login"; - public const string AccountAccessDeniedPage = "/Account/AccessDenied/"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs deleted file mode 100644 index 8525f0513..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Client.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace Skoruba.IdentityServer4.Admin.Configuration.Identity -{ - public class Client: global::IdentityServer4.Models.Client - { - public List ClientClaims { get; set; } = new List(); - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Users.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Users.cs deleted file mode 100644 index e541be57c..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Identity/Users.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Skoruba.IdentityServer4.Admin.Configuration.Identity -{ - public class Users - { - public const string AdminUserName = "admin"; - public const string AdminPassword = "Pa$$word123"; - public const string AdminEmail = "admin@example.com"; - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Client.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Client.cs new file mode 100644 index 000000000..dfd80e838 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServer/Client.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Skoruba.IdentityServer4.Admin.Configuration.Identity; + +namespace Skoruba.IdentityServer4.Admin.Configuration.IdentityServer +{ + public class Client : global::IdentityServer4.Models.Client + { + public List ClientClaims { get; set; } = new List(); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs index 1dabb5278..d578981c4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs @@ -4,14 +4,10 @@ public interface IAdminConfiguration { string IdentityAdminRedirectUri { get; } string IdentityServerBaseUrl { get; } - string IdentityAdminBaseUrl { get; } string ClientId { get; } string ClientSecret { get; } string OidcResponseType { get; } string[] Scopes { get; } - string IdentityAdminApiSwaggerUIClientId { get; } - string IdentityAdminApiSwaggerUIRedirectUrl { get; } - string IdentityAdminApiScope { get; } string AdministrationRole { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs index 610bd9e32..2a60da1f2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs @@ -1,11 +1,12 @@ using IdentityServer4.Models; using System.Collections.Generic; +using Client = Skoruba.IdentityServer4.Admin.Configuration.IdentityServer.Client; namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { public interface IClientDataConfiguration { - List Clients { get; } + List Clients { get; } List IdentityResources { get; } List ApiResources { get; } } diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index b66cb711f..3f4b854a6 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -1,12 +1,11 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" - }, + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000", "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", "IdentityServerBaseUrl": "http://localhost:5000", "ClientId": "skoruba_identity_admin", @@ -18,10 +17,7 @@ "email", "roles" ], - "AdministrationRole": "SkorubaIdentityAdminAdministrator", - "IdentityAdminApiSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "IdentityAdminApiSwaggerUIRedirectUrl": "http://localhost:5001/swagger/oauth2-redirect.html", - "IdentityAdminApiScope": "skoruba_identity_admin_api" + "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, "Serilog": { "MinimumLevel": { @@ -48,146 +44,161 @@ "removeStandardColumns": [ "Properties" ] } } - } - ] - }, - "UserData": { - "Roles": [ - { - "Name": "SkorubaIdentityAdminAdministrator" - } - ], - "Users": [ - { - "Username": "administrator", - "Password": "Pa$$word123", - "Email": "admin@example.com", - "Roles": [ - "SkorubaIdentityAdminAdministrator" - ], - "Claims": [ - { - "Type": "name", - "Value": "Administrator" - } - ] - } - ] - }, - "ClientData": { - "IdentityResources": [ - { - "Name": "roles", - "Enabled": true, - "DisplayName": "Roles", - "UserClaims": [ - "role" - ] - }, - { - "Name": "openid", - "Enabled": true, - "Required": true, - "DisplayName": "Your user identifier", - "UserClaims": [ - "sub" - ] - }, - { - "Name": "profile", - "Enabled": true, - "DisplayName": "User profile", - "Description": "Your user profile information (first name, last name, etc.)", - "Emphasize": true, - "UserClaims": [ - "name", - "family_name", - "given_name", - "middle_name", - "nickname", - "preferred_username", - "profile", - "picture", - "website", - "gender", - "birthdate", - "zoneinfo", - "locale", - "updated_at" - ] - }, - { - "Name": "email", - "Enabled": true, - "DisplayName": "Your email address", - "Emphasize": true, - "UserClaims": [ - "email", - "email_verified" - ] - }, - { - "Name": "address", - "Enabled": true, - "DisplayName": "Your address", - "Emphasize": true, - "UserClaims": [ - "address" + } ] - } - ], - "ApiResources": [ - { - "Name": "api1", - "DisplayName" : "Some API 1" - }, - { - "Name": "api2", - "UserClaims": [ - "name", - "email" + }, + "UserData": { + "Roles": [ + { + "Name": "SkorubaIdentityAdminAdministrator" + } ], - "Scopes": [ - { - "Name": "api2.full_access", - "DisplayName": "Full access to API 2" - }, - { - "Name": "api2.read_only", - "DisplayName": "Read only access to API 2" - } + "Users": [ + { + "Username": "admin", + "Password": "Pa$$word123", + "Email": "admin@skoruba.com", + "Roles": [ + "SkorubaIdentityAdminAdministrator" + ], + "Claims": [ + { + "Type": "name", + "Value": "admin" + } + ] + } ] - } - ], - "Clients": [ - { - "ClientId": "skoruba_identity_admin", - "ClientName": "skoruba_identity_admin", - "ClientUri": "http://localhost:9000", - "AllowedGrantTypes": [ - "hybrid" - ], - "ClientSecrets": [ - { - "Value": "skoruba_admin_client_secret" - } - ], - "RedirectUris": [ - "http://localhost:9000/signin-oidc" - ], - "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", - "PostLogoutRedirectUris": [ - "http://localhost:9000/signout-callback-oidc" + }, + "ClientData": { + "IdentityResources": [ + { + "Name": "roles", + "Enabled": true, + "DisplayName": "Roles", + "UserClaims": [ + "role" + ] + }, + { + "Name": "openid", + "Enabled": true, + "Required": true, + "DisplayName": "Your user identifier", + "UserClaims": [ + "sub" + ] + }, + { + "Name": "profile", + "Enabled": true, + "DisplayName": "User profile", + "Description": "Your user profile information (first name, last name, etc.)", + "Emphasize": true, + "UserClaims": [ + "name", + "family_name", + "given_name", + "middle_name", + "nickname", + "preferred_username", + "profile", + "picture", + "website", + "gender", + "birthdate", + "zoneinfo", + "locale", + "updated_at" + ] + }, + { + "Name": "email", + "Enabled": true, + "DisplayName": "Your email address", + "Emphasize": true, + "UserClaims": [ + "email", + "email_verified" + ] + }, + { + "Name": "address", + "Enabled": true, + "DisplayName": "Your address", + "Emphasize": true, + "UserClaims": [ + "address" + ] + } ], - "AllowedCorsOrigins": [ - "http://localhost:9000" + "ApiResources": [ + { + "Name": "api1", + "DisplayName": "Some API 1" + }, + { + "Name": "api2", + "UserClaims": [ + "name", + "email" + ], + "Scopes": [ + { + "Name": "api2.full_access", + "DisplayName": "Full access to API 2" + }, + { + "Name": "api2.read_only", + "DisplayName": "Read only access to API 2" + } + ] + } ], - "AllowedScopes": [ - "openid", - "email", - "profile", - "roles" - ] + "Clients": [ + { + "ClientId": "skoruba_identity_admin", + "ClientName": "skoruba_identity_admin", + "ClientUri": "http://localhost:9000", + "AllowedGrantTypes": [ + "hybrid" + ], + "ClientSecrets": [ + { + "Value": "skoruba_admin_client_secret" + } + ], + "RedirectUris": [ + "http://localhost:9000/signin-oidc" + ], + "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", + "PostLogoutRedirectUris": [ + "http://localhost:9000/signout-callback-oidc" + ], + "AllowedCorsOrigins": [ + "http://localhost:9000" + ], + "AllowedScopes": [ + "openid", + "email", + "profile", + "roles" + ] + }, + { + "ClientId": "skoruba_identity_admin_api_swaggerui", + "ClientName": "skoruba_identity_admin_api_swaggerui", + "AllowedGrantTypes": [ + "implicit" + ], + "RedirectUris": [ + "http://localhost:5001/swagger/oauth2-redirect.html" + ], + "AllowedScopes": [ + "skoruba_identity_admin_api" + ], + "AllowAccessTokensViaBrowser": true + } ] } From 93ea959fb284ac5cbf95c26a60e79e1fa8455f75 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 12:33:57 +0200 Subject: [PATCH 155/338] Clean api resources and use api swagger only; Polish DbMigrationHelpers naming convention; --- .../Helpers/DbMigrationHelpers.cs | 36 ++++++++++--------- .../appsettings.json | 22 ++++-------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 152cdccd6..a8d82dd4d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -90,24 +90,25 @@ private static async Task EnsureSeedIdentityData(UserManager(UserManager Date: Sat, 5 Oct 2019 12:40:11 +0200 Subject: [PATCH 156/338] Rename UserDataConfiguration to IdentityDataConfiguration and ClientDataConfiguration to IdentityServerDataConfiguration --- .../Constants/ConfigurationConsts.cs | 4 ++-- ...uration.cs => IdentityDataConfiguration.cs} | 2 +- ...n.cs => IdentityServerDataConfiguration.cs} | 2 +- ...ration.cs => IIdentityDataConfiguration.cs} | 2 +- ....cs => IIdentityServerDataConfiguration.cs} | 2 +- .../Interfaces/IRootConfiguration.cs | 4 ++-- .../Configuration/RootConfiguration.cs | 12 ++++++------ .../Helpers/DbMigrationHelpers.cs | 18 +++++++++--------- .../Helpers/StartupHelpers.cs | 4 ++-- .../appsettings.json | 4 ++-- 10 files changed, 27 insertions(+), 27 deletions(-) rename src/Skoruba.IdentityServer4.Admin/Configuration/{UserDataConfiguration.cs => IdentityDataConfiguration.cs} (81%) rename src/Skoruba.IdentityServer4.Admin/Configuration/{ClientDataConfiguration.cs => IdentityServerDataConfiguration.cs} (86%) rename src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/{IUserDataConfiguration.cs => IIdentityDataConfiguration.cs} (83%) rename src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/{IClientDataConfiguration.cs => IIdentityServerDataConfiguration.cs} (87%) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs index 885b085d9..abe313da9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs @@ -16,8 +16,8 @@ public class ConfigurationConsts public const string AdminConfigurationKey = "AdminConfiguration"; - public const string ClientDataConfigurationKey = "ClientData"; + public const string IdentityServerDataConfigurationKey = "IdentityServerData"; - public const string UserDataConfigurationKey = "UserData"; + public const string IdentityDataConfigurationKey = "IdentityData"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs similarity index 81% rename from src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs rename to src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs index d14143d80..561fb7bb6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/UserDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs @@ -4,7 +4,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { - public class UserDataConfiguration : IUserDataConfiguration + public class IdentityDataConfiguration : IIdentityDataConfiguration { public List Roles { get; set; } public List Users { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs similarity index 86% rename from src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs rename to src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs index 8b44a238b..fa20f64d4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/ClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs @@ -5,7 +5,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { - public class ClientDataConfiguration : IClientDataConfiguration + public class IdentityServerDataConfiguration : IIdentityServerDataConfiguration { public List Clients { get; set; } = new List(); public List IdentityResources { get; set; } = new List(); diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs similarity index 83% rename from src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs rename to src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs index 901e86721..ee98b9dc6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IUserDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs @@ -3,7 +3,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { - public interface IUserDataConfiguration + public interface IIdentityDataConfiguration { List Roles { get; } List Users { get; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs similarity index 87% rename from src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs rename to src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs index 2a60da1f2..6886105f4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IClientDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs @@ -4,7 +4,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces { - public interface IClientDataConfiguration + public interface IIdentityServerDataConfiguration { List Clients { get; } List IdentityResources { get; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs index 150d684f8..8edca3601 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs @@ -3,7 +3,7 @@ public interface IRootConfiguration { IAdminConfiguration AdminConfiguration { get; } - IUserDataConfiguration UserDataConfiguration { get; } - IClientDataConfiguration ClientDataConfiguration { get; } + IIdentityDataConfiguration IdentityDataConfiguration { get; } + IIdentityServerDataConfiguration IdentityServerDataConfiguration { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs index 2924ae275..7a56dbbcb 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs @@ -6,15 +6,15 @@ namespace Skoruba.IdentityServer4.Admin.Configuration public class RootConfiguration : IRootConfiguration { public IAdminConfiguration AdminConfiguration { get; set; } - public IUserDataConfiguration UserDataConfiguration { get; set; } - public IClientDataConfiguration ClientDataConfiguration { get; set; } + public IIdentityDataConfiguration IdentityDataConfiguration { get; set; } + public IIdentityServerDataConfiguration IdentityServerDataConfiguration { get; set; } - public RootConfiguration(IOptions adminConfiguration, IOptions clientConfiguration, - IOptions userConfiguration) + public RootConfiguration(IOptions adminConfiguration, IOptions clientConfiguration, + IOptions userConfiguration) { AdminConfiguration = adminConfiguration.Value; - UserDataConfiguration = userConfiguration.Value; - ClientDataConfiguration = clientConfiguration.Value; + IdentityDataConfiguration = userConfiguration.Value; + IdentityServerDataConfiguration = clientConfiguration.Value; } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index a8d82dd4d..9f72c78b4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -77,8 +77,8 @@ public static async Task EnsureSeedData( var roleManager = scope.ServiceProvider.GetRequiredService>(); var rootConfiguration = scope.ServiceProvider.GetRequiredService(); - await EnsureSeedIdentityServerData(context, rootConfiguration.ClientDataConfiguration); - await EnsureSeedIdentityData(userManager, roleManager, rootConfiguration.UserDataConfiguration); + await EnsureSeedIdentityServerData(context, rootConfiguration.IdentityServerDataConfiguration); + await EnsureSeedIdentityData(userManager, roleManager, rootConfiguration.IdentityDataConfiguration); } } @@ -86,14 +86,14 @@ public static async Task EnsureSeedData( /// Generate default admin user / role /// private static async Task EnsureSeedIdentityData(UserManager userManager, - RoleManager roleManager, IUserDataConfiguration userDataConfiguration) + RoleManager roleManager, IIdentityDataConfiguration identityDataConfiguration) where TUser : IdentityUser, new() where TRole : IdentityRole, new() { if (!await roleManager.Roles.AnyAsync()) { // adding roles from seed - foreach (var r in userDataConfiguration.Roles) + foreach (var r in identityDataConfiguration.Roles) { if (!await roleManager.RoleExistsAsync(r.Name)) { @@ -118,7 +118,7 @@ private static async Task EnsureSeedIdentityData(UserManager(UserManager /// Generate default clients, identity and api resources /// - private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IClientDataConfiguration clientDataConfiguration) + private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IIdentityServerDataConfiguration identityServerDataConfiguration) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext { if (!context.IdentityResources.Any()) { - foreach (var resource in clientDataConfiguration.IdentityResources) + foreach (var resource in identityServerDataConfiguration.IdentityResources) { await context.IdentityResources.AddAsync(resource.ToEntity()); } @@ -167,7 +167,7 @@ private static async Task EnsureSeedIdentityServerData if (!context.ApiResources.Any()) { - foreach (var resource in clientDataConfiguration.ApiResources) + foreach (var resource in identityServerDataConfiguration.ApiResources) { foreach (var s in resource.ApiSecrets) { @@ -182,7 +182,7 @@ private static async Task EnsureSeedIdentityServerData if (!context.Clients.Any()) { - foreach (var client in clientDataConfiguration.Clients) + foreach (var client in identityServerDataConfiguration.Clients) { foreach (var secret in client.ClientSecrets) { diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index dabfd19a0..5a5738ce5 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -487,8 +487,8 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect services.AddOptions(); services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.UserDataConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.ClientDataConfigurationKey)); + services.Configure(configuration.GetSection(ConfigurationConsts.IdentityDataConfigurationKey)); + services.Configure(configuration.GetSection(ConfigurationConsts.IdentityServerDataConfigurationKey)); services.TryAddSingleton(); diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 4125f449e..517ddd199 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -47,7 +47,7 @@ } ] }, - "UserData": { + "IdentityData": { "Roles": [ { "Name": "SkorubaIdentityAdminAdministrator" @@ -70,7 +70,7 @@ } ] }, - "ClientData": { + "IdentityServerData": { "IdentityResources": [ { "Name": "roles", From 47aeea84074673bd35c43d6132c8f01b8339f718 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 13:14:59 +0200 Subject: [PATCH 157/338] Remove AuthorizationConsts from API, expose adminrole into appsettings --- .../Configuration/AdminApiConfiguration.cs | 16 ++++++++++------ .../Constants/ApiConfigurationConsts.cs | 9 --------- .../Constants/AuthorizationConsts.cs | 5 ----- .../Helpers/StartupHelpers.cs | 4 +++- src/Skoruba.IdentityServer4.Admin.Api/Startup.cs | 8 ++++---- .../appsettings.json | 5 ++++- 6 files changed, 21 insertions(+), 26 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ApiConfigurationConsts.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs index d6eb104d1..d207559c5 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs @@ -1,13 +1,17 @@ -using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; - -namespace Skoruba.IdentityServer4.Admin.Api.Configuration +namespace Skoruba.IdentityServer4.Admin.Api.Configuration { public class AdminApiConfiguration { - public string IdentityServerBaseUrl { get; set; } = AuthorizationConsts.IdentityServerBaseUrl; + public string ApiName { get; set; } + + public string ApiVersion { get; set; } + + public string IdentityServerBaseUrl { get; set; } + + public string OidcSwaggerUIClientId { get; set; } - public string OidcSwaggerUIClientId { get; set; } = AuthorizationConsts.OidcSwaggerUIClientId; + public string OidcApiName { get; set; } - public string OidcApiName { get; set; } = AuthorizationConsts.OidcApiName; + public string AdministrationRole { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ApiConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ApiConfigurationConsts.cs deleted file mode 100644 index c19bcdd5a..000000000 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ApiConfigurationConsts.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Skoruba.IdentityServer4.Admin.Api.Configuration.Constants -{ - public class ApiConfigurationConsts - { - public const string ApiName = "Skoruba IdentityServer4 Admin Api"; - - public const string ApiVersionV1 = "v1"; - } -} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/AuthorizationConsts.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/AuthorizationConsts.cs index a702c8db3..a533491d4 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/AuthorizationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/AuthorizationConsts.cs @@ -2,11 +2,6 @@ { public class AuthorizationConsts { - public const string IdentityServerBaseUrl = "http://localhost:5000"; - public const string OidcSwaggerUIClientId = "skoruba_identity_admin_api_swaggerui"; - public const string OidcApiName = "skoruba_identity_admin_api"; - public const string AdministrationPolicy = "RequireAdministratorRole"; - public const string AdministrationRole = "SkorubaIdentityAdminAdministrator"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 1ea3cfe7e..614b25b58 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -150,10 +150,12 @@ public static void AddApiAuthentication(this I public static void AddAuthorizationPolicies(this IServiceCollection services) { + var adminApiConfiguration = services.BuildServiceProvider().GetService(); + services.AddAuthorization(options => { options.AddPolicy(AuthorizationConsts.AdministrationPolicy, - policy => policy.RequireRole(AuthorizationConsts.AdministrationRole)); + policy => policy.RequireRole(adminApiConfiguration.AdministrationRole)); }); } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 79cc6f4a6..ebc26d5e6 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -75,14 +75,14 @@ public void ConfigureServices(IServiceCollection services) services.AddSwaggerGen(options => { - options.SwaggerDoc(ApiConfigurationConsts.ApiVersionV1, new Info { Title = ApiConfigurationConsts.ApiName, Version = ApiConfigurationConsts.ApiVersionV1 }); + options.SwaggerDoc(adminApiConfiguration.ApiVersion, new Info { Title = adminApiConfiguration.ApiName, Version = adminApiConfiguration.ApiVersion }); options.AddSecurityDefinition("oauth2", new OAuth2Scheme { Flow = "implicit", AuthorizationUrl = $"{adminApiConfiguration.IdentityServerBaseUrl}/connect/authorize", Scopes = new Dictionary { - { adminApiConfiguration.OidcApiName, ApiConfigurationConsts.ApiName } + { adminApiConfiguration.OidcApiName, adminApiConfiguration.ApiName } } }); @@ -102,10 +102,10 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApi app.UseSwagger(); app.UseSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/v1/swagger.json", ApiConfigurationConsts.ApiName); + c.SwaggerEndpoint("/swagger/v1/swagger.json", adminApiConfiguration.ApiName); c.OAuthClientId(adminApiConfiguration.OidcSwaggerUIClientId); - c.OAuthAppName(ApiConfigurationConsts.ApiName); + c.OAuthAppName(adminApiConfiguration.ApiName); }); app.UseMvc(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 631dbf529..fda21058a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -6,8 +6,11 @@ "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, "AdminApiConfiguration": { + "ApiName": "Skoruba IdentityServer4 Admin Api", + "ApiVersion": "v1", "IdentityServerBaseUrl": "http://localhost:5000", "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "OidcApiName": "skoruba_identity_admin_api" + "OidcApiName": "skoruba_identity_admin_api", + "AdministrationRole": "SkorubaIdentityAdminAdministrator" } } \ No newline at end of file From 0e0ea47fa3bd49009a9b84f812efdff27f88d036 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 13:47:21 +0200 Subject: [PATCH 158/338] Add configuration of Authentication middleware into appsettings --- .../Configuration/AdminConfiguration.cs | 5 ++++ .../Constants/AuthenticationConsts.cs | 2 -- .../Interfaces/IAdminConfiguration.cs | 5 ++++ .../Helpers/StartupHelpers.cs | 26 ++++++++----------- .../appsettings.json | 5 ++++ 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index 74e29b178..3b046107f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -7,6 +7,11 @@ public class AdminConfiguration : IAdminConfiguration public string IdentityAdminRedirectUri { get; set; } public string[] Scopes { get; set; } public string AdministrationRole { get; set; } + public bool RequireHttpsMetadata { get; set; } + public string IdentityAdminCookieName { get; set; } + public double IdentityAdminCookieExpiresUtcHours { get; set; } + public string TokenValidationClaimName { get; set; } + public string TokenValidationClaimRole { get; set; } public string IdentityServerBaseUrl { get; set; } public string ClientId { get; set; } public string ClientSecret { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs index f0a62bf46..f7add6ecc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/AuthenticationConsts.cs @@ -2,10 +2,8 @@ { public class AuthenticationConsts { - public const string IdentityAdminCookieName = "IdentityServerAdmin"; public const string SignInScheme = "Cookies"; public const string OidcAuthenticationScheme = "oidc"; - public const string RoleClaim = "role"; public const string AccountLoginPage = "Account/Login"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs index d578981c4..3647a16ba 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs @@ -9,5 +9,10 @@ public interface IAdminConfiguration string OidcResponseType { get; } string[] Scopes { get; } string AdministrationRole { get; } + bool RequireHttpsMetadata { get; } + string IdentityAdminCookieName { get; } + double IdentityAdminCookieExpiresUtcHours { get; } + string TokenValidationClaimName { get; } + string TokenValidationClaimRole { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 5a5738ce5..0c9defbc7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -415,7 +415,7 @@ public static void AddAuthenticationServices { options.Cookie.Name = AuthenticationConsts.IdentityAdminCookieName; }); + options => { options.Cookie.Name = adminConfiguration.IdentityAdminCookieName; }); } else { @@ -432,19 +432,15 @@ public static void AddAuthenticationServices { - options.Cookie.Name = AuthenticationConsts.IdentityAdminCookieName; - + options.Cookie.Name = adminConfiguration.IdentityAdminCookieName; + // Issue: https://github.com/aspnet/Announcements/issues/318 options.Cookie.SameSite = SameSiteMode.None; }) .AddOpenIdConnect(AuthenticationConsts.OidcAuthenticationScheme, options => { options.Authority = adminConfiguration.IdentityServerBaseUrl; -#if DEBUG - options.RequireHttpsMetadata = false; -#else - options.RequireHttpsMetadata = true; -#endif + options.RequireHttpsMetadata = adminConfiguration.RequireHttpsMetadata; options.ClientId = adminConfiguration.ClientId; options.ClientSecret = adminConfiguration.ClientSecret; options.ResponseType = adminConfiguration.OidcResponseType; @@ -455,7 +451,7 @@ public static void AddAuthenticationServices OnRedirectToIdentityProvider(n, adminConfiguration) + OnMessageReceived = context => OnMessageReceived(context, adminConfiguration), + OnRedirectToIdentityProvider = context => OnRedirectToIdentityProvider(context, adminConfiguration) }; }); } @@ -495,10 +491,10 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect return services; } - private static Task OnMessageReceived(MessageReceivedContext context) + private static Task OnMessageReceived(MessageReceivedContext context, IAdminConfiguration adminConfiguration) { context.Properties.IsPersistent = true; - context.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddHours(12)); + context.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddHours(adminConfiguration.IdentityAdminCookieExpiresUtcHours)); return Task.FromResult(0); } diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 517ddd199..7efa94a3e 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -8,6 +8,11 @@ "AdminConfiguration": { "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", "IdentityServerBaseUrl": "http://localhost:5000", + "IdentityAdminCookieName": "IdentityServerAdmin", + "IdentityAdminCookieExpiresUtcHours": 12, + "RequireHttpsMetadata": false, + "TokenValidationClaimName": "name", + "TokenValidationClaimRole": "role", "ClientId": "skoruba_identity_admin", "ClientSecret": "skoruba_admin_client_secret", "OidcResponseType": "code id_token", From c4a6e6c1f5d94484865a3368fadf469d63917a30 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 15:13:25 +0200 Subject: [PATCH 159/338] Extract base class for IClassFixture; Read admin role from configuration; --- .../Common/HttpClientExtensions.cs | 13 ++++---- .../Tests/Base/BaseClassFixture.cs | 31 +++++++++++++++++++ .../Tests/ConfigurationControllerTests.cs | 21 +++++++------ .../Tests/GrantControllerTests.cs | 18 +++++------ .../Tests/HomeControllerTests.cs | 20 +++++------- .../Tests/IdentityControllerTests.cs | 17 +++++----- .../Tests/LogControllerTests.cs | 19 +++++------- 7 files changed, 78 insertions(+), 61 deletions(-) create mode 100644 tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs index 7b577bdd1..327c39799 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs @@ -1,20 +1,21 @@ -using System.IdentityModel.Tokens.Jwt; +using System; +using System.IdentityModel.Tokens.Jwt; using System.Net.Http; using System.Security.Claims; -using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.Middlewares; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Common { public static class HttpClientExtensions { - public static void SetAdminClaimsViaHeaders(this HttpClient client) + public static void SetAdminClaimsViaHeaders(this HttpClient client, IAdminConfiguration adminConfiguration) { var claims = new[] { - new Claim(ClaimTypes.NameIdentifier, "1"), - new Claim(ClaimTypes.Name, "test"), - new Claim(ClaimTypes.Role, AuthorizationConsts.AdministrationRole) + new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()), + new Claim(ClaimTypes.Name, Guid.NewGuid().ToString()), + new Claim(ClaimTypes.Role, adminConfiguration.AdministrationRole) }; var token = new JwtSecurityToken(claims: claims); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs new file mode 100644 index 000000000..cb2ccc03f --- /dev/null +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -0,0 +1,31 @@ +using System.Net.Http; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base +{ + public class BaseClassFixture : IClassFixture> + { + protected readonly WebApplicationFactory Factory; + protected readonly HttpClient Client; + + public BaseClassFixture(WebApplicationFactory factory) + { + Factory = factory; + Client = factory.SetupClient(); + Factory.CreateClient(); + } + + protected virtual void SetupAdminClaimsViaHeaders() + { + using (var scope = Factory.Server.Host.Services.CreateScope()) + { + var configuration = scope.ServiceProvider.GetRequiredService(); + Client.SetAdminClaimsViaHeaders(configuration.AdminConfiguration); + } + } + } +} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs index e6c3dcd0c..edff1b0c1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs @@ -3,31 +3,31 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class ConfigurationControllerTests : IClassFixture> + public class ConfigurationControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public ConfigurationControllerTests(WebApplicationFactory factory) + public ConfigurationControllerTests(WebApplicationFactory factory) + : base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task ReturnSuccessWithAdminRole() { - //Get claims for admin - _client.SetAdminClaimsViaHeaders(); + SetupAdminClaimsViaHeaders(); foreach (var route in RoutesConstants.GetConfigureRoutes()) { // Act - var response = await _client.GetAsync($"/Configuration/{route}"); + var response = await Client.GetAsync($"/Configuration/{route}"); // Assert response.EnsureSuccessStatusCode(); @@ -35,16 +35,17 @@ public async Task ReturnSuccessWithAdminRole() } } + [Fact] public async Task ReturnRedirectWithoutAdminRole() { //Remove - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); foreach (var route in RoutesConstants.GetConfigureRoutes()) { // Act - var response = await _client.GetAsync($"/Configuration/{route}"); + var response = await Client.GetAsync($"/Configuration/{route}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs index c89e9f2ba..df62e0428 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs @@ -1,33 +1,29 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class GrantControllerTests : IClassFixture> + public class GrantControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public GrantControllerTests(WebApplicationFactory factory) + public GrantControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task ReturnSuccessWithAdminRole() { - //Get claims for admin - _client.SetAdminClaimsViaHeaders(); + SetupAdminClaimsViaHeaders(); foreach (var route in RoutesConstants.GetGrantRoutes()) { // Act - var response = await _client.GetAsync($"/Grant/{route}"); + var response = await Client.GetAsync($"/Grant/{route}"); // Assert response.EnsureSuccessStatusCode(); @@ -39,12 +35,12 @@ public async Task ReturnSuccessWithAdminRole() public async Task ReturnRedirectWithoutAdminRole() { //Remove - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); foreach (var route in RoutesConstants.GetGrantRoutes()) { // Act - var response = await _client.GetAsync($"/Grant/{route}"); + var response = await Client.GetAsync($"/Grant/{route}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs index da33a23d1..4f71bdaf2 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs @@ -1,31 +1,27 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; -using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class HomeControllerTests : IClassFixture> + public class HomeControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public HomeControllerTests(WebApplicationFactory factory) + public HomeControllerTests(WebApplicationFactory factory) : + base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task ReturnSuccessWithAdminRole() { - //Get claims for admin - _client.SetAdminClaimsViaHeaders(); + SetupAdminClaimsViaHeaders(); // Act - var response = await _client.GetAsync("/home/index"); + var response = await Client.GetAsync("/home/index"); // Assert response.EnsureSuccessStatusCode(); @@ -36,10 +32,10 @@ public async Task ReturnSuccessWithAdminRole() public async Task ReturnRedirectWithoutAdminRole() { //Remove - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Act - var response = await _client.GetAsync("/home/index"); + var response = await Client.GetAsync("/home/index"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs index 04e7dc219..55b764f41 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs @@ -5,29 +5,26 @@ using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class IdentityControllerTests : IClassFixture> + public class IdentityControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public IdentityControllerTests(WebApplicationFactory factory) + public IdentityControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task ReturnSuccessWithAdminRole() { - //Get claims for admin - _client.SetAdminClaimsViaHeaders(); + SetupAdminClaimsViaHeaders(); foreach (var route in RoutesConstants.GetIdentityRoutes()) { // Act - var response = await _client.GetAsync($"/Identity/{route}"); + var response = await Client.GetAsync($"/Identity/{route}"); // Assert response.EnsureSuccessStatusCode(); @@ -39,12 +36,12 @@ public async Task ReturnSuccessWithAdminRole() public async Task ReturnRedirectWithoutAdminRole() { //Remove - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); foreach (var route in RoutesConstants.GetIdentityRoutes()) { // Act - var response = await _client.GetAsync($"/Identity/{route}"); + var response = await Client.GetAsync($"/Identity/{route}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs index 373464bff..eacc18e04 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs @@ -1,31 +1,27 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; -using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { - public class LogControllerTests : IClassFixture> + public class LogControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public LogControllerTests(WebApplicationFactory factory) + public LogControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task ReturnRedirectInErrorsLogWithoutAdminRole() { //Remove - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Act - var response = await _client.GetAsync("/log/errorslog"); + var response = await Client.GetAsync("/log/errorslog"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); @@ -37,11 +33,10 @@ public async Task ReturnRedirectInErrorsLogWithoutAdminRole() [Fact] public async Task ReturnSuccessInErrorsLogWithAdminRole() { - //Get claims for admin - _client.SetAdminClaimsViaHeaders(); + SetupAdminClaimsViaHeaders(); // Act - var response = await _client.GetAsync("/log/errorslog"); + var response = await Client.GetAsync("/log/errorslog"); // Assert response.EnsureSuccessStatusCode(); From a1f699ec8c87532d210f43b4aea2d0c01b0f8dcc Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 15:21:12 +0200 Subject: [PATCH 160/338] Extract base class for IClassFixture for STS --- .../Tests/AccountControllerTests.cs | 9 +++------ .../Tests/Base/BaseClassFixture.cs | 17 +++++++++++++++++ .../Tests/DiagnosticsControllerTests.cs | 10 +++------- .../Tests/GrantsControllerTests.cs | 9 +++------ .../Tests/HomeControllerTests.cs | 10 +++------- .../Tests/IdentityServerTests.cs | 14 +++++--------- .../Tests/ManageControllerTests.cs | 9 +++------ 7 files changed, 37 insertions(+), 41 deletions(-) create mode 100644 tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs index 1653485b2..3cbdd2843 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs @@ -2,24 +2,21 @@ using System.Collections.Generic; using System.Linq; using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using HtmlAgilityPack; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class AccountControllerTests : IClassFixture> + public class AccountControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public AccountControllerTests(WebApplicationFactory factory) + public AccountControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs new file mode 100644 index 000000000..5fdf6c564 --- /dev/null +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -0,0 +1,17 @@ +using System.Net.Http; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; +using Xunit; + +namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base +{ + public class BaseClassFixture : IClassFixture> + { + protected readonly HttpClient _client; + + public BaseClassFixture(WebApplicationFactory factory) + { + _client = factory.SetupClient(); + } + } +} \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs index 4d46d437e..049a2c186 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs @@ -1,20 +1,16 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; -using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class DiagnosticsControllerTests : IClassFixture> + public class DiagnosticsControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public DiagnosticsControllerTests(WebApplicationFactory factory) + public DiagnosticsControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs index 0126ffb70..f1a1f457c 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs @@ -1,21 +1,18 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class GrantsControllerTests : IClassFixture> + public class GrantsControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public GrantsControllerTests(WebApplicationFactory factory) + public GrantsControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs index db00a321d..281eae6b2 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs @@ -1,20 +1,16 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; -using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class HomeControllerTests : IClassFixture> + public class HomeControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public HomeControllerTests(WebApplicationFactory factory) + public HomeControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs index a4a5d12e4..a7ad22463 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs @@ -1,27 +1,23 @@ -using System.Net.Http; -using System.Threading.Tasks; +using System.Threading.Tasks; using FluentAssertions; using IdentityModel.Client; using Microsoft.AspNetCore.Mvc.Testing; -using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class IdentityServerTests : IClassFixture> + public class IdentityServerTests : BaseClassFixture { - private readonly HttpClient _client; - - public IdentityServerTests(WebApplicationFactory factory) + public IdentityServerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] public async Task CanShowDiscoveryEndpoint() { var disco = await _client.GetDiscoveryDocumentAsync("http://localhost"); - + disco.Should().NotBeNull(); disco.IsError.Should().Be(false); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs index ba95638c6..7bde548cc 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs @@ -1,21 +1,18 @@ using System.Net; -using System.Net.Http; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; +using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { - public class ManageControllerTests : IClassFixture> + public class ManageControllerTests : BaseClassFixture { - private readonly HttpClient _client; - - public ManageControllerTests(WebApplicationFactory factory) + public ManageControllerTests(WebApplicationFactory factory) : base(factory) { - _client = factory.SetupClient(); } [Fact] From e9fd10775dcd3fe8d0711677f943ad69a519cc44 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 18:53:25 +0200 Subject: [PATCH 161/338] #304 - Add validation for inserting new items; Add property RequireHttpsMetadata into appsettings --- .../Configuration/AdminApiConfiguration.cs | 2 + .../Controllers/ApiResourcesController.cs | 26 +++- .../Controllers/ClientsController.cs | 26 +++- .../IdentityResourcesController.cs | 16 ++- .../Controllers/RolesController.cs | 17 ++- .../Controllers/UsersController.cs | 27 +++- .../ExceptionHandling/ApiError.cs | 9 ++ .../Helpers/StartupHelpers.cs | 6 +- .../Resources/ApiErrorResource.Designer.cs | 72 ++++++++++ .../Resources/ApiErrorResource.resx | 123 ++++++++++++++++++ .../Resources/ApiErrorResources.cs | 16 +++ .../Resources/IApiErrorResources.cs | 9 ++ .../Skoruba.IdentityServer4.Admin.Api.csproj | 15 +++ .../Startup.cs | 3 +- .../appsettings.json | 3 +- 15 files changed, 353 insertions(+), 17 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/ExceptionHandling/ApiError.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.resx create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResources.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Resources/IApiErrorResources.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs index d207559c5..e3512245f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs @@ -10,6 +10,8 @@ public class AdminApiConfiguration public string OidcSwaggerUIClientId { get; set; } + public bool RequireHttpsMetadata { get; set; } + public string OidcApiName { get; set; } public string AdministrationRole { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs index c38b7758b..b7855ef91 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs @@ -6,6 +6,7 @@ using Skoruba.IdentityServer4.Admin.Api.Dtos.ApiResources; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Mappers; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; @@ -19,10 +20,12 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers public class ApiResourcesController : ControllerBase { private readonly IApiResourceService _apiResourceService; + private readonly IApiErrorResources _errorResources; - public ApiResourcesController(IApiResourceService apiResourceService) + public ApiResourcesController(IApiResourceService apiResourceService, IApiErrorResources errorResources) { _apiResourceService = apiResourceService; + _errorResources = errorResources; } [HttpGet] @@ -47,6 +50,12 @@ public async Task> Get(int id) public async Task Post([FromBody]ApiResourceApiDto apiResourceApi) { var apiResourceDto = apiResourceApi.ToApiResourceApiModel(); + + if (!apiResourceDto.Id.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _apiResourceService.AddApiResourceAsync(apiResourceDto); return Ok(); @@ -98,6 +107,11 @@ public async Task PostScope(int id, [FromBody]ApiScopeApiDto apiS var apiScope = apiScopeApi.ToApiResourceApiModel(); apiScope.ApiResourceId = id; + if (!apiScope.ApiScopeId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _apiResourceService.GetApiResourceAsync(apiScope.ApiResourceId); await _apiResourceService.AddApiScopeAsync(apiScope); @@ -155,6 +169,11 @@ public async Task PostSecret(int id, [FromBody]ApiSecretApiDto cl var secretsDto = clientSecretApi.ToApiResourceApiModel(); secretsDto.ApiResourceId = id; + if (!secretsDto.ApiSecretId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _apiResourceService.AddApiSecretAsync(secretsDto); return Ok(); @@ -195,6 +214,11 @@ public async Task PostProperty(int id, [FromBody]ApiResourcePrope var apiResourcePropertiesDto = apiPropertyApi.ToApiResourceApiModel(); apiResourcePropertiesDto.ApiResourceId = id; + if (!apiResourcePropertiesDto.ApiResourcePropertyId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _apiResourceService.AddApiResourcePropertyAsync(apiResourcePropertiesDto); return Ok(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs index 052f10bf2..7c3ac3dc0 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs @@ -6,6 +6,7 @@ using Skoruba.IdentityServer4.Admin.Api.Dtos.Clients; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Mappers; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; @@ -19,10 +20,12 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers public class ClientsController : ControllerBase { private readonly IClientService _clientService; + private readonly IApiErrorResources _errorResources; - public ClientsController(IClientService clientService) + public ClientsController(IClientService clientService, IApiErrorResources errorResources) { _clientService = clientService; + _errorResources = errorResources; } [HttpGet] @@ -47,6 +50,12 @@ public async Task> Get(int id) public async Task Post([FromBody]ClientApiDto client) { var clientDto = client.ToClientApiModel(); + + if (!clientDto.Id.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _clientService.AddClientAsync(clientDto); return Ok(); @@ -109,6 +118,11 @@ public async Task PostSecret(int id, [FromBody]ClientSecretApiDto var secretsDto = clientSecretApi.ToClientApiModel(); secretsDto.ClientId = id; + if (!secretsDto.ClientSecretId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _clientService.AddClientSecretAsync(secretsDto); return Ok(); @@ -149,6 +163,11 @@ public async Task PostProperty(int id, [FromBody]ClientPropertyAp var clientPropertiesDto = clientPropertyApi.ToClientApiModel(); clientPropertiesDto.ClientId = id; + if (!clientPropertiesDto.ClientPropertyId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _clientService.AddClientPropertyAsync(clientPropertiesDto); return Ok(); @@ -189,6 +208,11 @@ public async Task PostClaim(int id, [FromBody]ClientClaimApiDto c var clientClaimsDto = clientClaimApiDto.ToClientApiModel(); clientClaimsDto.ClientId = id; + if (!clientClaimsDto.ClientClaimId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _clientService.AddClientClaimAsync(clientClaimsDto); return Ok(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs index 267d54277..91a29886c 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs @@ -6,6 +6,7 @@ using Skoruba.IdentityServer4.Admin.Api.Dtos.IdentityResources; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Mappers; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; @@ -19,10 +20,12 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers public class IdentityResourcesController : ControllerBase { private readonly IIdentityResourceService _identityResourceService; + private readonly IApiErrorResources _errorResources; - public IdentityResourcesController(IIdentityResourceService identityResourceService) + public IdentityResourcesController(IIdentityResourceService identityResourceService, IApiErrorResources errorResources) { _identityResourceService = identityResourceService; + _errorResources = errorResources; } [HttpGet] @@ -47,6 +50,12 @@ public async Task> Get(int id) public async Task Post([FromBody]IdentityResourceApiDto identityResourceApi) { var identityResourceDto = identityResourceApi.ToIdentityResourceApiModel(); + + if (!identityResourceDto.Id.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityResourceService.AddIdentityResourceAsync(identityResourceDto); return Ok(); @@ -98,6 +107,11 @@ public async Task PostProperty(int id, [FromBody]IdentityResource var identityResourcePropertiesDto = identityResourcePropertyApi.ToIdentityResourceApiModel(); identityResourcePropertiesDto.IdentityResourceId = id; + if (!identityResourcePropertiesDto.IdentityResourcePropertyId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityResourceService.AddIdentityResourcePropertyAsync(identityResourcePropertiesDto); return Ok(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs index bec0a6c37..38023511a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using AutoMapper; using IdentityServer4.AccessTokenValidation; @@ -9,6 +10,7 @@ using Skoruba.IdentityServer4.Admin.Api.Dtos.Roles; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Helpers.Localization; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; @@ -51,17 +53,19 @@ public class RolesController> _localizer; private readonly IMapper _mapper; + private readonly IApiErrorResources _errorResources; public RolesController(IIdentityService identityService, IGenericControllerLocalizer> localizer, IMapper mapper) + TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto>> localizer, IMapper mapper, IApiErrorResources errorResources) { _identityService = identityService; _localizer = localizer; _mapper = mapper; + _errorResources = errorResources; } [HttpGet("{id}")] @@ -83,6 +87,11 @@ public async Task> Get(string searchText, int page = 1, [HttpPost] public async Task Post([FromBody]TRoleDto role) { + if (!EqualityComparer.Default.Equals(role.Id, default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityService.CreateRoleAsync(role); return Ok(); @@ -129,6 +138,12 @@ public async Task>> GetRoleClaims(str public async Task PostRoleClaims([FromBody]RoleClaimApiDto roleClaims) { var roleClaimsDto = _mapper.Map(roleClaims); + + if (!roleClaimsDto.ClaimId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityService.CreateRoleClaimsAsync(roleClaimsDto); return Ok(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index 44c0be89b..5710e3ba3 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using AutoMapper; using IdentityServer4.AccessTokenValidation; @@ -9,6 +10,7 @@ using Skoruba.IdentityServer4.Admin.Api.Dtos.Users; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Helpers.Localization; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; @@ -51,24 +53,26 @@ public class UsersController> _localizer; private readonly IMapper _mapper; + private readonly IApiErrorResources _errorResources; public UsersController(IIdentityService identityService, IGenericControllerLocalizer> localizer, IMapper mapper) + TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto>> localizer, IMapper mapper, IApiErrorResources errorResources) { _identityService = identityService; _localizer = localizer; _mapper = mapper; + _errorResources = errorResources; } [HttpGet("{id}")] public async Task> Get(TUserDtoKey id) { var user = await _identityService.GetUserAsync(id.ToString()); - + return Ok(user); } @@ -83,6 +87,11 @@ public async Task> Get(string searchText, int page = 1, [HttpPost] public async Task Post([FromBody]TUserDto user) { + if (!EqualityComparer.Default.Equals(user.Id, default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityService.CreateUserAsync(user); return Ok(); @@ -109,11 +118,11 @@ public async Task Delete(TUserDtoKey id) } [HttpGet("{id}/Roles")] - public async Task>> GetUserRoles(string id, int page = 1, int pageSize = 10) + public async Task>> GetUserRoles(TRoleDtoKey id, int page = 1, int pageSize = 10) { - var userRoles = await _identityService.GetUserRolesAsync(id, page, pageSize); + var userRoles = await _identityService.GetUserRolesAsync(id.ToString(), page, pageSize); var userRolesApiDto = _mapper.Map>(userRoles); - + return Ok(userRolesApiDto); } @@ -121,6 +130,7 @@ public async Task>> GetUserRoles(string i public async Task PostUserRoles([FromBody]UserRoleApiDto role) { var userRolesDto = _mapper.Map(role); + await _identityService.CreateUserRoleAsync(userRolesDto); return Ok(); @@ -154,6 +164,11 @@ public async Task PostUserClaims([FromBody]UserClaimApiDto(claim); + if (!userClaimDto.ClaimId.Equals(default)) + { + return BadRequest(_errorResources.CannotSetId()); + } + await _identityService.CreateUserClaimsAsync(userClaimDto); return Ok(); @@ -179,7 +194,7 @@ public async Task>> GetUserProvide { var userProvidersDto = await _identityService.GetUserProvidersAsync(id.ToString()); var userProvidersApiDto = _mapper.Map>(userProvidersDto); - + return Ok(userProvidersApiDto); } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/ExceptionHandling/ApiError.cs b/src/Skoruba.IdentityServer4.Admin.Api/ExceptionHandling/ApiError.cs new file mode 100644 index 000000000..3b28ff200 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/ExceptionHandling/ApiError.cs @@ -0,0 +1,9 @@ +namespace Skoruba.IdentityServer4.Admin.Api.ExceptionHandling +{ + public class ApiError + { + public string Code { get; set; } + + public string Description { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 614b25b58..433f61469 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -133,11 +133,7 @@ public static void AddApiAuthentication(this I { options.Authority = adminApiConfiguration.IdentityServerBaseUrl; options.ApiName = adminApiConfiguration.OidcApiName; -#if DEBUG - options.RequireHttpsMetadata = false; -#else - options.RequireHttpsMetadata = true; -#endif + options.RequireHttpsMetadata = adminApiConfiguration.RequireHttpsMetadata; }); services.AddIdentity(options => diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs new file mode 100644 index 000000000..6be84cdf9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Skoruba.IdentityServer4.Admin.Api.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class ApiErrorResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal ApiErrorResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Skoruba.IdentityServer4.Admin.Api.Resources.ApiErrorResource", typeof(ApiErrorResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Cannot set ID when creating a new entity. + /// + public static string CannotSetId { + get { + return ResourceManager.GetString("CannotSetId", resourceCulture); + } + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.resx b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.resx new file mode 100644 index 000000000..a20c6f7d6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cannot set ID when creating a new entity + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResources.cs b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResources.cs new file mode 100644 index 000000000..2bf305d31 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResources.cs @@ -0,0 +1,16 @@ +using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; + +namespace Skoruba.IdentityServer4.Admin.Api.Resources +{ + public class ApiErrorResources : IApiErrorResources + { + public virtual ApiError CannotSetId() + { + return new ApiError + { + Code = nameof(CannotSetId), + Description = ApiErrorResource.CannotSetId + }; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Resources/IApiErrorResources.cs b/src/Skoruba.IdentityServer4.Admin.Api/Resources/IApiErrorResources.cs new file mode 100644 index 000000000..4d5f8637d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Resources/IApiErrorResources.cs @@ -0,0 +1,9 @@ +using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; + +namespace Skoruba.IdentityServer4.Admin.Api.Resources +{ + public interface IApiErrorResources + { + ApiError CannotSetId(); + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index bb25052ce..331c49895 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -22,4 +22,19 @@ + + + True + True + ApiErrorResource.resx + + + + + + PublicResXFileCodeGenerator + ApiErrorResource.Designer.cs + + + diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index ebc26d5e6..82176297e 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -6,10 +6,10 @@ using Microsoft.Extensions.DependencyInjection; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.Authorization; -using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Api.Helpers; using Skoruba.IdentityServer4.Admin.Api.Mappers; +using Skoruba.IdentityServer4.Admin.Api.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; @@ -48,6 +48,7 @@ public void ConfigureServices(IServiceCollection services) services.AddDbContexts(Configuration); services.AddScoped(); + services.AddScoped(); services.AddApiAuthentication(adminApiConfiguration); services.AddAuthorizationPolicies(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index fda21058a..c799983f0 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -11,6 +11,7 @@ "IdentityServerBaseUrl": "http://localhost:5000", "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", "OidcApiName": "skoruba_identity_admin_api", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + "AdministrationRole": "SkorubaIdentityAdminAdministrator", + "RequireHttpsMetadata": false } } \ No newline at end of file From 8616c92b215d0e04026990ead563771c722fb111 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 18:56:24 +0200 Subject: [PATCH 162/338] Change ApiErrorResource to internal --- .../Resources/ApiErrorResource.Designer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs index 6be84cdf9..d73d6b381 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Resources/ApiErrorResource.Designer.cs @@ -22,7 +22,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Resources { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class ApiErrorResource { + internal class ApiErrorResource { private static global::System.Resources.ResourceManager resourceMan; @@ -36,7 +36,7 @@ internal ApiErrorResource() { /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { + internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Skoruba.IdentityServer4.Admin.Api.Resources.ApiErrorResource", typeof(ApiErrorResource).Assembly); @@ -51,7 +51,7 @@ internal ApiErrorResource() { /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { + internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -63,7 +63,7 @@ internal ApiErrorResource() { /// /// Looks up a localized string similar to Cannot set ID when creating a new entity. /// - public static string CannotSetId { + internal static string CannotSetId { get { return ResourceManager.GetString("CannotSetId", resourceCulture); } From b9534692e87a74bf01cf83bfaf2a7525dc03df31 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 5 Oct 2019 19:18:29 +0200 Subject: [PATCH 163/338] #363 - Add error logging --- .../Helpers/StartupHelpers.cs | 13 ++++++++ .../Program.cs | 5 +++- .../Skoruba.IdentityServer4.Admin.Api.csproj | 6 +++- .../Startup.cs | 2 ++ .../appsettings.json | 30 ++++++++++++++++++- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 433f61469..f1669099b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -9,6 +9,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; +using Serilog; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.ApplicationParts; using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; @@ -67,6 +69,17 @@ public static class StartupHelpers }); } + /// + /// Add configuration for logging + /// + /// + /// + public static void AddLogging(this IApplicationBuilder app,IConfiguration configuration) + { + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .CreateLogger(); + } ///
    /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs index 9c7b0fd86..3112ee351 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Serilog; namespace Skoruba.IdentityServer4.Admin.Api { @@ -7,7 +8,9 @@ public class Program { public static void Main(string[] args) { - CreateWebHostBuilder(args).Build().Run(); + CreateWebHostBuilder(args) + .UseSerilog() + .Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index 331c49895..73af90ce8 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -13,6 +13,10 @@ + + + + @@ -32,7 +36,7 @@ - PublicResXFileCodeGenerator + ResXFileCodeGenerator ApiErrorResource.Designer.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 82176297e..5871056b4 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -93,6 +93,8 @@ public void ConfigureServices(IServiceCollection services) public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApiConfiguration adminApiConfiguration) { + app.AddLogging(Configuration); + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index c799983f0..c834fc4a7 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -12,6 +12,34 @@ "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", "OidcApiName": "skoruba_identity_admin_api", "AdministrationRole": "SkorubaIdentityAdminAdministrator", - "RequireHttpsMetadata": false + "RequireHttpsMetadata": false + }, + "Serilog": { + "MinimumLevel": { + "Default": "Error", + "Override": { + "Skoruba": "Information" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Log\\skoruba_admin_api.txt", + "rollingInterval": "Day" + } + }, + { + "Name": "MSSqlServer", + "Args": { + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], + "removeStandardColumns": [ "Properties" ] + } + } + } + ] } } \ No newline at end of file From ccd677bfee26c656d5b92d729b79063e0396fdc2 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 7 Oct 2019 11:02:47 +0200 Subject: [PATCH 164/338] Added French to available cultures --- .../Configuration/CultureConfiguration.cs | 2 +- .../Configuration/CultureConfiguration.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs index ae3dc743f..83ad26bf2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs @@ -7,7 +7,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "ru", "sv", "zh" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs index 74db62c94..cf96c3fa5 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs @@ -7,7 +7,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "ru", "sv", "zh" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } From beb27b84cdcd3ba09e309c759c29b60dd1945ee9 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 7 Oct 2019 11:59:46 +0200 Subject: [PATCH 165/338] Added spanish culture --- .../Configuration/CultureConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs index 83ad26bf2..1d13c56f8 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs @@ -7,7 +7,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "es" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } From 711433ef5c463768437c2d74b6a451469c52645b Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 7 Oct 2019 17:24:35 +0200 Subject: [PATCH 166/338] Users are disallowed to delete themselves, both from IdentityServer4.Admin and from IdentityServer4.Admin.Api --- .../Controllers/UsersController.cs | 5 +++++ .../Controllers/IdentityController.cs | 16 +++++++++++++--- .../Controllers/IdentityController.en.resx | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index 44c0be89b..968e72bbf 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using AutoMapper; using IdentityServer4.AccessTokenValidation; +using IdentityServer4.Extensions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -100,6 +101,10 @@ public async Task Put([FromBody]TUserDto user) [HttpDelete("{id}")] public async Task Delete(TUserDtoKey id) { + var currentUserId = User.GetSubjectId(); + if (id.ToString() == currentUserId) + return StatusCode((int)System.Net.HttpStatusCode.Forbidden); + var user = new TUserDto { Id = id }; await _identityService.GetUserAsync(user.Id.ToString()); diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs index 5108f3c94..30425997a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using IdentityServer4.Extensions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -418,10 +419,19 @@ public async Task RoleDelete(TRoleDto role) [ValidateAntiForgeryToken] public async Task UserDelete(TUserDto user) { - await _identityService.DeleteUserAsync(user.Id.ToString(), user); - SuccessNotification(_localizer["SuccessDeleteUser"], _localizer["SuccessTitle"]); + var currentUserId = User.GetSubjectId(); + if (user.Id.ToString() == currentUserId) + { + CreateNotification(Helpers.NotificationHelpers.AlertType.Warning, _localizer["ErrorDeleteUser_CannotSelfDelete"]); + return RedirectToAction(nameof(UserDelete), user.Id); + } + else + { + await _identityService.DeleteUserAsync(user.Id.ToString(), user); + SuccessNotification(_localizer["SuccessDeleteUser"], _localizer["SuccessTitle"]); - return RedirectToAction(nameof(Users)); + return RedirectToAction(nameof(Users)); + } } [HttpGet] diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.en.resx index 5552f0b49..512ceed17 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.en.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.en.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + You cannot delete yourself. If you want to delete this account, first create a new administrative account, then switch to it and delete this account from there. + Role {0} is successfully saved! From 5d8007c075ecd7801300ad9c110073d856fd7727 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 7 Oct 2019 19:06:08 +0200 Subject: [PATCH 167/338] Modified unit test accordingly --- .../Controllers/IdentityControllerTests.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs index 1c4f9a4fe..a23b66504 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs @@ -25,6 +25,7 @@ using Skoruba.IdentityServer4.Admin.Helpers; using Skoruba.IdentityServer4.Admin.Helpers.Localization; using Xunit; +using System.Security.Claims; namespace Skoruba.IdentityServer4.Admin.UnitTests.Controllers { @@ -88,13 +89,28 @@ public async Task DeleteUser() var userId = await dbContext.Users.Where(x => x.UserName == userDto.UserName).Select(x => x.Id).SingleOrDefaultAsync(); userDto.Id = userId; + // A user cannot delete own account + var subjectClaim = new Claim(IdentityModel.JwtClaimTypes.Subject, userDto.Id); + ProvideControllerContextWithClaimsPrincipal(controller, subjectClaim); + var result = await controller.UserDelete(userDto); // Assert var viewResult = Assert.IsType(result); - viewResult.ActionName.Should().Be("Users"); + viewResult.ActionName.Should().Be("UserDelete", "Users cannot delete their own account"); var user = await dbContext.Users.Where(x => x.Id == userDto.Id).SingleOrDefaultAsync(); + user.Should().NotBeNull(); + + subjectClaim = new Claim(IdentityModel.JwtClaimTypes.Subject, "1"); + ProvideControllerContextWithClaimsPrincipal(controller, subjectClaim); + result = await controller.UserDelete(userDto); + + // Assert + viewResult = Assert.IsType(result); + viewResult.ActionName.Should().Be("Users"); + + user = await dbContext.Users.Where(x => x.Id == userDto.Id).SingleOrDefaultAsync(); user.Should().BeNull(); } @@ -627,5 +643,17 @@ private IServiceProvider GetServices() return services.BuildServiceProvider(); } + + private void ProvideControllerContextWithClaimsPrincipal(ControllerBase controller, params Claim[] claims) + { + controller.ControllerContext = new ControllerContext + { + HttpContext = new DefaultHttpContext + { + User = new System.Security.Claims.ClaimsPrincipal( + new ClaimsIdentity(claims, "mock")) + } + }; + } } } \ No newline at end of file From 3a3c8f9cdd48ca9182dd46fc3835785e96ef2fee Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Wed, 9 Oct 2019 15:24:10 +0200 Subject: [PATCH 168/338] Removed wrong RedirectUri in SignOutResult --- .../Controllers/AccountController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/AccountController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/AccountController.cs index 205521dbb..cd3ab5c8d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/AccountController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/AccountController.cs @@ -27,8 +27,7 @@ public IActionResult AccessDenied() public IActionResult Logout() { - return new SignOutResult(new List { AuthenticationConsts.SignInScheme, AuthenticationConsts.OidcAuthenticationScheme }, - new AuthenticationProperties { RedirectUri = "/" }); + return new SignOutResult(new List { AuthenticationConsts.SignInScheme, AuthenticationConsts.OidcAuthenticationScheme }); } } } From c4fff447e7b19d8b4a3fe46b93aec42877f4170e Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Wed, 9 Oct 2019 18:29:25 +0200 Subject: [PATCH 169/338] Added AdminApi base url setting: when the AdminApi is hosted in a sub-site, Swagger could not find the swagger endpoint (same type of problem as the logout redirect solved by this PR) --- .../Configuration/AdminApiConfiguration.cs | 2 ++ .../Startup.cs | 2 +- .../appsettings.json | 17 +++++++++-------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs index d207559c5..06dee45e1 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AdminApiConfiguration.cs @@ -8,6 +8,8 @@ public class AdminApiConfiguration public string IdentityServerBaseUrl { get; set; } + public string ApiBaseUrl { get; set; } + public string OidcSwaggerUIClientId { get; set; } public string OidcApiName { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index ebc26d5e6..e86eb4b8d 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -102,7 +102,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApi app.UseSwagger(); app.UseSwaggerUI(c => { - c.SwaggerEndpoint("/swagger/v1/swagger.json", adminApiConfiguration.ApiName); + c.SwaggerEndpoint($"{adminApiConfiguration.ApiBaseUrl}/swagger/v1/swagger.json", adminApiConfiguration.ApiName); c.OAuthClientId(adminApiConfiguration.OidcSwaggerUIClientId); c.OAuthAppName(adminApiConfiguration.ApiName); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index fda21058a..49923091f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -5,12 +5,13 @@ "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, - "AdminApiConfiguration": { - "ApiName": "Skoruba IdentityServer4 Admin Api", - "ApiVersion": "v1", - "IdentityServerBaseUrl": "http://localhost:5000", - "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "OidcApiName": "skoruba_identity_admin_api", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" - } + "AdminApiConfiguration": { + "ApiName": "Skoruba IdentityServer4 Admin Api", + "ApiVersion": "v1", + "ApiBaseUrl": "http://localhost:5001", + "IdentityServerBaseUrl": "http://localhost:5000", + "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", + "OidcApiName": "skoruba_identity_admin_api", + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + } } \ No newline at end of file From 289aec2be4b32e3be17fb5b88908672581b6eac7 Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 16 Oct 2019 12:07:19 +0200 Subject: [PATCH 170/338] Register without username, only using email --- .../Controllers/AccountController.cs | 27 +++++++++++- .../RegisterWithoutUsernameViewModel.cs | 20 +++++++++ .../Account/RegisterWithoutUsername.cshtml | 41 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs index 758127bb4..3f8a345d1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs @@ -540,7 +540,15 @@ public IActionResult Register(string returnUrl = null) ViewData["ReturnUrl"] = returnUrl; - return View(); + switch (_loginConfiguration.ResolutionPolicy) + { + case LoginResolutionPolicy.Username: + return View(); + case LoginResolutionPolicy.Email: + return View("RegisterWithoutUsername"); + default: + return View("RegisterFailure"); + } } [HttpPost] @@ -578,6 +586,23 @@ public async Task Register(RegisterViewModel model, string return return View(model); } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task RegisterWithoutUsername(RegisterWithoutUsernameViewModel model, string returnUrl = null) + { + var registerModel = new RegisterViewModel + { + UserName = model.Email, + Email = model.Email, + Password = model.Password, + ConfirmPassword = model.ConfirmPassword + }; + + return await Register(registerModel, returnUrl); + } + + /*****************************************/ /* helper APIs for the AccountController */ /*****************************************/ diff --git a/src/Skoruba.IdentityServer4.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs b/src/Skoruba.IdentityServer4.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs new file mode 100644 index 000000000..ad5d3885b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations; + +namespace Skoruba.IdentityServer4.STS.Identity.ViewModels.Account +{ + public class RegisterWithoutUsernameViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Compare("Password")] + public string ConfirmPassword { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml new file mode 100644 index 000000000..67e06c425 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml @@ -0,0 +1,41 @@ +@inject IViewLocalizer Localizer +@using Microsoft.AspNetCore.Mvc.Localization +@model Skoruba.IdentityServer4.STS.Identity.ViewModels.Account.RegisterWithoutUsernameViewModel +@{ + ViewData["Title"] = Localizer["Title"]; +} + +

    @ViewData["Title"].

    + +@await Html.PartialAsync("_ValidationSummary") + +
    +

    @Localizer["SubTitle"]

    +
    +
    + +
    + + +
    +
    +
    + +
    + + +
    +
    +
    + +
    + + +
    +
    +
    +
    + +
    +
    +
    \ No newline at end of file From 13851c2231b230275796e663ce368ddc92b75bde Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sun, 20 Oct 2019 13:59:20 +0200 Subject: [PATCH 171/338] Fix formatting in appsettings. --- .../appsettings.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 0468e2786..4ed72607f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -5,13 +5,13 @@ "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, - "AdminApiConfiguration": { - "ApiName": "Skoruba IdentityServer4 Admin Api", - "ApiVersion": "v1", - "ApiBaseUrl": "http://localhost:5001", - "IdentityServerBaseUrl": "http://localhost:5000", - "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "OidcApiName": "skoruba_identity_admin_api", + "AdminApiConfiguration": { + "ApiName": "Skoruba IdentityServer4 Admin Api", + "ApiVersion": "v1", + "ApiBaseUrl": "http://localhost:5001", + "IdentityServerBaseUrl": "http://localhost:5000", + "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", + "OidcApiName": "skoruba_identity_admin_api", "AdministrationRole": "SkorubaIdentityAdminAdministrator", "RequireHttpsMetadata": false }, @@ -42,5 +42,5 @@ } } ] - } + } } \ No newline at end of file From 8cdbd81b0311ee4a167f7cf61a384a8adcb69fee Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sun, 20 Oct 2019 14:20:34 +0200 Subject: [PATCH 172/338] Remove .ConfigureAwait(false) --- .../Repositories/IdentityRepository.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs index c7210e95f..ccee2c25a 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Repositories/IdentityRepository.cs @@ -284,20 +284,20 @@ public virtual async Task CreateRoleClaimsAsync(TRoleClaim claim public virtual async Task DeleteUserClaimsAsync(string userId, int claimId) { - var user = await UserManager.FindByIdAsync(userId).ConfigureAwait(false);; + var user = await UserManager.FindByIdAsync(userId); var userClaim = await DbContext.Set().Where(x => x.Id == claimId).SingleOrDefaultAsync(); - await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue)).ConfigureAwait(false); + await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue)); return await AutoSaveChangesAsync(); } public virtual async Task DeleteRoleClaimsAsync(string roleId, int claimId) { - var role = await RoleManager.FindByIdAsync(roleId).ConfigureAwait(false); + var role = await RoleManager.FindByIdAsync(roleId); var roleClaim = await DbContext.Set().Where(x => x.Id == claimId).SingleOrDefaultAsync(); - await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue)).ConfigureAwait(false); + await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue)); return await AutoSaveChangesAsync(); } From 3a1971bb08dc650b6e8aab17a27de5a9149eeedb Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sun, 20 Oct 2019 14:25:44 +0200 Subject: [PATCH 173/338] Remove login button from header, because of missing localization for now. I will add it in the future. --- .../Views/Shared/_Layout.cshtml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml index 2c83d3917..3ed839abc 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml @@ -67,10 +67,6 @@
    @Localizer["Signout"] } - else - { - @Localizer["Login"] - } From d259f963328db8c79405fac7af85863686bf29c0 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 21 Oct 2019 16:33:53 +0200 Subject: [PATCH 174/338] Add audit logging support; add events for api resources; --- .../Events/ApiResource/ApiResourceAdded.cs | 15 +++++++ .../Events/ApiResource/ApiResourceDeleted.cs | 15 +++++++ .../ApiResourcePropertiesRequested.cs | 17 +++++++ .../ApiResource/ApiResourcePropertyAdded.cs | 15 +++++++ .../ApiResource/ApiResourcePropertyDeleted.cs | 15 +++++++ .../ApiResourcePropertyRequested.cs | 17 +++++++ .../ApiResource/ApiResourceRequested.cs | 17 +++++++ .../Events/ApiResource/ApiResourceUpdated.cs | 17 +++++++ .../ApiResource/ApiResourcesRequested.cs | 15 +++++++ .../Services/ApiResourceService.cs | 44 ++++++++++++++++--- .../DbContexts/AuditLoggingDbContext.cs | 24 ++++++++++ ...erver4.Admin.EntityFramework.Shared.csproj | 4 ++ .../Constants/ConfigurationConsts.cs | 2 + .../Helpers/StartupHelpers.cs | 41 ++++++++++++++++- src/Skoruba.IdentityServer4.Admin/Startup.cs | 4 ++ 15 files changed, 255 insertions(+), 7 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs new file mode 100644 index 000000000..e92544990 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourceAdded : AuditEvent + { + public ApiResourceDto ApiResource { get; } + + public ApiResourceAdded(ApiResourceDto apiResource) + { + ApiResource = apiResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs new file mode 100644 index 000000000..f898d727e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourceDeleted : AuditEvent + { + public ApiResourceDto ApiResource { get; } + + public ApiResourceDeleted(ApiResourceDto apiResource) + { + ApiResource = apiResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs new file mode 100644 index 000000000..e777e2675 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourcePropertiesRequested : AuditEvent + { + public ApiResourcePropertiesRequested(int apiResourceId, ApiResourcePropertiesDto apiResourceProperties) + { + ApiResourceId = apiResourceId; + ApiResourceProperties = apiResourceProperties; + } + + public int ApiResourceId { get; set; } + public ApiResourcePropertiesDto ApiResourceProperties { get; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs new file mode 100644 index 000000000..aaec420e9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourcePropertyAdded : AuditEvent + { + public ApiResourcePropertyAdded(ApiResourcePropertiesDto apiResourceProperty) + { + ApiResourceProperty = apiResourceProperty; + } + + public ApiResourcePropertiesDto ApiResourceProperty { get; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs new file mode 100644 index 000000000..01da5d7fd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourcePropertyDeleted : AuditEvent + { + public ApiResourcePropertyDeleted(ApiResourcePropertiesDto apiResourceProperty) + { + ApiResourceProperty = apiResourceProperty; + } + + public ApiResourcePropertiesDto ApiResourceProperty { get; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs new file mode 100644 index 000000000..5caf39f68 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourcePropertyRequested : AuditEvent + { + public ApiResourcePropertyRequested(int apiResourcePropertyId, ApiResourcePropertiesDto apiResourceProperties) + { + ApiResourcePropertyId = apiResourcePropertyId; + ApiResourceProperties = apiResourceProperties; + } + + public int ApiResourcePropertyId { get; } + public ApiResourcePropertiesDto ApiResourceProperties { get; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs new file mode 100644 index 000000000..b171b5f98 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourceRequested : AuditEvent + { + public int ApiResourceId { get; } + public ApiResourceDto ApiResource { get; } + + public ApiResourceRequested(int apiResourceId, ApiResourceDto apiResource) + { + ApiResourceId = apiResourceId; + ApiResource = apiResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs new file mode 100644 index 000000000..8cafb7f83 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourceUpdated : AuditEvent + { + public ApiResourceDto OriginalApiResource { get; } + public ApiResourceDto ApiResource { get; } + + public ApiResourceUpdated(ApiResourceDto originalApiResource, ApiResourceDto apiResource) + { + OriginalApiResource = originalApiResource; + ApiResource = apiResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs new file mode 100644 index 000000000..28aad5c65 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiResourcesRequested : AuditEvent + { + public ApiResourcesRequested(ApiResourcesDto apiResources) + { + ApiResources = apiResources; + } + + public ApiResourcesDto ApiResources { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs index fde87ef11..3c2d17c07 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs @@ -1,6 +1,9 @@ using System.Threading.Tasks; using IdentityServer4.Models; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource; using Skoruba.IdentityServer4.Admin.BusinessLogic.Helpers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; @@ -16,15 +19,18 @@ public class ApiResourceService : IApiResourceService protected readonly IApiResourceRepository ApiResourceRepository; protected readonly IApiResourceServiceResources ApiResourceServiceResources; protected readonly IClientService ClientService; + protected readonly IAuditEventLogger AuditEventLogger; private const string SharedSecret = "SharedSecret"; public ApiResourceService(IApiResourceRepository apiResourceRepository, IApiResourceServiceResources apiResourceServiceResources, - IClientService clientService) + IClientService clientService, + IAuditEventLogger auditEventLogger) { ApiResourceRepository = apiResourceRepository; ApiResourceServiceResources = apiResourceServiceResources; ClientService = clientService; + AuditEventLogger = auditEventLogger; } public virtual async Task GetApiResourcesAsync(string search, int page = 1, int pageSize = 10) @@ -32,6 +38,8 @@ public virtual async Task GetApiResourcesAsync(string search, i var pagedList = await ApiResourceRepository.GetApiResourcesAsync(search, page, pageSize); var apiResourcesDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new ApiResourcesRequested(apiResourcesDto)); + return apiResourcesDto; } @@ -45,6 +53,8 @@ public virtual async Task GetApiResourcePropertiesAsyn apiResourcePropertiesDto.ApiResourceId = apiResourceId; apiResourcePropertiesDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceId); + await AuditEventLogger.LogEventAsync(new ApiResourcePropertiesRequested(apiResourceId, apiResourcePropertiesDto)); + return apiResourcePropertiesDto; } @@ -57,6 +67,8 @@ public virtual async Task GetApiResourcePropertyAsync( apiResourcePropertiesDto.ApiResourceId = apiResourceProperty.ApiResourceId; apiResourcePropertiesDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceProperty.ApiResourceId); + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyRequested(apiResourcePropertyId, apiResourcePropertiesDto)); + return apiResourcePropertiesDto; } @@ -71,14 +83,22 @@ public virtual async Task AddApiResourcePropertyAsync(ApiResourceProperties var apiResourceProperty = apiResourceProperties.ToEntity(); - return await ApiResourceRepository.AddApiResourcePropertyAsync(apiResourceProperties.ApiResourceId, apiResourceProperty); + var saved = await ApiResourceRepository.AddApiResourcePropertyAsync(apiResourceProperties.ApiResourceId, apiResourceProperty); + + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyAdded(apiResourceProperties)); + + return saved; } public virtual async Task DeleteApiResourcePropertyAsync(ApiResourcePropertiesDto apiResourceProperty) { var propertyEntity = apiResourceProperty.ToEntity(); - return await ApiResourceRepository.DeleteApiResourcePropertyAsync(propertyEntity); + var deleted = await ApiResourceRepository.DeleteApiResourcePropertyAsync(propertyEntity); + + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyDeleted(apiResourceProperty)); + + return deleted; } public virtual async Task CanInsertApiResourcePropertyAsync(ApiResourcePropertiesDto apiResourceProperty) @@ -116,6 +136,8 @@ public virtual async Task GetApiResourceAsync(int apiResourceId) if (apiResource == null) throw new UserFriendlyErrorPageException(ApiResourceServiceResources.ApiResourceDoesNotExist().Description, ApiResourceServiceResources.ApiResourceDoesNotExist().Description); var apiResourceDto = apiResource.ToModel(); + await AuditEventLogger.LogEventAsync(new ApiResourceRequested(apiResourceId, apiResourceDto)); + return apiResourceDto; } @@ -129,7 +151,11 @@ public virtual async Task AddApiResourceAsync(ApiResourceDto apiResource) var resource = apiResource.ToEntity(); - return await ApiResourceRepository.AddApiResourceAsync(resource); + var added = await ApiResourceRepository.AddApiResourceAsync(resource); + + await AuditEventLogger.LogEventAsync(new ApiResourceAdded(apiResource)); + + return added; } public virtual async Task UpdateApiResourceAsync(ApiResourceDto apiResource) @@ -142,6 +168,10 @@ public virtual async Task UpdateApiResourceAsync(ApiResourceDto apiResource var resource = apiResource.ToEntity(); + var originalApiResource = await GetApiResourceAsync(apiResource.Id); + + await AuditEventLogger.LogEventAsync(new ApiResourceUpdated(originalApiResource, apiResource)); + return await ApiResourceRepository.UpdateApiResourceAsync(resource); } @@ -149,7 +179,11 @@ public virtual async Task DeleteApiResourceAsync(ApiResourceDto apiResource { var resource = apiResource.ToEntity(); - return await ApiResourceRepository.DeleteApiResourceAsync(resource); + var deleted = await ApiResourceRepository.DeleteApiResourceAsync(resource); + + await AuditEventLogger.LogEventAsync(new ApiResourceDeleted(apiResource)); + + return deleted; } public virtual async Task CanInsertApiResourceAsync(ApiResourceDto apiResource) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs new file mode 100644 index 000000000..e4f068ec4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts +{ + public class AuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + public AuditLoggingDbContext(DbContextOptions dbContextOptions) + : base(dbContextOptions) + { + + } + + public Task SaveChangesAsync() + { + return base.SaveChangesAsync(); + } + + public DbSet AuditLog { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj index 19deef54e..fec341ea5 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj @@ -11,6 +11,10 @@ https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png + + + + diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs index abe313da9..215ef83ac 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs @@ -19,5 +19,7 @@ public class ConfigurationConsts public const string IdentityServerDataConfigurationKey = "IdentityServerData"; public const string IdentityDataConfigurationKey = "IdentityData"; + + public const string AuditLoggingDbConnectionStringKey = "AuditLoggingDbConnection"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 8c973d744..28497bc27 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; +using System.Security.Claims; using System.Threading.Tasks; using IdentityModel; using IdentityServer4.EntityFramework.Options; @@ -26,6 +27,11 @@ using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Serilog; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.AuditLogging.EntityFramework.Extensions; +using Skoruba.AuditLogging.EntityFramework.Repositories; +using Skoruba.AuditLogging.EntityFramework.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Middlewares; @@ -34,12 +40,30 @@ using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.Helpers.Localization; namespace Skoruba.IdentityServer4.Admin.Helpers { public static class StartupHelpers { + public static IServiceCollection AddAuditEventLogging(this IServiceCollection services, IConfiguration configuration) + where TAuditLog : AuditLog, new() + where TAuditLoggingDbContext : IAuditLoggingDbContext + { + services.AddAuditLogging() + .AddDefaultHttpEventData(options => + { + options.SubjectIdentifierClaim = JwtClaimTypes.Subject; + options.SubjectNameClaim = JwtClaimTypes.Name; + }) + .AddAuditSinks>(); + + services.AddTransient, AuditLoggingRepository>(); + + return services; + } + /// /// Register shared DbContext for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging /// Configure the connection string in AppSettings.json - use AdminConnection key @@ -88,13 +112,16 @@ public static void RegisterDbContextsStaging(this IServiceCollection s /// /// /// + /// + /// /// /// - public static void RegisterDbContexts(this IServiceCollection services, IConfigurationRoot configuration) + public static void RegisterDbContexts(this IServiceCollection services, IConfigurationRoot configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext { var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; @@ -124,6 +151,12 @@ public static void RegisterDbContexts optionsSql.MigrationsAssembly(migrationsAssembly))); + + // Audit logging connection + services.AddDbContext(options => + options.UseSqlServer( + configuration.GetConnectionString(ConfigurationConsts.AuditLoggingDbConnectionStringKey), + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); } /// @@ -134,17 +167,20 @@ public static void RegisterDbContexts /// /// + /// /// - public static void RegisterDbContextsStaging(this IServiceCollection services) + public static void RegisterDbContextsStaging(this IServiceCollection services) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext { var persistedGrantsDatabaseName = Guid.NewGuid().ToString(); var configurationDatabaseName = Guid.NewGuid().ToString(); var logDatabaseName = Guid.NewGuid().ToString(); var identityDatabaseName = Guid.NewGuid().ToString(); + var auditLoggingDatabaseName = Guid.NewGuid().ToString(); var operationalStoreOptions = new OperationalStoreOptions(); services.AddSingleton(operationalStoreOptions); @@ -156,6 +192,7 @@ public static void RegisterDbContextsStaging(optionsBuilder => optionsBuilder.UseInMemoryDatabase(persistedGrantsDatabaseName)); services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(configurationDatabaseName)); services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(logDatabaseName)); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(auditLoggingDatabaseName)); } /// diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 34fbdddc6..67e1b9cfa 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; @@ -77,6 +78,9 @@ public void ConfigureServices(IServiceCollection services) // Add authorization policies for MVC services.AddAuthorizationPolicies(rootConfiguration); + + // Add audit logging + services.AddAuditEventLogging(Configuration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) From 49eae03aad6d53dc47594826529c71d4f9365c36 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 21 Oct 2019 17:17:25 +0200 Subject: [PATCH 175/338] Move ApiResource events into subfolder; add events for IdentityResources --- ...ourceAdded.cs => ApiResourceAddedEvent.cs} | 6 +- ...eDeleted.cs => ApiResourceDeletedEvent.cs} | 6 +- ...=> ApiResourcePropertiesRequestedEvent.cs} | 4 +- ...ed.cs => ApiResourcePropertyAddedEvent.cs} | 6 +- ....cs => ApiResourcePropertyDeletedEvent.cs} | 6 +- ...s => ApiResourcePropertyRequestedEvent.cs} | 6 +- ...uested.cs => ApiResourceRequestedEvent.cs} | 8 +-- ...eUpdated.cs => ApiResourceUpdatedEvent.cs} | 8 +-- ...ested.cs => ApiResourcesRequestedEvent.cs} | 4 +- .../Events/ApiResource/ApiScopeAddedEvent.cs | 15 +++++ .../ApiResource/ApiScopeDeletedEvent.cs | 15 +++++ .../ApiResource/ApiScopeRequestedEvent.cs | 15 +++++ .../ApiResource/ApiScopeUpdatedEvent.cs | 17 ++++++ .../ApiResource/ApiScopesRequestedEvent.cs | 15 +++++ .../Events/ApiResource/ApiSecretAddedEvent.cs | 15 +++++ .../ApiResource/ApiSecretDeletedEvent.cs | 15 +++++ .../ApiResource/ApiSecretRequestedEvent.cs | 15 +++++ .../ApiResource/ApiSecretsRequestedEvent.cs | 15 +++++ .../IdentityResourceAddedEvent.cs | 15 +++++ .../IdentityResourceDeletedEvent.cs | 15 +++++ ...dentityResourcePropertiesRequestedEvent.cs | 15 +++++ .../IdentityResourcePropertyAddedEvent.cs | 15 +++++ .../IdentityResourcePropertyDeletedEvent.cs | 15 +++++ .../IdentityResourcePropertyRequestedEvent.cs | 15 +++++ .../IdentityResourceRequestedEvent.cs | 15 +++++ .../IdentityResourceUpdatedEvent.cs | 17 ++++++ .../IdentityResourcesRequestedEvent.cs | 15 +++++ .../Services/ApiResourceService.cs | 61 ++++++++++++++----- .../Services/IdentityResourceService.cs | 55 ++++++++++++++--- ...IdentityServer4.Admin.BusinessLogic.csproj | 1 + .../Skoruba.IdentityServer4.Admin.csproj | 1 + 31 files changed, 393 insertions(+), 53 deletions(-) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourceAdded.cs => ApiResourceAddedEvent.cs} (59%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourceDeleted.cs => ApiResourceDeletedEvent.cs} (59%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourcePropertiesRequested.cs => ApiResourcePropertiesRequestedEvent.cs} (70%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourcePropertyDeleted.cs => ApiResourcePropertyAddedEvent.cs} (67%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourcePropertyAdded.cs => ApiResourcePropertyDeletedEvent.cs} (67%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourcePropertyRequested.cs => ApiResourcePropertyRequestedEvent.cs} (69%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourceRequested.cs => ApiResourceRequestedEvent.cs} (54%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourceUpdated.cs => ApiResourceUpdatedEvent.cs} (52%) rename src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/{ApiResourcesRequested.cs => ApiResourcesRequestedEvent.cs} (71%) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeUpdatedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertiesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceUpdatedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcesRequestedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAddedEvent.cs similarity index 59% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAddedEvent.cs index e92544990..3b063299c 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAdded.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceAddedEvent.cs @@ -3,11 +3,11 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourceAdded : AuditEvent + public class ApiResourceAddedEvent : AuditEvent { - public ApiResourceDto ApiResource { get; } + public ApiResourceDto ApiResource { get; set; } - public ApiResourceAdded(ApiResourceDto apiResource) + public ApiResourceAddedEvent(ApiResourceDto apiResource) { ApiResource = apiResource; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeletedEvent.cs similarity index 59% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeletedEvent.cs index f898d727e..d5d743f87 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeleted.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceDeletedEvent.cs @@ -3,11 +3,11 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourceDeleted : AuditEvent + public class ApiResourceDeletedEvent : AuditEvent { - public ApiResourceDto ApiResource { get; } + public ApiResourceDto ApiResource { get; set; } - public ApiResourceDeleted(ApiResourceDto apiResource) + public ApiResourceDeletedEvent(ApiResourceDto apiResource) { ApiResource = apiResource; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequestedEvent.cs similarity index 70% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequestedEvent.cs index e777e2675..421a6c87a 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequested.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertiesRequestedEvent.cs @@ -3,9 +3,9 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourcePropertiesRequested : AuditEvent + public class ApiResourcePropertiesRequestedEvent : AuditEvent { - public ApiResourcePropertiesRequested(int apiResourceId, ApiResourcePropertiesDto apiResourceProperties) + public ApiResourcePropertiesRequestedEvent(int apiResourceId, ApiResourcePropertiesDto apiResourceProperties) { ApiResourceId = apiResourceId; ApiResourceProperties = apiResourceProperties; diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAddedEvent.cs similarity index 67% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAddedEvent.cs index 01da5d7fd..9b96f006a 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeleted.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAddedEvent.cs @@ -3,13 +3,13 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourcePropertyDeleted : AuditEvent + public class ApiResourcePropertyAddedEvent : AuditEvent { - public ApiResourcePropertyDeleted(ApiResourcePropertiesDto apiResourceProperty) + public ApiResourcePropertyAddedEvent(ApiResourcePropertiesDto apiResourceProperty) { ApiResourceProperty = apiResourceProperty; } - public ApiResourcePropertiesDto ApiResourceProperty { get; } + public ApiResourcePropertiesDto ApiResourceProperty { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeletedEvent.cs similarity index 67% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeletedEvent.cs index aaec420e9..9d4949fec 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyAdded.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyDeletedEvent.cs @@ -3,13 +3,13 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourcePropertyAdded : AuditEvent + public class ApiResourcePropertyDeletedEvent : AuditEvent { - public ApiResourcePropertyAdded(ApiResourcePropertiesDto apiResourceProperty) + public ApiResourcePropertyDeletedEvent(ApiResourcePropertiesDto apiResourceProperty) { ApiResourceProperty = apiResourceProperty; } - public ApiResourcePropertiesDto ApiResourceProperty { get; } + public ApiResourcePropertiesDto ApiResourceProperty { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequestedEvent.cs similarity index 69% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequestedEvent.cs index 5caf39f68..ba77a1c0a 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequested.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcePropertyRequestedEvent.cs @@ -3,15 +3,15 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourcePropertyRequested : AuditEvent + public class ApiResourcePropertyRequestedEvent : AuditEvent { - public ApiResourcePropertyRequested(int apiResourcePropertyId, ApiResourcePropertiesDto apiResourceProperties) + public ApiResourcePropertyRequestedEvent(int apiResourcePropertyId, ApiResourcePropertiesDto apiResourceProperties) { ApiResourcePropertyId = apiResourcePropertyId; ApiResourceProperties = apiResourceProperties; } public int ApiResourcePropertyId { get; } - public ApiResourcePropertiesDto ApiResourceProperties { get; } + public ApiResourcePropertiesDto ApiResourceProperties { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequestedEvent.cs similarity index 54% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequestedEvent.cs index b171b5f98..59e61777f 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequested.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceRequestedEvent.cs @@ -3,12 +3,12 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourceRequested : AuditEvent + public class ApiResourceRequestedEvent : AuditEvent { - public int ApiResourceId { get; } - public ApiResourceDto ApiResource { get; } + public int ApiResourceId { get; set; } + public ApiResourceDto ApiResource { get; set; } - public ApiResourceRequested(int apiResourceId, ApiResourceDto apiResource) + public ApiResourceRequestedEvent(int apiResourceId, ApiResourceDto apiResource) { ApiResourceId = apiResourceId; ApiResource = apiResource; diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdatedEvent.cs similarity index 52% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdatedEvent.cs index 8cafb7f83..e75029a0d 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdated.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourceUpdatedEvent.cs @@ -3,12 +3,12 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourceUpdated : AuditEvent + public class ApiResourceUpdatedEvent : AuditEvent { - public ApiResourceDto OriginalApiResource { get; } - public ApiResourceDto ApiResource { get; } + public ApiResourceDto OriginalApiResource { get; set; } + public ApiResourceDto ApiResource { get; set; } - public ApiResourceUpdated(ApiResourceDto originalApiResource, ApiResourceDto apiResource) + public ApiResourceUpdatedEvent(ApiResourceDto originalApiResource, ApiResourceDto apiResource) { OriginalApiResource = originalApiResource; ApiResource = apiResource; diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequestedEvent.cs similarity index 71% rename from src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs rename to src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequestedEvent.cs index 28aad5c65..329674f24 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequested.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiResourcesRequestedEvent.cs @@ -3,9 +3,9 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { - public class ApiResourcesRequested : AuditEvent + public class ApiResourcesRequestedEvent : AuditEvent { - public ApiResourcesRequested(ApiResourcesDto apiResources) + public ApiResourcesRequestedEvent(ApiResourcesDto apiResources) { ApiResources = apiResources; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeAddedEvent.cs new file mode 100644 index 000000000..1376c4566 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiScopeAddedEvent : AuditEvent + { + public ApiScopesDto ApiScope { get; set; } + + public ApiScopeAddedEvent(ApiScopesDto apiScope) + { + ApiScope = apiScope; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeDeletedEvent.cs new file mode 100644 index 000000000..db8407d0d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiScopeDeletedEvent : AuditEvent + { + public ApiScopesDto ApiScope { get; set; } + + public ApiScopeDeletedEvent(ApiScopesDto apiScope) + { + ApiScope = apiScope; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeRequestedEvent.cs new file mode 100644 index 000000000..5886f3e17 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiScopeRequestedEvent : AuditEvent + { + public ApiScopesDto ApiScopes { get; set; } + + public ApiScopeRequestedEvent(ApiScopesDto apiScopes) + { + ApiScopes = apiScopes; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeUpdatedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeUpdatedEvent.cs new file mode 100644 index 000000000..6580a6d34 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopeUpdatedEvent.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiScopeUpdatedEvent : AuditEvent + { + public ApiScopesDto OriginalApiScope { get; set; } + public ApiScopesDto ApiScope { get; set; } + + public ApiScopeUpdatedEvent(ApiScopesDto originalApiScope, ApiScopesDto apiScope) + { + OriginalApiScope = originalApiScope; + ApiScope = apiScope; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopesRequestedEvent.cs new file mode 100644 index 000000000..f5eaace1b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiScopesRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiScopesRequestedEvent : AuditEvent + { + public ApiScopesDto ApiScope { get; set; } + + public ApiScopesRequestedEvent(ApiScopesDto apiScope) + { + ApiScope = apiScope; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs new file mode 100644 index 000000000..85e072a42 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiSecretAddedEvent : AuditEvent + { + public ApiSecretsDto ApiSecret { get; set; } + + public ApiSecretAddedEvent(ApiSecretsDto apiSecret) + { + ApiSecret = apiSecret; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs new file mode 100644 index 000000000..fd63e2e44 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiSecretDeletedEvent : AuditEvent + { + public ApiSecretsDto ApiSecret { get; set; } + + public ApiSecretDeletedEvent(ApiSecretsDto apiSecret) + { + ApiSecret = apiSecret; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs new file mode 100644 index 000000000..b3698d0f3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiSecretRequestedEvent : AuditEvent + { + public ApiSecretsDto ApiSecrets { get; set; } + + public ApiSecretRequestedEvent(ApiSecretsDto apiSecrets) + { + ApiSecrets = apiSecrets; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs new file mode 100644 index 000000000..041b0d510 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource +{ + public class ApiSecretsRequestedEvent : AuditEvent + { + public ApiSecretsDto ApiSecrets { get; set; } + + public ApiSecretsRequestedEvent(ApiSecretsDto apiSecrets) + { + ApiSecrets = apiSecrets; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceAddedEvent.cs new file mode 100644 index 000000000..fc7177742 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourceAddedEvent : AuditEvent + { + public IdentityResourceDto IdentityResource { get; set; } + + public IdentityResourceAddedEvent(IdentityResourceDto identityResource) + { + IdentityResource = identityResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceDeletedEvent.cs new file mode 100644 index 000000000..b2319358d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourceDeletedEvent : AuditEvent + { + public IdentityResourceDto IdentityResource { get; set; } + + public IdentityResourceDeletedEvent(IdentityResourceDto identityResource) + { + IdentityResource = identityResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertiesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertiesRequestedEvent.cs new file mode 100644 index 000000000..6d82bcfda --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertiesRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourcePropertiesRequestedEvent : AuditEvent + { + public IdentityResourcePropertiesDto IdentityResourceProperties { get; set; } + + public IdentityResourcePropertiesRequestedEvent(IdentityResourcePropertiesDto identityResourceProperties) + { + IdentityResourceProperties = identityResourceProperties; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyAddedEvent.cs new file mode 100644 index 000000000..fb9f77b31 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourcePropertyAddedEvent : AuditEvent + { + public IdentityResourcePropertiesDto IdentityResourceProperty { get; set; } + + public IdentityResourcePropertyAddedEvent(IdentityResourcePropertiesDto identityResourceProperty) + { + IdentityResourceProperty = identityResourceProperty; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyDeletedEvent.cs new file mode 100644 index 000000000..56738e52d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourcePropertyDeletedEvent : AuditEvent + { + public IdentityResourcePropertiesDto IdentityResourceProperty { get; set; } + + public IdentityResourcePropertyDeletedEvent(IdentityResourcePropertiesDto identityResourceProperty) + { + IdentityResourceProperty = identityResourceProperty; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyRequestedEvent.cs new file mode 100644 index 000000000..e88b17daf --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcePropertyRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourcePropertyRequestedEvent : AuditEvent + { + public IdentityResourcePropertiesDto IdentityResourceProperties { get; set; } + + public IdentityResourcePropertyRequestedEvent(IdentityResourcePropertiesDto identityResourceProperties) + { + IdentityResourceProperties = identityResourceProperties; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceRequestedEvent.cs new file mode 100644 index 000000000..ae2b5394a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourceRequestedEvent : AuditEvent + { + public IdentityResourceDto IdentityResource { get; set; } + + public IdentityResourceRequestedEvent(IdentityResourceDto identityResource) + { + IdentityResource = identityResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceUpdatedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceUpdatedEvent.cs new file mode 100644 index 000000000..cda43b162 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourceUpdatedEvent.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourceUpdatedEvent : AuditEvent + { + public IdentityResourceDto OriginalIdentityResource { get; set; } + public IdentityResourceDto IdentityResource { get; set; } + + public IdentityResourceUpdatedEvent(IdentityResourceDto originalIdentityResource, IdentityResourceDto identityResource) + { + OriginalIdentityResource = originalIdentityResource; + IdentityResource = identityResource; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcesRequestedEvent.cs new file mode 100644 index 000000000..9fdcbb820 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/IdentityResource/IdentityResourcesRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource +{ + public class IdentityResourcesRequestedEvent : AuditEvent + { + public IdentityResourcesDto IdentityResources { get; } + + public IdentityResourcesRequestedEvent(IdentityResourcesDto identityResources) + { + IdentityResources = identityResources; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs index 3c2d17c07..293a6026e 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs @@ -2,7 +2,6 @@ using IdentityServer4.Models; using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Events; using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource; using Skoruba.IdentityServer4.Admin.BusinessLogic.Helpers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; @@ -38,7 +37,7 @@ public virtual async Task GetApiResourcesAsync(string search, i var pagedList = await ApiResourceRepository.GetApiResourcesAsync(search, page, pageSize); var apiResourcesDto = pagedList.ToModel(); - await AuditEventLogger.LogEventAsync(new ApiResourcesRequested(apiResourcesDto)); + await AuditEventLogger.LogEventAsync(new ApiResourcesRequestedEvent(apiResourcesDto)); return apiResourcesDto; } @@ -53,7 +52,7 @@ public virtual async Task GetApiResourcePropertiesAsyn apiResourcePropertiesDto.ApiResourceId = apiResourceId; apiResourcePropertiesDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceId); - await AuditEventLogger.LogEventAsync(new ApiResourcePropertiesRequested(apiResourceId, apiResourcePropertiesDto)); + await AuditEventLogger.LogEventAsync(new ApiResourcePropertiesRequestedEvent(apiResourceId, apiResourcePropertiesDto)); return apiResourcePropertiesDto; } @@ -67,7 +66,7 @@ public virtual async Task GetApiResourcePropertyAsync( apiResourcePropertiesDto.ApiResourceId = apiResourceProperty.ApiResourceId; apiResourcePropertiesDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceProperty.ApiResourceId); - await AuditEventLogger.LogEventAsync(new ApiResourcePropertyRequested(apiResourcePropertyId, apiResourcePropertiesDto)); + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyRequestedEvent(apiResourcePropertyId, apiResourcePropertiesDto)); return apiResourcePropertiesDto; } @@ -85,8 +84,8 @@ public virtual async Task AddApiResourcePropertyAsync(ApiResourceProperties var saved = await ApiResourceRepository.AddApiResourcePropertyAsync(apiResourceProperties.ApiResourceId, apiResourceProperty); - await AuditEventLogger.LogEventAsync(new ApiResourcePropertyAdded(apiResourceProperties)); - + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyAddedEvent(apiResourceProperties)); + return saved; } @@ -96,7 +95,7 @@ public virtual async Task DeleteApiResourcePropertyAsync(ApiResourcePropert var deleted = await ApiResourceRepository.DeleteApiResourcePropertyAsync(propertyEntity); - await AuditEventLogger.LogEventAsync(new ApiResourcePropertyDeleted(apiResourceProperty)); + await AuditEventLogger.LogEventAsync(new ApiResourcePropertyDeletedEvent(apiResourceProperty)); return deleted; } @@ -136,7 +135,7 @@ public virtual async Task GetApiResourceAsync(int apiResourceId) if (apiResource == null) throw new UserFriendlyErrorPageException(ApiResourceServiceResources.ApiResourceDoesNotExist().Description, ApiResourceServiceResources.ApiResourceDoesNotExist().Description); var apiResourceDto = apiResource.ToModel(); - await AuditEventLogger.LogEventAsync(new ApiResourceRequested(apiResourceId, apiResourceDto)); + await AuditEventLogger.LogEventAsync(new ApiResourceRequestedEvent(apiResourceId, apiResourceDto)); return apiResourceDto; } @@ -153,7 +152,7 @@ public virtual async Task AddApiResourceAsync(ApiResourceDto apiResource) var added = await ApiResourceRepository.AddApiResourceAsync(resource); - await AuditEventLogger.LogEventAsync(new ApiResourceAdded(apiResource)); + await AuditEventLogger.LogEventAsync(new ApiResourceAddedEvent(apiResource)); return added; } @@ -170,7 +169,7 @@ public virtual async Task UpdateApiResourceAsync(ApiResourceDto apiResource var originalApiResource = await GetApiResourceAsync(apiResource.Id); - await AuditEventLogger.LogEventAsync(new ApiResourceUpdated(originalApiResource, apiResource)); + await AuditEventLogger.LogEventAsync(new ApiResourceUpdatedEvent(originalApiResource, apiResource)); return await ApiResourceRepository.UpdateApiResourceAsync(resource); } @@ -181,7 +180,7 @@ public virtual async Task DeleteApiResourceAsync(ApiResourceDto apiResource var deleted = await ApiResourceRepository.DeleteApiResourceAsync(resource); - await AuditEventLogger.LogEventAsync(new ApiResourceDeleted(apiResource)); + await AuditEventLogger.LogEventAsync(new ApiResourceDeletedEvent(apiResource)); return deleted; } @@ -204,6 +203,8 @@ public virtual async Task GetApiScopesAsync(int apiResourceId, int apiScopesDto.ApiResourceId = apiResourceId; apiScopesDto.ResourceName = await GetApiResourceNameAsync(apiResourceId); + await AuditEventLogger.LogEventAsync(new ApiScopesRequestedEvent(apiScopesDto)); + return apiScopesDto; } @@ -218,6 +219,8 @@ public virtual async Task GetApiScopeAsync(int apiResourceId, int var apiScopesDto = apiScope.ToModel(); apiScopesDto.ResourceName = await GetApiResourceNameAsync(apiResourceId); + await AuditEventLogger.LogEventAsync(new ApiScopeRequestedEvent(apiScopesDto)); + return apiScopesDto; } @@ -232,7 +235,11 @@ public virtual async Task AddApiScopeAsync(ApiScopesDto apiScope) var scope = apiScope.ToEntity(); - return await ApiResourceRepository.AddApiScopeAsync(apiScope.ApiResourceId, scope); + var added = await ApiResourceRepository.AddApiScopeAsync(apiScope.ApiResourceId, scope); + + await AuditEventLogger.LogEventAsync(new ApiScopeAddedEvent(apiScope)); + + return added; } public virtual ApiScopesDto BuildApiScopeViewModel(ApiScopesDto apiScope) @@ -270,14 +277,24 @@ public virtual async Task UpdateApiScopeAsync(ApiScopesDto apiScope) var scope = apiScope.ToEntity(); - return await ApiResourceRepository.UpdateApiScopeAsync(apiScope.ApiResourceId, scope); + var updated = await ApiResourceRepository.UpdateApiScopeAsync(apiScope.ApiResourceId, scope); + + var originalApiScope = await GetApiScopeAsync(apiScope.ApiResourceId, apiScope.ApiScopeId); + + await AuditEventLogger.LogEventAsync(new ApiScopeUpdatedEvent(originalApiScope, apiScope)); + + return updated; } public virtual async Task DeleteApiScopeAsync(ApiScopesDto apiScope) { var scope = apiScope.ToEntity(); - return await ApiResourceRepository.DeleteApiScopeAsync(scope); + var deleted = await ApiResourceRepository.DeleteApiScopeAsync(scope); + + await AuditEventLogger.LogEventAsync(new ApiScopeDeletedEvent(apiScope)); + + return deleted; } public virtual async Task GetApiSecretsAsync(int apiResourceId, int page = 1, int pageSize = 10) @@ -291,6 +308,8 @@ public virtual async Task GetApiSecretsAsync(int apiResourceId, i apiSecretsDto.ApiResourceId = apiResourceId; apiSecretsDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceId); + await AuditEventLogger.LogEventAsync(new ApiSecretsRequestedEvent(apiSecretsDto)); + return apiSecretsDto; } @@ -300,7 +319,11 @@ public virtual async Task AddApiSecretAsync(ApiSecretsDto apiSecret) var secret = apiSecret.ToEntity(); - return await ApiResourceRepository.AddApiSecretAsync(apiSecret.ApiResourceId, secret); + var added = await ApiResourceRepository.AddApiSecretAsync(apiSecret.ApiResourceId, secret); + + await AuditEventLogger.LogEventAsync(new ApiSecretAddedEvent(apiSecret)); + + return added; } public virtual async Task GetApiSecretAsync(int apiSecretId) @@ -309,6 +332,8 @@ public virtual async Task GetApiSecretAsync(int apiSecretId) if (apiSecret == null) throw new UserFriendlyErrorPageException(string.Format(ApiResourceServiceResources.ApiSecretDoesNotExist().Description, apiSecretId), ApiResourceServiceResources.ApiSecretDoesNotExist().Description); var apiSecretsDto = apiSecret.ToModel(); + await AuditEventLogger.LogEventAsync(new ApiSecretRequestedEvent(apiSecretsDto)); + return apiSecretsDto; } @@ -316,7 +341,11 @@ public virtual async Task DeleteApiSecretAsync(ApiSecretsDto apiSecret) { var secret = apiSecret.ToEntity(); - return await ApiResourceRepository.DeleteApiSecretAsync(secret); + var deleted = await ApiResourceRepository.DeleteApiSecretAsync(secret); + + await AuditEventLogger.LogEventAsync(new ApiSecretDeletedEvent(apiSecret)); + + return deleted; } public virtual async Task CanInsertApiScopeAsync(ApiScopesDto apiScopes) diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs index fcf5a4f17..41ac5c3da 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs @@ -1,5 +1,7 @@ using System.Threading.Tasks; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.IdentityResource; using Skoruba.IdentityServer4.Admin.BusinessLogic.Helpers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; @@ -13,12 +15,15 @@ public class IdentityResourceService : IIdentityResourceService { protected readonly IIdentityResourceRepository IdentityResourceRepository; protected readonly IIdentityResourceServiceResources IdentityResourceServiceResources; + protected readonly IAuditEventLogger AuditEventLogger; public IdentityResourceService(IIdentityResourceRepository identityResourceRepository, - IIdentityResourceServiceResources identityResourceServiceResources) + IIdentityResourceServiceResources identityResourceServiceResources, + IAuditEventLogger auditEventLogger) { IdentityResourceRepository = identityResourceRepository; IdentityResourceServiceResources = identityResourceServiceResources; + AuditEventLogger = auditEventLogger; } public virtual async Task GetIdentityResourcesAsync(string search, int page = 1, int pageSize = 10) @@ -26,6 +31,8 @@ public virtual async Task GetIdentityResourcesAsync(string var pagedList = await IdentityResourceRepository.GetIdentityResourcesAsync(search, page, pageSize); var identityResourcesDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new IdentityResourcesRequestedEvent(identityResourcesDto)); + return identityResourcesDto; } @@ -36,6 +43,8 @@ public virtual async Task GetIdentityResourceAsync(int iden var identityResourceDto = identityResource.ToModel(); + await AuditEventLogger.LogEventAsync(new IdentityResourceRequestedEvent(identityResourceDto)); + return identityResourceDto; } @@ -45,11 +54,13 @@ public virtual async Task GetIdentityResourceProp if (identityResource == null) throw new UserFriendlyErrorPageException(string.Format(IdentityResourceServiceResources.IdentityResourceDoesNotExist().Description, identityResourceId), IdentityResourceServiceResources.IdentityResourceDoesNotExist().Description); var pagedList = await IdentityResourceRepository.GetIdentityResourcePropertiesAsync(identityResourceId, page, pageSize); - var apiResourcePropertiesDto = pagedList.ToModel(); - apiResourcePropertiesDto.IdentityResourceId = identityResourceId; - apiResourcePropertiesDto.IdentityResourceName = identityResource.Name; + var identityResourcePropertiesAsync = pagedList.ToModel(); + identityResourcePropertiesAsync.IdentityResourceId = identityResourceId; + identityResourcePropertiesAsync.IdentityResourceName = identityResource.Name; - return apiResourcePropertiesDto; + await AuditEventLogger.LogEventAsync(new IdentityResourcePropertiesRequestedEvent(identityResourcePropertiesAsync)); + + return identityResourcePropertiesAsync; } public virtual async Task GetIdentityResourcePropertyAsync(int identityResourcePropertyId) @@ -63,6 +74,8 @@ public virtual async Task GetIdentityResourceProp identityResourcePropertiesDto.IdentityResourceId = identityResourceProperty.IdentityResourceId; identityResourcePropertiesDto.IdentityResourceName = identityResource.Name; + await AuditEventLogger.LogEventAsync(new IdentityResourcePropertyRequestedEvent(identityResourcePropertiesDto)); + return identityResourcePropertiesDto; } @@ -77,7 +90,11 @@ public virtual async Task AddIdentityResourcePropertyAsync(IdentityResource var identityResourceProperty = identityResourceProperties.ToEntity(); - return await IdentityResourceRepository.AddIdentityResourcePropertyAsync(identityResourceProperties.IdentityResourceId, identityResourceProperty); + var added = await IdentityResourceRepository.AddIdentityResourcePropertyAsync(identityResourceProperties.IdentityResourceId, identityResourceProperty); + + await AuditEventLogger.LogEventAsync(new IdentityResourcePropertyAddedEvent(identityResourceProperties)); + + return added; } private async Task BuildIdentityResourcePropertiesViewModelAsync(IdentityResourcePropertiesDto identityResourceProperties) @@ -98,7 +115,11 @@ public virtual async Task DeleteIdentityResourcePropertyAsync(IdentityResou { var propertyEntity = identityResourceProperty.ToEntity(); - return await IdentityResourceRepository.DeleteIdentityResourcePropertyAsync(propertyEntity); + var deleted = await IdentityResourceRepository.DeleteIdentityResourcePropertyAsync(propertyEntity); + + await AuditEventLogger.LogEventAsync(new IdentityResourcePropertyDeletedEvent(identityResourceProperty)); + + return deleted; } public virtual async Task CanInsertIdentityResourceAsync(IdentityResourceDto identityResource) @@ -118,7 +139,11 @@ public virtual async Task AddIdentityResourceAsync(IdentityResourceDto iden var resource = identityResource.ToEntity(); - return await IdentityResourceRepository.AddIdentityResourceAsync(resource); + var saved = await IdentityResourceRepository.AddIdentityResourceAsync(resource); + + await AuditEventLogger.LogEventAsync(new IdentityResourceAddedEvent(identityResource)); + + return saved; } public virtual async Task UpdateIdentityResourceAsync(IdentityResourceDto identityResource) @@ -131,14 +156,24 @@ public virtual async Task UpdateIdentityResourceAsync(IdentityResourceDto i var resource = identityResource.ToEntity(); - return await IdentityResourceRepository.UpdateIdentityResourceAsync(resource); + var updated = await IdentityResourceRepository.UpdateIdentityResourceAsync(resource); + + var originalIdentityResource = await GetIdentityResourceAsync(resource.Id); + + await AuditEventLogger.LogEventAsync(new IdentityResourceUpdatedEvent(originalIdentityResource, identityResource)); + + return updated; } public virtual async Task DeleteIdentityResourceAsync(IdentityResourceDto identityResource) { var resource = identityResource.ToEntity(); - return await IdentityResourceRepository.DeleteIdentityResourceAsync(resource); + var deleted = await IdentityResourceRepository.DeleteIdentityResourceAsync(resource); + + await AuditEventLogger.LogEventAsync(new IdentityResourceDeletedEvent(identityResource)); + + return deleted; } public virtual IdentityResourceDto BuildIdentityResourceViewModel(IdentityResourceDto identityResource) diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj index 9a5b8a421..07702f7a6 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index cdbd636f7..cc329d1c3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -19,6 +19,7 @@ + From 496a68cf4140d9bbfb8325c080f5a26c59f7add6 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 21 Oct 2019 17:22:47 +0200 Subject: [PATCH 176/338] Add client events; fix getting of original entity before updating --- .../Events/Client/ClientAddedEvent.cs | 15 ++++++++++++++ .../Events/Client/ClientUpdatedEvent.cs | 17 ++++++++++++++++ .../Services/ApiResourceService.cs | 8 +++++--- .../Services/ClientService.cs | 20 ++++++++++++++++--- .../Services/IdentityResourceService.cs | 4 ++-- 5 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientUpdatedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientAddedEvent.cs new file mode 100644 index 000000000..48985cc95 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientAddedEvent : AuditEvent + { + public ClientDto Client { get; set; } + + public ClientAddedEvent(ClientDto client) + { + Client = client; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientUpdatedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientUpdatedEvent.cs new file mode 100644 index 000000000..4a24a1439 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientUpdatedEvent.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientUpdatedEvent: AuditEvent + { + public ClientDto OriginalClient { get; set; } + public ClientDto Client { get; set; } + + public ClientUpdatedEvent(ClientDto originalClient, ClientDto client) + { + OriginalClient = originalClient; + Client = client; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs index 293a6026e..d1ea1b83c 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs @@ -169,9 +169,11 @@ public virtual async Task UpdateApiResourceAsync(ApiResourceDto apiResource var originalApiResource = await GetApiResourceAsync(apiResource.Id); + var updated = await ApiResourceRepository.UpdateApiResourceAsync(resource); + await AuditEventLogger.LogEventAsync(new ApiResourceUpdatedEvent(originalApiResource, apiResource)); - return await ApiResourceRepository.UpdateApiResourceAsync(resource); + return updated; } public virtual async Task DeleteApiResourceAsync(ApiResourceDto apiResource) @@ -276,11 +278,11 @@ public virtual async Task UpdateApiScopeAsync(ApiScopesDto apiScope) } var scope = apiScope.ToEntity(); + + var originalApiScope = await GetApiScopeAsync(apiScope.ApiResourceId, apiScope.ApiScopeId); var updated = await ApiResourceRepository.UpdateApiScopeAsync(apiScope.ApiResourceId, scope); - var originalApiScope = await GetApiScopeAsync(apiScope.ApiResourceId, apiScope.ApiScopeId); - await AuditEventLogger.LogEventAsync(new ApiScopeUpdatedEvent(originalApiScope, apiScope)); return updated; diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs index 469ef4a1d..190edbf83 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Threading.Tasks; using IdentityServer4.Models; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Enums; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client; using Skoruba.IdentityServer4.Admin.BusinessLogic.Helpers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; @@ -19,12 +21,14 @@ public class ClientService : IClientService { protected readonly IClientRepository ClientRepository; protected readonly IClientServiceResources ClientServiceResources; + protected readonly IAuditEventLogger AuditEventLogger; private const string SharedSecret = "SharedSecret"; - public ClientService(IClientRepository clientRepository, IClientServiceResources clientServiceResources) + public ClientService(IClientRepository clientRepository, IClientServiceResources clientServiceResources, IAuditEventLogger auditEventLogger) { ClientRepository = clientRepository; ClientServiceResources = clientServiceResources; + AuditEventLogger = auditEventLogger; } private void HashClientSharedSecret(ClientSecretsDto clientSecret) @@ -151,7 +155,11 @@ public virtual async Task AddClientAsync(ClientDto client) PrepareClientTypeForNewClient(client); var clientEntity = client.ToEntity(); - return await ClientRepository.AddClientAsync(clientEntity); + var added = await ClientRepository.AddClientAsync(clientEntity); + + await AuditEventLogger.LogEventAsync(new ClientAddedEvent(client)); + + return added; } public virtual async Task UpdateClientAsync(ClientDto client) @@ -164,7 +172,13 @@ public virtual async Task UpdateClientAsync(ClientDto client) var clientEntity = client.ToEntity(); - return await ClientRepository.UpdateClientAsync(clientEntity); + var originalClient = await GetClientAsync(client.Id); + + var updated = await ClientRepository.UpdateClientAsync(clientEntity); + + await AuditEventLogger.LogEventAsync(new ClientUpdatedEvent(originalClient, client)); + + return updated; } public virtual async Task RemoveClientAsync(ClientDto client) diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs index 41ac5c3da..f1a75cfa8 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/IdentityResourceService.cs @@ -156,10 +156,10 @@ public virtual async Task UpdateIdentityResourceAsync(IdentityResourceDto i var resource = identityResource.ToEntity(); - var updated = await IdentityResourceRepository.UpdateIdentityResourceAsync(resource); - var originalIdentityResource = await GetIdentityResourceAsync(resource.Id); + var updated = await IdentityResourceRepository.UpdateIdentityResourceAsync(resource); + await AuditEventLogger.LogEventAsync(new IdentityResourceUpdatedEvent(originalIdentityResource, identityResource)); return updated; From c22a55e0bbd4b3b28d43c914f990e28c2d100fce Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 21 Oct 2019 17:30:06 +0200 Subject: [PATCH 177/338] Add client events; --- .../Events/Client/ClientClonedEvent.cs | 15 ++++++++++++ .../Events/Client/ClientDeletedEvent.cs | 15 ++++++++++++ .../Events/Client/ClientRequestedEvent.cs | 15 ++++++++++++ .../Events/Client/ClientSecretAddedEvent.cs | 15 ++++++++++++ .../Events/Client/ClientSecretDeletedEvent.cs | 15 ++++++++++++ .../Events/Client/ClientsRequestedEvent.cs | 15 ++++++++++++ .../Services/ClientService.cs | 24 ++++++++++++++++--- 7 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClonedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientsRequestedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClonedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClonedEvent.cs new file mode 100644 index 000000000..15b03dc48 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClonedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientClonedEvent : AuditEvent + { + public ClientCloneDto Client { get; set; } + + public ClientClonedEvent(ClientCloneDto client) + { + Client = client; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientDeletedEvent.cs new file mode 100644 index 000000000..19756647c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientDeletedEvent : AuditEvent + { + public ClientDto Client { get; set; } + + public ClientDeletedEvent(ClientDto client) + { + Client = client; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientRequestedEvent.cs new file mode 100644 index 000000000..19b3be16e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientRequestedEvent : AuditEvent + { + public ClientDto ClientDto { get; set; } + + public ClientRequestedEvent(ClientDto clientDto) + { + ClientDto = clientDto; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs new file mode 100644 index 000000000..54f54ee24 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientSecretAddedEvent : AuditEvent + { + public ClientSecretsDto ClientSecret { get; set; } + + public ClientSecretAddedEvent(ClientSecretsDto clientSecret) + { + ClientSecret = clientSecret; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs new file mode 100644 index 000000000..9fb7268c8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientSecretDeletedEvent : AuditEvent + { + public ClientSecretsDto ClientSecret { get; set; } + + public ClientSecretDeletedEvent(ClientSecretsDto clientSecret) + { + ClientSecret = clientSecret; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientsRequestedEvent.cs new file mode 100644 index 000000000..d623c31fd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientsRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientsRequestedEvent : AuditEvent + { + public ClientsDto ClientsDto { get; set; } + + public ClientsRequestedEvent(ClientsDto clientsDto) + { + ClientsDto = clientsDto; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs index 190edbf83..82ee3b1ab 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs @@ -185,7 +185,11 @@ public virtual async Task RemoveClientAsync(ClientDto client) { var clientEntity = client.ToEntity(); - return await ClientRepository.RemoveClientAsync(clientEntity); + var deleted = await ClientRepository.RemoveClientAsync(clientEntity); + + await AuditEventLogger.LogEventAsync(new ClientDeletedEvent(client)); + + return deleted; } public virtual async Task CloneClientAsync(ClientCloneDto client) @@ -208,6 +212,8 @@ public virtual async Task CloneClientAsync(ClientCloneDto client) client.CloneClientPostLogoutRedirectUris, client.CloneClientScopes, client.CloneClientRedirectUris, client.CloneClientClaims, client.CloneClientProperties); + await AuditEventLogger.LogEventAsync(new ClientClonedEvent(client)); + return clonedClientId; } @@ -226,6 +232,8 @@ public virtual async Task GetClientAsync(int clientId) var clientDto = client.ToModel(); + await AuditEventLogger.LogEventAsync(new ClientRequestedEvent(clientDto)); + return clientDto; } @@ -234,6 +242,8 @@ public virtual async Task GetClientsAsync(string search, int page = var pagedList = await ClientRepository.GetClientsAsync(search, page, pageSize); var clientsDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new ClientsRequestedEvent(clientsDto)); + return clientsDto; } @@ -305,14 +315,22 @@ public virtual async Task AddClientSecretAsync(ClientSecretsDto clientSecre HashClientSharedSecret(clientSecret); var clientSecretEntity = clientSecret.ToEntity(); - return await ClientRepository.AddClientSecretAsync(clientSecret.ClientId, clientSecretEntity); + var added = await ClientRepository.AddClientSecretAsync(clientSecret.ClientId, clientSecretEntity); + + await AuditEventLogger.LogEventAsync(new ClientSecretAddedEvent(clientSecret)); + + return added; } public virtual async Task DeleteClientSecretAsync(ClientSecretsDto clientSecret) { var clientSecretEntity = clientSecret.ToEntity(); - return await ClientRepository.DeleteClientSecretAsync(clientSecretEntity); + var deleted = await ClientRepository.DeleteClientSecretAsync(clientSecretEntity); + + await AuditEventLogger.LogEventAsync(new ClientSecretDeletedEvent(clientSecret)); + + return deleted; } public virtual async Task GetClientSecretsAsync(int clientId, int page = 1, int pageSize = 10) From 0a625be7e03ae579336f993bb1843b7b4c0ac6d6 Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Tue, 22 Oct 2019 14:31:11 +0200 Subject: [PATCH 178/338] Added Created HTTP response code for Role and User post methods --- .../Controllers/RolesController.cs | 13 ++++++++----- .../Controllers/UsersController.cs | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs index 38023511a..49dd6529a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs @@ -19,7 +19,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class RolesController> Get(string searchText, int page = 1, } [HttpPost] - public async Task Post([FromBody]TRoleDto role) + [ProducesResponseType(201)] + [ProducesResponseType(400)] + public async Task> Post([FromBody]TRoleDto role) { if (!EqualityComparer.Default.Equals(role.Id, default)) { return BadRequest(_errorResources.CannotSetId()); } + + var (identityResult, roleId) = await _identityService.CreateRoleAsync(role); + var createdRole = await _identityService.GetRoleAsync(roleId.ToString()); - await _identityService.CreateRoleAsync(role); - - return Ok(); + return CreatedAtAction(nameof(Get), new { id = createdRole.Id }, createdRole); } [HttpPut] diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index 5710e3ba3..1986c6050 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -19,7 +19,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class UsersController> Get(string searchText, int page = 1, } [HttpPost] - public async Task Post([FromBody]TUserDto user) + [ProducesResponseType(201)] + [ProducesResponseType(400)] + public async Task> Post([FromBody]TUserDto user) { if (!EqualityComparer.Default.Equals(user.Id, default)) { return BadRequest(_errorResources.CannotSetId()); } - await _identityService.CreateUserAsync(user); + var (identityResult, userId) = await _identityService.CreateUserAsync(user); + var createdUser = await _identityService.GetUserAsync(userId.ToString()); - return Ok(); + return CreatedAtAction(nameof(Get), new { id = createdUser.Id }, createdUser); } [HttpPut] From 148c178ae0fb828026d5334a739740a4becb66aa Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 22 Oct 2019 17:08:23 +0200 Subject: [PATCH 179/338] Add audit events for client, logs and persisted grants --- .../Events/Client/ClientClaimAddedEvent.cs | 15 ++++++++ .../Events/Client/ClientClaimDeletedEvent.cs | 15 ++++++++ .../Client/ClientClaimRequestedEvent.cs | 15 ++++++++ .../Client/ClientClaimsRequestedEvent.cs | 15 ++++++++ .../Client/ClientPropertiesRequestedEvent.cs | 15 ++++++++ .../Events/Client/ClientPropertyAddedEvent.cs | 15 ++++++++ .../Client/ClientPropertyDeletedEvent.cs | 15 ++++++++ .../Client/ClientPropertyRequestedEvent.cs | 15 ++++++++ .../Client/ClientSecretRequestedEvent.cs | 15 ++++++++ .../Client/ClientSecretsRequestedEvent.cs | 15 ++++++++ .../PersistedGrantDeletedEvent.cs | 14 ++++++++ .../PersistedGrantRequestedEvent.cs | 15 ++++++++ .../PersistedGrantsByUserRequestedEvent.cs | 15 ++++++++ .../PersistedGrantsByUsersRequestedEvent.cs | 15 ++++++++ .../PersistedGrantsDeletedEvent.cs | 14 ++++++++ .../Services/ClientService.cs | 36 ++++++++++++++++--- .../Services/LogService.cs | 10 +++++- .../Services/PersistedGrantService.cs | 25 +++++++++++-- 18 files changed, 286 insertions(+), 8 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimsRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertiesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUserRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUsersRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsDeletedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimAddedEvent.cs new file mode 100644 index 000000000..9444244d3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientClaimAddedEvent : AuditEvent + { + public ClientClaimsDto ClientClaim { get; set; } + + public ClientClaimAddedEvent(ClientClaimsDto clientClaim) + { + ClientClaim = clientClaim; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimDeletedEvent.cs new file mode 100644 index 000000000..2c173a861 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientClaimDeletedEvent : AuditEvent + { + public ClientClaimsDto ClientClaim { get; set; } + + public ClientClaimDeletedEvent(ClientClaimsDto clientClaim) + { + ClientClaim = clientClaim; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimRequestedEvent.cs new file mode 100644 index 000000000..b205088bc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientClaimRequestedEvent : AuditEvent + { + public ClientClaimsDto ClientClaims { get; set; } + + public ClientClaimRequestedEvent(ClientClaimsDto clientClaims) + { + ClientClaims = clientClaims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimsRequestedEvent.cs new file mode 100644 index 000000000..5bd93de5a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientClaimsRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientClaimsRequestedEvent : AuditEvent + { + public ClientClaimsDto ClientClaims { get; set; } + + public ClientClaimsRequestedEvent(ClientClaimsDto clientClaims) + { + ClientClaims = clientClaims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertiesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertiesRequestedEvent.cs new file mode 100644 index 000000000..bfb3d1c02 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertiesRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientPropertiesRequestedEvent : AuditEvent + { + public ClientPropertiesDto ClientProperties { get; set; } + + public ClientPropertiesRequestedEvent(ClientPropertiesDto clientProperties) + { + ClientProperties = clientProperties; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyAddedEvent.cs new file mode 100644 index 000000000..4a99c4110 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyAddedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientPropertyAddedEvent : AuditEvent + { + public ClientPropertiesDto ClientProperties { get; set; } + + public ClientPropertyAddedEvent(ClientPropertiesDto clientProperties) + { + ClientProperties = clientProperties; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyDeletedEvent.cs new file mode 100644 index 000000000..77de4b29a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyDeletedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientPropertyDeletedEvent : AuditEvent + { + public ClientPropertiesDto ClientProperty { get; set; } + + public ClientPropertyDeletedEvent(ClientPropertiesDto clientProperty) + { + ClientProperty = clientProperty; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyRequestedEvent.cs new file mode 100644 index 000000000..da7def0de --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientPropertyRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientPropertyRequestedEvent : AuditEvent + { + public ClientPropertiesDto ClientProperties { get; set; } + + public ClientPropertyRequestedEvent(ClientPropertiesDto clientProperties) + { + ClientProperties = clientProperties; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs new file mode 100644 index 000000000..8bc32e62d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientSecretRequestedEvent : AuditEvent + { + public ClientSecretsDto ClientSecrets { get; set; } + + public ClientSecretRequestedEvent(ClientSecretsDto clientSecrets) + { + ClientSecrets = clientSecrets; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs new file mode 100644 index 000000000..faeada5b8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client +{ + public class ClientSecretsRequestedEvent : AuditEvent + { + public ClientSecretsDto ClientSecrets { get; set; } + + public ClientSecretsRequestedEvent(ClientSecretsDto clientSecrets) + { + ClientSecrets = clientSecrets; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantDeletedEvent.cs new file mode 100644 index 000000000..d263f97f2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant +{ + public class PersistedGrantDeletedEvent : AuditEvent + { + public string PersistedGrantKey { get; set; } + + public PersistedGrantDeletedEvent(string persistedGrantKey) + { + PersistedGrantKey = persistedGrantKey; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantRequestedEvent.cs new file mode 100644 index 000000000..40701f9d5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant +{ + public class PersistedGrantRequestedEvent : AuditEvent + { + public PersistedGrantDto PersistedGrant { get; set; } + + public PersistedGrantRequestedEvent(PersistedGrantDto persistedGrant) + { + PersistedGrant = persistedGrant; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUserRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUserRequestedEvent.cs new file mode 100644 index 000000000..d32dbf950 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUserRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant +{ + public class PersistedGrantsByUserRequestedEvent : AuditEvent + { + public PersistedGrantsDto PersistedGrants { get; set; } + + public PersistedGrantsByUserRequestedEvent(PersistedGrantsDto persistedGrants) + { + PersistedGrants = persistedGrants; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUsersRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUsersRequestedEvent.cs new file mode 100644 index 000000000..79a208dd4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsByUsersRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant +{ + public class PersistedGrantsByUsersRequestedEvent : AuditEvent + { + public PersistedGrantsDto PersistedGrants { get; set; } + + public PersistedGrantsByUsersRequestedEvent(PersistedGrantsDto persistedGrants) + { + PersistedGrants = persistedGrants; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsDeletedEvent.cs new file mode 100644 index 000000000..02c309216 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/PersistedGrant/PersistedGrantsDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant +{ + public class PersistedGrantsDeletedEvent : AuditEvent + { + public string UserId { get; set; } + + public PersistedGrantsDeletedEvent(string userId) + { + UserId = userId; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs index 82ee3b1ab..a3ed485d7 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs @@ -343,6 +343,8 @@ public virtual async Task GetClientSecretsAsync(int clientId, clientSecretsDto.ClientId = clientId; clientSecretsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientSecretsRequestedEvent(clientSecretsDto)); + return clientSecretsDto; } @@ -358,6 +360,8 @@ public virtual async Task GetClientSecretAsync(int clientSecre clientSecretsDto.ClientId = clientSecret.Client.Id; clientSecretsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientSecretRequestedEvent(clientSecretsDto)); + return clientSecretsDto; } @@ -371,6 +375,8 @@ public virtual async Task GetClientClaimsAsync(int clientId, in clientClaimsDto.ClientId = clientId; clientClaimsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientClaimsRequestedEvent(clientClaimsDto)); + return clientClaimsDto; } @@ -384,6 +390,8 @@ public virtual async Task GetClientPropertiesAsync(int clie clientPropertiesDto.ClientId = clientId; clientPropertiesDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientPropertiesRequestedEvent(clientPropertiesDto)); + return clientPropertiesDto; } @@ -399,6 +407,8 @@ public virtual async Task GetClientClaimAsync(int clientClaimId clientClaimsDto.ClientId = clientClaim.Client.Id; clientClaimsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientClaimRequestedEvent(clientClaimsDto)); + return clientClaimsDto; } @@ -414,6 +424,8 @@ public virtual async Task GetClientPropertyAsync(int client clientPropertiesDto.ClientId = clientProperty.Client.Id; clientPropertiesDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); + await AuditEventLogger.LogEventAsync(new ClientPropertyRequestedEvent(clientPropertiesDto)); + return clientPropertiesDto; } @@ -421,28 +433,44 @@ public virtual async Task AddClientClaimAsync(ClientClaimsDto clientClaim) { var clientClaimEntity = clientClaim.ToEntity(); - return await ClientRepository.AddClientClaimAsync(clientClaim.ClientId, clientClaimEntity); + var saved = await ClientRepository.AddClientClaimAsync(clientClaim.ClientId, clientClaimEntity); + + await AuditEventLogger.LogEventAsync(new ClientClaimAddedEvent(clientClaim)); + + return saved; } public virtual async Task AddClientPropertyAsync(ClientPropertiesDto clientProperties) { var clientProperty = clientProperties.ToEntity(); - return await ClientRepository.AddClientPropertyAsync(clientProperties.ClientId, clientProperty); + var saved = await ClientRepository.AddClientPropertyAsync(clientProperties.ClientId, clientProperty); + + await AuditEventLogger.LogEventAsync(new ClientPropertyAddedEvent(clientProperties)); + + return saved; } public virtual async Task DeleteClientClaimAsync(ClientClaimsDto clientClaim) { var clientClaimEntity = clientClaim.ToEntity(); - return await ClientRepository.DeleteClientClaimAsync(clientClaimEntity); + var deleted = await ClientRepository.DeleteClientClaimAsync(clientClaimEntity); + + await AuditEventLogger.LogEventAsync(new ClientClaimDeletedEvent(clientClaim)); + + return deleted; } public virtual async Task DeleteClientPropertyAsync(ClientPropertiesDto clientProperty) { var clientPropertyEntity = clientProperty.ToEntity(); - return await ClientRepository.DeleteClientPropertyAsync(clientPropertyEntity); + var deleted = await ClientRepository.DeleteClientPropertyAsync(clientPropertyEntity); + + await AuditEventLogger.LogEventAsync(new ClientPropertyDeletedEvent(clientProperty)); + + return deleted; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/LogService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/LogService.cs index a09336ac9..2f7a0f626 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/LogService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/LogService.cs @@ -1,6 +1,8 @@ using System; using System.Threading.Tasks; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Log; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; @@ -10,10 +12,12 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Services public class LogService : ILogService { protected readonly ILogRepository Repository; + protected readonly IAuditEventLogger AuditEventLogger; - public LogService(ILogRepository repository) + public LogService(ILogRepository repository, IAuditEventLogger auditEventLogger) { Repository = repository; + AuditEventLogger = auditEventLogger; } public virtual async Task GetLogsAsync(string search, int page = 1, int pageSize = 10) @@ -21,12 +25,16 @@ public virtual async Task GetLogsAsync(string search, int page = 1, int var pagedList = await Repository.GetLogsAsync(search, page, pageSize); var logs = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new LogsRequestedEvent()); + return logs; } public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) { await Repository.DeleteLogsOlderThanAsync(deleteOlderThan); + + await AuditEventLogger.LogEventAsync(new LogsDeletedEvent(deleteOlderThan)); } } } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/PersistedGrantService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/PersistedGrantService.cs index 9ae90c868..b798a7456 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/PersistedGrantService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/PersistedGrantService.cs @@ -1,5 +1,7 @@ using System.Threading.Tasks; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Grant; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Events.PersistedGrant; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; @@ -12,12 +14,15 @@ public class PersistedGrantService : IPersistedGrantService { protected readonly IPersistedGrantRepository PersistedGrantRepository; protected readonly IPersistedGrantServiceResources PersistedGrantServiceResources; + protected readonly IAuditEventLogger AuditEventLogger; public PersistedGrantService(IPersistedGrantRepository persistedGrantRepository, - IPersistedGrantServiceResources persistedGrantServiceResources) + IPersistedGrantServiceResources persistedGrantServiceResources, + IAuditEventLogger auditEventLogger) { PersistedGrantRepository = persistedGrantRepository; PersistedGrantServiceResources = persistedGrantServiceResources; + AuditEventLogger = auditEventLogger; } public virtual async Task GetPersistedGrantsByUsersAsync(string search, int page = 1, int pageSize = 10) @@ -25,6 +30,8 @@ public virtual async Task GetPersistedGrantsByUsersAsync(str var pagedList = await PersistedGrantRepository.GetPersistedGrantsByUsersAsync(search, page, pageSize); var persistedGrantsDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantsByUsersRequestedEvent(persistedGrantsDto)); + return persistedGrantsDto; } @@ -36,6 +43,8 @@ public virtual async Task GetPersistedGrantsByUserAsync(stri var pagedList = await PersistedGrantRepository.GetPersistedGrantsByUserAsync(subjectId, page, pageSize); var persistedGrantsDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantsByUserRequestedEvent(persistedGrantsDto)); + return persistedGrantsDto; } @@ -45,17 +54,27 @@ public virtual async Task GetPersistedGrantAsync(string key) if (persistedGrant == null) throw new UserFriendlyErrorPageException(string.Format(PersistedGrantServiceResources.PersistedGrantDoesNotExist().Description, key), PersistedGrantServiceResources.PersistedGrantDoesNotExist().Description); var persistedGrantDto = persistedGrant.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantRequestedEvent(persistedGrantDto)); + return persistedGrantDto; } public virtual async Task DeletePersistedGrantAsync(string key) { - return await PersistedGrantRepository.DeletePersistedGrantAsync(key); + var deleted = await PersistedGrantRepository.DeletePersistedGrantAsync(key); + + await AuditEventLogger.LogEventAsync(new PersistedGrantDeletedEvent(key)); + + return deleted; } public virtual async Task DeletePersistedGrantsAsync(string userId) { - return await PersistedGrantRepository.DeletePersistedGrantsAsync(userId); + var deleted = await PersistedGrantRepository.DeletePersistedGrantsAsync(userId); + + await AuditEventLogger.LogEventAsync(new PersistedGrantsDeletedEvent(userId)); + + return deleted; } } } From 4a001b1322234379320927f2a95111d179e3a9c9 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 22 Oct 2019 17:27:14 +0200 Subject: [PATCH 180/338] Add events for identity --- .../Events/Identity/AllRolesRequestedEvent.cs | 15 +++++++++++++++ .../Events/Identity/RoleAddedEvent.cs | 14 ++++++++++++++ .../Events/Identity/RoleRequestedEvent.cs | 14 ++++++++++++++ .../Identity/RoleUsersRequestedEvent.cs | 15 +++++++++++++++ .../Events/Identity/RolesRequestedEvent.cs | 13 +++++++++++++ .../Events/Identity/UsersRequestedEvent.cs | 14 ++++++++++++++ .../Services/IdentityService.cs | 19 ++++++++++++++++++- ...erver4.Admin.BusinessLogic.Identity.csproj | 1 + .../Helpers/StartupHelpers.cs | 8 +++++--- src/Skoruba.IdentityServer4.Admin/Startup.cs | 2 +- 10 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/AllRolesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleAddedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUsersRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RolesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UsersRequestedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/AllRolesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/AllRolesRequestedEvent.cs new file mode 100644 index 000000000..afe0d2b55 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/AllRolesRequestedEvent.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class AllRolesRequestedEvent : AuditEvent + { + public List Roles { get; set; } + + public AllRolesRequestedEvent(List roles) + { + Roles = roles; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleAddedEvent.cs new file mode 100644 index 000000000..d862db8e8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleAddedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleAddedEvent : AuditEvent + { + public TRoleDto Role { get; set; } + + public RoleAddedEvent(TRoleDto role) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleRequestedEvent.cs new file mode 100644 index 000000000..48c091421 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleRequestedEvent : AuditEvent + { + public TRoleDto Role { get; set; } + + public RoleRequestedEvent(TRoleDto role) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUsersRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUsersRequestedEvent.cs new file mode 100644 index 000000000..469e10454 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUsersRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleUsersRequestedEvent : AuditEvent + { + public TUsersDto Users { get; set; } + + public RoleUsersRequestedEvent(TUsersDto users) + { + Users = users; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RolesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RolesRequestedEvent.cs new file mode 100644 index 000000000..2a8e9e473 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RolesRequestedEvent.cs @@ -0,0 +1,13 @@ +using Skoruba.AuditLogging.Events; +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RolesRequestedEvent : AuditEvent + { + public TRolesDto Roles { get; set; } + + public RolesRequestedEvent(TRolesDto roles) + { + Roles = roles; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UsersRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UsersRequestedEvent.cs new file mode 100644 index 000000000..0570e4ede --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UsersRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UsersRequestedEvent : AuditEvent + { + public TUsersDto Users { get; set; } + + public UsersRequestedEvent(TUsersDto users) + { + Users = users; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs index 8ed96768b..c995062aa 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs @@ -5,7 +5,9 @@ using System.Threading.Tasks; using AutoMapper; using Microsoft.AspNetCore.Identity; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common; @@ -44,14 +46,17 @@ public class IdentityService IdentityRepository; protected readonly IIdentityServiceResources IdentityServiceResources; protected readonly IMapper Mapper; + protected readonly IAuditEventLogger AuditEventLogger; public IdentityService(IIdentityRepository identityRepository, IIdentityServiceResources identityServiceResources, - IMapper mapper) + IMapper mapper, + IAuditEventLogger auditEventLogger) { IdentityRepository = identityRepository; IdentityServiceResources = identityServiceResources; Mapper = mapper; + AuditEventLogger = auditEventLogger; } public virtual async Task ExistsUserAsync(string userId) @@ -75,6 +80,8 @@ public virtual async Task GetUsersAsync(string search, int page = 1, var pagedList = await IdentityRepository.GetUsersAsync(search, page, pageSize); var usersDto = Mapper.Map(pagedList); + await AuditEventLogger.LogEventAsync(new UsersRequestedEvent(usersDto)); + return usersDto; } @@ -88,6 +95,8 @@ public virtual async Task GetRoleUsersAsync(string roleId, string sea var pagedList = await IdentityRepository.GetRoleUsersAsync(roleId, search, page, pageSize); var usersDto = Mapper.Map(pagedList); + await AuditEventLogger.LogEventAsync(new RoleUsersRequestedEvent(usersDto)); + return usersDto; } @@ -96,6 +105,8 @@ public virtual async Task GetRolesAsync(string search, int page = 1, PagedList pagedList = await IdentityRepository.GetRolesAsync(search, page, pageSize); var rolesDto = Mapper.Map(pagedList); + await AuditEventLogger.LogEventAsync(new RolesRequestedEvent(rolesDto)); + return rolesDto; } @@ -105,6 +116,8 @@ public virtual async Task GetRolesAsync(string search, int page = 1, var (identityResult, roleId) = await IdentityRepository.CreateRoleAsync(roleEntity); var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role); + await AuditEventLogger.LogEventAsync(new RoleAddedEvent(role)); + return (handleIdentityError, roleId); } @@ -125,6 +138,8 @@ public virtual async Task GetRoleAsync(string roleId) var roleDto = Mapper.Map(userIdentityRole); + await AuditEventLogger.LogEventAsync(new RoleRequestedEvent(roleDto)); + return roleDto; } @@ -133,6 +148,8 @@ public virtual async Task> GetRolesAsync() var roles = await IdentityRepository.GetRolesAsync(); var roleDtos = Mapper.Map>(roles); + await AuditEventLogger.LogEventAsync(new AllRolesRequestedEvent(roleDtos)); + return roleDtos; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj index 435da070b..eedfe012f 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 28497bc27..59407ab15 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -306,22 +306,24 @@ public static void AddDbContexts(this IServiceCollection services, IHo /// /// /// + /// /// /// /// - public static void AddDbContexts(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfigurationRoot configuration) + public static void AddDbContexts(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfigurationRoot configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext { if (hostingEnvironment.IsStaging()) { - services.RegisterDbContextsStaging(); + services.RegisterDbContextsStaging(); } else { - services.RegisterDbContexts(configuration); + services.RegisterDbContexts(configuration); } } diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 67e1b9cfa..c695dc295 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -46,7 +46,7 @@ public void ConfigureServices(IServiceCollection services) var rootConfiguration = services.BuildServiceProvider().GetService(); // Add DbContexts for Asp.Net Core Identity, Logging and IdentityServer - Configuration store and Operational store - services.AddDbContexts(HostingEnvironment, Configuration); + services.AddDbContexts(HostingEnvironment, Configuration); // Add Asp.Net Core Identity Configuration and OpenIdConnect auth as well services.AddAuthenticationServices(HostingEnvironment, rootConfiguration.AdminConfiguration); From 6231f8a9a5d39e5b83e28598c3a4727b92344eed Mon Sep 17 00:00:00 2001 From: janskoruba Date: Fri, 25 Oct 2019 17:23:38 +0200 Subject: [PATCH 181/338] Add events for identity --- .../Identity/RoleClaimRequestedEvent.cs | 14 +++++ .../Events/Identity/RoleClaimsDeletedEvent.cs | 14 +++++ .../Identity/RoleClaimsRequestedEvent.cs | 14 +++++ .../Events/Identity/RoleClaimsSavedEvent.cs | 14 +++++ .../Events/Identity/RoleDeletedEvent.cs | 14 +++++ .../Events/Identity/RoleUpdatedEvent.cs | 17 +++++ .../Identity/UserClaimRequestedEvent.cs | 14 +++++ .../Events/Identity/UserClaimsDeletedEvent.cs | 14 +++++ .../Identity/UserClaimsRequestedEvent.cs | 14 +++++ .../Events/Identity/UserClaimsSavedEvent.cs | 14 +++++ .../Events/Identity/UserDeletedEvent.cs | 14 +++++ .../Identity/UserPasswordChangedEvent.cs | 14 +++++ .../Identity/UserProviderRequestedEvent.cs | 13 ++++ .../Identity/UserProvidersDeletedEvent.cs | 14 +++++ .../Identity/UserProvidersRequestedEvent.cs | 14 +++++ .../Events/Identity/UserRequestedEvent.cs | 15 +++++ .../Events/Identity/UserRoleDeletedEvent.cs | 14 +++++ .../Events/Identity/UserRoleSavedEvent.cs | 14 +++++ .../Identity/UserRolesRequestedEvent.cs | 14 +++++ .../Events/Identity/UserSavedEvent.cs | 14 +++++ .../Events/Identity/UserUpdatedEvent.cs | 16 +++++ .../Services/IdentityService.cs | 63 +++++++++++++++++-- 22 files changed, 357 insertions(+), 5 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsSavedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUpdatedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsSavedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProviderRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleSavedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRolesRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserSavedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserUpdatedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimRequestedEvent.cs new file mode 100644 index 000000000..b42e00e6f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleClaimRequestedEvent : AuditEvent + { + public TRoleClaimsDto RoleClaim { get; set; } + + public RoleClaimRequestedEvent(TRoleClaimsDto roleClaim) + { + RoleClaim = roleClaim; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsDeletedEvent.cs new file mode 100644 index 000000000..2525a162c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleClaimsDeletedEvent : AuditEvent + { + public TRoleClaimsDto RoleClaim { get; set; } + + public RoleClaimsDeletedEvent(TRoleClaimsDto roleClaim) + { + RoleClaim = roleClaim; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsRequestedEvent.cs new file mode 100644 index 000000000..fefe30064 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleClaimsRequestedEvent : AuditEvent + { + public TRoleClaimsDto RoleClaims { get; set; } + + public RoleClaimsRequestedEvent(TRoleClaimsDto roleClaims) + { + RoleClaims = roleClaims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsSavedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsSavedEvent.cs new file mode 100644 index 000000000..24a2a2e5e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleClaimsSavedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleClaimsSavedEvent : AuditEvent + { + public TRoleClaimsDto Claims { get; set; } + + public RoleClaimsSavedEvent(TRoleClaimsDto claims) + { + Claims = claims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleDeletedEvent.cs new file mode 100644 index 000000000..cb2a8c464 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleDeletedEvent : AuditEvent + { + public TRoleDto Role { get; set; } + + public RoleDeletedEvent(TRoleDto role) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUpdatedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUpdatedEvent.cs new file mode 100644 index 000000000..3c6ef9b1f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/RoleUpdatedEvent.cs @@ -0,0 +1,17 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class RoleUpdatedEvent : AuditEvent + { + public TRoleDto OriginalRole { get; set; } + public TRoleDto Role { get; set; } + + public RoleUpdatedEvent(TRoleDto originalRole, TRoleDto role) + { + OriginalRole = originalRole; + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimRequestedEvent.cs new file mode 100644 index 000000000..4eea1e3ee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserClaimRequestedEvent : AuditEvent + { + public TUserClaimsDto UserClaims { get; set; } + + public UserClaimRequestedEvent(TUserClaimsDto userClaims) + { + UserClaims = userClaims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsDeletedEvent.cs new file mode 100644 index 000000000..e60752e42 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserClaimsDeletedEvent : AuditEvent + { + public TUserClaimsDto Claim { get; set; } + + public UserClaimsDeletedEvent(TUserClaimsDto claim) + { + Claim = claim; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsRequestedEvent.cs new file mode 100644 index 000000000..8c6927259 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserClaimsRequestedEvent : AuditEvent + { + public TUserClaimsDto Claims { get; set; } + + public UserClaimsRequestedEvent(TUserClaimsDto claims) + { + Claims = claims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsSavedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsSavedEvent.cs new file mode 100644 index 000000000..ae66d1b49 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserClaimsSavedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserClaimsSavedEvent : AuditEvent + { + public TUserClaimsDto Claims { get; set; } + + public UserClaimsSavedEvent(TUserClaimsDto claims) + { + Claims = claims; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserDeletedEvent.cs new file mode 100644 index 000000000..32cdf29c7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserDeletedEvent : AuditEvent + { + public TUserDto User { get; set; } + + public UserDeletedEvent(TUserDto user) + { + User = user; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs new file mode 100644 index 000000000..6496237f0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserPasswordChangedEvent : AuditEvent + { + public TUserChangePasswordDto UserPassword { get; set; } + + public UserPasswordChangedEvent(TUserChangePasswordDto userPassword) + { + UserPassword = userPassword; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProviderRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProviderRequestedEvent.cs new file mode 100644 index 000000000..10b2dfb29 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProviderRequestedEvent.cs @@ -0,0 +1,13 @@ +using Skoruba.AuditLogging.Events; +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserProviderRequestedEvent : AuditEvent + { + public TUserProviderDto Provider { get; set; } + + public UserProviderRequestedEvent(TUserProviderDto provider) + { + Provider = provider; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersDeletedEvent.cs new file mode 100644 index 000000000..a0535f608 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserProvidersDeletedEvent : AuditEvent + { + public TUserProviderDto Provider { get; set; } + + public UserProvidersDeletedEvent(TUserProviderDto provider) + { + Provider = provider; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersRequestedEvent.cs new file mode 100644 index 000000000..922859bee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserProvidersRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserProvidersRequestedEvent : AuditEvent + { + public TUserProvidersDto Providers { get; set; } + + public UserProvidersRequestedEvent(TUserProvidersDto providers) + { + Providers = providers; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRequestedEvent.cs new file mode 100644 index 000000000..4b38d2e94 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserRequestedEvent : AuditEvent + { + public TUserDto UserDto { get; set; } + + public UserRequestedEvent(TUserDto userDto) + { + UserDto = userDto; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleDeletedEvent.cs new file mode 100644 index 000000000..f1b8ac9fe --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserRoleDeletedEvent : AuditEvent + { + public TUserRolesDto Role { get; set; } + + public UserRoleDeletedEvent(TUserRolesDto role) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleSavedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleSavedEvent.cs new file mode 100644 index 000000000..9962d14ef --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRoleSavedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserRoleSavedEvent : AuditEvent + { + public TUserRolesDto Role { get; set; } + + public UserRoleSavedEvent(TUserRolesDto role) + { + Role = role; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRolesRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRolesRequestedEvent.cs new file mode 100644 index 000000000..91b4a109d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserRolesRequestedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserRolesRequestedEvent : AuditEvent + { + public TUserRolesDto Roles { get; set; } + + public UserRolesRequestedEvent(TUserRolesDto roles) + { + Roles = roles; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserSavedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserSavedEvent.cs new file mode 100644 index 000000000..a52c18f61 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserSavedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserSavedEvent : AuditEvent + { + public TUserDto User { get; set; } + + public UserSavedEvent(TUserDto user) + { + User = user; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserUpdatedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserUpdatedEvent.cs new file mode 100644 index 000000000..2c6907c1e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserUpdatedEvent.cs @@ -0,0 +1,16 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity +{ + public class UserUpdatedEvent : AuditEvent + { + public TUserDto OriginalUser { get; set; } + public TUserDto User { get; set; } + + public UserUpdatedEvent(TUserDto originalUser, TUserDto user) + { + OriginalUser = originalUser; + User = user; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs index c995062aa..272a727bc 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs @@ -17,10 +17,10 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services { - public class IdentityService: IIdentityService : IIdentityService @@ -106,7 +106,7 @@ public virtual async Task GetRolesAsync(string search, int page = 1, var rolesDto = Mapper.Map(pagedList); await AuditEventLogger.LogEventAsync(new RolesRequestedEvent(rolesDto)); - + return rolesDto; } @@ -156,8 +156,13 @@ public virtual async Task> GetRolesAsync() public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRoleDto role) { var userIdentityRole = Mapper.Map(role); + + var originalRole = await GetRoleAsync(role.Id.ToString()); + var (identityResult, roleId) = await IdentityRepository.UpdateRoleAsync(userIdentityRole); + await AuditEventLogger.LogEventAsync(new RoleUpdatedEvent(originalRole, role)); + var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role); return (handleIdentityError, roleId); @@ -170,6 +175,8 @@ public virtual async Task GetUserAsync(string userId) var userDto = Mapper.Map(identity); + await AuditEventLogger.LogEventAsync(new UserRequestedEvent(userDto)); + return userDto; } @@ -177,8 +184,11 @@ public virtual async Task GetUserAsync(string userId) { var userIdentity = Mapper.Map(user); var (identityResult, userId) = await IdentityRepository.CreateUserAsync(userIdentity); + var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user); + await AuditEventLogger.LogEventAsync(new UserSavedEvent(user)); + return (handleIdentityError, userId); } @@ -192,9 +202,13 @@ public virtual async Task GetUserAsync(string userId) var userIdentity = Mapper.Map(user); await MapOriginalPasswordHashAsync(userIdentity); + var originalUser = await GetUserAsync(user.Id.ToString()); + var (identityResult, userId) = await IdentityRepository.UpdateUserAsync(userIdentity); var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user); + await AuditEventLogger.LogEventAsync(new UserUpdatedEvent(originalUser, user)); + return (handleIdentityError, userId); } @@ -213,6 +227,8 @@ public virtual async Task DeleteUserAsync(string userId, TUserDt { var identityResult = await IdentityRepository.DeleteUserAsync(userId); + await AuditEventLogger.LogEventAsync(new UserDeletedEvent(user)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user); } @@ -223,6 +239,9 @@ public virtual async Task CreateUserRoleAsync(TUserRolesDto role if (!identityResult.Errors.Any()) return identityResult; var userRolesDto = await BuildUserRolesViewModel(role.UserId, 1); + + await AuditEventLogger.LogEventAsync(new UserRoleSavedEvent(role)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userRolesDto); } @@ -247,6 +266,8 @@ public virtual async Task GetUserRolesAsync(string userId, int pa var user = await IdentityRepository.GetUserAsync(userId); roleDtos.UserName = user.UserName; + await AuditEventLogger.LogEventAsync(new UserRolesRequestedEvent(roleDtos)); + return roleDtos; } @@ -254,6 +275,8 @@ public virtual async Task DeleteUserRoleAsync(TUserRolesDto role { var identityResult = await IdentityRepository.DeleteUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString()); + await AuditEventLogger.LogEventAsync(new UserRoleDeletedEvent(role)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role); } @@ -268,6 +291,8 @@ public virtual async Task GetUserClaimsAsync(string userId, int var user = await IdentityRepository.GetUserAsync(userId); claimDtos.UserName = user.UserName; + await AuditEventLogger.LogEventAsync(new UserClaimsRequestedEvent(claimDtos)); + return claimDtos; } @@ -281,6 +306,8 @@ public virtual async Task GetUserClaimAsync(string userId, int c var userClaimsDto = Mapper.Map(identityUserClaim); + await AuditEventLogger.LogEventAsync(new UserClaimRequestedEvent(userClaimsDto)); + return userClaimsDto; } @@ -289,12 +316,18 @@ public virtual async Task CreateUserClaimsAsync(TUserClaimsDto c var userIdentityUserClaim = Mapper.Map(claimsDto); var identityResult = await IdentityRepository.CreateUserClaimsAsync(userIdentityUserClaim); + await AuditEventLogger.LogEventAsync(new UserClaimsSavedEvent(claimsDto)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto); } public virtual async Task DeleteUserClaimsAsync(TUserClaimsDto claim) { - return await IdentityRepository.DeleteUserClaimsAsync(claim.UserId.ToString(), claim.ClaimId); + var deleted = await IdentityRepository.DeleteUserClaimsAsync(claim.UserId.ToString(), claim.ClaimId); + + await AuditEventLogger.LogEventAsync(new UserClaimsDeletedEvent(claim)); + + return deleted; } public virtual TUserDtoKey ConvertUserDtoKeyFromString(string id) @@ -327,6 +360,8 @@ public virtual async Task GetUserProvidersAsync(string userId var user = await IdentityRepository.GetUserAsync(userId); providersDto.UserName = user.UserName; + await AuditEventLogger.LogEventAsync(new UserProvidersRequestedEvent(providersDto)); + return providersDto; } @@ -334,6 +369,8 @@ public virtual async Task DeleteUserProvidersAsync(TUserProvider { var identityResult = await IdentityRepository.DeleteUserProvidersAsync(provider.UserId.ToString(), provider.ProviderKey, provider.LoginProvider); + await AuditEventLogger.LogEventAsync(new UserProvidersDeletedEvent(provider)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserProviderDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, provider); } @@ -349,6 +386,8 @@ public virtual async Task GetUserProviderAsync(string userId, var user = await GetUserAsync(userId); userProviderDto.UserName = user.UserName; + await AuditEventLogger.LogEventAsync(new UserProviderRequestedEvent(userProviderDto)); + return userProviderDto; } @@ -359,6 +398,8 @@ public virtual async Task UserChangePasswordAsync(TUserChangePas var identityResult = await IdentityRepository.UserChangePasswordAsync(userPassword.UserId.ToString(), userPassword.Password); + await AuditEventLogger.LogEventAsync(new UserPasswordChangedEvent(userPassword)); + return HandleIdentityError(identityResult, IdentityServiceResources.UserChangePasswordFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userPassword); } @@ -367,6 +408,8 @@ public virtual async Task CreateRoleClaimsAsync(TRoleClaimsDto c var identityRoleClaim = Mapper.Map(claimsDto); var identityResult = await IdentityRepository.CreateRoleClaimsAsync(identityRoleClaim); + await AuditEventLogger.LogEventAsync(new RoleClaimsSavedEvent(claimsDto)); + return HandleIdentityError(identityResult, IdentityServiceResources.RoleClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto); } @@ -380,6 +423,8 @@ public virtual async Task GetRoleClaimsAsync(string roleId, int var roleDto = await GetRoleAsync(roleId); roleClaimDtos.RoleName = roleDto.Name; + await AuditEventLogger.LogEventAsync(new RoleClaimsRequestedEvent(roleClaimDtos)); + return roleClaimDtos; } @@ -394,12 +439,18 @@ public virtual async Task GetRoleClaimAsync(string roleId, int c var roleDto = await GetRoleAsync(roleId); roleClaimsDto.RoleName = roleDto.Name; + await AuditEventLogger.LogEventAsync(new RoleClaimRequestedEvent(roleClaimsDto)); + return roleClaimsDto; } public virtual async Task DeleteRoleClaimsAsync(TRoleClaimsDto role) { - return await IdentityRepository.DeleteRoleClaimsAsync(role.RoleId.ToString(), role.ClaimId); + var deleted = await IdentityRepository.DeleteRoleClaimsAsync(role.RoleId.ToString(), role.ClaimId); + + await AuditEventLogger.LogEventAsync(new RoleClaimsDeletedEvent(role)); + + return deleted; } public virtual async Task DeleteRoleAsync(TRoleDto role) @@ -407,6 +458,8 @@ public virtual async Task DeleteRoleAsync(TRoleDto role) var userIdentityRole = Mapper.Map(role); var identityResult = await IdentityRepository.DeleteRoleAsync(userIdentityRole); + await AuditEventLogger.LogEventAsync(new RoleDeletedEvent(role)); + return HandleIdentityError(identityResult, IdentityServiceResources.RoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role); } } From e4c5d20ea99e181f81e15d3dd52b85c72c339a9a Mon Sep 17 00:00:00 2001 From: janskoruba Date: Fri, 25 Oct 2019 17:33:41 +0200 Subject: [PATCH 182/338] Add events for PersistedGrant regarding to Identity --- .../PersistedGrantIdentityDeletedEvent.cs | 14 +++++++++++ .../PersistedGrantIdentityRequestedEvent.cs | 15 +++++++++++ ...istedGrantsIdentityByUserRequestedEvent.cs | 15 +++++++++++ ...stedGrantsIdentityByUsersRequestedEvent.cs | 15 +++++++++++ .../PersistedGrantsIdentityDeletedEvent.cs | 14 +++++++++++ .../PersistedGrantAspNetIdentityService.cs | 25 ++++++++++++++++--- 6 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUserRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUsersRequestedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityDeletedEvent.cs diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityDeletedEvent.cs new file mode 100644 index 000000000..4a02b1909 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant +{ + public class PersistedGrantIdentityDeletedEvent : AuditEvent + { + public string Key { get; set; } + + public PersistedGrantIdentityDeletedEvent(string key) + { + Key = key; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityRequestedEvent.cs new file mode 100644 index 000000000..c07efc1de --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantIdentityRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant +{ + public class PersistedGrantIdentityRequestedEvent : AuditEvent + { + public PersistedGrantDto PersistedGrant { get; set; } + + public PersistedGrantIdentityRequestedEvent(PersistedGrantDto persistedGrant) + { + PersistedGrant = persistedGrant; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUserRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUserRequestedEvent.cs new file mode 100644 index 000000000..ff00276d4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUserRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant +{ + public class PersistedGrantsIdentityByUserRequestedEvent : AuditEvent + { + public PersistedGrantsDto PersistedGrants { get; set; } + + public PersistedGrantsIdentityByUserRequestedEvent(PersistedGrantsDto persistedGrants) + { + PersistedGrants = persistedGrants; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUsersRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUsersRequestedEvent.cs new file mode 100644 index 000000000..40c233c52 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityByUsersRequestedEvent.cs @@ -0,0 +1,15 @@ +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant +{ + public class PersistedGrantsIdentityByUsersRequestedEvent : AuditEvent + { + public PersistedGrantsDto PersistedGrants { get; set; } + + public PersistedGrantsIdentityByUsersRequestedEvent(PersistedGrantsDto persistedGrants) + { + PersistedGrants = persistedGrants; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityDeletedEvent.cs new file mode 100644 index 000000000..dc782fc80 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/PersistedGrant/PersistedGrantsIdentityDeletedEvent.cs @@ -0,0 +1,14 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant +{ + public class PersistedGrantsIdentityDeletedEvent : AuditEvent + { + public string UserId { get; set; } + + public PersistedGrantsIdentityDeletedEvent(string userId) + { + UserId = userId; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/PersistedGrantAspNetIdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/PersistedGrantAspNetIdentityService.cs index ea605a978..e0db3d798 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/PersistedGrantAspNetIdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/PersistedGrantAspNetIdentityService.cs @@ -1,5 +1,7 @@ using System.Threading.Tasks; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.PersistedGrant; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; @@ -12,12 +14,15 @@ public class PersistedGrantAspNetIdentityService : IPersistedGrantAspNetIdentity { protected readonly IPersistedGrantAspNetIdentityRepository PersistedGrantAspNetIdentityRepository; protected readonly IPersistedGrantAspNetIdentityServiceResources PersistedGrantAspNetIdentityServiceResources; + protected readonly IAuditEventLogger AuditEventLogger; public PersistedGrantAspNetIdentityService(IPersistedGrantAspNetIdentityRepository persistedGrantAspNetIdentityRepository, - IPersistedGrantAspNetIdentityServiceResources persistedGrantAspNetIdentityServiceResources) + IPersistedGrantAspNetIdentityServiceResources persistedGrantAspNetIdentityServiceResources, + IAuditEventLogger auditEventLogger) { PersistedGrantAspNetIdentityRepository = persistedGrantAspNetIdentityRepository; PersistedGrantAspNetIdentityServiceResources = persistedGrantAspNetIdentityServiceResources; + AuditEventLogger = auditEventLogger; } public virtual async Task GetPersistedGrantsByUsersAsync(string search, int page = 1, int pageSize = 10) @@ -25,6 +30,8 @@ public virtual async Task GetPersistedGrantsByUsersAsync(str var pagedList = await PersistedGrantAspNetIdentityRepository.GetPersistedGrantsByUsersAsync(search, page, pageSize); var persistedGrantsDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantsIdentityByUsersRequestedEvent(persistedGrantsDto)); + return persistedGrantsDto; } @@ -36,6 +43,8 @@ public virtual async Task GetPersistedGrantsByUserAsync(stri var pagedList = await PersistedGrantAspNetIdentityRepository.GetPersistedGrantsByUserAsync(subjectId, page, pageSize); var persistedGrantsDto = pagedList.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantsIdentityByUserRequestedEvent(persistedGrantsDto)); + return persistedGrantsDto; } @@ -45,6 +54,8 @@ public virtual async Task GetPersistedGrantAsync(string key) if (persistedGrant == null) throw new UserFriendlyErrorPageException(string.Format(PersistedGrantAspNetIdentityServiceResources.PersistedGrantDoesNotExist().Description, key), PersistedGrantAspNetIdentityServiceResources.PersistedGrantDoesNotExist().Description); var persistedGrantDto = persistedGrant.ToModel(); + await AuditEventLogger.LogEventAsync(new PersistedGrantIdentityRequestedEvent(persistedGrantDto)); + return persistedGrantDto; } @@ -53,7 +64,11 @@ public virtual async Task DeletePersistedGrantAsync(string key) var exists = await PersistedGrantAspNetIdentityRepository.ExistsPersistedGrantAsync(key); if (!exists) throw new UserFriendlyErrorPageException(string.Format(PersistedGrantAspNetIdentityServiceResources.PersistedGrantDoesNotExist().Description, key), PersistedGrantAspNetIdentityServiceResources.PersistedGrantDoesNotExist().Description); - return await PersistedGrantAspNetIdentityRepository.DeletePersistedGrantAsync(key); + var deleted = await PersistedGrantAspNetIdentityRepository.DeletePersistedGrantAsync(key); + + await AuditEventLogger.LogEventAsync(new PersistedGrantIdentityDeletedEvent(key)); + + return deleted; } public virtual async Task DeletePersistedGrantsAsync(string userId) @@ -61,7 +76,11 @@ public virtual async Task DeletePersistedGrantsAsync(string userId) var exists = await PersistedGrantAspNetIdentityRepository.ExistsPersistedGrantsAsync(userId); if (!exists) throw new UserFriendlyErrorPageException(string.Format(PersistedGrantAspNetIdentityServiceResources.PersistedGrantWithSubjectIdDoesNotExist().Description, userId), PersistedGrantAspNetIdentityServiceResources.PersistedGrantWithSubjectIdDoesNotExist().Description); - return await PersistedGrantAspNetIdentityRepository.DeletePersistedGrantsAsync(userId); + var deleted = await PersistedGrantAspNetIdentityRepository.DeletePersistedGrantsAsync(userId); + + await AuditEventLogger.LogEventAsync(new PersistedGrantsIdentityDeletedEvent(userId)); + + return deleted; } } } From 982f6c024afc7c45b072e40cf14497548033ea5c Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 14:14:55 +0100 Subject: [PATCH 183/338] Fix tests after adding audit logging layer --- .../ConfigurationControllerTests.cs | 12 + .../Controllers/IdentityControllerTests.cs | 12 + .../Services/ApiResourceServiceTests.cs | 241 +++++------------- .../Services/ClientServiceTests.cs | 120 +++------ .../Services/IdentityResourceServiceTests.cs | 105 ++++---- .../Services/IdentityServiceTests.cs | 146 +++-------- .../Services/PersistedGrantServiceTests.cs | 20 +- 7 files changed, 222 insertions(+), 434 deletions(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs index cf722a12f..36d1c591c 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using FluentAssertions; +using IdentityModel; using IdentityServer4.EntityFramework.Entities; using IdentityServer4.EntityFramework.Options; using Microsoft.AspNetCore.Builder; @@ -16,6 +17,10 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.AuditLogging.EntityFramework.Extensions; +using Skoruba.AuditLogging.EntityFramework.Repositories; +using Skoruba.AuditLogging.EntityFramework.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; @@ -787,6 +792,7 @@ private IServiceProvider GetServices() var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); services.AddOptions(); services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); + services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); //Http Context var context = new DefaultHttpContext(); @@ -796,6 +802,12 @@ private IServiceProvider GetServices() services.AddSingleton(); services.AddSingleton(); + //Audit logging + services.AddAuditLogging() + .AddDefaultEventData() + .AddAuditSinks>(); + services.AddTransient, AuditLoggingRepository>(); + //Add Admin services services.AddMvcExceptionFilters(); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs index 1c4f9a4fe..e40b7a020 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs @@ -16,6 +16,10 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.AuditLogging.EntityFramework.Extensions; +using Skoruba.AuditLogging.EntityFramework.Repositories; +using Skoruba.AuditLogging.EntityFramework.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; using Skoruba.IdentityServer4.Admin.Controllers; @@ -573,6 +577,7 @@ private IServiceProvider GetServices() var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); services.AddOptions(); services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); + services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); //Http Context var context = new DefaultHttpContext(); @@ -582,6 +587,13 @@ private IServiceProvider GetServices() services.AddSingleton(); services.AddSingleton(); + //Audit logging + services.AddAuditLogging() + .AddDefaultEventData() + .AddAuditSinks>(); + services.AddTransient, AuditLoggingRepository>(); + + //Add Admin services services.AddMvcExceptionFilters(); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ApiResourceServiceTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ApiResourceServiceTests.cs index 0b4b237cf..d10d8191d 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ApiResourceServiceTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ApiResourceServiceTests.cs @@ -5,6 +5,7 @@ using IdentityServer4.EntityFramework.Options; using Microsoft.EntityFrameworkCore; using Moq; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services; @@ -49,39 +50,49 @@ private IApiResourceRepository GetApiResourceRepository(IdentityServerConfigurat return apiResourceRepository; } - private IClientService GetClientService(IClientRepository repository, IClientServiceResources resources) + private IClientService GetClientService(IClientRepository repository, IClientServiceResources resources, IAuditEventLogger auditEventLogger) { - IClientService clientService = new ClientService(repository, resources); + IClientService clientService = new ClientService(repository, resources, auditEventLogger); return clientService; } - private IApiResourceService GetApiResourceService(IApiResourceRepository repository, IApiResourceServiceResources resources, IClientService clientService) + private IApiResourceService GetApiResourceService(IApiResourceRepository repository, IApiResourceServiceResources resources, IClientService clientService, IAuditEventLogger auditEventLogger) { - IApiResourceService apiResourceService = new ApiResourceService(repository, resources, clientService); + IApiResourceService apiResourceService = new ApiResourceService(repository, resources, clientService, auditEventLogger); return apiResourceService; } - [Fact] - public async Task AddApiResourceAsync() - { - using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) - { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); + private IApiResourceService GetApiResourceService(IdentityServerConfigurationDbContext context) + { + var apiResourceRepository = GetApiResourceRepository(context); + var clientRepository = GetClientRepository(context); + + var localizerApiResourceMock = new Mock(); + var localizerApiResource = localizerApiResourceMock.Object; - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var localizerClientResourceMock = new Mock(); + var localizerClientResource = localizerClientResourceMock.Object; - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); + var clientService = GetClientService(clientRepository, localizerClientResource, auditLogger); + var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService, auditLogger); - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + return apiResourceService; + } + + [Fact] + public async Task AddApiResourceAsync() + { + using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) + { + var apiResourceService = GetApiResourceService(context); + + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -100,20 +111,10 @@ public async Task GetApiResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -132,20 +133,10 @@ public async Task RemoveApiResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -174,20 +165,10 @@ public async Task UpdateApiResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -220,20 +201,10 @@ public async Task AddApiScopeAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -271,20 +242,10 @@ public async Task GetApiScopeAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -322,20 +283,10 @@ public async Task UpdateApiScopeAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -386,20 +337,10 @@ public async Task DeleteApiScopeAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -446,20 +387,10 @@ public async Task AddApiSecretAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -497,20 +428,10 @@ public async Task DeleteApiSecretAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResourceDto = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResourceDto); @@ -557,20 +478,10 @@ public async Task AddApiResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResource); @@ -610,20 +521,10 @@ public async Task GetApiResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; + var apiResourceService = GetApiResourceService(context); - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); - - //Generate random new api resource - var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResource); @@ -663,20 +564,10 @@ public async Task DeleteApiResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var apiResourceRepository = GetApiResourceRepository(context); - var clientRepository = GetClientRepository(context); - - var localizerApiResourceMock = new Mock(); - var localizerApiResource = localizerApiResourceMock.Object; - - var localizerClientResourceMock = new Mock(); - var localizerClientResource = localizerClientResourceMock.Object; - - var clientService = GetClientService(clientRepository, localizerClientResource); - var apiResourceService = GetApiResourceService(apiResourceRepository, localizerApiResource, clientService); + var apiResourceService = GetApiResourceService(context); - //Generate random new api resource - var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); + //Generate random new api resource + var apiResource = ApiResourceDtoMock.GenerateRandomApiResource(0); await apiResourceService.AddApiResourceAsync(apiResource); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ClientServiceTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ClientServiceTests.cs index 47d080734..435ae35ba 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ClientServiceTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/ClientServiceTests.cs @@ -5,6 +5,7 @@ using IdentityServer4.EntityFramework.Options; using Microsoft.EntityFrameworkCore; using Moq; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services; @@ -42,9 +43,24 @@ private IClientRepository GetClientRepository(IdentityServerConfigurationDbConte return clientRepository; } - private IClientService GetClientService(IClientRepository repository, IClientServiceResources resources) + private IClientService GetClientService(IClientRepository repository, IClientServiceResources resources, IAuditEventLogger auditEventLogger) { - IClientService clientService = new ClientService(repository, resources); + IClientService clientService = new ClientService(repository, resources, auditEventLogger); + + return clientService; + } + + private IClientService GetClientService(IdentityServerConfigurationDbContext context) + { + var clientRepository = GetClientRepository(context); + + var localizerMock = new Mock(); + var localizer = localizerMock.Object; + + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var clientService = GetClientService(clientRepository, localizer, auditLogger); return clientService; } @@ -54,12 +70,7 @@ public async Task AddClientAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -87,12 +98,7 @@ public async Task CloneClientAsync() //Generate random new client var clientDto = ClientDtoMock.GenerateRandomClient(0); - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Add new client await clientService.AddClientAsync(clientDto); @@ -197,12 +203,7 @@ public async Task UpdateClientAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client without id var client = ClientDtoMock.GenerateRandomClient(0); @@ -243,12 +244,7 @@ public async Task RemoveClientAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client without id var client = ClientDtoMock.GenerateRandomClient(0); @@ -285,12 +281,7 @@ public async Task GetClientAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -313,12 +304,7 @@ public async Task AddClientClaimAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -362,12 +348,7 @@ public async Task DeleteClientClaimAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -419,12 +400,7 @@ public async Task GetClientClaimAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -467,12 +443,7 @@ public async Task AddClientPropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -516,12 +487,7 @@ public async Task GetClientPropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -564,12 +530,7 @@ public async Task DeleteClientPropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -621,12 +582,7 @@ public async Task AddClientSecretAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -670,12 +626,7 @@ public async Task GetClientSecretAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); + var clientService = GetClientService(context); //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); @@ -718,13 +669,8 @@ public async Task DeleteClientSecretAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var clientRepository = GetClientRepository(context); - - var localizerMock = new Mock(); - var localizer = localizerMock.Object; - - var clientService = GetClientService(clientRepository, localizer); - + var clientService = GetClientService(context); + //Generate random new client var client = ClientDtoMock.GenerateRandomClient(0); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityResourceServiceTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityResourceServiceTests.cs index 53f727019..1b3dddbbd 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityResourceServiceTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityResourceServiceTests.cs @@ -5,6 +5,7 @@ using IdentityServer4.EntityFramework.Options; using Microsoft.EntityFrameworkCore; using Moq; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services; @@ -42,27 +43,37 @@ private IIdentityResourceRepository GetIdentityResourceRepository(IdentityServer return identityResourceRepository; } - private IIdentityResourceService GetIdentityResourceService(IIdentityResourceRepository repository, IIdentityResourceServiceResources identityResourceServiceResources) + private IIdentityResourceService GetIdentityResourceService(IIdentityResourceRepository repository, IIdentityResourceServiceResources identityResourceServiceResources, IAuditEventLogger auditEventLogger) { - IIdentityResourceService identityResourceService = new IdentityResourceService(repository, identityResourceServiceResources); + IIdentityResourceService identityResourceService = new IdentityResourceService(repository, identityResourceServiceResources, auditEventLogger); return identityResourceService; } - [Fact] + private IIdentityResourceService GetIdentityResourceService(IdentityServerConfigurationDbContext context) + { + var identityResourceRepository = GetIdentityResourceRepository(context); + + var localizerIdentityResourceMock = new Mock(); + var localizerIdentityResource = localizerIdentityResourceMock.Object; + + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource, auditLogger); + + return identityResourceService; + } + + [Fact] public async Task AddIdentityResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) - { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); + { + var identityResourceService = GetIdentityResourceService(context); - //Generate random new identity resource - var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + //Generate random new identity resource + var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResourceDto); @@ -81,15 +92,10 @@ public async Task GetIdentityResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); - - //Generate random new identity resource - var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + var identityResourceService = GetIdentityResourceService(context); + + //Generate random new identity resource + var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResourceDto); @@ -108,15 +114,10 @@ public async Task RemoveIdentityResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); - - //Generate random new identity resource - var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + var identityResourceService = GetIdentityResourceService(context); + + //Generate random new identity resource + var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResourceDto); @@ -145,15 +146,10 @@ public async Task UpdateIdentityResourceAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); + var identityResourceService = GetIdentityResourceService(context); - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); - - //Generate random new identity resource - var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + //Generate random new identity resource + var identityResourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResourceDto); @@ -186,15 +182,10 @@ public async Task AddIdentityResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; + var identityResourceService = GetIdentityResourceService(context); - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); - - //Generate random new identity resource - var identityResource = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + //Generate random new identity resource + var identityResource = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResource); @@ -234,15 +225,10 @@ public async Task GetIdentityResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); + var identityResourceService = GetIdentityResourceService(context); - //Generate random new identity resource - var identityResource = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + //Generate random new identity resource + var identityResource = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(identityResource); @@ -282,15 +268,10 @@ public async Task DeleteIdentityResourcePropertyAsync() { using (var context = new IdentityServerConfigurationDbContext(_dbContextOptions, _storeOptions)) { - var identityResourceRepository = GetIdentityResourceRepository(context); - - var localizerIdentityResourceMock = new Mock(); - var localizerIdentityResource = localizerIdentityResourceMock.Object; - - var identityResourceService = GetIdentityResourceService(identityResourceRepository, localizerIdentityResource); + var identityResourceService = GetIdentityResourceService(context); - //Generate random new identity resource - var resourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); + //Generate random new identity resource + var resourceDto = IdentityResourceDtoMock.GenerateRandomIdentityResource(0); await identityResourceService.AddIdentityResourceAsync(resourceDto); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityServiceTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityServiceTests.cs index efb90b95c..faf14d641 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityServiceTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/IdentityServiceTests.cs @@ -7,6 +7,8 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Moq; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Mappers; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources; @@ -59,7 +61,7 @@ public IdentityServiceTests() UserClaimsDto, UserProviderDto, UserProvidersDto, UserChangePasswordDto, RoleClaimsDto> GetIdentityService(IIdentityRepository identityRepository, IIdentityServiceResources identityServiceResources, - IMapper mapper) + IMapper mapper, IAuditEventLogger auditEventLogger) { return new IdentityService, string, RoleDto, string, string, string, UserIdentity, UserIdentityRole, string, @@ -67,7 +69,7 @@ RoleClaimsDto> GetIdentityService(IIdentityRepository, string>, RolesDto, string>, UserRolesDto, string, string>, UserClaimsDto, UserProviderDto, UserProvidersDto, UserChangePasswordDto, - RoleClaimsDto>(identityRepository, identityServiceResources, mapper); + RoleClaimsDto>(identityRepository, identityServiceResources, mapper, auditEventLogger); } private IMapper GetMapper() @@ -96,18 +98,36 @@ private RoleManager GetTestRoleManager(AdminIdentityDbContext return testRoleManager; } + private IIdentityService, string, RoleDto, string, string, string, UserIdentity, + UserIdentityRole, string, + UserIdentityUserClaim, UserIdentityUserRole, UserIdentityUserLogin, UserIdentityRoleClaim, + UserIdentityUserToken, + UsersDto, string>, RolesDto, string>, + UserRolesDto, string, string>, + UserClaimsDto, UserProviderDto, UserProvidersDto, UserChangePasswordDto, + RoleClaimsDto> GetIdentityService(AdminIdentityDbContext context) + { + var testUserManager = GetTestUserManager(context); + var testRoleManager = GetTestRoleManager(context); + var mapper = GetMapper(); + + var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); + var localizerIdentityResource = new IdentityServiceResources(); + + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper, auditLogger); + + return identityService; + } + [Fact] public async Task AddUserAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -130,14 +150,7 @@ public async Task DeleteUserProviderAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -180,14 +193,7 @@ public async Task AddUserRoleAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -233,14 +239,7 @@ public async Task DeleteUserRoleAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -291,14 +290,7 @@ public async Task AddUserClaimAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -335,14 +327,7 @@ public async Task DeleteUserClaimAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -385,14 +370,7 @@ public async Task UpdateUserAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -429,14 +407,7 @@ public async Task DeleteUserAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new user var userDto = IdentityDtoMock.GenerateRandomUser(); @@ -469,14 +440,7 @@ public async Task AddRoleAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new role var roleDto = IdentityDtoMock.GenerateRandomRole(); @@ -499,14 +463,7 @@ public async Task UpdateRoleAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new role var roleDto = IdentityDtoMock.GenerateRandomRole(); @@ -543,14 +500,7 @@ public async Task DeleteRoleAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new role var roleDto = IdentityDtoMock.GenerateRandomRole(); @@ -583,14 +533,7 @@ public async Task AddRoleClaimAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new role var roleDto = IdentityDtoMock.GenerateRandomRole(); @@ -627,14 +570,7 @@ public async Task RemoveRoleClaimAsync() { using (var context = new AdminIdentityDbContext(_dbContextOptions)) { - var testUserManager = GetTestUserManager(context); - var testRoleManager = GetTestRoleManager(context); - - var mapper = GetMapper(); - - var identityRepository = GetIdentityRepository(context, testUserManager, testRoleManager, mapper); - var localizerIdentityResource = new IdentityServiceResources(); - var identityService = GetIdentityService(identityRepository, localizerIdentityResource, mapper); + var identityService = GetIdentityService(context); //Generate random new role var roleDto = IdentityDtoMock.GenerateRandomRole(); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/PersistedGrantServiceTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/PersistedGrantServiceTests.cs index 03df70a32..eee4645c5 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/PersistedGrantServiceTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Services/PersistedGrantServiceTests.cs @@ -4,6 +4,7 @@ using IdentityServer4.EntityFramework.Options; using Microsoft.EntityFrameworkCore; using Moq; +using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces; @@ -48,10 +49,10 @@ private IPersistedGrantAspNetIdentityRepository GetPersistedGrantRepository(Admi } private IPersistedGrantAspNetIdentityService - GetPersistedGrantService(IPersistedGrantAspNetIdentityRepository repository, IPersistedGrantAspNetIdentityServiceResources persistedGrantServiceResources) + GetPersistedGrantService(IPersistedGrantAspNetIdentityRepository repository, IPersistedGrantAspNetIdentityServiceResources persistedGrantServiceResources, IAuditEventLogger auditEventLogger) { var persistedGrantService = new PersistedGrantAspNetIdentityService(repository, - persistedGrantServiceResources); + persistedGrantServiceResources, auditEventLogger); return persistedGrantService; } @@ -68,7 +69,10 @@ public async Task GetPersistedGrantAsync() var localizerMock = new Mock(); var localizer = localizerMock.Object; - var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer); + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer, auditLogger); //Generate persisted grant var persistedGrantKey = Guid.NewGuid().ToString(); @@ -99,7 +103,10 @@ public async Task DeletePersistedGrantAsync() var localizerMock = new Mock(); var localizer = localizerMock.Object; - var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer); + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer, auditLogger); //Generate persisted grant var persistedGrantKey = Guid.NewGuid().ToString(); @@ -132,7 +139,10 @@ public async Task DeletePersistedGrantsAsync() var localizerMock = new Mock(); var localizer = localizerMock.Object; - var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer); + var auditLoggerMock = new Mock(); + var auditLogger = auditLoggerMock.Object; + + var persistedGrantService = GetPersistedGrantService(persistedGrantRepository, localizer, auditLogger); const int subjectId = 1; From 0d972b6229113fd4c21e3f90729c7de582175409 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 14:40:28 +0100 Subject: [PATCH 184/338] Rename AuditLoggingDbContext to AdminAuditLogDbContext --- .../{AuditLoggingDbContext.cs => AdminAuditLogDbContext.cs} | 4 ++-- .../Configuration/Constants/ConfigurationConsts.cs | 2 +- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 2 +- src/Skoruba.IdentityServer4.Admin/Startup.cs | 4 ++-- src/Skoruba.IdentityServer4.Admin/appsettings.json | 3 ++- .../Controllers/ConfigurationControllerTests.cs | 4 ++-- .../Controllers/IdentityControllerTests.cs | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/{AuditLoggingDbContext.cs => AdminAuditLogDbContext.cs} (73%) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AdminAuditLogDbContext.cs similarity index 73% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AdminAuditLogDbContext.cs index e4f068ec4..99ecf3fb6 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AuditLoggingDbContext.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/DbContexts/AdminAuditLogDbContext.cs @@ -6,9 +6,9 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts { - public class AuditLoggingDbContext : DbContext, IAuditLoggingDbContext + public class AdminAuditLogDbContext : DbContext, IAuditLoggingDbContext { - public AuditLoggingDbContext(DbContextOptions dbContextOptions) + public AdminAuditLogDbContext(DbContextOptions dbContextOptions) : base(dbContextOptions) { diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs index 215ef83ac..80e288eb9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Constants/ConfigurationConsts.cs @@ -20,6 +20,6 @@ public class ConfigurationConsts public const string IdentityDataConfigurationKey = "IdentityData"; - public const string AuditLoggingDbConnectionStringKey = "AuditLoggingDbConnection"; + public const string AdminAuditLogDbConnectionStringKey = "AdminAuditLogDbConnection"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 59407ab15..4eae469aa 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -155,7 +155,7 @@ public static void RegisterDbContexts(options => options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.AuditLoggingDbConnectionStringKey), + configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey), optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); } diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index c695dc295..85c92fb17 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -46,7 +46,7 @@ public void ConfigureServices(IServiceCollection services) var rootConfiguration = services.BuildServiceProvider().GetService(); // Add DbContexts for Asp.Net Core Identity, Logging and IdentityServer - Configuration store and Operational store - services.AddDbContexts(HostingEnvironment, Configuration); + services.AddDbContexts(HostingEnvironment, Configuration); // Add Asp.Net Core Identity Configuration and OpenIdConnect auth as well services.AddAuthenticationServices(HostingEnvironment, rootConfiguration.AdminConfiguration); @@ -80,7 +80,7 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthorizationPolicies(rootConfiguration); // Add audit logging - services.AddAuditEventLogging(Configuration); + services.AddAuditEventLogging(Configuration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 7efa94a3e..14be9966f 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -3,7 +3,8 @@ "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, "AdminConfiguration": { "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs index 36d1c591c..a31a77b5a 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs @@ -792,7 +792,7 @@ private IServiceProvider GetServices() var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); services.AddOptions(); services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); - services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); + services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); //Http Context var context = new DefaultHttpContext(); @@ -806,7 +806,7 @@ private IServiceProvider GetServices() services.AddAuditLogging() .AddDefaultEventData() .AddAuditSinks>(); - services.AddTransient, AuditLoggingRepository>(); + services.AddTransient, AuditLoggingRepository>(); //Add Admin services services.AddMvcExceptionFilters(); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs index e40b7a020..5b0690c03 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs @@ -577,7 +577,7 @@ private IServiceProvider GetServices() var efServiceProvider = new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider(); services.AddOptions(); services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); - services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); + services.AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(efServiceProvider)); //Http Context var context = new DefaultHttpContext(); @@ -591,7 +591,7 @@ private IServiceProvider GetServices() services.AddAuditLogging() .AddDefaultEventData() .AddAuditSinks>(); - services.AddTransient, AuditLoggingRepository>(); + services.AddTransient, AuditLoggingRepository>(); //Add Admin services From c4df9f19221ff0c62c5922ceeaf0064a30e4db79 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 15:30:53 +0100 Subject: [PATCH 185/338] Update audit logging to beta6, --- ...erver4.Admin.EntityFramework.Shared.csproj | 2 +- .../AuditLoggingConfiguration.cs | 13 +++++++++++++ .../Helpers/StartupHelpers.cs | 19 ++++++++++++++----- .../Skoruba.IdentityServer4.Admin.csproj | 2 +- .../appsettings.json | 6 ++++++ 5 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/AuditLoggingConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj index fec341ea5..c0c0e1ad8 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AuditLoggingConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AuditLoggingConfiguration.cs new file mode 100644 index 000000000..3ef2c5fc4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AuditLoggingConfiguration.cs @@ -0,0 +1,13 @@ +namespace Skoruba.IdentityServer4.Admin.Configuration +{ + public class AuditLoggingConfiguration + { + public string Source { get; set; } + + public string SubjectIdentifierClaim { get; set; } + + public string SubjectNameClaim { get; set; } + + public bool IncludeFormVariables { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 4eae469aa..699a0eb9c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -47,16 +47,25 @@ namespace Skoruba.IdentityServer4.Admin.Helpers { public static class StartupHelpers { - public static IServiceCollection AddAuditEventLogging(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddAuditEventLogging(this IServiceCollection services, IConfiguration configuration) where TAuditLog : AuditLog, new() where TAuditLoggingDbContext : IAuditLoggingDbContext { - services.AddAuditLogging() - .AddDefaultHttpEventData(options => + var auditLoggingConfiguration = configuration.GetSection(nameof(AuditLoggingConfiguration)).Get(); + + services.AddAuditLogging(options => { - options.SubjectIdentifierClaim = JwtClaimTypes.Subject; - options.SubjectNameClaim = JwtClaimTypes.Name; + options.Source = auditLoggingConfiguration.Source }) + .AddDefaultHttpEventData(subjectOptions => + { + subjectOptions.SubjectIdentifierClaim = auditLoggingConfiguration.SubjectIdentifierClaim; + subjectOptions.SubjectNameClaim = auditLoggingConfiguration.SubjectIdentifierClaim; + }, + actionOptions => + { + actionOptions.IncludeFormVariables = auditLoggingConfiguration.IncludeFormVariables; + }) .AddAuditSinks>(); services.AddTransient, AuditLoggingRepository>(); diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index cc329d1c3..a6b959453 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 14be9966f..50757ec11 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -25,6 +25,12 @@ ], "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, + "AuditLoggingConfiguration": { + "Source": "IdentityServer.Admin.Web", + "SubjectIdentifierClaim": "sub", + "SubjectNameClaim": "name", + "IncludeFormVariables": false + }, "Serilog": { "MinimumLevel": { "Default": "Error", From d693d3dc3aacf2ed7dc5417576c0c563727a4216 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 15:35:13 +0100 Subject: [PATCH 186/338] Missing semicolon --- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 699a0eb9c..cd35eafd2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -53,10 +53,7 @@ public static IServiceCollection AddAuditEventLogging(); - services.AddAuditLogging(options => - { - options.Source = auditLoggingConfiguration.Source - }) + services.AddAuditLogging(options => { options.Source = auditLoggingConfiguration.Source; }) .AddDefaultHttpEventData(subjectOptions => { subjectOptions.SubjectIdentifierClaim = auditLoggingConfiguration.SubjectIdentifierClaim; From ba95653475fd3f2f934ad3831dfd7ececf65b3bf Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 15:38:43 +0100 Subject: [PATCH 187/338] Fix SubjectNameClaim in setting --- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index cd35eafd2..3ad7e46d2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -57,7 +57,7 @@ public static IServiceCollection AddAuditEventLogging { subjectOptions.SubjectIdentifierClaim = auditLoggingConfiguration.SubjectIdentifierClaim; - subjectOptions.SubjectNameClaim = auditLoggingConfiguration.SubjectIdentifierClaim; + subjectOptions.SubjectNameClaim = auditLoggingConfiguration.SubjectNameClaim; }, actionOptions => { From 428c2793f1933375106d251ae44026a44e50f9a8 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 29 Oct 2019 17:49:38 +0100 Subject: [PATCH 188/338] Add audit logging into API, extend authorization for machine clients --- .../AuditLogging/ApiAuditAction.cs | 21 +++++ .../AuditLogging/ApiAuditSubject.cs | 37 ++++++++ .../AuditLoggingConfiguration.cs | 13 +++ .../Constants/ConfigurationConsts.cs | 2 + .../Helpers/StartupHelpers.cs | 89 +++++++++++++------ .../Skoruba.IdentityServer4.Admin.Api.csproj | 1 + .../Startup.cs | 5 +- .../appsettings.json | 9 +- 8 files changed, 150 insertions(+), 27 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs new file mode 100644 index 000000000..cd6531c3d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.Api.AuditLogging +{ + public class ApiAuditAction : IAuditAction + { + public ApiAuditAction(IHttpContextAccessor accessor) + { + Action = new + { + TraceIdentifier = accessor.HttpContext.TraceIdentifier, + RequestUrl = accessor.HttpContext.Request.GetDisplayUrl(), + HttpMethod = accessor.HttpContext.Request.Method + }; + } + + public object Action { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs new file mode 100644 index 000000000..87c070266 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs @@ -0,0 +1,37 @@ +using System.Linq; +using Microsoft.AspNetCore.Http; +using Skoruba.AuditLogging.Constants; +using Skoruba.AuditLogging.Events; +using Skoruba.IdentityServer4.Admin.Api.Configuration; + +namespace Skoruba.IdentityServer4.Admin.Api.AuditLogging +{ + public class ApiAuditSubject : IAuditSubject + { + public ApiAuditSubject(IHttpContextAccessor accessor, AuditLoggingConfiguration auditLoggingConfiguration) + { + var subClaim = accessor.HttpContext.User.FindFirst(auditLoggingConfiguration.SubjectIdentifierClaim); + var nameClaim = accessor.HttpContext.User.FindFirst(auditLoggingConfiguration.SubjectNameClaim); + var clientIdClaim = accessor.HttpContext.User.FindFirst(auditLoggingConfiguration.ClientIdClaim); + + SubjectIdentifier = subClaim == null ? clientIdClaim.Value : subClaim.Value; + SubjectName = subClaim == null ? clientIdClaim.Value : nameClaim.Value; + SubjectType = subClaim == null ? AuditSubjectTypes.Machine : AuditSubjectTypes.User; + + SubjectAdditionalData = new + { + RemoteIpAddress = accessor.HttpContext.Connection?.RemoteIpAddress?.ToString(), + LocalIpAddress = accessor.HttpContext.Connection?.LocalIpAddress?.ToString(), + Claims = accessor.HttpContext.User.Claims?.Select(x => new { x.Type, x.Value }) + }; + } + + public string SubjectName { get; set; } + + public string SubjectType { get; set; } + + public object SubjectAdditionalData { get; set; } + + public string SubjectIdentifier { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs new file mode 100644 index 000000000..87e82ab27 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs @@ -0,0 +1,13 @@ +namespace Skoruba.IdentityServer4.Admin.Api.Configuration +{ + public class AuditLoggingConfiguration + { + public string Source { get; set; } + + public string SubjectIdentifierClaim { get; set; } + + public string SubjectNameClaim { get; set; } + + public string ClientIdClaim { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ConfigurationConsts.cs index c40333ea0..805f54a26 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Constants/ConfigurationConsts.cs @@ -9,5 +9,7 @@ public class ConfigurationConsts public const string IdentityDbConnectionStringKey = "IdentityDbConnection"; public const string AdminLogDbConnectionStringKey = "AdminLogDbConnection"; + + public const string AdminAuditLogDbConnectionStringKey = "AdminAuditLogDbConnection"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index f1669099b..ba8e40e6d 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using IdentityModel; using IdentityServer4.AccessTokenValidation; using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Builder; @@ -11,6 +12,13 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using Serilog; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.AuditLogging.EntityFramework.Extensions; +using Skoruba.AuditLogging.EntityFramework.Repositories; +using Skoruba.AuditLogging.EntityFramework.Services; +using Skoruba.AuditLogging.Events.Http; +using Skoruba.IdentityServer4.Admin.Api.AuditLogging; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.ApplicationParts; using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; @@ -22,6 +30,25 @@ namespace Skoruba.IdentityServer4.Admin.Api.Helpers { public static class StartupHelpers { + public static IServiceCollection AddAuditEventLogging( + this IServiceCollection services, IConfiguration configuration) + where TAuditLog : AuditLog, new() + where TAuditLoggingDbContext : IAuditLoggingDbContext + { + var auditLoggingConfiguration = configuration.GetSection(nameof(AuditLoggingConfiguration)) + .Get(); + services.AddSingleton(auditLoggingConfiguration); + + services.AddAuditLogging(options => { options.Source = auditLoggingConfiguration.Source; }) + .AddEventData() + .AddAuditSinks>(); + + services + .AddTransient, + AuditLoggingRepository>(); + + return services; + } /// /// Register services for MVC @@ -55,17 +82,16 @@ public static class StartupHelpers { services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - services.AddMvc(o => - { - o.Conventions.Add(new GenericControllerRouteConvention()); - }) + services.AddMvc(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddDataAnnotationsLocalization() .ConfigureApplicationPartManager(m => { - m.FeatureProviders.Add(new GenericTypeControllerFeatureProvider()); + m.FeatureProviders.Add( + new GenericTypeControllerFeatureProvider()); }); } @@ -74,7 +100,7 @@ public static class StartupHelpers /// /// /// - public static void AddLogging(this IApplicationBuilder app,IConfiguration configuration) + public static void AddLogging(this IApplicationBuilder app, IConfiguration configuration) { Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) @@ -91,24 +117,28 @@ public static void AddLogging(this IApplicationBuilder app,IConfiguration config /// /// /// - public static void AddDbContexts(this IServiceCollection services, IConfiguration configuration) - where TIdentityDbContext : DbContext - where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext - where TLogDbContext : DbContext, IAdminLogDbContext + public static void AddDbContexts(this IServiceCollection services, IConfiguration configuration) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext { var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; // Config DB for identity services.AddDbContext(options => - options.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey), + options.UseSqlServer( + configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey), sql => sql.MigrationsAssembly(migrationsAssembly))); // Config DB from existing connection services.AddConfigurationDbContext(options => { options.ConfigureDbContext = b => - b.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), + b.UseSqlServer( + configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), sql => sql.MigrationsAssembly(migrationsAssembly)); }); @@ -116,7 +146,8 @@ public static void AddDbContexts(options => { options.ConfigureDbContext = b => - b.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), + b.UseSqlServer( + configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), sql => sql.MigrationsAssembly(migrationsAssembly)); }); @@ -125,6 +156,12 @@ public static void AddDbContexts optionsSql.MigrationsAssembly(migrationsAssembly))); + + // Audit logging connection + services.AddDbContext(options => + options.UseSqlServer( + configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey), + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); } /// @@ -136,9 +173,9 @@ public static void AddDbContexts /// public static void AddApiAuthentication(this IServiceCollection services, - AdminApiConfiguration adminApiConfiguration) - where TIdentityDbContext : DbContext - where TRole : class + AdminApiConfiguration adminApiConfiguration) + where TIdentityDbContext : DbContext + where TRole : class where TUser : class { services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) @@ -149,10 +186,7 @@ public static void AddApiAuthentication(this I options.RequireHttpsMetadata = adminApiConfiguration.RequireHttpsMetadata; }); - services.AddIdentity(options => - { - options.User.RequireUniqueEmail = true; - }) + services.AddIdentity(options => { options.User.RequireUniqueEmail = true; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); } @@ -164,8 +198,13 @@ public static void AddAuthorizationPolicies(this IServiceCollection services) services.AddAuthorization(options => { options.AddPolicy(AuthorizationConsts.AdministrationPolicy, - policy => policy.RequireRole(adminApiConfiguration.AdministrationRole)); + policy => + policy.RequireAssertion(context => context.User.HasClaim(c => + (c.Type == JwtClaimTypes.Role && c.Value == adminApiConfiguration.AdministrationRole) || + (c.Type == $"client_{JwtClaimTypes.Role}" && c.Value == adminApiConfiguration.AdministrationRole) + ) + )); }); } } -} +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index 73af90ce8..e2fdc7c8b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 4d30d9df4..571cc7489 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.Authorization; using Skoruba.IdentityServer4.Admin.Api.ExceptionHandling; @@ -46,7 +47,7 @@ public void ConfigureServices(IServiceCollection services) var adminApiConfiguration = Configuration.GetSection(nameof(AdminApiConfiguration)).Get(); services.AddSingleton(adminApiConfiguration); - services.AddDbContexts(Configuration); + services.AddDbContexts(Configuration); services.AddScoped(); services.AddScoped(); @@ -89,6 +90,8 @@ public void ConfigureServices(IServiceCollection services) options.OperationFilter(); }); + + services.AddAuditEventLogging(Configuration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApiConfiguration adminApiConfiguration) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 4ed72607f..644f04951 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -3,7 +3,8 @@ "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, "AdminApiConfiguration": { "ApiName": "Skoruba IdentityServer4 Admin Api", @@ -15,6 +16,12 @@ "AdministrationRole": "SkorubaIdentityAdminAdministrator", "RequireHttpsMetadata": false }, + "AuditLoggingConfiguration": { + "Source": "IdentityServer.Admin.Api", + "SubjectIdentifierClaim": "sub", + "SubjectNameClaim": "name", + "ClientIdClaim": "client_id" + }, "Serilog": { "MinimumLevel": { "Default": "Error", From c9ff67fe6e1d8aab2deb1cd4212875c41cc2c379 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 30 Oct 2019 09:07:46 +0100 Subject: [PATCH 189/338] Add ignored files - related to logging :-) --- .gitignore | 3 ++- .../Events/Log/LogsDeletedEvent.cs | 15 +++++++++++++++ .../Events/Log/LogsRequestedEvent.cs | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsDeletedEvent.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsRequestedEvent.cs diff --git a/.gitignore b/.gitignore index 93de3a9a9..4255d6756 100644 --- a/.gitignore +++ b/.gitignore @@ -277,4 +277,5 @@ __pycache__/ # Don't ignore these log folders !/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ !/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/ -!/src/Skoruba.IdentityServer4.Admin/Views/Log/ \ No newline at end of file +!/src/Skoruba.IdentityServer4.Admin/Views/Log/ +!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/ \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsDeletedEvent.cs new file mode 100644 index 000000000..9bd20cef0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsDeletedEvent.cs @@ -0,0 +1,15 @@ +using System; +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Log +{ + public class LogsDeletedEvent : AuditEvent + { + public DateTime DeleteOlderThan { get; set; } + + public LogsDeletedEvent(DateTime deleteOlderThan) + { + DeleteOlderThan = deleteOlderThan; + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsRequestedEvent.cs new file mode 100644 index 000000000..0fe5751bf --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/LogsRequestedEvent.cs @@ -0,0 +1,8 @@ +using Skoruba.AuditLogging.Events; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Log +{ + public class LogsRequestedEvent : AuditEvent + { + } +} \ No newline at end of file From 59771d74bcedf2681d6e35caf8521d82c06c304e Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 30 Oct 2019 10:35:43 +0100 Subject: [PATCH 190/338] Add UI for audit logging --- .../Skoruba.IdentityServer4.Admin.Api.csproj | 1 - ...erver4.Admin.BusinessLogic.Identity.csproj | 1 - .../Dtos/Log/AuditLogDto.cs | 62 +++++++++++++++++ .../Dtos/Log/AuditLogsDto.cs | 19 ++++++ .../Mappers/LogMapperProfile.cs | 7 ++ .../Mappers/LogMappers.cs | 14 +++- .../Services/AuditLogService.cs | 29 ++++++++ .../Services/Interfaces/IAuditLogService.cs | 10 +++ ...IdentityServer4.Admin.BusinessLogic.csproj | 1 - ...erver4.Admin.EntityFramework.Shared.csproj | 2 +- .../Repositories/AuditLogRepository.cs | 38 +++++++++++ .../Interfaces/IAuditLogRepository.cs | 11 ++++ ...entityServer4.Admin.EntityFramework.csproj | 1 + .../Controllers/LogController.cs | 14 +++- .../Helpers/StartupHelpers.cs | 9 +++ .../Skoruba.IdentityServer4.Admin.csproj | 3 +- .../Views/Log/AuditLog.cshtml | 66 +++++++++++++++++++ .../Views/Log/ErrorsLog.cshtml | 18 ++--- 18 files changed, 289 insertions(+), 17 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogDto.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index e2fdc7c8b..73af90ce8 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj index eedfe012f..435da070b 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj @@ -14,7 +14,6 @@ - diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogDto.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogDto.cs new file mode 100644 index 000000000..5a26f8cfe --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogDto.cs @@ -0,0 +1,62 @@ +using System; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log +{ + public class AuditLogDto + { + /// + /// Unique identifier for event + /// + public int Id { get; set; } + + /// + /// Event name + /// + public string Event { get; set; } + + /// + /// Source of logging events + /// + public string Source { get; set; } + + /// + /// Event category + /// + public string Category { get; set; } + + /// + /// Subject Identifier - who is responsible for current action + /// + public string SubjectIdentifier { get; set; } + + /// + /// Subject Name - who is responsible for current action + /// + public string SubjectName { get; set; } + + /// + /// Subject Type - User/Machine + /// + public string SubjectType { get; set; } + + /// + /// Subject - some additional data + /// + public string SubjectAdditionalData { get; set; } + + /// + /// Information about request/action + /// + public string Action { get; set; } + + /// + /// Data which are serialized into JSON format + /// + public string Data { get; set; } + + /// + /// Date and time for creating of the event + /// + public DateTime Created { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs new file mode 100644 index 000000000..2bcb2092d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log +{ + public class AuditLogsDto + { + public AuditLogsDto() + { + Logs = new List(); + } + + + public List Logs { get; set; } + + public int TotalCount { get; set; } + + public int PageSize { get; set; } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMapperProfile.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMapperProfile.cs index 92d5b11ec..8d0c1279a 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMapperProfile.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMapperProfile.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; using Skoruba.IdentityServer4.Admin.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common; @@ -14,6 +15,12 @@ public LogMapperProfile() CreateMap, LogsDto>(MemberList.Destination) .ForMember(x => x.Logs, opt => opt.MapFrom(src => src.Data)); + + CreateMap(MemberList.Destination) + .ReverseMap(); + + CreateMap, AuditLogsDto>(MemberList.Destination) + .ForMember(x => x.Logs, opt => opt.MapFrom(src => src.Data)); } } } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMappers.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMappers.cs index dbfcfded0..40716f2e2 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMappers.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Mappers/LogMappers.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; using Skoruba.IdentityServer4.Admin.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common; @@ -24,7 +25,18 @@ public static LogsDto ToModel(this PagedList logs) { return Mapper.Map(logs); } - + + public static AuditLogsDto ToModel(this PagedList auditLogs) + where TAuditLog : AuditLog + { + return Mapper.Map(auditLogs); + } + + public static AuditLogDto ToModel(this AuditLog auditLog) + { + return Mapper.Map(auditLog); + } + public static Log ToEntity(this LogDto log) { return Mapper.Map(log); diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs new file mode 100644 index 000000000..e4a3a8119 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; +using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Services +{ + public class AuditLogService : IAuditLogService + where TAuditLog : AuditLog + { + private readonly IAuditLogRepository _auditLogRepository; + + public AuditLogService(IAuditLogRepository auditLogRepository) + { + _auditLogRepository = auditLogRepository; + } + + public async Task GetAsync(int page = 1, int pageSize = 10) + { + var pagedList = await _auditLogRepository.GetAsync(page, pageSize); + + var auditLogsDto = pagedList.ToModel(); + + return auditLogsDto; + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs new file mode 100644 index 000000000..e4d45723d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces +{ + public interface IAuditLogService + { + Task GetAsync(int page = 1, int pageSize = 10); + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj index 07702f7a6..9a5b8a421 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj index c0c0e1ad8..0a1bfa6a8 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs new file mode 100644 index 000000000..a7e66cb21 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs @@ -0,0 +1,38 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common; +using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Repositories +{ + public class AuditLogRepository : IAuditLogRepository + where TDbContext : IAuditLoggingDbContext + where TAuditLog : AuditLog + { + protected readonly TDbContext DbContext; + + public AuditLogRepository(TDbContext dbContext) + { + DbContext = dbContext; + } + + public async Task> GetAsync(int page = 1, int pageSize = 10) + { + var pagedList = new PagedList(); + + var auditLogs = await DbContext.AuditLog + .PageBy(x => x.Id, page, pageSize) + .ToListAsync(); + + pagedList.Data.AddRange(auditLogs); + pagedList.PageSize = pageSize; + pagedList.TotalCount = await DbContext.AuditLog.CountAsync(); + + + return pagedList; + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs new file mode 100644 index 000000000..49d4461b5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces +{ + public interface IAuditLogRepository where TAuditLog : AuditLog + { + Task> GetAsync(int page = 1, int pageSize = 10); + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj index a28c19707..3a5a8fa55 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs index 24ef6a621..b915366fa 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs @@ -12,11 +12,14 @@ namespace Skoruba.IdentityServer4.Admin.Controllers public class LogController : BaseController { private readonly ILogService _logService; + private readonly IAuditLogService _auditLogService; public LogController(ILogService logService, - ILogger logger) : base(logger) + ILogger logger, + IAuditLogService auditLogService) : base(logger) { _logService = logService; + _auditLogService = auditLogService; } [HttpGet] @@ -28,6 +31,15 @@ public async Task ErrorsLog(int? page, string search) return View(logs); } + [HttpGet] + public async Task AuditLog(int? page, string search) + { + ViewBag.Search = search; + var logs = await _auditLogService.GetAsync(page ?? 1); + + return View(logs); + } + [HttpPost] [ValidateAntiForgeryToken] public async Task DeleteLogs(LogsDto logs) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 3ad7e46d2..7d91f660e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -33,6 +33,8 @@ using Skoruba.AuditLogging.EntityFramework.Repositories; using Skoruba.AuditLogging.EntityFramework.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Services; +using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; using Skoruba.IdentityServer4.Admin.ExceptionHandling; using Skoruba.IdentityServer4.Admin.Middlewares; using Skoruba.IdentityServer4.Admin.Configuration; @@ -40,6 +42,8 @@ using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; +using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories; +using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.Helpers.Localization; @@ -65,8 +69,13 @@ public static IServiceCollection AddAuditEventLogging>(); + // repository for library services.AddTransient, AuditLoggingRepository>(); + // repository and service for admin + services.AddTransient, AuditLogRepository>(); + services.AddTransient>(); + return services; } diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index a6b959453..72e4ed4f5 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -13,13 +13,12 @@ - + - diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml new file mode 100644 index 000000000..7e72d90e0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml @@ -0,0 +1,66 @@ +@using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common +@model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log.AuditLogsDto + +@{ + ViewData["Title"] = "Audit Log"; +} + +

    @ViewData["Title"]

    + +
    +
    + @await Html.PartialAsync("Common/Search", new Search { Action = "AuditLog", Controller = "Log" }) +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + @foreach (var auditLog in Model.Logs) + { + + + + + + + + + + + + + + + } + +
    SourceSubject TypeSubject IdentifierSubject NameSubject Additional DataActionCreatedData
    Detail@auditLog.Source@auditLog.SubjectType@auditLog.SubjectIdentifier@auditLog.SubjectName@auditLog.SubjectAdditionalData@auditLog.Action + + @auditLog.Created + + + @auditLog.Event
    +
    +
    +
    + +
    +
    + @await Html.PartialAsync("Common/Pager", new Pager { Action = "AuditLog", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search }) +
    +
    \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Log/ErrorsLog.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Log/ErrorsLog.cshtml index 629f85046..d7fff1d4c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Log/ErrorsLog.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Log/ErrorsLog.cshtml @@ -72,21 +72,21 @@
    @Localizer["TableShowDetail"]@client.Level@Localizer["TableShowDetail"]@log.Level - - @client.TimeStamp + + @log.TimeStamp - + @client.Message@log.Message
    Event SourceSubject TypeSubject IdentifierSubject NameSubject Additional DataSubject Action CreatedData
    Detail@auditLog.Source@auditLog.SubjectType@auditLog.SubjectIdentifier@auditLog.SubjectName@auditLog.SubjectAdditionalData@auditLog.Action - +
    Detail@auditLog.Event@auditLog.Source @auditLog.Created - - - @auditLog.Event
    ","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
  • ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
    "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(S("").append(S("").append(S("").append(S("").append(S("").append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S(" + @foreach (var auditLog in Model.Logs) + { + + + + + + + + + + + + } + +
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-type"),n=$(this).data("subject-additional-data");$(".audit-modal-title").html(e+" ("+t+")"),$(".audit-modal-value").html(auditLog.createJsonTree(n)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action");$(".audit-modal-title").html(""),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i Date: Fri, 1 Nov 2019 14:27:31 +0100 Subject: [PATCH 193/338] Add support for localization, add scrollbar into dialog - because of long text --- .../Resources/Views/Log/AuditLog.en.resx | 141 ++++++++++++++++++ .../Scripts/App/pages/AuditLog.js | 15 +- .../Styles/pages/_all.scss | 3 +- .../Styles/pages/auditlog.scss | 11 ++ .../Views/Log/AuditLog.cshtml | 126 ++++++++-------- .../wwwroot/dist/css/web.css | 7 + .../wwwroot/dist/css/web.min.css | 2 +- .../wwwroot/dist/js/bundle.min.js | 2 +- 8 files changed, 230 insertions(+), 77 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Styles/pages/auditlog.scss diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx new file mode 100644 index 000000000..5e0284744 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Action + + + Audit Log + + + Detail + + + Event + + + Show detail + + + Source + + + Subject + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js index 6360e89b3..d5b0b854d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js @@ -1,6 +1,6 @@ var auditLog = { - createJsonTree: function(json) { + createJsonTree: function (json) { var result; try { @@ -12,7 +12,7 @@ return result; }, - initJsonTrees: function() { + initJsonTrees: function () { $(".json-tree").each(function () { var json = $(this).data("json-tree"); @@ -22,28 +22,29 @@ }); }, - eventHandlers: function() { + eventHandlers: function () { $(".audit-subject-button").click(function () { var subjectId = $(this).data("subject-identifier"); + var subjectName = $(this).data("subject-name"); var subjectType = $(this).data("subject-type"); var json = $(this).data("subject-additional-data"); - $(".audit-modal-title").html(subjectId + " (" + subjectType + ")"); + $(".modal-title").html(subjectName + " - " + subjectId + " - " + "(" + subjectType + ")"); $(".audit-modal-value").html(auditLog.createJsonTree(json)); $(".audit-modal").modal("show"); }); $(".audit-action-button").click(function () { var json = $(this).data("action"); - $(".audit-modal-title").html(""); + $(".modal-title").html(""); $(".audit-modal-value").html(auditLog.createJsonTree(json)); $(".audit-modal").modal("show"); }); }, - init: function() { + init: function () { - $(function() { + $(function () { auditLog.eventHandlers(); auditLog.initJsonTrees(); }); diff --git a/src/Skoruba.IdentityServer4.Admin/Styles/pages/_all.scss b/src/Skoruba.IdentityServer4.Admin/Styles/pages/_all.scss index b25685e6f..3db374dca 100644 --- a/src/Skoruba.IdentityServer4.Admin/Styles/pages/_all.scss +++ b/src/Skoruba.IdentityServer4.Admin/Styles/pages/_all.scss @@ -1,2 +1,3 @@ /*Pages*/ -@import "client.scss"; \ No newline at end of file +@import "client.scss"; +@import "auditlog.scss"; \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Styles/pages/auditlog.scss b/src/Skoruba.IdentityServer4.Admin/Styles/pages/auditlog.scss new file mode 100644 index 000000000..8301d38e6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Styles/pages/auditlog.scss @@ -0,0 +1,11 @@ +.audit-log-container { + + .modal-dialog { + overflow-y: initial !important + } + + .modal-body { + max-height: calc(100vh - 200px); + overflow-y: auto; + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml index a2b5d4e28..01f8a0656 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml @@ -1,84 +1,76 @@ -@using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common +@using Microsoft.AspNetCore.Mvc.Localization +@using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log.AuditLogsDto - +@inject IViewLocalizer Localizer @{ - ViewData["Title"] = "Audit Log"; + ViewData["Title"] = Localizer["Audit Log"]; } -

    @ViewData["Title"]

    +
    +

    @ViewData["Title"]

    -
    -
    - @await Html.PartialAsync("Common/Search", new Search { Action = "AuditLog", Controller = "Log" }) +
    +
    + @await Html.PartialAsync("Common/Search", new Search { Action = "AuditLog", Controller = "Log" }) +
    -
    -
    -
    -
    - - - - - - - - - - - - - @foreach (var auditLog in Model.Logs) - { +
    +
    +
    +
    EventSourceSubjectActionCreated
    + - - - - - - + + + + + + - - - - } - -
    Detail@auditLog.Event@auditLog.Source - @auditLog.Created - @Localizer["Event"]@Localizer["Source"]@Localizer["Subject"]@Localizer["Action"]@Localizer["Created"]
    + +
    @Localizer["Detail"]@auditLog.Event@auditLog.Source + @auditLog.Created +
    +
    - -
    -
    - @await Html.PartialAsync("Common/Pager", new Pager { Action = "AuditLog", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search }) +
    +
    + @await Html.PartialAsync("Common/Pager", new Pager { Action = "AuditLog", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search }) +
    -
    -
    "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(S("").append(S("").append(S("").append(S("").append(S("").append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-type"),n=$(this).data("subject-additional-data");$(".audit-modal-title").html(e+" ("+t+")"),$(".audit-modal-value").html(auditLog.createJsonTree(n)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action");$(".audit-modal-title").html(""),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S(" + @foreach (var auditLog in Model.Logs) + { + + + + + + + + + + + + } + +
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-name"),n=$(this).data("subject-type"),i=$(this).data("subject-additional-data");$(".modal-title").html(t+" - "+e+" - ("+n+")"),$(".audit-modal-value").html(auditLog.createJsonTree(i)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action");$(".modal-title").html(""),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i Date: Fri, 1 Nov 2019 15:05:06 +0100 Subject: [PATCH 194/338] Remove sensitive information from events --- .../Identity/UserPasswordChangedEvent.cs | 8 ++++---- .../Services/IdentityService.cs | 2 +- .../Events/ApiResource/ApiSecretAddedEvent.cs | 16 +++++++++++----- .../ApiResource/ApiSecretDeletedEvent.cs | 10 ++++++---- .../ApiResource/ApiSecretRequestedEvent.cs | 19 ++++++++++++++----- .../ApiResource/ApiSecretsRequestedEvent.cs | 15 ++++++++++----- .../Events/Client/ClientSecretAddedEvent.cs | 16 +++++++++++----- .../Events/Client/ClientSecretDeletedEvent.cs | 10 ++++++---- .../Client/ClientSecretRequestedEvent.cs | 19 ++++++++++++++----- .../Client/ClientSecretsRequestedEvent.cs | 14 +++++++++----- .../Services/ApiResourceService.cs | 11 ++++++----- .../Services/ClientService.cs | 11 ++++++----- 12 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs index 6496237f0..da7f793c5 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Events/Identity/UserPasswordChangedEvent.cs @@ -2,13 +2,13 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity { - public class UserPasswordChangedEvent : AuditEvent + public class UserPasswordChangedEvent : AuditEvent { - public TUserChangePasswordDto UserPassword { get; set; } + public string UserName { get; set; } - public UserPasswordChangedEvent(TUserChangePasswordDto userPassword) + public UserPasswordChangedEvent(string userName) { - UserPassword = userPassword; + UserName = userName; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs index 272a727bc..92e116e9d 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs @@ -398,7 +398,7 @@ public virtual async Task UserChangePasswordAsync(TUserChangePas var identityResult = await IdentityRepository.UserChangePasswordAsync(userPassword.UserId.ToString(), userPassword.Password); - await AuditEventLogger.LogEventAsync(new UserPasswordChangedEvent(userPassword)); + await AuditEventLogger.LogEventAsync(new UserPasswordChangedEvent(userPassword.UserName)); return HandleIdentityError(identityResult, IdentityServiceResources.UserChangePasswordFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userPassword); } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs index 85e072a42..1060ab788 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretAddedEvent.cs @@ -1,15 +1,21 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { public class ApiSecretAddedEvent : AuditEvent { - public ApiSecretsDto ApiSecret { get; set; } + public string Type { get; set; } - public ApiSecretAddedEvent(ApiSecretsDto apiSecret) + public DateTime? Expiration { get; set; } + + public int ApiResourceId { get; set; } + + public ApiSecretAddedEvent(int apiResourceId, string type, DateTime? expiration) { - ApiSecret = apiSecret; + ApiResourceId = apiResourceId; + Type = type; + Expiration = expiration; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs index fd63e2e44..6b240ec64 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretDeletedEvent.cs @@ -1,15 +1,17 @@ using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { public class ApiSecretDeletedEvent : AuditEvent { - public ApiSecretsDto ApiSecret { get; set; } + public int ApiResourceId { get; set; } - public ApiSecretDeletedEvent(ApiSecretsDto apiSecret) + public int ApiSecretId { get; set; } + + public ApiSecretDeletedEvent(int apiResourceId, int apiSecretId) { - ApiSecret = apiSecret; + ApiResourceId = apiResourceId; + ApiSecretId = apiSecretId; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs index b3698d0f3..6a4e33a67 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretRequestedEvent.cs @@ -1,15 +1,24 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { public class ApiSecretRequestedEvent : AuditEvent { - public ApiSecretsDto ApiSecrets { get; set; } + public int ApiResourceId { get; set; } - public ApiSecretRequestedEvent(ApiSecretsDto apiSecrets) + public int ApiSecretId { get; set; } + + public string Type { get; set; } + + public DateTime? Expiration { get; set; } + + public ApiSecretRequestedEvent(int apiResourceId, int apiSecretId, string type, DateTime? expiration) { - ApiSecrets = apiSecrets; + ApiResourceId = apiResourceId; + ApiSecretId = apiSecretId; + Type = type; + Expiration = expiration; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs index 041b0d510..766d8c910 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/ApiResource/ApiSecretsRequestedEvent.cs @@ -1,15 +1,20 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using System.Collections.Generic; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.ApiResource { public class ApiSecretsRequestedEvent : AuditEvent { - public ApiSecretsDto ApiSecrets { get; set; } + public int ApiResourceId { get; set; } - public ApiSecretsRequestedEvent(ApiSecretsDto apiSecrets) + public List<(int apiSecretId, string type, DateTime? expiration)> Secrets { get; set; } + + + public ApiSecretsRequestedEvent(int apiResourceId, List<(int apiSecretId, string type, DateTime? expiration)> secrets) { - ApiSecrets = apiSecrets; + ApiResourceId = apiResourceId; + Secrets = secrets; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs index 54f54ee24..81f3e2faf 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretAddedEvent.cs @@ -1,15 +1,21 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client { public class ClientSecretAddedEvent : AuditEvent { - public ClientSecretsDto ClientSecret { get; set; } + public string Type { get; set; } - public ClientSecretAddedEvent(ClientSecretsDto clientSecret) + public DateTime? Expiration { get; set; } + + public int ClientId { get; set; } + + public ClientSecretAddedEvent(int clientId, string type, DateTime? expiration) { - ClientSecret = clientSecret; + ClientId = clientId; + Type = type; + Expiration = expiration; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs index 9fb7268c8..95942352a 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretDeletedEvent.cs @@ -1,15 +1,17 @@ using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client { public class ClientSecretDeletedEvent : AuditEvent { - public ClientSecretsDto ClientSecret { get; set; } + public int ClientId { get; set; } - public ClientSecretDeletedEvent(ClientSecretsDto clientSecret) + public int ClientSecretId { get; set; } + + public ClientSecretDeletedEvent(int clientId, int clientSecretId) { - ClientSecret = clientSecret; + ClientId = clientId; + ClientSecretId = clientSecretId; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs index 8bc32e62d..df7f26ca0 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretRequestedEvent.cs @@ -1,15 +1,24 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client { public class ClientSecretRequestedEvent : AuditEvent { - public ClientSecretsDto ClientSecrets { get; set; } + public int ClientId { get; set; } - public ClientSecretRequestedEvent(ClientSecretsDto clientSecrets) + public int ClientSecretId { get; set; } + + public string Type { get; set; } + + public DateTime? Expiration { get; set; } + + public ClientSecretRequestedEvent(int clientId, int clientSecretId, string type, DateTime? expiration) { - ClientSecrets = clientSecrets; + ClientId = clientId; + ClientSecretId = clientSecretId; + Type = type; + Expiration = expiration; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs index faeada5b8..5292b4de5 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Client/ClientSecretsRequestedEvent.cs @@ -1,15 +1,19 @@ -using Skoruba.AuditLogging.Events; -using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; +using System; +using System.Collections.Generic; +using Skoruba.AuditLogging.Events; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Events.Client { public class ClientSecretsRequestedEvent : AuditEvent { - public ClientSecretsDto ClientSecrets { get; set; } + public int ClientId { get; set; } - public ClientSecretsRequestedEvent(ClientSecretsDto clientSecrets) + public List<(int clientSecretId, string type, DateTime? expiration)> Secrets { get; set; } + + public ClientSecretsRequestedEvent(int clientId, List<(int clientSecretId, string type, DateTime? expiration)> secrets) { - ClientSecrets = clientSecrets; + ClientId = clientId; + Secrets = secrets; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs index d1ea1b83c..753df3bf4 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ApiResourceService.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using IdentityServer4.Models; using Skoruba.AuditLogging.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration; @@ -310,7 +311,7 @@ public virtual async Task GetApiSecretsAsync(int apiResourceId, i apiSecretsDto.ApiResourceId = apiResourceId; apiSecretsDto.ApiResourceName = await ApiResourceRepository.GetApiResourceNameAsync(apiResourceId); - await AuditEventLogger.LogEventAsync(new ApiSecretsRequestedEvent(apiSecretsDto)); + await AuditEventLogger.LogEventAsync(new ApiSecretsRequestedEvent(apiSecretsDto.ApiResourceId, apiSecretsDto.ApiSecrets.Select(x => (x.Id, x.Type, x.Expiration)).ToList())); return apiSecretsDto; } @@ -323,7 +324,7 @@ public virtual async Task AddApiSecretAsync(ApiSecretsDto apiSecret) var added = await ApiResourceRepository.AddApiSecretAsync(apiSecret.ApiResourceId, secret); - await AuditEventLogger.LogEventAsync(new ApiSecretAddedEvent(apiSecret)); + await AuditEventLogger.LogEventAsync(new ApiSecretAddedEvent(apiSecret.ApiResourceId, apiSecret.Type, apiSecret.Expiration)); return added; } @@ -334,7 +335,7 @@ public virtual async Task GetApiSecretAsync(int apiSecretId) if (apiSecret == null) throw new UserFriendlyErrorPageException(string.Format(ApiResourceServiceResources.ApiSecretDoesNotExist().Description, apiSecretId), ApiResourceServiceResources.ApiSecretDoesNotExist().Description); var apiSecretsDto = apiSecret.ToModel(); - await AuditEventLogger.LogEventAsync(new ApiSecretRequestedEvent(apiSecretsDto)); + await AuditEventLogger.LogEventAsync(new ApiSecretRequestedEvent(apiSecretsDto.ApiResourceId, apiSecretsDto.ApiSecretId, apiSecretsDto.Type, apiSecretsDto.Expiration)); return apiSecretsDto; } @@ -345,7 +346,7 @@ public virtual async Task DeleteApiSecretAsync(ApiSecretsDto apiSecret) var deleted = await ApiResourceRepository.DeleteApiSecretAsync(secret); - await AuditEventLogger.LogEventAsync(new ApiSecretDeletedEvent(apiSecret)); + await AuditEventLogger.LogEventAsync(new ApiSecretDeletedEvent(apiSecret.ApiResourceId, apiSecret.ApiSecretId)); return deleted; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs index a3ed485d7..c8f0499c0 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/ClientService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using IdentityServer4.Models; using Skoruba.AuditLogging.Services; @@ -55,7 +56,7 @@ private void PrepareClientTypeForNewClient(ClientDto client) client.AllowedGrantTypes.AddRange(GrantTypes.Hybrid); break; case ClientType.Spa: - client.AllowedGrantTypes.AddRange(GrantTypes.Code); + client.AllowedGrantTypes.AddRange(GrantTypes.Code); client.RequirePkce = true; client.RequireClientSecret = false; break; @@ -317,7 +318,7 @@ public virtual async Task AddClientSecretAsync(ClientSecretsDto clientSecre var clientSecretEntity = clientSecret.ToEntity(); var added = await ClientRepository.AddClientSecretAsync(clientSecret.ClientId, clientSecretEntity); - await AuditEventLogger.LogEventAsync(new ClientSecretAddedEvent(clientSecret)); + await AuditEventLogger.LogEventAsync(new ClientSecretAddedEvent(clientSecret.ClientId, clientSecret.Type, clientSecret.Expiration)); return added; } @@ -328,7 +329,7 @@ public virtual async Task DeleteClientSecretAsync(ClientSecretsDto clientSe var deleted = await ClientRepository.DeleteClientSecretAsync(clientSecretEntity); - await AuditEventLogger.LogEventAsync(new ClientSecretDeletedEvent(clientSecret)); + await AuditEventLogger.LogEventAsync(new ClientSecretDeletedEvent(clientSecret.ClientId, clientSecret.ClientSecretId)); return deleted; } @@ -343,7 +344,7 @@ public virtual async Task GetClientSecretsAsync(int clientId, clientSecretsDto.ClientId = clientId; clientSecretsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); - await AuditEventLogger.LogEventAsync(new ClientSecretsRequestedEvent(clientSecretsDto)); + await AuditEventLogger.LogEventAsync(new ClientSecretsRequestedEvent(clientSecretsDto.ClientId, clientSecretsDto.ClientSecrets.Select(x => (x.Id, x.Type, x.Expiration)).ToList())); return clientSecretsDto; } @@ -360,7 +361,7 @@ public virtual async Task GetClientSecretAsync(int clientSecre clientSecretsDto.ClientId = clientSecret.Client.Id; clientSecretsDto.ClientName = ViewHelpers.GetClientName(clientInfo.ClientId, clientInfo.ClientName); - await AuditEventLogger.LogEventAsync(new ClientSecretRequestedEvent(clientSecretsDto)); + await AuditEventLogger.LogEventAsync(new ClientSecretRequestedEvent(clientSecretsDto.ClientId, clientSecretsDto.ClientSecretId, clientSecretsDto.Type, clientSecretsDto.Expiration)); return clientSecretsDto; } From 2326155a19b5f000b7dfeab12bb16402fec7dc6f Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 4 Nov 2019 16:23:47 +0100 Subject: [PATCH 195/338] Add deleting of audit logging; fix user roles pagination; Add dynamic pager; --- .../Dtos/Log/AuditLogFilterDto.cs | 23 +++ .../Dtos/Log/AuditLogsDto.cs | 6 +- .../Services/AuditLogService.cs | 21 ++- .../Services/Interfaces/IAuditLogService.cs | 7 +- .../Repositories/AuditLogRepository.cs | 32 +++- .../Interfaces/IAuditLogRepository.cs | 7 +- .../Controllers/IdentityController.cs | 6 +- .../Controllers/LogController.cs | 25 ++- .../Helpers/PagerHelpers.cs | 36 +++- .../Resources/Views/Log/AuditLog.en.resx | 30 +++ .../Common/PagerDynamic.en.resx} | 44 +---- .../Common/PagerDynamic.es.resx} | 44 +---- .../Common/PagerDynamic.fa.resx} | 44 +---- .../Common/PagerDynamic.fr.resx} | 45 +---- .../Views/Shared/Common/PagerDynamic.ru.resx | 126 +++++++++++++ .../Views/Shared/Common/PagerDynamic.sv.resx | 126 +++++++++++++ .../Scripts/App/pages/AuditLog.js | 18 +- .../Views/Identity/Role.cshtml | 2 +- .../Views/Identity/Roles.cshtml | 2 +- .../Views/Log/AuditLog.cshtml | 177 ++++++++++++------ .../Views/Shared/Common/PagerDynamic.cshtml | 44 +++++ .../wwwroot/dist/js/bundle.min.js | 2 +- 22 files changed, 620 insertions(+), 247 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogFilterDto.cs rename src/Skoruba.IdentityServer4.Admin/Resources/Views/{ClientClone.en.resx => Shared/Common/PagerDynamic.en.resx} (79%) rename src/Skoruba.IdentityServer4.Admin/Resources/Views/{ClientClone.es.resx => Shared/Common/PagerDynamic.es.resx} (78%) rename src/Skoruba.IdentityServer4.Admin/Resources/Views/{ClientClone.sv.resx => Shared/Common/PagerDynamic.fa.resx} (79%) rename src/Skoruba.IdentityServer4.Admin/Resources/Views/{ClientClone.fr.resx => Shared/Common/PagerDynamic.fr.resx} (78%) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.ru.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.sv.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Views/Shared/Common/PagerDynamic.cshtml diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogFilterDto.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogFilterDto.cs new file mode 100644 index 000000000..b940cebb2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogFilterDto.cs @@ -0,0 +1,23 @@ +using System; + +namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log +{ + public class AuditLogFilterDto + { + public string Event { get; set; } + + public string Source { get; set; } + + public string Category { get; set; } + + public DateTime? Created { get; set; } + + public string SubjectIdentifier { get; set; } + + public string SubjectName { get; set; } + + public int PageSize { get; set; } = 10; + + public int Page { get; set; } = 1; + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs index 2bcb2092d..6c802bd05 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/AuditLogsDto.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log { @@ -9,6 +11,8 @@ public AuditLogsDto() Logs = new List(); } + [Required] + public DateTime? DeleteOlderThan { get; set; } public List Logs { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs index e4a3a8119..35868fe2e 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/AuditLogService.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; using Skoruba.IdentityServer4.Admin.BusinessLogic.Mappers; @@ -7,23 +8,27 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Services { - public class AuditLogService : IAuditLogService + public class AuditLogService : IAuditLogService where TAuditLog : AuditLog { - private readonly IAuditLogRepository _auditLogRepository; + protected readonly IAuditLogRepository AuditLogRepository; public AuditLogService(IAuditLogRepository auditLogRepository) { - _auditLogRepository = auditLogRepository; + AuditLogRepository = auditLogRepository; } - - public async Task GetAsync(int page = 1, int pageSize = 10) - { - var pagedList = await _auditLogRepository.GetAsync(page, pageSize); + public async Task GetAsync(AuditLogFilterDto filters) + { + var pagedList = await AuditLogRepository.GetAsync(filters.Event, filters.Source, filters.Category, filters.Created, filters.SubjectIdentifier, filters.SubjectName, filters.Page, filters.PageSize); var auditLogsDto = pagedList.ToModel(); return auditLogsDto; } + + public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) + { + await AuditLogRepository.DeleteLogsOlderThanAsync(deleteOlderThan); + } } } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs index e4d45723d..b6c6144c3 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Services/Interfaces/IAuditLogService.cs @@ -1,10 +1,13 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Log; namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces { public interface IAuditLogService { - Task GetAsync(int page = 1, int pageSize = 10); + Task GetAsync(AuditLogFilterDto filters); + + Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan); } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs index a7e66cb21..fe18dbbea 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System; +using System.Linq; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Skoruba.AuditLogging.EntityFramework.DbContexts; using Skoruba.AuditLogging.EntityFramework.Entities; @@ -19,20 +21,42 @@ public AuditLogRepository(TDbContext dbContext) DbContext = dbContext; } - public async Task> GetAsync(int page = 1, int pageSize = 10) + public async Task> GetAsync(string @event, string source, string category, DateTime? created, string subjectIdentifier, string subjectName, int page = 1, int pageSize = 10) { var pagedList = new PagedList(); var auditLogs = await DbContext.AuditLog .PageBy(x => x.Id, page, pageSize) + .WhereIf(!string.IsNullOrEmpty(subjectIdentifier), log => log.SubjectIdentifier.Contains(subjectIdentifier)) + .WhereIf(!string.IsNullOrEmpty(subjectName), log => log.SubjectName.Contains(subjectName)) + .WhereIf(!string.IsNullOrEmpty(@event), log => log.Event.Contains(@event)) + .WhereIf(!string.IsNullOrEmpty(source), log => log.Source.Contains(source)) + .WhereIf(!string.IsNullOrEmpty(category), log => log.Category.Contains(category)) + .WhereIf(created.HasValue, log => log.Created.Date == created.Value.Date) .ToListAsync(); pagedList.Data.AddRange(auditLogs); pagedList.PageSize = pageSize; - pagedList.TotalCount = await DbContext.AuditLog.CountAsync(); + pagedList.TotalCount = await DbContext.AuditLog + .WhereIf(!string.IsNullOrEmpty(subjectIdentifier), log => log.SubjectIdentifier.Contains(subjectIdentifier)) + .WhereIf(!string.IsNullOrEmpty(subjectName), log => log.SubjectName.Contains(subjectName)) + .WhereIf(!string.IsNullOrEmpty(@event), log => log.Event.Contains(@event)) + .WhereIf(!string.IsNullOrEmpty(source), log => log.Source.Contains(source)) + .WhereIf(!string.IsNullOrEmpty(category), log => log.Category.Contains(category)) + .WhereIf(created.HasValue, log => log.Created.Date == created.Value.Date) + .CountAsync(); + + return pagedList; + } + public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) + { + var logsToDelete = await DbContext.AuditLog.Where(x => x.Created.Date < deleteOlderThan.Date).ToListAsync(); - return pagedList; + if (logsToDelete.Count == 0) return; + + DbContext.AuditLog.RemoveRange(logsToDelete); + await DbContext.SaveChangesAsync(); } } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs index 49d4461b5..3966e1ef3 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/Interfaces/IAuditLogRepository.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common; @@ -6,6 +7,8 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces { public interface IAuditLogRepository where TAuditLog : AuditLog { - Task> GetAsync(int page = 1, int pageSize = 10); + Task> GetAsync(string @event, string source, string category, DateTime? created, string subjectIdentifier, string subjectName, int page = 1, int pageSize = 10); + + Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan); } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs index 5108f3c94..e3aa2b90a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/IdentityController.cs @@ -121,12 +121,12 @@ public async Task Users(int? page, string search) } [HttpGet] - public async Task RoleUsers(string roleId, int? page, string search) + public async Task RoleUsers(string id, int? page, string search) { ViewBag.Search = search; - var roleUsers = await _identityService.GetRoleUsersAsync(roleId, search, page ?? 1); + var roleUsers = await _identityService.GetRoleUsersAsync(id, search, page ?? 1); - var roleDto = await _identityService.GetRoleAsync(roleId); + var roleDto = await _identityService.GetRoleAsync(id); ViewData["RoleName"] = roleDto.Name; return View(roleUsers); diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs index b915366fa..2acfdd22c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs @@ -32,10 +32,15 @@ public async Task ErrorsLog(int? page, string search) } [HttpGet] - public async Task AuditLog(int? page, string search) + public async Task AuditLog([FromQuery]AuditLogFilterDto filters) { - ViewBag.Search = search; - var logs = await _auditLogService.GetAsync(page ?? 1); + ViewBag.SubjectIdentifier = filters.SubjectIdentifier; + ViewBag.SubjectName = filters.SubjectName; + ViewBag.Event = filters.Event; + ViewBag.Source = filters.Source; + ViewBag.Category = filters.Category; + + var logs = await _auditLogService.GetAsync(filters); return View(logs); } @@ -53,5 +58,19 @@ public async Task DeleteLogs(LogsDto logs) return RedirectToAction(nameof(ErrorsLog)); } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task DeleteAuditLogs(AuditLogsDto logs) + { + if (!ModelState.IsValid) + { + return View(nameof(AuditLog), logs); + } + + await _auditLogService.DeleteLogsOlderThanAsync(logs.DeleteOlderThan.Value); + + return RedirectToAction(nameof(AuditLog)); + } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs index f23172c16..c325ed5aa 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs @@ -1,4 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Hosting.Internal; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; namespace Skoruba.IdentityServer4.Admin.Helpers { @@ -6,7 +11,7 @@ public static class PagerHelpers { public static int GetTotalPages(int pageSize, int totalCount) { - return (int)Math.Ceiling((double)totalCount / pageSize); + return (int) Math.Ceiling((double) totalCount / pageSize); } public static bool IsActivePage(int currentPage, int currentIteration) @@ -34,7 +39,7 @@ public static int GetMinPageToRender(int maxPages, int totalPages, int currentPa var currentMaxPages = GetMaxPageToRender(maxPages, totalPages, currentPage); if (currentMaxPages == defaultPageNumber) return currentMaxPages; - + if (currentMaxPages == totalPages) { currentMaxPages = GetMaxPage(maxPages, totalPages, currentPage); @@ -47,7 +52,7 @@ public static int GetMinPageToRender(int maxPages, int totalPages, int currentPa public static int GetMaxPage(int maxPages, int totalPages, int currentPage) { - var result = (int)Math.Ceiling((double)currentPage / maxPages); + var result = (int) Math.Ceiling((double) currentPage / maxPages); return result * maxPages; } @@ -73,5 +78,30 @@ public static int GetCurrentPage(string currentPage) return 1; } } + + public static QueryString GetQueryString(HttpContext context, int page) + { + const string pageKey = "page"; + + var queryString = context.Request.QueryString.Value; + var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(queryString); + var items = queryDictionary.SelectMany(x => x.Value, (col, value) => new KeyValuePair(col.Key, value)).ToList(); + + // Remove existing page key + items.RemoveAll(x => x.Key == pageKey); + + // Setup new page key + var queryBuilder = new QueryBuilder(items) + { + { pageKey, page.ToString() } + }; + + return queryBuilder.ToQueryString(); + } + + public static string GetUrl(string baseUrl, QueryString queryString) + { + return $"{baseUrl}{queryString}"; + } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx index 5e0284744..ae3c2281f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.en.resx @@ -120,15 +120,33 @@ Action + + Are you sure? + Audit Log + + Category + + + Created + + + Delete logs older than + Detail Event + + No - close + + + Search + Show detail @@ -138,4 +156,16 @@ Subject + + Subject Identifier + + + Subject Name + + + Warning + + + Yes - delete + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.en.resx similarity index 79% rename from src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.en.resx rename to src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.en.resx index b6f3bbca3..e6616a794 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.en.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.en.resx @@ -117,46 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Clone Client + + First - - The client secrets will not be cloned. - - - Info: - - - Client Claims - - - Client Cors Origins - - - Client Grant Types - - - Client IdP Restrictions - - - Client Post Logout Redirect Uris - - - Client Properties - - - Client Redirect Uris - - - Client Scopes - - - Clients - - - Clone Client - - - Client + + Last \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.es.resx similarity index 78% rename from src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx rename to src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.es.resx index e76d438dd..582ee28f1 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.es.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.es.resx @@ -117,46 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Clonar cliente + + Primero - - Los secretos de cliente no seran clonados. - - - Info: - - - Reclamaciones del cliente - - - Origenes CORS del cliente - - - Tipos de concesión del cliente - - - Restricciones de proveedores de identidad del cliente - - - URIs de redirección post cierre de sesión del cliente - - - Propiedades del cliente - - - URIs de redirección del cliente - - - Alcances del cliente - - - Clientes - - - Clonar cliente - - - Cliente + + Ultimo diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.sv.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fa.resx similarity index 79% rename from src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.sv.resx rename to src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fa.resx index 009391317..2a8f22314 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.sv.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fa.resx @@ -117,46 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Duplicera klient + + اولین - - Klientenhemligheter kommer inte att dupliceras. - - - Information: - - - Klientanspråk - - - Klient Cors ursprung - - - Klientens medgivandetyper - - - Klient IdP begränsningar - - - Klient Post Logout Redirect Uri:er - - - Klientegenskaper - - - Klient Redirect Uri:er - - - Klientbegränsningar - - - Klienter - - - Duplicera klient - - - Klient + + آخرین \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.fr.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fr.resx similarity index 78% rename from src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.fr.resx rename to src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fr.resx index a34c5c161..bfe81715a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.fr.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fr.resx @@ -117,47 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Dupliquer Client + + Premier - - Les secrets client ne seront pas dupliqués. - - - Info: - - - Claims Client - - - Origines Client Cors - - - Types Grant Client - - - Restrictions Client IdP - - - Uris Client de Redirection (Post Déconnexion) - Client Post Logout Redirect Uris - - - Propriétés Client - - - Uris Client de Redirection - - - Scopes Client - - - Clients - - - Dupliquer Client - - - Client + + Dernier \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.ru.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.ru.resx new file mode 100644 index 000000000..d5f176b9e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.ru.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Первый + + + Последний + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.sv.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.sv.resx new file mode 100644 index 000000000..1d61f4d56 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.sv.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Först + + + Sist + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js index d5b0b854d..3df549a2f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js +++ b/src/Skoruba.IdentityServer4.Admin/Scripts/App/pages/AuditLog.js @@ -36,10 +36,26 @@ $(".audit-action-button").click(function () { var json = $(this).data("action"); - $(".modal-title").html(""); + var actionTitle = $(this).data("action-title"); + + $(".modal-title").html(actionTitle); $(".audit-modal-value").html(auditLog.createJsonTree(json)); $(".audit-modal").modal("show"); }); + + $(".audit-log-delete-button").click(function () { + + $(".audit-log-form").validate(); + + if ($(".audit-log-form").validate().form()) { + + $("#deleteLogsModal").modal("show"); + return false; + } else { + $(this).submit(); + return false; + } + }); }, init: function () { diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Identity/Role.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Identity/Role.cshtml index 19c063458..395cf6d94 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Identity/Role.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Identity/Role.cshtml @@ -33,7 +33,7 @@
    diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Identity/Roles.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Identity/Roles.cshtml index 382f04e49..c21b07043 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Identity/Roles.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Identity/Roles.cshtml @@ -35,7 +35,7 @@
    @Localizer["TableButtonEdit"] - @Localizer["TableButtonUsers"] + @Localizer["TableButtonUsers"] @role.Name diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml index 01f8a0656..dc673054c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Log/AuditLog.cshtml @@ -6,71 +6,136 @@ ViewData["Title"] = Localizer["Audit Log"]; } -
    -

    @ViewData["Title"]

    +
    +

    @ViewData["Title"]

    -
    -
    - @await Html.PartialAsync("Common/Search", new Search { Action = "AuditLog", Controller = "Log" }) -
    -
    +
    + + + + +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    + +
    -
    -
    -
    - - - - - - - - - - - - - @foreach (var auditLog in Model.Logs) - { +
    + +
    + +
    + +
    + + +
    +
    + +
    +
    + + + + +
    +
    +
    +
    @Localizer["Event"]@Localizer["Source"]@Localizer["Subject"]@Localizer["Action"]@Localizer["Created"]
    + - - - - - - + + + + + + - - - - } - -
    @Localizer["Detail"]@auditLog.Event@auditLog.Source - @auditLog.Created - @Localizer["Event"]@Localizer["Source"]@Localizer["Subject"]@Localizer["Action"]@Localizer["Created"]
    + +
    @Localizer["Detail"]@auditLog.Event@auditLog.Source + @auditLog.Created +
    +
    - -
    -
    - @await Html.PartialAsync("Common/Pager", new Pager { Action = "AuditLog", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search }) +
    +
    + @await Html.PartialAsync("Common/PagerDynamic", new Pager { Action = Url.Action("AuditLog", "Log"), PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search }) +
    -
    - ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
    "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("").append(S("").append(S("").append(S("").append(E("").append(E("").append(E("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-name"),n=$(this).data("subject-type"),i=$(this).data("subject-additional-data");$(".modal-title").html(t+" - "+e+" - ("+n+")"),$(".audit-modal-value").html(auditLog.createJsonTree(i)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action");$(".modal-title").html(""),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-name"),n=$(this).data("subject-type"),i=$(this).data("subject-additional-data");$(".modal-title").html(t+" - "+e+" - ("+n+")"),$(".audit-modal-value").html(auditLog.createJsonTree(i)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action"),t=$(this).data("action-title");$(".modal-title").html(t),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")}),$(".audit-log-delete-button").click(function(){return $(".audit-log-form").validate(),$(".audit-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;i Date: Mon, 4 Nov 2019 16:58:05 +0100 Subject: [PATCH 196/338] Add link for audit logging from user profile --- .../Views/Identity/UserProfile.en.resx | 3 +++ .../Views/Identity/UserProfile.cshtml | 1 + .../Services/AuditEventSink.cs | 19 +++++++++++++++++++ ...koruba.IdentityServer4.STS.Identity.csproj | 5 +++++ 4 files changed, 28 insertions(+) create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Services/AuditEventSink.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.en.resx index 3f7717a18..0b08dc710 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.en.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.en.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Audit Log + Change Password diff --git a/src/Skoruba.IdentityServer4.Admin/Views/Identity/UserProfile.cshtml b/src/Skoruba.IdentityServer4.Admin/Views/Identity/UserProfile.cshtml index 4fb21f778..ba75e18e1 100644 --- a/src/Skoruba.IdentityServer4.Admin/Views/Identity/UserProfile.cshtml +++ b/src/Skoruba.IdentityServer4.Admin/Views/Identity/UserProfile.cshtml @@ -34,6 +34,7 @@
    @Localizer["ButtonManageUserClaims"] @Localizer["ButtonManageUserRoles"] @Localizer["ButtonManageUserExternalProviders"] + @Localizer["Audit Log"] @Localizer["ButtonChangePassword"] @Localizer["ButtonDeleteUser"] diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Services/AuditEventSink.cs b/src/Skoruba.IdentityServer4.STS.Identity/Services/AuditEventSink.cs new file mode 100644 index 000000000..559888a78 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Services/AuditEventSink.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; +using IdentityServer4.Events; +using IdentityServer4.Services; +using Microsoft.Extensions.Logging; + +namespace Skoruba.IdentityServer4.STS.Identity.Services +{ + public class AuditEventSink : DefaultEventSink + { + public AuditEventSink(ILogger logger) : base(logger) + { + } + + public override Task PersistAsync(Event evt) + { + return base.PersistAsync(evt); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 108a933ba..6c7a22af1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -17,6 +17,7 @@ + @@ -25,4 +26,8 @@ + + + + From 8cfe2d1d16dbb59db7d838515dddb5c40ce1a71d Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 5 Nov 2019 11:31:15 +0100 Subject: [PATCH 197/338] Update to .NET Core 3 --- .../AuthorizeCheckOperationFilter.cs | 24 ++- .../Helpers/StartupHelpers.cs | 3 +- .../Program.cs | 1 + .../Skoruba.IdentityServer4.Admin.Api.csproj | 75 +++---- .../Startup.cs | 32 +-- ...erver4.Admin.BusinessLogic.Identity.csproj | 6 +- ...yServer4.Admin.BusinessLogic.Shared.csproj | 2 +- ...IdentityServer4.Admin.BusinessLogic.csproj | 4 +- ...r4.Admin.EntityFramework.Extensions.csproj | 2 +- ...ver4.Admin.EntityFramework.Identity.csproj | 6 +- ...erver4.Admin.EntityFramework.Shared.csproj | 4 +- ...entityServer4.Admin.EntityFramework.csproj | 6 +- .../Helpers/DbMigrationHelpers.cs | 3 +- .../Helpers/PagerHelpers.cs | 1 - .../Helpers/StartupHelpers.cs | 15 +- src/Skoruba.IdentityServer4.Admin/Program.cs | 22 +- .../Skoruba.IdentityServer4.Admin.csproj | 196 +++++++++--------- src/Skoruba.IdentityServer4.Admin/Startup.cs | 17 +- src/Skoruba.IdentityServer4.Admin/web.config | 7 +- .../Helpers/StartupHelpers.cs | 14 +- .../Program.cs | 7 +- ...koruba.IdentityServer4.STS.Identity.csproj | 57 ++--- .../Startup.cs | 12 +- ...ntityServer4.Admin.IntegrationTests.csproj | 12 +- ...uba.IdentityServer4.Admin.UnitTests.csproj | 4 +- ...rver4.STS.Identity.IntegrationTests.csproj | 14 +- 26 files changed, 293 insertions(+), 253 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Authorization/AuthorizeCheckOperationFilter.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Authorization/AuthorizeCheckOperationFilter.cs index f94309e84..d927b05d1 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Authorization/AuthorizeCheckOperationFilter.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Authorization/AuthorizeCheckOperationFilter.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Authorization; -using Swashbuckle.AspNetCore.Swagger; +using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; namespace Skoruba.IdentityServer4.Admin.Api.Configuration.Authorization @@ -14,8 +14,7 @@ public AuthorizeCheckOperationFilter(AdminApiConfiguration adminApiConfiguration { _adminApiConfiguration = adminApiConfiguration; } - - public void Apply(Operation operation, OperationFilterContext context) + public void Apply(OpenApiOperation operation, OperationFilterContext context) { var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true) .Union(context.MethodInfo.GetCustomAttributes(true)) @@ -23,11 +22,20 @@ public void Apply(Operation operation, OperationFilterContext context) if (hasAuthorize) { - operation.Responses.Add("401", new Response { Description = "Unauthorized" }); - operation.Responses.Add("403", new Response { Description = "Forbidden" }); - - operation.Security = new List>> { - new Dictionary> {{"oauth2", new[] { _adminApiConfiguration.OidcApiName } }} + operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" }); + operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" }); + var oAuthScheme = new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "oauth2" + } + }; + operation.Security = new List { + new OpenApiSecurityRequirement { + [oAuthScheme] = new[] { _adminApiConfiguration.OidcApiName } + } }; } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index ba8e40e6d..9127c864e 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -82,8 +82,7 @@ public static IServiceCollection AddAuditEventLogging), typeof(GenericControllerLocalizer<>)); - services.AddMvc(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) + services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) .AddDataAnnotationsLocalization() .ConfigureApplicationPartManager(m => { diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs index 3112ee351..e8fd12e41 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs @@ -15,6 +15,7 @@ public static void Main(string[] args) public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) + .UseIISIntegration() .UseStartup(); } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index 73af90ce8..e85eefdbb 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -1,44 +1,47 @@  - - netcoreapp2.2 - InProcess - 1cc472a2-4e4b-48ce-846b-5219f71fc643 - + + netcoreapp3.0 + 1cc472a2-4e4b-48ce-846b-5219f71fc643 + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - True - True - ApiErrorResource.resx - - + + + True + True + ApiErrorResource.resx + + - - - ResXFileCodeGenerator - ApiErrorResource.Designer.cs - - + + + ResXFileCodeGenerator + ApiErrorResource.Designer.cs + + diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 571cc7489..73ddf1eb7 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -4,6 +4,8 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.Authorization; @@ -20,7 +22,7 @@ namespace Skoruba.IdentityServer4.Admin.Api { public class Startup { - public Startup(IHostingEnvironment env) + public Startup(IWebHostEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) @@ -40,7 +42,7 @@ public Startup(IHostingEnvironment env) public IConfiguration Configuration { get; } - public IHostingEnvironment HostingEnvironment { get; } + public IWebHostEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { @@ -77,24 +79,29 @@ public void ConfigureServices(IServiceCollection services) services.AddSwaggerGen(options => { - options.SwaggerDoc(adminApiConfiguration.ApiVersion, new Info { Title = adminApiConfiguration.ApiName, Version = adminApiConfiguration.ApiVersion }); + options.SwaggerDoc(adminApiConfiguration.ApiVersion, new OpenApiInfo { Title = adminApiConfiguration.ApiName, Version = adminApiConfiguration.ApiVersion }); - options.AddSecurityDefinition("oauth2", new OAuth2Scheme + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { - Flow = "implicit", - AuthorizationUrl = $"{adminApiConfiguration.IdentityServerBaseUrl}/connect/authorize", - Scopes = new Dictionary { - { adminApiConfiguration.OidcApiName, adminApiConfiguration.ApiName } + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows + { + Implicit = new OpenApiOAuthFlow + { + AuthorizationUrl = new Uri($"{adminApiConfiguration.IdentityServerBaseUrl}/connect/authorize"), + Scopes = new Dictionary { + { adminApiConfiguration.OidcApiName, adminApiConfiguration.ApiName } + } + } } }); - options.OperationFilter(); }); services.AddAuditEventLogging(Configuration); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApiConfiguration adminApiConfiguration) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApiConfiguration adminApiConfiguration) { app.AddLogging(Configuration); @@ -104,7 +111,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApi } app.UseAuthentication(); - + app.UseAuthorization(); app.UseSwagger(); app.UseSwaggerUI(c => { @@ -114,7 +121,8 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, AdminApi c.OAuthAppName(adminApiConfiguration.ApiName); }); - app.UseMvc(); + app.UseRouting(); + app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); } } } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj index 435da070b..97c7afb42 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba Business Logic layer for the administration of the Asp.Net Core Identity and IdentityServer4 @@ -12,8 +12,8 @@ - - + + diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj index 858289418..1316be6fa 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared/Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba IdentityServer4 Admin OpenIDConnect OAuth2 Identity diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj index 9a5b8a421..ff4ea8761 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba Business Logic layer for the administration of the IdentityServer4 @@ -12,7 +12,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj index cb54ed775..a0badf826 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions/Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba IdentityServer4 Admin OpenIDConnect OAuth2 Identity diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj index cf7daf569..52635ce5c 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba Entity Framework layer for the administration of the Asp.Net Core Identity and IdentityServer4 @@ -12,8 +12,8 @@ - - + + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj index 0a1bfa6a8..9a5a248c3 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Skoruba.IdentityServer4.Admin.EntityFramework.Shared.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba IdentityServer4 Admin OpenIDConnect OAuth2 Identity @@ -12,7 +12,7 @@ - + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj index 3a5a8fa55..fdf80efb0 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Skoruba.IdentityServer4.Admin.EntityFramework.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.0 1.0.0-beta7 Jan Škoruba IdentityServer4 Admin OpenIDConnect OAuth2 Identity @@ -12,8 +12,8 @@ - - + + diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 9f72c78b4..c04b2a6fc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; @@ -19,7 +20,7 @@ public static class DbMigrationHelpers /// https://github.com/skoruba/IdentityServer4.Admin#ef-core--data-access /// /// - public static async Task EnsureSeedData(IWebHost host) + public static async Task EnsureSeedData(IHost host) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs index c325ed5aa..d51851727 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/PagerHelpers.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 7d91f660e..cecb90094 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -2,9 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; -using System.Security.Claims; using System.Threading.Tasks; -using IdentityModel; using IdentityServer4.EntityFramework.Options; using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Authentication; @@ -44,8 +42,8 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories; using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; -using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.Helpers.Localization; +using Microsoft.Extensions.Hosting; namespace Skoruba.IdentityServer4.Admin.Helpers { @@ -261,7 +259,7 @@ public static void UseSecurityHeaders(this IApplicationBuilder app) /// /// /// - public static void ConfigureAuthenticationServices(this IApplicationBuilder app, IHostingEnvironment env) + public static void ConfigureAuthenticationServices(this IApplicationBuilder app, IWebHostEnvironment env) { app.UseAuthentication(); @@ -301,7 +299,7 @@ public static void AddLogging(this IApplicationBuilder app, ILoggerFactory logge /// /// /// - public static void AddDbContexts(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfigurationRoot configuration) + public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfigurationRoot configuration) where TContext : DbContext { if (hostingEnvironment.IsStaging()) @@ -325,7 +323,7 @@ public static void AddDbContexts(this IServiceCollection services, IHo /// /// /// - public static void AddDbContexts(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfigurationRoot configuration) + public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfigurationRoot configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext @@ -399,11 +397,10 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - services.AddMvc(o => + services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }) @@ -446,7 +443,7 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) /// /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IAdminConfiguration adminConfiguration) + public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IAdminConfiguration adminConfiguration) where TContext : DbContext where TUserIdentity : class where TUserIdentityRole : class { services.AddIdentity(options => diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index 2384446c2..628047df5 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -1,7 +1,8 @@ -using System.Linq; +using System.IO; +using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; using Serilog; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; @@ -18,7 +19,7 @@ public static async Task Main(string[] args) var seed = args.Any(x => x == SeedArgs); if (seed) args = args.Except(new[] { SeedArgs }).ToArray(); - var host = CreateWebHostBuilder(args).Build(); + var host = CreateHostBuilder(args).Build(); // Uncomment this to seed upon startup, alternatively pass in `dotnet run /seed` to seed using CLI // await DbMigrationHelpers.EnsureSeedData(host); @@ -30,10 +31,15 @@ public static async Task Main(string[] args) host.Run(); } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseKestrel(c => c.AddServerHeader = false) - .UseStartup() - .UseSerilog(); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseContentRoot(Directory.GetCurrentDirectory()); + webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); + webBuilder.UseIISIntegration(); + webBuilder.UseStartup(); + webBuilder.UseSerilog(); + }); } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index 72e4ed4f5..cb448fb4e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -1,104 +1,108 @@  - - netcoreapp2.2 - latest - 8fe260ca-ef4c-4fa3-9364-029146f8d339 - + + netcoreapp3.0 + latest + 8fe260ca-ef4c-4fa3-9364-029146f8d339 + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 85c92fb17..8bdfca6c6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; @@ -15,7 +16,7 @@ namespace Skoruba.IdentityServer4.Admin { public class Startup { - public Startup(IHostingEnvironment env) + public Startup(IWebHostEnvironment env) { JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); @@ -37,7 +38,7 @@ public Startup(IHostingEnvironment env) public IConfigurationRoot Configuration { get; } - public IHostingEnvironment HostingEnvironment { get; } + public IWebHostEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { @@ -65,7 +66,7 @@ public void ConfigureServices(IServiceCollection services) UsersDto, string>, RolesDto, string>, UserRolesDto, string, string>, UserClaimsDto, UserProviderDto, UserProvidersDto, UserChangePasswordDto, RoleClaimsDto, UserClaimDto, RoleClaimDto>(); - + // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization // If you want to change primary keys or use another db model for Asp.Net Core Identity: @@ -83,7 +84,7 @@ public void ConfigureServices(IServiceCollection services) services.AddAuditEventLogging(Configuration); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { app.AddLogging(loggerFactory, Configuration); @@ -104,13 +105,13 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF // Use authentication and for integration tests use custom middleware which is used only in Staging environment app.ConfigureAuthenticationServices(env); + app.UseAuthorization(); + // Use Localization app.ConfigureLocalization(); - app.UseMvc(routes => - { - routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); - }); + app.UseRouting(); + app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/web.config b/src/Skoruba.IdentityServer4.Admin/web.config index 3d49211e5..5e0ce7695 100644 --- a/src/Skoruba.IdentityServer4.Admin/web.config +++ b/src/Skoruba.IdentityServer4.Admin/web.config @@ -7,8 +7,11 @@ - - + + + + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 74034a991..997f08f21 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -26,6 +26,7 @@ using Skoruba.IdentityServer4.STS.Identity.Helpers.Localization; using Skoruba.IdentityServer4.STS.Identity.Services; using ILogger = Microsoft.Extensions.Logging.ILogger; +using Microsoft.Extensions.Hosting; namespace Skoruba.IdentityServer4.STS.Identity.Helpers { @@ -42,12 +43,11 @@ public static void AddMvcWithLocalization(this IServiceCollection s services.AddLocalization(opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }); services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - - services.AddMvc(o => + + services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }) @@ -131,7 +131,7 @@ public static void AddEmailSenders(this IServiceCollection services, IConfigurat /// /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfiguration configuration, ILogger logger) + public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfiguration configuration, ILogger logger) where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext where TConfigurationDbContext : DbContext, IConfigurationDbContext where TIdentityDbContext : DbContext @@ -231,7 +231,7 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect /// private static void AddIdentityServer( IServiceCollection services, - IConfiguration configuration, ILogger logger, IHostingEnvironment hostingEnvironment) + IConfiguration configuration, ILogger logger, IWebHostEnvironment hostingEnvironment) where TUserIdentity : class where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext where TConfigurationDbContext : DbContext, IConfigurationDbContext @@ -279,7 +279,7 @@ private static void AddExternalProviders(AuthenticationBuilder authenticationBui /// /// public static void AddIdentityDbContext(this IServiceCollection services, - IConfiguration configuration, IHostingEnvironment hostingEnvironment) + IConfiguration configuration, IWebHostEnvironment hostingEnvironment) where TContext : DbContext { if (hostingEnvironment.IsStaging()) @@ -329,7 +329,7 @@ public static void AddDbContexts(this IServiceCollection services, ICo /// public static IIdentityServerBuilder AddIdentityServerStoresWithDbContexts(this IIdentityServerBuilder builder, IConfiguration configuration, - IHostingEnvironment hostingEnvironment) + IWebHostEnvironment hostingEnvironment) where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext where TConfigurationDbContext : DbContext, IConfigurationDbContext { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs index 2703eb948..4fe593c7f 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs @@ -9,12 +9,13 @@ public class Program public static void Main(string[] args) { CreateWebHostBuilder(args) - .UseSerilog() - .Build().Run(); + .UseSerilog() + .Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) + WebHost.CreateDefaultBuilder(args) + .UseIISIntegration() .UseStartup(); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 6c7a22af1..ffeddbd66 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -1,33 +1,38 @@  - - netcoreapp2.2 - 9c91d295-54c5-4d09-9bd6-fa56fb74011b - + + netcoreapp3.0 + 9c91d295-54c5-4d09-9bd6-fa56fb74011b + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - + + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 10cfff0f0..a17af95e7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; @@ -13,10 +14,10 @@ namespace Skoruba.IdentityServer4.STS.Identity public class Startup { public IConfiguration Configuration { get; } - public IHostingEnvironment Environment { get; } + public IWebHostEnvironment Environment { get; } public ILogger Logger { get; set; } - public Startup(IHostingEnvironment environment, ILoggerFactory loggerFactory) + public Startup(IWebHostEnvironment environment, ILoggerFactory loggerFactory) { var builder = new ConfigurationBuilder() .SetBasePath(environment.ContentRootPath) @@ -57,7 +58,7 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthorizationPolicies(rootConfiguration); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { app.AddLogging(loggerFactory, Configuration); @@ -71,8 +72,11 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF app.UseStaticFiles(); app.UseIdentityServer(); + app.UseAuthorization(); app.UseMvcLocalizationServices(); - app.UseMvcWithDefaultRoute(); + + app.UseRouting(); + app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } } } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj index 74883d67a..db85a7b6a 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj @@ -1,21 +1,21 @@  - netcoreapp2.2 + netcoreapp3.0 true false Full - + all runtime; build; native; contentfiles; analyzers - - - - + + + + all diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj index 7db71b7cf..599da8914 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2 + netcoreapp3.0 Full false @@ -17,7 +17,7 @@ runtime; build; native; contentfiles; analyzers - + diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj index 157b57337..11c542d37 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj @@ -1,19 +1,19 @@  - netcoreapp2.2 + netcoreapp3.0 true false Full - - - - - - + + + + + + all From 6149102e727fa0d966b13a01ded490feca62e03f Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 6 Nov 2019 09:21:19 +0100 Subject: [PATCH 198/338] Update versions of libs --- .../Controllers/IdentityControllerTests.cs | 3 +-- .../Skoruba.IdentityServer4.Admin.UnitTests.csproj | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs index 5b0690c03..93fba21d1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/IdentityControllerTests.cs @@ -614,8 +614,7 @@ private IServiceProvider GetServices() services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) + services.AddControllersWithViews() .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; }) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj index 599da8914..55de22551 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Skoruba.IdentityServer4.Admin.UnitTests.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers @@ -19,9 +19,8 @@ - - - + + From 6601e4fa1ee7fff10d77c90e4bc91d2392e06f29 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 6 Nov 2019 17:03:26 +0100 Subject: [PATCH 199/338] Clean up, fix tests, update versions. --- .../Skoruba.IdentityServer4.Admin.Api.csproj | 1 - src/Skoruba.IdentityServer4.Admin.Api/Startup.cs | 2 +- .../Mappers/IdentityMapperProfile.cs | 6 ++++-- .../Controllers/LogController.cs | 12 ++++++------ .../Skoruba.IdentityServer4.Admin.csproj | 1 - src/Skoruba.IdentityServer4.Admin/Startup.cs | 3 +-- .../Controllers/DiagnosticsController.cs | 4 ++-- .../Skoruba.IdentityServer4.STS.Identity.csproj | 1 - src/Skoruba.IdentityServer4.STS.Identity/Startup.cs | 2 +- .../Views/Shared/Error.cshtml | 5 +++-- .../Common/WebApplicationFactoryExtensions.cs | 2 +- ...uba.IdentityServer4.Admin.IntegrationTests.csproj | 3 +-- .../Tests/Base/BaseClassFixture.cs | 2 +- .../Tests/ConfigurationControllerTests.cs | 2 +- .../Controllers/ConfigurationControllerTests.cs | 1 - .../Common/WebApplicationFactoryExtensions.cs | 2 +- ...ntityServer4.STS.Identity.IntegrationTests.csproj | 5 ++--- 17 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index e85eefdbb..f24339354 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -6,7 +6,6 @@ - diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 73ddf1eb7..5503c086f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -111,7 +111,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi } app.UseAuthentication(); - app.UseAuthorization(); app.UseSwagger(); app.UseSwaggerUI(c => { @@ -122,6 +121,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi }); app.UseRouting(); + app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); } } diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Mappers/IdentityMapperProfile.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Mappers/IdentityMapperProfile.cs index 2be36e2bc..413c74dff 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Mappers/IdentityMapperProfile.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Mappers/IdentityMapperProfile.cs @@ -94,7 +94,8 @@ public IdentityMapperProfile() CreateMap(MemberList.Destination); // model to entity - CreateMap(MemberList.Source); + CreateMap(MemberList.Source) + .ForMember(dest => dest.Id, opt => opt.Condition(srs => srs.Id != null)); ; CreateMap(MemberList.Source); @@ -103,7 +104,8 @@ public IdentityMapperProfile() opt => opt.MapFrom(src => src.ClaimId)); // model to entity - CreateMap(MemberList.Source); + CreateMap(MemberList.Source) + .ForMember(dest => dest.Id, opt => opt.Condition(srs => srs.Id != null)); ; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs index 2acfdd22c..4599af6a7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs +++ b/src/Skoruba.IdentityServer4.Admin/Controllers/LogController.cs @@ -47,28 +47,28 @@ public async Task AuditLog([FromQuery]AuditLogFilterDto filters) [HttpPost] [ValidateAntiForgeryToken] - public async Task DeleteLogs(LogsDto logs) + public async Task DeleteLogs(LogsDto log) { if (!ModelState.IsValid) { - return View(nameof(ErrorsLog), logs); + return View(nameof(ErrorsLog), log); } - await _logService.DeleteLogsOlderThanAsync(logs.DeleteOlderThan.Value); + await _logService.DeleteLogsOlderThanAsync(log.DeleteOlderThan.Value); return RedirectToAction(nameof(ErrorsLog)); } [HttpPost] [ValidateAntiForgeryToken] - public async Task DeleteAuditLogs(AuditLogsDto logs) + public async Task DeleteAuditLogs(AuditLogsDto log) { if (!ModelState.IsValid) { - return View(nameof(AuditLog), logs); + return View(nameof(AuditLog), log); } - await _auditLogService.DeleteLogsOlderThanAsync(logs.DeleteOlderThan.Value); + await _auditLogService.DeleteLogsOlderThanAsync(log.DeleteOlderThan.Value); return RedirectToAction(nameof(AuditLog)); } diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index cb448fb4e..18d31d21c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -7,7 +7,6 @@ - diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 8bdfca6c6..670ccdba7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -105,12 +105,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF // Use authentication and for integration tests use custom middleware which is used only in Staging environment app.ConfigureAuthenticationServices(env); - app.UseAuthorization(); - // Use Localization app.ConfigureLocalization(); app.UseRouting(); + app.UseAuthorization(); app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/DiagnosticsController.cs b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/DiagnosticsController.cs index 355f6fad1..e037e5450 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/DiagnosticsController.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/DiagnosticsController.cs @@ -20,8 +20,8 @@ public class DiagnosticsController : Controller { public async Task Index() { - var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection.LocalIpAddress.ToString() }; - if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString())) + var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection?.LocalIpAddress?.ToString() }; + if (!localAddresses.Contains(HttpContext.Connection?.RemoteIpAddress?.ToString())) { return NotFound(); } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index ffeddbd66..13ce1c9ba 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -6,7 +6,6 @@ - diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index a17af95e7..0d46bcb47 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -72,10 +72,10 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseStaticFiles(); app.UseIdentityServer(); - app.UseAuthorization(); app.UseMvcLocalizationServices(); app.UseRouting(); + app.UseAuthorization(); app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/Error.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/Error.cshtml index 4a587e8cb..950e798d1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/Error.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/Error.cshtml @@ -1,12 +1,13 @@ @using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Hosting +@using Microsoft.Extensions.Hosting @model Skoruba.IdentityServer4.STS.Identity.ViewModels.Home.ErrorViewModel -@inject IHostingEnvironment host +@inject IWebHostEnvironment Host @{ var error = Model?.Error?.Error; - var errorDescription = host.IsDevelopment() ? Model?.Error?.ErrorDescription : null; + var errorDescription = Host.IsDevelopment() ? Model?.Error?.ErrorDescription : null; var request_id = Model?.Error?.RequestId; } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs index 76ad9fe6b..e7f21379e 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -16,7 +16,7 @@ public static HttpClient SetupClient(this WebApplicationFactory fixture return fixture.WithWebHostBuilder( builder => builder - .UseEnvironment(EnvironmentName.Staging) + .UseEnvironment(Microsoft.Extensions.Hosting.Environments.Staging) .ConfigureTestServices(services => { }) ).CreateClient(options); } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj index db85a7b6a..b091e502a 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Skoruba.IdentityServer4.Admin.IntegrationTests.csproj @@ -15,13 +15,12 @@ - + all runtime; build; native; contentfiles; analyzers - diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs index cb2ccc03f..a01e750f7 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -21,7 +21,7 @@ public BaseClassFixture(WebApplicationFactory factory) protected virtual void SetupAdminClaimsViaHeaders() { - using (var scope = Factory.Server.Host.Services.CreateScope()) + using (var scope = Factory.Services.CreateScope()) { var configuration = scope.ServiceProvider.GetRequiredService(); Client.SetAdminClaimsViaHeaders(configuration.AdminConfiguration); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs index edff1b0c1..64d57c475 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs @@ -41,7 +41,7 @@ public async Task ReturnRedirectWithoutAdminRole() { //Remove Client.DefaultRequestHeaders.Clear(); - + foreach (var route in RoutesConstants.GetConfigureRoutes()) { // Act diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs index a31a77b5a..51cb4ba73 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Controllers/ConfigurationControllerTests.cs @@ -822,7 +822,6 @@ private IServiceProvider GetServices() services.AddSession(); services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; }) diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs index 9b962e782..38fa03348 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -18,7 +18,7 @@ public static HttpClient SetupClient(this WebApplicationFactory fixture return fixture.WithWebHostBuilder( builder => builder - .UseEnvironment(EnvironmentName.Staging) + .UseEnvironment(Microsoft.Extensions.Hosting.Environments.Staging) .ConfigureTestServices(services => { }) ).CreateClient(options); } diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj index 11c542d37..52d9fa187 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests.csproj @@ -10,16 +10,15 @@ - + - + all runtime; build; native; contentfiles; analyzers - From 9c64af3ac9d44390e1096e0749e53904c6a0d3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Wed, 6 Nov 2019 17:14:50 +0100 Subject: [PATCH 200/338] Update README.md --- README.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index edceaa317..2d26f0937 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ This is currently in **beta version** -The application is written in the **Asp.Net Core MVC - using .NET Core 2.2** +The application is written in the **Asp.Net Core MVC - using .NET Core 3.0** -**NOTE:** Works only with **IdentityServer4 version 2.3.0 and higher** 🚀 +**NOTE:** Works only with **IdentityServer4 version 3.0.0 and higher** 🚀 ## Requirements @@ -147,6 +147,13 @@ Add-Migration IdentityServerPersistedGrantsDbInit -context IdentityServerPersist Update-Database -context IdentityServerPersistedGrantDbContext ``` +#### Migrations for AuditLogging DbContext: + +```powershell +Add-Migration AuditLoggingDbInit -context AuditLoggingDbContext -output Data/Migrations/AuditLogging +Update-Database -context AuditLoggingDbContext +``` + ### Or via `dotnet CLI`: #### Migrations for Asp.Net Core Identity DbContext: @@ -177,13 +184,20 @@ dotnet ef migrations add IdentityServerPersistedGrantsDbInit -c IdentityServerPe dotnet ef database update -c IdentityServerPersistedGrantDbContext ``` +#### Migrations for AuditLogging DbContext: + +```powershell +dotnet ef migrations add AuditLoggingDbInit -c AuditLoggingDbContext -o Data/Migrations/AuditLogging +dotnet ef database update -c AuditLoggingDbContext +``` + Migrations are not a part of the repository - they are ignored in `.gitignore`. ### We suggest to use seed data: - In `Program.cs` -> `Main`, uncomment `DbMigrationHelpers.EnsureSeedData(host)` or use dotnet CLI `dotnet run /seed` -- The `Clients` and `Resources` files in `Configuration/IdentityServer` are the initial data, based on a sample from IdentityServer4 -- The `Users` file in `Configuration/Identity` contains the default admin username and password for the first login +- The `Clients` and `Resources` files in `appsettings.json` (section called: IdentityServerData) - are the initial data, based on a sample from IdentityServer4 +- The `Users` file in `appsettings.json` (section called: IdentityData) contains the default admin username and password for the first login ### Using other database engines - PostgreSQL, SQLite, MySQL etc. @@ -191,9 +205,8 @@ Migrations are not a part of the repository - they are ignored in `.gitignore`. ## Authentication and Authorization -- Change the specific URLs and names for the IdentityServer and Authentication settings in `Constants/AuthenticationConsts` or `appsettings.json` -- `Constants/AuthorizationConsts.cs` contains configuration of constants connected with authorization - definition of the default name of admin policy -- In the controllers is used the policy which name is stored in - `AuthorizationConsts.AdministrationPolicy`. In the policy - `AuthorizationConsts.AdministrationPolicy` is defined required role stored in - `AuthorizationConsts.AdministrationRole`. +- Change the specific URLs and names for the IdentityServer and Authentication settings in `appsettings.json` +- In the controllers is used the policy which name is stored in - `AuthorizationConsts.AdministrationPolicy`. In the policy - `AuthorizationConsts.AdministrationPolicy` is defined required role stored in - `appsettings.json` - `AdministrationRole`. - With the default configuration, it is necessary to configure and run instance of IdentityServer4. It is possible to use initial migration for creating the client as it mentioned above ### Login Configuration @@ -447,9 +460,7 @@ It is possible to define the configuration according the client type - by defaul - [x] IdentityServer4 - [x] Asp.Net Core Identity - [x] Add swagger support - -### 1.1.0 -- [ ] Add audit logs to track changes ([#61](https://github.com/skoruba/IdentityServer4.Admin/issues/61)) +[x] Add audit logs to track changes ([#61](https://github.com/skoruba/IdentityServer4.Admin/issues/61)) ### 2.0.0: From e49f2f89112722fd2b6a9c4a5a764fef650eb70b Mon Sep 17 00:00:00 2001 From: Nicolai Dahl Date: Fri, 8 Nov 2019 12:40:06 +0100 Subject: [PATCH 201/338] Added Danish translation into Localization --- .../Helpers/StartupHelpers.cs | 1 + .../ConfigurationController.da.resx | 189 ++++++++++++++ .../Controllers/GrantController.da.resx | 129 ++++++++++ .../Controllers/IdentityController.da.resx | 159 ++++++++++++ .../Services/ApiResourceService.da.resx | 150 +++++++++++ .../Resources/Services/ClientService.da.resx | 138 +++++++++++ .../Services/IdentityResourceService.da.resx | 135 ++++++++++ .../Services/IdentityService.da.resx | 180 ++++++++++++++ .../Services/PersistedGrantService.da.resx | 126 ++++++++++ .../Views/Account/AccessDenied.da.resx | 129 ++++++++++ .../Resources/Views/ClientClone.da.resx | 162 ++++++++++++ .../Views/Configuration/ApiResource.da.resx | 165 ++++++++++++ .../ApiResource/Section/Label.da.resx | 192 ++++++++++++++ .../Configuration/ApiResourceDelete.da.resx | 132 ++++++++++ .../ApiResourceProperties.da.resx | 147 +++++++++++ .../ApiResourcePropertyDelete.da.resx | 135 ++++++++++ .../Views/Configuration/ApiResources.da.resx | 135 ++++++++++ .../Configuration/ApiScopeDelete.da.resx | 135 ++++++++++ .../Views/Configuration/ApiScopes.da.resx | 165 ++++++++++++ .../Configuration/ApiSecretDelete.da.resx | 135 ++++++++++ .../Views/Configuration/ApiSecrets.da.resx | 162 ++++++++++++ .../Views/Configuration/Client.da.resx | 129 ++++++++++ .../Client/Section/ActionButtons.da.resx | 129 ++++++++++ .../Client/Section/Authentication.da.resx | 144 +++++++++++ .../Client/Section/Basics.da.resx | 150 +++++++++++ .../Configuration/Client/Settings.da.resx | 141 +++++++++++ .../Configuration/ClientClaimDelete.da.resx | 135 ++++++++++ .../Views/Configuration/ClientClaims.da.resx | 171 +++++++++++++ .../Views/Configuration/ClientClone.da.resx | 162 ++++++++++++ .../Views/Configuration/ClientDelete.da.resx | 129 ++++++++++ .../Configuration/ClientProperties.da.resx | 147 +++++++++++ .../ClientPropertyDelete.da.resx | 135 ++++++++++ .../Configuration/ClientSecretDelete.da.resx | 135 ++++++++++ .../Views/Configuration/ClientSecrets.da.resx | 162 ++++++++++++ .../Views/Configuration/Clients.da.resx | 135 ++++++++++ .../Configuration/IdentityResource.da.resx | 159 ++++++++++++ .../IdentityResource/Section/Label.da.resx | 186 ++++++++++++++ .../IdentityResourceDelete.da.resx | 132 ++++++++++ .../IdentityResourceProperties.da.resx | 147 +++++++++++ .../IdentityResourcePropertyDelete.da.resx | 135 ++++++++++ .../Configuration/IdentityResources.da.resx | 132 ++++++++++ .../Views/Grant/PersistedGrant.da.resx | 156 ++++++++++++ .../Views/Grant/PersistedGrantDelete.da.resx | 144 +++++++++++ .../Views/Grant/PersistedGrants.da.resx | 132 ++++++++++ .../Resources/Views/Home/Index.da.resx | 147 +++++++++++ .../Resources/Views/Identity/Role.da.resx | 138 +++++++++++ .../Views/Identity/Role/Section/Label.da.resx | 138 +++++++++++ .../Views/Identity/RoleClaims.da.resx | 168 +++++++++++++ .../Views/Identity/RoleClaimsDelete.da.resx | 135 ++++++++++ .../Views/Identity/RoleDelete.da.resx | 129 ++++++++++ .../Views/Identity/RoleUsers.da.resx | 141 +++++++++++ .../Resources/Views/Identity/Roles.da.resx | 135 ++++++++++ .../Views/Identity/User/Section/Label.da.resx | 234 ++++++++++++++++++ .../Views/Identity/UserChangePassword.da.resx | 132 ++++++++++ .../Views/Identity/UserClaims.da.resx | 168 +++++++++++++ .../Views/Identity/UserClaimsDelete.da.resx | 135 ++++++++++ .../Views/Identity/UserDelete.da.resx | 129 ++++++++++ .../Views/Identity/UserProfile.da.resx | 147 +++++++++++ .../Views/Identity/UserProviders.da.resx | 138 +++++++++++ .../Identity/UserProvidersDelete.da.resx | 135 ++++++++++ .../Views/Identity/UserRoles.da.resx | 141 +++++++++++ .../Views/Identity/UserRolesDelete.da.resx | 135 ++++++++++ .../Resources/Views/Identity/Users.da.resx | 138 +++++++++++ .../Resources/Views/Log/ErrorsLog.da.resx | 150 +++++++++++ .../Views/Shared/Common/ErrorPage.da.resx | 123 +++++++++ .../Views/Shared/Common/Pager.da.resx | 126 ++++++++++ .../Views/Shared/Common/Search.da.resx | 126 ++++++++++ .../Shared/Common/SelectLanguage.da.resx | 123 +++++++++ .../IdentityServerLink/Default.da.resx | 123 +++++++++ .../Resources/Views/Shared/_Layout.da.resx | 162 ++++++++++++ .../Helpers/StartupHelpers.cs | 1 + .../Controllers/AccountController.da.resx | 147 +++++++++++ .../Controllers/ManageController.da.resx | 207 ++++++++++++++++ .../Views/Account/ConfirmEmail.da.resx | 126 ++++++++++ .../Account/ExternalLoginConfirmation.da.resx | 140 +++++++++++ .../Account/ExternalLoginFailure.da.resx | 126 ++++++++++ .../Views/Account/ForgotPassword.da.resx | 132 ++++++++++ .../ForgotPasswordConfirmation.da.resx | 126 ++++++++++ .../Resources/Views/Account/Lockout.da.resx | 126 ++++++++++ .../Resources/Views/Account/LoggedOut.da.resx | 135 ++++++++++ .../Resources/Views/Account/Login.da.resx | 159 ++++++++++++ .../Views/Account/LoginWith2fa.da.resx | 141 +++++++++++ .../Account/LoginWithRecoveryCode.da.resx | 133 ++++++++++ .../Resources/Views/Account/Logout.da.resx | 129 ++++++++++ .../Resources/Views/Account/Register.da.resx | 141 +++++++++++ .../Views/Account/RegisterFailure.da.resx | 126 ++++++++++ .../Views/Account/ResetPassword.da.resx | 138 +++++++++++ .../Account/ResetPasswordConfirmation.da.resx | 129 ++++++++++ .../Resources/Views/Consent/Index.da.resx | 141 +++++++++++ .../Resources/Views/Device/Success.da.resx | 126 ++++++++++ .../Views/Device/UserCodeCapture.da.resx | 129 ++++++++++ .../Views/Device/UserCodeConfirmation.da.resx | 144 +++++++++++ .../Resources/Views/Diagnostics/Index.da.resx | 132 ++++++++++ .../Resources/Views/Grants/Index.da.resx | 144 +++++++++++ .../Resources/Views/Home/Index.da.resx | 156 ++++++++++++ .../Views/Manage/ChangePassword.da.resx | 135 ++++++++++ .../Views/Manage/DeletePersonalData.da.resx | 132 ++++++++++ .../Resources/Views/Manage/Disable2fa.da.resx | 135 ++++++++++ .../Views/Manage/DownloadPersonalData.da.resx | 123 +++++++++ .../Views/Manage/EnableAuthenticator.da.resx | 148 +++++++++++ .../Views/Manage/ExternalLogins.da.resx | 132 ++++++++++ .../Manage/GenerateRecoveryCodes.da.resx | 138 +++++++++++ .../Resources/Views/Manage/Index.da.resx | 162 ++++++++++++ .../Views/Manage/LinkLoginFailure.da.resx | 126 ++++++++++ .../Views/Manage/PersonalData.da.resx | 135 ++++++++++ .../Views/Manage/ResetAuthenticator.da.resx | 133 ++++++++++ .../Views/Manage/SetPassword.da.resx | 138 +++++++++++ .../Views/Manage/ShowRecoveryCodes.da.resx | 129 ++++++++++ .../Manage/TwoFactorAuthentication.da.resx | 171 +++++++++++++ .../Shared/Common/SelectLanguage.da.resx | 123 +++++++++ .../IdentityServerAdminLink/Default.da.resx | 123 +++++++++ .../Resources/Views/Shared/Error.da.resx | 129 ++++++++++ .../Resources/Views/Shared/Redirect.da.resx | 126 ++++++++++ .../Resources/Views/Shared/_Layout.da.resx | 159 ++++++++++++ .../Views/Shared/_ScopeListItem.da.resx | 123 +++++++++ .../Views/Shared/_ValidationSummary.da.resx | 123 +++++++++ 116 files changed, 16201 insertions(+) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.da.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 3ea8f9ac9..7ccd72d35 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -367,6 +367,7 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) var supportedCultures = new[] { new CultureInfo("en"), + new CultureInfo("da"), new CultureInfo("fa"), new CultureInfo("ru"), new CultureInfo("sv"), diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.da.resx new file mode 100644 index 000000000..39126867f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.da.resx @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Api Ressource {0} er gemt succesfuldt! + + + Api Resource property {0} for api resource {1} is successfully saved! + + + Api Scope {0} er gemt succesfuldt! + + + Api Secret er oprettet succesfuldt! + + + Client {0} er oprettet succesfuldt! + + + Client claim {0} for client {1} er gemt succesfuldt! + + + Client egenskab {0} for client {1} er gemt succesfuldt! + + + Client secret for client {0} er gemt succesfuldt! + + + Identity Resource {0} er gemt succesfuldt! + + + Identity Resource egenskab {0} for api ressource {1} er gemt succesfuldt! + + + Client {0} er klonet succesfuldt! + + + Client er slettet succesfuldt! + + + Api Ressource er slettet succesfuldt! + + + Api ressource egenskab er slettet succesfuldt! + + + Api Scope er slettet succesfuldt! + + + Api Secret er slettet succesfuldt! + + + Client claim er slettet succesfuldt! + + + Client egenskab er slettet succesfuldt! + + + Client secret er slettet succesfuldt! + + + Identity Ressource er slettet succesfuldt! + + + Identity ressource egenskab er slettet succesfuldt! + + + Succes + + + Client {0} er oprettet succesfuldt! + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.da.resx new file mode 100644 index 000000000..886e55e44 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Persisted Grant er slettet succesfuldt! + + + Persisted Grants er slettet succesfuldt! + + + Succes + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.da.resx new file mode 100644 index 000000000..f34c3053c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.da.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Rolle {0} er gemt succesfuldt! + + + Claim {0} - {1} er gemt succesfuldt! + + + Bruger {0} er gemt succesfuldt! + + + Claim {0} - {1} er gemt succesfuldt! + + + Rolle er slettet succesfuldt! + + + Rolle er slettet succesfuldt! + + + Claim er slettet succesfuldt! + + + Brugeren er slettet succesfuldt! + + + Claim er slettet succesfuldt! + + + Brugerudbyder er slettet succesfuldt! + + + Rolle er slettet succesfuldt! + + + Succes + + + Nyt kodeord er oprettet succesfuldt! + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.da.resx new file mode 100644 index 000000000..8f42ecbee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.da.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Api Ressource med id {0} eksistere ikke + + + Api Ressource eksisterer allerede + + + Api Ressource ({0}) eksisterer allerede + + + Api Ressource Egenskab med id {0} eksistere ikke + + + Api Ressource Egenskab eksisterer allerede + + + Api Ressource Egenskab med nøgle ({0}) eksisterer allerede + + + Api Scope med id {0} eksistere ikke + + + Api Scope eksisterer allerede + + + Api Scope ({0}) eksisterer allerede + + + Api Secret med id {0} eksistere ikke + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.da.resx new file mode 100644 index 000000000..72d29f892 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Client claim med id {0} eksistere ikke + + + Client med id {0} eksistere ikke + + + Client eksisterer allerede + + + Client Id ({0}) eksisterer allerede + + + Client egenskab med id {0} eksistere ikke + + + Client secret med id {0} eksistere ikke + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.da.resx new file mode 100644 index 000000000..fdd20465f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Identity Ressource {0} eksisterer allerede + + + Identity Ressource {0} eksisterer allerede + + + Identity Ressource Egenskab med id {0} eksistere ikke + + + Identity Ressource Egenskab eksisterer allerede + + + Identity Ressource Egenskab med nøgle ({0}) eksisterer allerede + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.da.resx new file mode 100644 index 000000000..489e5f785 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.da.resx @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + + + Rolle Claim med id {0} eksistere ikke + + + Rolle Claims oprettelse fejlede + + + Role Claims sletning fejlede + + + Rolle oprettelse fejlede + + + Rolle sletning fejlede + + + Rolle med id {0} eksistere ikke + + + Rolle opdatering fejlede + + + Ændring af password fejlede + + + Bruger Claim med id {0} eksistere ikke + + + Bruger Claims oprettelse fejlede + + + Bruger Claims sletning fejlede + + + Bruger oprettelse fejlede + + + Bruger sletning fejlede + + + Bruger med id {0} eksistere ikke + + + Brugerudbyder sletning fejlede + + + Brugerudbyder med id {0} eksistere ikke + + + Bruger Rolle oprettelse fejlede + + + Bruger Rolle sletning fejlede + + + Bruger opdatering fejlede + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.da.resx new file mode 100644 index 000000000..73d60e97c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gemt tilladelse med id {0} eksistere ikke + + + Gemt tilladelse for dette subjekt id {0} eksistere ikke + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.da.resx new file mode 100644 index 000000000..7189a43a8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Log ud + + + Adgang nægtet! + + + Vend tilbage til IdentityServer + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.da.resx new file mode 100644 index 000000000..0f6e403ff --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/ClientClone.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kopier Client + + + Client secrets vil ikke blive kopieret. + + + Info: + + + Client Claims + + + Client CORS Origins + + + Client Grant Types + + + Client IdP Restrictions + + + Client Post Logout Redirect Uris + + + Client Egenskaber + + + Client Redirect Uris + + + Client Scopes + + + Clients + + + Kopier Client + + + Client + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.da.resx new file mode 100644 index 000000000..1c078ee6a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.da.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet API Ressource + + + Konfigurer API Ressource Egenskaber + + + Konfigurer API Scopes + + + Konfigurer API Secrets + + + Gem API Ressource + + + API Ressources + + + API Ressource + + + API Ressource + + + valget er allerede valgt + + + Ingen valg valgt + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.da.resx new file mode 100644 index 000000000..0198c28ac --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.da.resx @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne værdi kan f.eks. blive brugt på samtykke siden. + + + Beskrivelse + + + Denne værdi kan f.eks. blive brugt på samtykke siden. + + + Visningsnavn + + + Angiver om denne ressource er aktiveret og kan anmodes om. Standardindstillingen er at den er aktiveret. + + + Aktiveret + + + Udløb + + + Udløb + + + API'ets unikke navn. Denne værdi bruges til godkendelse ved introspektion og vil blive tilføjet til audience nøglen på det udgående access token. + + + Navn + + + Ordbog til at indeholde eventuelle tilpassede api-ressource-specifikke værdier efter behov. + + + Egenskaber + + + Nøgle + + + Nøgle + + + Værdi + + + Værdi + + + Et API skal have mindst et Scope. Hvert scope kan have forskellige indstillinger. + + + Scopes + + + Beskrivelse + + + Beskrivelse + + + API Secret bruges til introspektions siden. API'et kan autentificeres med introspektion ved hjælp af API-navn og secret. + + + Secrets + + + Liste over tilknyttede Bruger Claims, der skal inkluderes i access token. + + + Bruger Claims + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.da.resx new file mode 100644 index 000000000..66c74b71f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet API Ressource + + + API Ressources + + + Slet API Ressource + + + Slet API Ressource + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.da.resx new file mode 100644 index 000000000..3a8c907f4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj API Ressource Egenskab + + + API Ressource Egenskaber + + + API Ressources + + + API Ressource Egenskaber + + + API Ressource Egenskaber + + + API Ressource Egenskab + + + Slet + + + Nøgle + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.da.resx new file mode 100644 index 000000000..8083d96f7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet API Ressource Egenskab + + + API Ressource Egenskaber + + + API Ressourcer + + + Slet API Ressource Egenskab + + + Slet API Ressource Egenskab + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.da.resx new file mode 100644 index 000000000..56408c7dd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj API Ressource + + + API Ressourcer + + + API Ressourcer + + + Konfigurer + + + Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.da.resx new file mode 100644 index 000000000..497d6005d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet API Scope + + + API Ressources + + + API Scopes + + + Slet API Scope + + + Slet API Scope + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.da.resx new file mode 100644 index 000000000..02de13d32 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.da.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gem API Scope + + + API Ressources + + + API Scopes + + + API Scopes + + + API Scope + + + valget er allerede valgt + + + Ingen valg valgt + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + + Konfigurer + + + Slet + + + Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.da.resx new file mode 100644 index 000000000..56643e494 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet API Secret + + + API Ressources + + + API Secrets + + + Slet API Secret + + + Slet API Secret + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.da.resx new file mode 100644 index 000000000..43cec8967 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj API Secret + + + HashType vil kun være gældende for SharedSecret typen. + + + Info: + + + API Ressourcer + + + API Secrets + + + API Secrets + + + API Secret + + + API Secrets + + + Slet + + + Oprettet + + + Beskrivelse + + + Udløb + + + Type + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.da.resx new file mode 100644 index 000000000..b5cd21214 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clients + + + Client + + + Client - + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.da.resx new file mode 100644 index 000000000..3f72c8ca7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kopier Client + + + Slet Client + + + Gem Client + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.da.resx new file mode 100644 index 000000000..b32e4c911 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autentifikation/Log ud + + + valget er allerede valgt + + + Ingen valg valgt + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.da.resx new file mode 100644 index 000000000..66b74d771 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.da.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Administrer Client Egenskaber + + + Administrer Client Secrets + + + Grundlæggende + + + valget er allerede valgt + + + Ingen valg valgt + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.da.resx new file mode 100644 index 000000000..95f46957c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autentificering/Log ud + + + Grundlæggende + + + Samtykke side + + + Device Flow + + + Navn + + + Token + + + Indstillinger + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.da.resx new file mode 100644 index 000000000..e429e0627 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Client Claim + + + Client Claims + + + Clients + + + Slet Client Claim + + + Slet Client Claim + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.da.resx new file mode 100644 index 000000000..283c3e9cd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.da.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Client Claim + + + Client Claims + + + Clients + + + Client Claims + + + Client Claim + + + Client Claims + + + valget er allerede valgt + + + Ingen valg valgt + + + Typen er påkrævet + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + + Slet + + + Type + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.da.resx new file mode 100644 index 000000000..0f6e403ff --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kopier Client + + + Client secrets vil ikke blive kopieret. + + + Info: + + + Client Claims + + + Client CORS Origins + + + Client Grant Types + + + Client IdP Restrictions + + + Client Post Logout Redirect Uris + + + Client Egenskaber + + + Client Redirect Uris + + + Client Scopes + + + Clients + + + Kopier Client + + + Client + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.da.resx new file mode 100644 index 000000000..57d18f827 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Client + + + Clients + + + Slet Client + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.da.resx new file mode 100644 index 000000000..7ea9d5849 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Client Egenskab + + + Client Egenskaber + + + Clients + + + Client Egenskaber + + + Client Egenskaber + + + Client Egenskab + + + Slet + + + Nøgle + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.da.resx new file mode 100644 index 000000000..83083c90b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Client Egenskab + + + Client Egenskaber + + + Clients + + + Slet Client Egenskab + + + Slet Client Egenskab + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.da.resx new file mode 100644 index 000000000..c31256421 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Client Secret + + + Clients + + + Client Secrets + + + Slet Client Secret + + + Slet Client Secret + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.da.resx new file mode 100644 index 000000000..9a8b33c39 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Client Secret + + + HashType vil kun være gældende for SharedSecret typen. + + + Info: + + + Clients + + + Client Secrets + + + Client Secrets + + + Client Secrets + + + Client Secret + + + Slet + + + Type + + + Værdi + + + Oprettet + + + Beskrivelse + + + Udløb + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.da.resx new file mode 100644 index 000000000..3ea7c1af3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Client + + + Clients + + + Konfigurer + + + Client Id + + + Client Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.da.resx new file mode 100644 index 000000000..65a94ec2e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.da.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Identity Resource + + + Konfigurer Identity Ressource Egenskaber + + + Gem Identity Ressource + + + Identity Ressources + + + Identity Ressource + + + Identity Ressource + + + valget er allerede valgt + + + Ingen valg valgt + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.da.resx new file mode 100644 index 000000000..3a0c48e95 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.da.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne værdi bruges f.eks. på samtykke siden + + + Beskrivelse + + + Denne værdi bruges f.eks. på samtykke siden + + + Visnings Navn + + + Specificerer om samtykke siden skal understrege dette scope (hvis samtykke siden ønsker at implementere en sådan funktion). Brug denne indstilling til følsomme eller vigtige scopes. Per standard er det ikke slået til. + + + Understreg Scopes på Samtykke siden + + + Angiver om denne ressource er aktiveret og kan anmodes om. Standardindstillingen er sat til aktiveret. + + + Aktiveret + + + Det unikke navn på Identitets Ressourcen. Dette er den værdi, en Client vil bruge til scope parametre i autorizations kaldet. + + + Navn + + + Ordbog til at indeholde alle tilpassede Identitets Ressourcers specifikke værdier efter behov. + + + Egenskaber + + + Nøgle + + + Nøgle + + + Værdi + + + Værdi + + + Specificerer om brugeren kan fravælge scope på samtykke siden (hvis samtykke siden ønsker at implementere en sådan funktion). Standardindstillinger er sat til nej. + + + Påkrævet + + + Specificerer om dette scope vises i discovery document. Standardindstillingen er sat til ja. + + + Vises i Discovery Document + + + Liste over tilknyttede Claim Types, der skal inkluderes i id token'et. + + + Bruger Claims + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.da.resx new file mode 100644 index 000000000..69e9b9992 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Identity Ressource + + + Identity Ressourcer + + + Slet Identity Ressource + + + Slet Identity Ressource + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.da.resx new file mode 100644 index 000000000..c8a0e70b6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Identity Ressource Egenskab + + + Identity Ressource Egenskaber + + + Identity Ressourcer + + + Identity Ressource Egenskaber + + + Identity Ressource Egenskaber + + + Identity Ressource Egenskab + + + Slet + + + Nøgle + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.da.resx new file mode 100644 index 000000000..6624f35e9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Identity Ressource Egenskab + + + Identity Ressource Egenskaber + + + Identity Ressourcer + + + Slet Identity Ressource Egenskab + + + Slet Identity Ressource Egenskab + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.da.resx new file mode 100644 index 000000000..1ca3e49d1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Identity Ressource + + + Identity Ressourcer + + + Konfigurer + + + Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.da.resx new file mode 100644 index 000000000..daa2b9055 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.da.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet alle + + + Er du sikker? Alle gemte grants til dette subject vil blive slettet. + + + Nej - luk + + + Advarsel + + + Ja - slet + + + Gemte Grants + + + Gemte Grant + + + Client + + + Data + + + Udløb + + + Subject Id + + + Type + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.da.resx new file mode 100644 index 000000000..a68ada756 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Gemt Grant + + + Gemte Grants + + + Slet Gemt Grant + + + Client + + + Data + + + Udløb + + + Subject Id + + + Type + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.da.resx new file mode 100644 index 000000000..f7ab709ae --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gemte Grants + + + Detaljer + + + Subject Id + + + Subject Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.da.resx new file mode 100644 index 000000000..381601e02 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + API Ressourcer + + + Clients + + + Identity Ressourcer + + + Konfigurer + + + Gemte Grants + + + Roller + + + Brugere + + + Administration af ​​IdentityServer4 og ASP.NET Core Identity + + + Skoruba IdentityServer4 Admin + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.da.resx new file mode 100644 index 000000000..31276755b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Rolle Claims + + + Slet Rolle + + + Brugerer + + + Gem Rolle + + + Roller + + + Rolle + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.da.resx new file mode 100644 index 000000000..05912e46b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Navn på rollen + + + Rolle Navn + + + + + + Claim Type + + + + + + Claim Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.da.resx new file mode 100644 index 000000000..d34e06fd8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.da.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Rolle Claim + + + Roller + + + Rolle Claims + + + Rolle Claims + + + Claim + + + valget er allerede valgt + + + Ingen valg valgt + + + Typen er påkrævet + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + + Slet + + + Type + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.da.resx new file mode 100644 index 000000000..6e97c212e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Rolle Claim + + + Rolle Claims + + + Roller + + + Slet Rolle Claim + + + Slet Rolle Claim + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.da.resx new file mode 100644 index 000000000..355381a09 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Rolle + + + Roller + + + Slet Rolle + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.da.resx new file mode 100644 index 000000000..e3d13e68d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Søg + + + Email + + + Søg + + + Roller + + + Bruger Roller + + + Bruger Id + + + Brugernavn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.da.resx new file mode 100644 index 000000000..075a6c13b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Rolle + + + Roller + + + Konfigurer + + + Brugerer + + + Navn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.da.resx new file mode 100644 index 000000000..7cb8ba536 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.da.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Navn på rollen + + + Rolle Navn + + + Rolle + + + Rolle + + + + + + Claim Type + + + Antal Fejlede Bruger Adgange + + + Antal Fejlede Bruger Adgange + + + Bekræft Password + + + Bekræft Password + + + Password + + + Password + + + Brugernavn + + + Brugernavn + + + Bruger Email Bekræftet + + + Bruger Email Bekræftet + + + Email + + + Email + + + Lås Bruger Ude Aktiveret + + + Lås Bruger Ude Aktiveret + + + Lås Bruger Ude Sluttidspunkt + + + Lås Bruger Ude Sluttidspunkt + + + Bruger Telefonnummer Bekræftet + + + Bruger Telefonnummer Bekræftet + + + Bruger Telefonnummer + + + Bruger Telefonnummer + + + Loginudbyder + + + Loginudbyder + + + Vist Navn + + + Vist Navn + + + Udbyder Nøgle + + + Udbyder Nøgle + + + Two-Factor Authentication Aktiveret + + + Two-Factor Authentication Aktiveret + + + Brugernavn + + + Brugernavn + + + + + + Claim Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.da.resx new file mode 100644 index 000000000..d31651a06 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Skift Password + + + Brugerer + + + Bruger Skift Password + + + Skift Password + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.da.resx new file mode 100644 index 000000000..8a5a5f412 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.da.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Bruger Claim + + + Brugerer + + + Bruger Claims + + + Bruger Claims + + + Bruger Claim + + + valget er allerede valgt + + + Ingen valg valgt + + + Typen er påkrævet + + + Indtast 2 og flere tegn + + + Søgeresultat: (klik på det valg, du vil vælge) + + + Valgte valg: + + + flere + + + Foreslåede valg: + + + Slet + + + Type + + + Værdi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.da.resx new file mode 100644 index 000000000..45606dc3d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Bruger Claim + + + Bruger Claims + + + Brugerer + + + Slet Bruger Claim + + + Slet Bruger Claim + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.da.resx new file mode 100644 index 000000000..b0200c06d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Bruger + + + Brugerer + + + Slet Bruger + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.da.resx new file mode 100644 index 000000000..a5fb69f45 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Skift Password + + + Slet Bruger + + + Konfigurer Bruger Claims + + + Konfigurer Bruger Externe Udbydere + + + Konfigurer Bruger Roller + + + Gem Bruger + + + Brugerer + + + Bruger + + + Bruger + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.da.resx new file mode 100644 index 000000000..e4fc7fe4b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Brugerer + + + Bruger Udbyderer + + + Slet + + + Login Udbyderer + + + Udbyder Vist Navn + + + Udbyder Nøgle + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.da.resx new file mode 100644 index 000000000..cecaaf2e3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Bruger Udbyder + + + Bruger Udbyderer + + + Brugerer + + + Slet Bruger Udbyder + + + Slet Bruger Udbyder + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.da.resx new file mode 100644 index 000000000..c085e7401 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Rolle + + + Slet + + + Brugerer + + + Navn + + + Bruger Rolle + + + Bruger Roller + + + Roller + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.da.resx new file mode 100644 index 000000000..088a619bd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet Rolle + + + Bruger Roller + + + Brugerer + + + Slet Rolle + + + Bruger Rolle + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.da.resx new file mode 100644 index 000000000..83ce1c9d8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Bruger + + + Konfigurer + + + Email + + + Brugerer + + + Bruger Id + + + Brugernavn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.da.resx new file mode 100644 index 000000000..aa8bc7564 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.da.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet logs ældre end + + + Er du sikker? + + + Nej - luk + + + Advarsel + + + Ja - slet + + + Logs + + + Level + + + Logged + + + Besked + + + Vis Detaljer + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.da.resx new file mode 100644 index 000000000..7056b268b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Fejl + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.da.resx new file mode 100644 index 000000000..ace68e64c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Første + + + Sidste + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.da.resx new file mode 100644 index 000000000..df2932957 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Søg + + + Søg + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.da.resx new file mode 100644 index 000000000..448e64e8c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sprog: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.da.resx new file mode 100644 index 000000000..27ad81e9d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.da.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.da.resx new file mode 100644 index 000000000..c08ef38bc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + &copy; 2019 + + + Skoruba IdentityServer4 Admin + + + API Ressourcer + + + Clients + + + Identity Ressourcer + + + Log ud + + + Gemte Grants + + + Roller + + + Brugerer + + + Menu + + + Skoruba IdentityServer4 Admin + + + Clients og Ressourcer + + + Logs + + + Brugerer og Roller + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index a219a9875..f8cf335b0 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -63,6 +63,7 @@ public static void AddMvcWithLocalization(this IServiceCollection s var supportedCultures = new[] { new CultureInfo("en"), + new CultureInfo("da"), new CultureInfo("fa"), new CultureInfo("ru"), new CultureInfo("sv"), diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.da.resx new file mode 100644 index 000000000..e1619132c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft venligst din email konto ved at <a href='{0}'>klikke her</a>. + + + Bekræft din email konto + + + Brugeren eksisterer ikke eller er ikke bekræftet + + + Fejl fra extern udbyder: {0} + + + Ugyldig autentifikator kode. + + + Ugyldig gendannelses kode. + + + Nulstil din adgangskode ved at <a href='{0}'>klikke her</a>. + + + Nulstil Adgangskode + + + Kan ikke indlæse Two-Factor Authentication for denne bruger. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.da.resx new file mode 100644 index 000000000..27fe9c34c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.da.resx @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bruger med ID '{0}' har bedt om at få deres personlige data. + + + Din Authenticator App er blevet bekræftet. + + + Bekræft venligst din email konto ved at <a href='{0}'>klikke her</a>. + + + Bekræft din email konto + + + Bruger med ID '{0}' har slettet sin bruger. + + + Kan ikke generere gendannelseskoder til bruger med ID {0}, fordi de ikke har 2FA aktiveret. + + + Fejl Kode + + + Der opstod en uventet fejl ved sletning af bruger med ID {0}. + + + Der opstod en uventet fejl, da der blev deaktiveret 2FA for bruger med ID {0}. + + + Kan ikke generere gendannelseskoder for brugeren, da brugeren ikke har 2FA aktiveret. + + + Der opstod en uventet fejl ved indlæsning af eksterne login informationer for bruger med ID {0}. + + + Der opstod en uventet fejl ved fjernelse af eksternt login til bruger med ID {0}. + + + Der opstod en uventet fejl ved indstilling af e-mail til bruger med ID {0}. + + + Der opstod en uventet fejl ved indstilling af telefonnummer for bruger med ID {0}. + + + Det eksterne login blev tilføjet. + + + Det eksterne login blev fjernet. + + + Bekræftelseskoden er ugyldig. + + + Dit password er blevet ændret. + + + Bruger {0} ændrede deres adgangskode succesfuldt. + + + Password er ikke korrekt. + + + Dit password er gemt. + + + Din profil er blevet opdateret + + + Bruger med ID {0} har deaktiveret 2FA. + + + Den aktuelle browser er glemt. Når du logger ind igen fra denne browser, bliver du bedt om din 2FA-kode. + + + Bruger med id {0} har nulstillet deres Authenticator App nøgle. + + + Bruger med ID {0} har aktiveret 2FA med en Authenticator App. + + + Bruger med ID {0} har genereret nye 2FA gendannelseskoder. + + + Kan ikke indlæse bruger med ID {0}. + + + Bekræftelses e-mail er sendt. Tjek venligst din email. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx new file mode 100644 index 000000000..e6205937c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tak for bekræftelsen af ​​din e-mail. + + + Bekræft Email + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx new file mode 100644 index 000000000..6a6278ffa --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Email + + + Du har godkendt med {0}. + Indtast en email adresse for dette websted nedenfor og klik på knappen Registrer for at afslutte + log ind. + + + Registrer + + + Tilknyt din {0} konto. + + + Registrer + + + Brugernavn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx new file mode 100644 index 000000000..283335e5c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mislykket login med service. + + + Login fejl + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx new file mode 100644 index 000000000..75ff569ed --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Indsend + + + Indtast din e-mail. + + + Glemt dit password? + + + Email + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx new file mode 100644 index 000000000..a5b02c3a1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kontroller din e-mail for at nulstille din adgangskode. + + + Glemt password bekræftelse + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.da.resx new file mode 100644 index 000000000..42c257513 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne konto er blevet låst. Prøv igen senere. + + + Låst ude + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.da.resx new file mode 100644 index 000000000..9e8933f9d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Klik + + + her + + + for at vende tilbage til + + + Du er nu logget ud + + + Log ud + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.da.resx new file mode 100644 index 000000000..359faf6b1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.da.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilbage + + + Email + + + Externt Log ind + + + Glemt password + + + Ugyldigt log ind + + + Lokalt Log ind + + + Log ind + + + Der er ingen log ind skemaer, der er konfigureret til denne Client. + + + Password + + + Registrer + + + Husk mit log ind + + + Log ind + + + Brugernavn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx new file mode 100644 index 000000000..3a034769d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authenticator kode + + + Dit login er beskyttet med en Authenticator App. Indtast din Authenticator Kode forneden. + + + Log ind + + + Log ind med en gendannelseskode + + + Har du ikke adgang til din Authenticator Device? Du kan + + + Husk denne maskine + + + Two-Factor Authentication + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx new file mode 100644 index 000000000..a6c6a3c26 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gendannelseskode + + + Du har anmodet om at logge ind med en gendannelseskode. Dette login vil ikke blive husket, før du angiver +    en Authenticator App kode ved log ind eller deaktiverer 2FA og logger ind igen. + + + Log ind + + + Bekræftelse af gendannelseskode + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.da.resx new file mode 100644 index 000000000..101dd3bb8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ønsker du at logge ud af IdentityServer? + + + Log ud + + + Ja + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.da.resx new file mode 100644 index 000000000..34827e105 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registrer + + + Bekræft Password + + + Email + + + Password + + + Opret en ny konto. + + + Registrer + + + Brugernavn + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx new file mode 100644 index 000000000..e71ebb51f --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registreringen er deaktiveret. + + + Registrerings Fejl + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.da.resx new file mode 100644 index 000000000..f29c3fba7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Email + + + Password + + + Nulstil + + + Nulstil dit password. + + + Nulstil password + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx new file mode 100644 index 000000000..d3bdfe775 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Din adgangskode er nulstillet. Vær venlig + + + klik her for at logge ind + + + Bekræftelse af nulstilling af password + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.da.resx new file mode 100644 index 000000000..df4f26d2e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Applikations Adgang + + + Nej, tillad ikke + + + Personlige Informationer + + + Husk min beslutning + + + anmoder om din tilladelse + + + Fjern markeringen af ​​de tilladelser, du ikke ønsker at give. + + + Ja, tillad + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.da.resx new file mode 100644 index 000000000..9d2cdf8af --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Succes + + + Du har godkendt enheden + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx new file mode 100644 index 000000000..688fca8a3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Indtast den kode, der vises på din enhed + + + Bekræft + + + Bruger Kode + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx new file mode 100644 index 000000000..937fc675d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Applikations Adgang + + + Bekræft, at autorisations anmodningen angiver koden: + + + Nej, tillad ikke + + + Personlige Informationer + + + Husk min beslutning + + + anmoder om din tilladelse + + + Fjern markeringen af ​​de tilladelser, du ikke ønsker at give. + + + Ja, tillad + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.da.resx new file mode 100644 index 000000000..fbf8cdcf5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Claims + + + Clients + + + Egenskaber + + + Authentication cookie + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.da.resx new file mode 100644 index 000000000..f36248b0a --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + API Grants + + + Oprettet: + + + Udløber: + + + Identity Grants + + + Du har ikke givet adgang til nogen applikationer + + + Fjern adgang + + + Nedenfor er listen over applikationer, du har givet adgang til, og navnene på de ressourcer, de har adgang til. + + + Client Applikations Adgang + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx new file mode 100644 index 000000000..50f00a21c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Two-Factor Authentication + + + Skift password + + + Discovery Document + + + Gemte Grants + + + prøve eksempler + + + kildekode lager + + + Her er links til + + + Log ind + + + Min personlige data + + + Min profil + + + Welcome to Skoruba IdentityServer4 + + + Skoruba IdentityServer4 + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx new file mode 100644 index 000000000..f102e61fb --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Nyt Password + + + Gammelt Password + + + Skift password + + + Opdater Password + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx new file mode 100644 index 000000000..cb8a61a01 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sletning af disse data fjerner din konto permanent, og kan ikke gendannes. + + + Slet data, og luk min konto + + + Password + + + Slet personlige data + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx new file mode 100644 index 000000000..c90e247fd --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Deaktiver 2FA + + + Deaktivering af 2FA ændrer ikke nøglerne, der bruges i Authenticator App'en. Hvis du ønsker at ændre den nøgle, der bruges i en Authenticator App, skal du gøre det + + + nulstil dine Authenticator nøgler + + + Denne handling deaktiverer kun 2FA. + + + Deaktiver Two-Factor Authentication (2FA) + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx new file mode 100644 index 000000000..41791dea5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Download dine data + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx new file mode 100644 index 000000000..3aa85bc5c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Verifikationskode + + + Download en Two-Factor Authenticator App som f.eks. Microsoft Authenticator til + + + Google Authenticator for + + + Når du har scannet QR-koden eller indtastet nøglen ovenfor, vil din Two-Factor Authentication App give dig +                med en unik kode. Indtast koden i bekræftelsesfeltet nedenfor. + + + Scan QR-koden, eller indtast denne nøgle + + + i din Two-Factor Authentication App. Mellemrum og skriftstørrelse betyder ikke noget. + + + For at bruge en Authentication App skal du gennemføre følgende trin: + + + Konfigurer Authentication App + + + Bekræft + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx new file mode 100644 index 000000000..ea2eda9e8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Fjern + + + Registrerede login + + + Administrer dine eksterne logins + + + Tilføj en anden service for at logge ind. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx new file mode 100644 index 000000000..1abb4ecb6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Generer gendannelseskoder + + + Generering af nye gendannelseskoder ændrer ikke nøglerne, der bruges i Authentication Appen. Hvis du ønsker at ændre den nøgle, der bruges i Authentication Appen, skal du gøre det + + + Hvis du mister din enhed og ikke har gendannelseskoder, mister du adgang til din konto. + + + nulstil dine Authentication nøgler. + + + Gem disse koder et sikkert sted. + + + Generer Two-Factor Authentication (2FA) gendannelseskoder + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.da.resx new file mode 100644 index 000000000..f038fa672 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Land + + + Email + + + By + + + Fuldt navn + + + Telefonnummer + + + Post adresse + + + Profil URL + + + Region + + + Gem + + + Send bekræftelses email + + + Adresse + + + Profil + + + Brugernavn + + + Website URL + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx new file mode 100644 index 000000000..c2d2e520e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mislykket login med service. + + + Login Fejlede + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.da.resx new file mode 100644 index 000000000..a4eee1ebc --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet + + + Download + + + Din konto indeholder personlige data, som du har givet os. Denne side giver dig mulighed for at downloade eller slette disse data. + + + Personlig data + + + Sletning af disse data fjerner din konto permanent, og den kan ikke gendannes. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx new file mode 100644 index 000000000..3f43486be --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne proces deaktiverer 2FA, indtil du bekræfter din Authentication App. +        Hvis du ikke afslutter din Authentication App konfiguration, kan du miste adgang til din konto. + + + Nulstil Authentication nøgler + + + Hvis du nulstiller din Authentication nøgle, fungerer din Authentication App ikke før du konfigurerer den igen. + + + Nulstil Authentication nøgle + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.da.resx new file mode 100644 index 000000000..4119cc1c6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Du har ikke et lokalt brugernavn / password til dette websted. Tilføj en lokal konto, så du kan logge på uden et eksternt login. + + + Nyt Password + + + Vælg Password + + + Vælg dit Password + + + Vælg Password + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx new file mode 100644 index 000000000..fd803f9e1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hvis du mister din enhed og ikke har gendannelseskoder, mister du adgang til din konto. + + + Gem disse koder et sikkert sted. + + + Gendannelseskoder + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx new file mode 100644 index 000000000..24794b6c2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Authentication App + + + Authentication App + + + før du kan logge ind med en gendannelseskode + + + Deaktiver 2FA + + + Glem din browser + + + generere et nyt sæt gendannelseskoder + + + Du har ingen gendannelseskoder tilbage + + + Du har 1 gendannelseskode tilbage + + + gendannelseskoder tilbage + + + Nulstil Authentication App + + + Nulstil gendannelseskoder + + + Konfigurer Authentication App + + + Two-Factor Authentication (2FA) + + + Du kan generere et nyt sæt gendannelseskoder + + + Du har + + + Du skal + + + Du burde + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx new file mode 100644 index 000000000..448e64e8c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sprog: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx new file mode 100644 index 000000000..2d9c29b62 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer Admin + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.da.resx new file mode 100644 index 000000000..5c5d9a763 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Beklager, der opstod en fejl + + + Kalde Id: + + + Fejl + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.da.resx new file mode 100644 index 000000000..dfe0a0154 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Når det er afsluttet, kan du lukke denne fane + + + Du vender nu tilbage til applikationen. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx new file mode 100644 index 000000000..357086479 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Two-Factor Authentication + + + Skift password + + + Mine eksterne logins + + + Skoruba IdentityServer4 + + + © 2019 + + + Grants + + + Mine personlige data + + + Min profil + + + Menu + + + IdentityServer4 + + + Indstillinger + + + log ud + + + Skoruba IdentityServer4 + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx new file mode 100644 index 000000000..86aa64669 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (påkrævet) + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx new file mode 100644 index 000000000..25888c27d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Fejl + + \ No newline at end of file From da2937c800e091f59c38e701aae9ee947fc73081 Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sat, 9 Nov 2019 20:17:07 +0100 Subject: [PATCH 202/338] Fixed IdentityServerBaseUrl for Swagger API --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 240d80cd0..2c110e535 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,7 +33,7 @@ services: - 5000:80 environment: - "AdminApiConfiguration:IdentityRequireHttpsMetadata=false" - - "AdminApiConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io:5000" + - "AdminApiConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io" - "ConnectionStrings:ConfigurationDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings:PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings:IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" From cc31f309960e17411dd0efeea16f014e5ea1ecef Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sat, 9 Nov 2019 20:17:47 +0100 Subject: [PATCH 203/338] Added the correct Swagger redirect URI for seed --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 2c110e535..564a5d553 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,7 @@ services: - "AdminConfiguration:IdentityAdminRedirectUri=http://127.0.0.1.xip.io:9000/signin-oidc" - "AdminConfiguration:IdentityServerBaseUrl=http://127.0.0.1.xip.io" - "AdminConfiguration:IdentityRequireHttpsMetadata=false" + - "AdminConfiguration:IdentityAdminApiSwaggerUIRedirectUrl=http://127.0.0.1.xip.io:5000/swagger/oauth2-redirect.html" command: dotnet Skoruba.IdentityServer4.Admin.dll /seed depends_on: - db From 6317d2541a4f980b95473f1ba21d4bd6d5e30216 Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sat, 9 Nov 2019 20:18:38 +0100 Subject: [PATCH 204/338] Prevent ReSharper.Caches be part of docker build --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 3729ff0cd..a93dfd9e5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,5 +21,6 @@ **/obj **/secrets.dev.yaml **/values.dev.yaml +**/_ReSharper.Caches LICENSE README.md \ No newline at end of file From d75553c01272d273cba3a34fd14cd086483d0f9e Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sun, 10 Nov 2019 18:37:41 +0100 Subject: [PATCH 205/338] Fix pagination of audit logging --- .../AuditLogging/ApiAuditSubject.cs | 2 +- .../Repositories/AuditLogRepository.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs index 87c070266..efae29aab 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs @@ -15,7 +15,7 @@ public ApiAuditSubject(IHttpContextAccessor accessor, AuditLoggingConfiguration var clientIdClaim = accessor.HttpContext.User.FindFirst(auditLoggingConfiguration.ClientIdClaim); SubjectIdentifier = subClaim == null ? clientIdClaim.Value : subClaim.Value; - SubjectName = subClaim == null ? clientIdClaim.Value : nameClaim.Value; + SubjectName = subClaim == null ? clientIdClaim.Value : nameClaim?.Value; SubjectType = subClaim == null ? AuditSubjectTypes.Machine : AuditSubjectTypes.User; SubjectAdditionalData = new diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs index fe18dbbea..eb612fff6 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/AuditLogRepository.cs @@ -26,13 +26,13 @@ public async Task> GetAsync(string @event, string source, s var pagedList = new PagedList(); var auditLogs = await DbContext.AuditLog - .PageBy(x => x.Id, page, pageSize) .WhereIf(!string.IsNullOrEmpty(subjectIdentifier), log => log.SubjectIdentifier.Contains(subjectIdentifier)) .WhereIf(!string.IsNullOrEmpty(subjectName), log => log.SubjectName.Contains(subjectName)) .WhereIf(!string.IsNullOrEmpty(@event), log => log.Event.Contains(@event)) .WhereIf(!string.IsNullOrEmpty(source), log => log.Source.Contains(source)) .WhereIf(!string.IsNullOrEmpty(category), log => log.Category.Contains(category)) .WhereIf(created.HasValue, log => log.Created.Date == created.Value.Date) + .PageBy(x => x.Id, page, pageSize) .ToListAsync(); pagedList.Data.AddRange(auditLogs); From d7ec14e17484cac9e0dea8aad0a0ed772cd08dd2 Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sun, 10 Nov 2019 21:26:56 +0100 Subject: [PATCH 206/338] Added seed argument during debugging with dcproj in VS2019 --- docker-compose.dcproj | 3 +++ docker-compose.vs.debug.yml | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 docker-compose.vs.debug.yml diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 4e83043c0..66680f2bc 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -9,6 +9,9 @@ skoruba.identityserver4.admin + + docker-compose.yml + docker-compose.yml diff --git a/docker-compose.vs.debug.yml b/docker-compose.vs.debug.yml new file mode 100644 index 000000000..6843273d7 --- /dev/null +++ b/docker-compose.vs.debug.yml @@ -0,0 +1,16 @@ +version: '3.4' + +services: + skoruba.identityserver4.admin: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + labels: + com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages "bin/Debug/netcoreapp2.2/Skoruba.IdentityServer4.Admin.dll" /seed' + + skoruba.identityserver4.admin.api: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + + skoruba.identityserver4.sts.identity: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro From 957625796dfa7e4fd293cf838c6b90e4dfa85e9f Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sun, 10 Nov 2019 22:49:13 +0100 Subject: [PATCH 207/338] Upgraded docker files to .NET Core 3.0 and added missing migration for AdminAuditLog --- docker-compose.vs.debug.yml | 2 +- docker-compose.yml | 1 + .../Dockerfile | 4 +- src/Skoruba.IdentityServer4.Admin/Dockerfile | 4 +- .../Helpers/DbMigrationHelpers.cs | 16 +++-- .../20191110214351_AuditLogInit.Designer.cs | 68 +++++++++++++++++++ .../20191110214351_AuditLogInit.cs | 39 +++++++++++ .../AdminAuditLogDbContextModelSnapshot.cs | 66 ++++++++++++++++++ src/Skoruba.IdentityServer4.Admin/Program.cs | 4 +- .../Dockerfile | 4 +- 10 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs diff --git a/docker-compose.vs.debug.yml b/docker-compose.vs.debug.yml index 6843273d7..93f913cc0 100644 --- a/docker-compose.vs.debug.yml +++ b/docker-compose.vs.debug.yml @@ -5,7 +5,7 @@ services: volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro labels: - com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages "bin/Debug/netcoreapp2.2/Skoruba.IdentityServer4.Admin.dll" /seed' + com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages "bin/Debug/netcoreapp3.0/Skoruba.IdentityServer4.Admin.dll" /seed' skoruba.identityserver4.admin.api: volumes: diff --git a/docker-compose.yml b/docker-compose.yml index 38bf03e94..c662c2dfe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,7 @@ services: - "ConnectionStrings__PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings__IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings__AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings__AdminAuditLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "AdminConfiguration__IdentityAdminBaseUrl=http://127.0.0.1.xip.io:9000" - "AdminConfiguration__IdentityAdminRedirectUri=http://127.0.0.1.xip.io:9000/signin-oidc" - "AdminConfiguration__IdentityServerBaseUrl=http://127.0.0.1.xip.io" diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile index d19b39113..6b7f9c53b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile +++ b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj", "src/Skoruba.IdentityServer4.Admin.Api/"] COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] diff --git a/src/Skoruba.IdentityServer4.Admin/Dockerfile b/src/Skoruba.IdentityServer4.Admin/Dockerfile index 92d6b6658..60fd7be88 100644 --- a/src/Skoruba.IdentityServer4.Admin/Dockerfile +++ b/src/Skoruba.IdentityServer4.Admin/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj", "src/Skoruba.IdentityServer4.Admin/"] COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index c04b2a6fc..1f486831f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -3,11 +3,12 @@ using System.Threading.Tasks; using IdentityModel; using IdentityServer4.EntityFramework.Mappers; -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; @@ -20,27 +21,29 @@ public static class DbMigrationHelpers /// https://github.com/skoruba/IdentityServer4.Admin#ef-core--data-access /// /// - public static async Task EnsureSeedData(IHost host) + public static async Task EnsureSeedData(IHost host) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLogDbContext: DbContext, IAuditLoggingDbContext where TUser : IdentityUser, new() where TRole : IdentityRole, new() { using (var serviceScope = host.Services.CreateScope()) { var services = serviceScope.ServiceProvider; - await EnsureDatabasesMigrated(services); + await EnsureDatabasesMigrated(services); await EnsureSeedData(services); } } - public static async Task EnsureDatabasesMigrated(IServiceProvider services) + public static async Task EnsureDatabasesMigrated(IServiceProvider services) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext where TConfigurationDbContext : DbContext where TLogDbContext : DbContext + where TAuditLogDbContext: DbContext { using (var scope = services.GetRequiredService().CreateScope()) { @@ -63,6 +66,11 @@ public static async Task EnsureDatabasesMigrated()) + { + await context.Database.MigrateAsync(); + } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs new file mode 100644 index 000000000..6b686f1fc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs @@ -0,0 +1,68 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + [Migration("20191110214351_AuditLogInit")] + partial class AuditLogInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Action") + .HasColumnType("nvarchar(max)"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("Event") + .HasColumnType("nvarchar(max)"); + + b.Property("Source") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectAdditionalData") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectName") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectType") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs new file mode 100644 index 000000000..0b65d0251 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging +{ + public partial class AuditLogInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AuditLog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Event = table.Column(nullable: true), + Source = table.Column(nullable: true), + Category = table.Column(nullable: true), + SubjectIdentifier = table.Column(nullable: true), + SubjectName = table.Column(nullable: true), + SubjectType = table.Column(nullable: true), + SubjectAdditionalData = table.Column(nullable: true), + Action = table.Column(nullable: true), + Data = table.Column(nullable: true), + Created = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AuditLog", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AuditLog"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..d8b7fb9ba --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs @@ -0,0 +1,66 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + partial class AdminAuditLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Action") + .HasColumnType("nvarchar(max)"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("Event") + .HasColumnType("nvarchar(max)"); + + b.Property("Source") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectAdditionalData") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectName") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectType") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index 628047df5..162a8b6e2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -22,10 +22,10 @@ public static async Task Main(string[] args) var host = CreateHostBuilder(args).Build(); // Uncomment this to seed upon startup, alternatively pass in `dotnet run /seed` to seed using CLI - // await DbMigrationHelpers.EnsureSeedData(host); + // await DbMigrationHelpers.EnsureSeedData(host); if (seed) { - await DbMigrationHelpers.EnsureSeedData(host); + await DbMigrationHelpers.EnsureSeedData(host); } host.Run(); diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile index 28fa50bf5..8a349c2ec 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile +++ b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj", "src/Skoruba.IdentityServer4.STS.Identity/"] COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] From 8a299dd168f7a04acd8a1a2a4db3990ece2cb0e4 Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Sun, 10 Nov 2019 23:27:17 +0100 Subject: [PATCH 208/338] Added docker-compose.vs.release.yml --- docker-compose.vs.release.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docker-compose.vs.release.yml diff --git a/docker-compose.vs.release.yml b/docker-compose.vs.release.yml new file mode 100644 index 000000000..93f913cc0 --- /dev/null +++ b/docker-compose.vs.release.yml @@ -0,0 +1,16 @@ +version: '3.4' + +services: + skoruba.identityserver4.admin: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + labels: + com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages "bin/Debug/netcoreapp3.0/Skoruba.IdentityServer4.Admin.dll" /seed' + + skoruba.identityserver4.admin.api: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + + skoruba.identityserver4.sts.identity: + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro From 9912d8c1706845cbfc29fdd9fd3ea63ae5ffca2b Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Mon, 11 Nov 2019 03:56:49 +0100 Subject: [PATCH 209/338] Removed AdminAutoLog migration as they are to be generated by the enduser --- .../20191110214351_AuditLogInit.Designer.cs | 68 ------------------- .../20191110214351_AuditLogInit.cs | 39 ----------- .../AdminAuditLogDbContextModelSnapshot.cs | 66 ------------------ 3 files changed, 173 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs deleted file mode 100644 index 6b686f1fc..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.Designer.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; - -namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging -{ - [DbContext(typeof(AdminAuditLogDbContext))] - [Migration("20191110214351_AuditLogInit")] - partial class AuditLogInit - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("Action") - .HasColumnType("nvarchar(max)"); - - b.Property("Category") - .HasColumnType("nvarchar(max)"); - - b.Property("Created") - .HasColumnType("datetime2"); - - b.Property("Data") - .HasColumnType("nvarchar(max)"); - - b.Property("Event") - .HasColumnType("nvarchar(max)"); - - b.Property("Source") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectAdditionalData") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectIdentifier") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectName") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectType") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.ToTable("AuditLog"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs deleted file mode 100644 index 0b65d0251..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/20191110214351_AuditLogInit.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging -{ - public partial class AuditLogInit : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AuditLog", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Event = table.Column(nullable: true), - Source = table.Column(nullable: true), - Category = table.Column(nullable: true), - SubjectIdentifier = table.Column(nullable: true), - SubjectName = table.Column(nullable: true), - SubjectType = table.Column(nullable: true), - SubjectAdditionalData = table.Column(nullable: true), - Action = table.Column(nullable: true), - Data = table.Column(nullable: true), - Created = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AuditLog", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AuditLog"); - } - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs deleted file mode 100644 index d8b7fb9ba..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Migrations/AdminAuditLogging/AdminAuditLogDbContextModelSnapshot.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; - -namespace Skoruba.IdentityServer4.Admin.Migrations.AdminAuditLogging -{ - [DbContext(typeof(AdminAuditLogDbContext))] - partial class AdminAuditLogDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("Action") - .HasColumnType("nvarchar(max)"); - - b.Property("Category") - .HasColumnType("nvarchar(max)"); - - b.Property("Created") - .HasColumnType("datetime2"); - - b.Property("Data") - .HasColumnType("nvarchar(max)"); - - b.Property("Event") - .HasColumnType("nvarchar(max)"); - - b.Property("Source") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectAdditionalData") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectIdentifier") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectName") - .HasColumnType("nvarchar(max)"); - - b.Property("SubjectType") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.ToTable("AuditLog"); - }); -#pragma warning restore 612, 618 - } - } -} From 321a3dcabaf43dfac12618e4e8ba0ed95f0d8f34 Mon Sep 17 00:00:00 2001 From: Brave Cobra Date: Mon, 11 Nov 2019 05:38:29 +0100 Subject: [PATCH 210/338] Allow build of windows containers as well --- src/Skoruba.IdentityServer4.Admin.Api/Dockerfile | 4 ++-- src/Skoruba.IdentityServer4.Admin/Dockerfile | 4 ++-- src/Skoruba.IdentityServer4.STS.Identity/Dockerfile | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile index 6b7f9c53b..7a61745a1 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile +++ b/src/Skoruba.IdentityServer4.Admin.Api/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj", "src/Skoruba.IdentityServer4.Admin.Api/"] COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] diff --git a/src/Skoruba.IdentityServer4.Admin/Dockerfile b/src/Skoruba.IdentityServer4.Admin/Dockerfile index 60fd7be88..0a4980a0c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Dockerfile +++ b/src/Skoruba.IdentityServer4.Admin/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj", "src/Skoruba.IdentityServer4.Admin/"] COPY ["src/Skoruba.IdentityServer4.Admin.BusinessLogic/Skoruba.IdentityServer4.Admin.BusinessLogic.csproj", "src/Skoruba.IdentityServer4.Admin.BusinessLogic/"] diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile index 8a349c2ec..127e992c1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile +++ b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj", "src/Skoruba.IdentityServer4.STS.Identity/"] COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] From 95a5c016d7b1cbf2f36bbcb02d4d2aedcded3b20 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 12 Nov 2019 12:50:24 +0100 Subject: [PATCH 211/338] Fix #389 --- .../Controllers/AccountController.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs index 3f8a345d1..9bf4ca9d3 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Controllers/AccountController.cs @@ -359,6 +359,14 @@ public async Task ExternalLoginCallback(string returnUrl = null, { return RedirectToLocal(returnUrl); } + if (result.RequiresTwoFactor) + { + return RedirectToAction(nameof(LoginWith2fa), new { ReturnUrl = returnUrl }); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } // If the user does not have an account, then ask the user to create an account. ViewData["ReturnUrl"] = returnUrl; From 523b57ce547e3e8a1e2bee424757063e7721b042 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 12 Nov 2019 12:51:26 +0100 Subject: [PATCH 212/338] Fix #397 --- .../Services/IdentityService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs index 92e116e9d..4dcc2d41f 100644 --- a/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs +++ b/src/Skoruba.IdentityServer4.Admin.BusinessLogic.Identity/Services/IdentityService.cs @@ -236,12 +236,12 @@ public virtual async Task CreateUserRoleAsync(TUserRolesDto role { var identityResult = await IdentityRepository.CreateUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString()); + await AuditEventLogger.LogEventAsync(new UserRoleSavedEvent(role)); + if (!identityResult.Errors.Any()) return identityResult; var userRolesDto = await BuildUserRolesViewModel(role.UserId, 1); - - await AuditEventLogger.LogEventAsync(new UserRoleSavedEvent(role)); - + return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userRolesDto); } From 813fa9dfc6e12a199ce279b6a3ac6c980030628a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Tue, 12 Nov 2019 12:57:24 +0100 Subject: [PATCH 213/338] Add docker support --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d26f0937..8bb598bf0 100644 --- a/README.md +++ b/README.md @@ -460,11 +460,11 @@ It is possible to define the configuration according the client type - by defaul - [x] IdentityServer4 - [x] Asp.Net Core Identity - [x] Add swagger support -[x] Add audit logs to track changes ([#61](https://github.com/skoruba/IdentityServer4.Admin/issues/61)) - +- [x] Add audit logs to track changes ([#61](https://github.com/skoruba/IdentityServer4.Admin/issues/61)) +- [x] Docker support ([#121](https://github.com/skoruba/IdentityServer4.Admin/issues/121)) + ### 2.0.0: -- [ ] Docker support ([#121](https://github.com/skoruba/IdentityServer4.Admin/issues/121)) - [ ] Create a project template using dotnet CLI - `dotnet new template` - [ ] Second template: The administration of the IdentityServer4 (without Asp.Net Core Identity) ([#79](https://github.com/skoruba/IdentityServer4.Admin/issues/79)) From a6b73e6ba96d2a6fefa549062182809bf6f5860e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Tue, 12 Nov 2019 14:26:22 +0100 Subject: [PATCH 214/338] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 8bb598bf0..b57a07c22 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ The following Gulp commands are available: - `AdminLogDbContext`: for logging - `IdentityServerConfigurationDbContext`: for IdentityServer configuration store - `IdentityServerPersistedGrantDbContext`: for IdentityServer operational store + - `AuditLoggingDbContext`: for Audit Logging - Run entity framework migrations: @@ -310,6 +311,9 @@ In STS project - in `appsettings.json`: - Russian - Persian - Swedish + - Danish + - Spanish + - French #### Feel free to send a PR with your translation. :blush: @@ -449,6 +453,9 @@ It is possible to define the configuration according the client type - by defaul - [x] Russian - [x] Persian - [x] Swedish + - [x] Danish + - [x] Spanish + - [x] French - [x] Manage profile - [x] Password reset - [x] Link account to an external provider (example with Github) From 64c6fad264efe58f9c0010a68fc6cf754eb99487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Tue, 12 Nov 2019 15:13:03 +0100 Subject: [PATCH 215/338] Update contribution section I am preparing new release of Admin UI and your changes (which are currently in dev branch) will be in this release. Thank you very much for your great contribution: @ChrisSzabo , @aiscrim , @HrDahl , @killerrin , @bravecobra , @sabitertan , @rherlt , @b0 , @DrQwertySilence , @nlz242 , @Aegide , @LobsterBandit , @mperk I added your profile link into contribution section - in README. Cc @TomasHubelbauer @xmichaelx --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b57a07c22..9b62d8e89 100644 --- a/README.md +++ b/README.md @@ -514,7 +514,9 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds | [
    Jan Škoruba](https://github.com/skoruba)
    💻 💬 📖 💡 🤔 | [
    Tomáš Hübelbauer](https://github.com/TomasHubelbauer)
    💻 👀 📖 🤔 | [
    Michał Drzał ](https://github.com/xmichaelx)
    💻 👀 📖 💡 🤔 | [
    cerginio ](https://github.com/cerginio)
    💻 🐛 💡 🤔 | [
    Sven Dummis ](https://github.com/svendu)
    📖| [
    Seaear](https://github.com/Seaear)
    💻 🌍| | :---: | :---: | :---: | :---: | :---: | :---: | |[
    Rune Antonsen ](https://github.com/ruant)
    🐛|[
    Sindre Njøsen ](https://github.com/Sindrenj)
    💻|[
    Alevtina Brown ](https://github.com/alev7ina)
    🌍|[
    Brice ](https://github.com/Brice-xCIT)
    💻|[
    TheEvilPenguin ](https://github.com/TheEvilPenguin)
    💻|[
    Saeed Rahmani ](https://github.com/saeedrahmo)
    🌍| -|[
    Andy Yu ](https://github.com/Zyxious)
    🌍| +|[
    Andy Yu ](https://github.com/Zyxious)
    🌍|[
    ChrisSzabo ](https://github.com/ChrisSzabo)
    💻|[
    aiscrim ](https://github.com/aiscrim)
    💻 💡 🤔|[
    HrDahl ](https://github.com/HrDahl)
    🌍|[
    Andrew Godfroy ](https://github.com/killerrin)
    📖|[
    bravecobra ](https://github.com/bravecobra)
    💻| +|[
    Sabit Igde ](https://github.com/sabitertan)
    💻|[
    Rico Herlt ](https://github.com/rherlt)
    💻|[
    b0 ](https://github.com/b0)
    💻|[
    DrQwertySilence ](https://github.com/DrQwertySilence)
    🌍|[
    Carl Quirion ](https://github.com/nlz242)
    💻|[
    Aegide ](https://github.com/Aegide)
    🌍| +|[
    LobsterBandit ](https://github.com/LobsterBandit)
    💻|[
    Mehmet Perk ](https://github.com/mperk)
    💻| This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. From 88f81f5b9d28c6ce92a42c2cdf38595fcfa85d0a Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 12 Nov 2019 15:55:30 +0100 Subject: [PATCH 216/338] Fix GenericControllerLocalizer --- .../Localization/GenericControllerLocalizer.cs | 10 ---------- .../Localization/IGenericControllerLocalizer.cs | 9 +++++++-- .../Helpers/Localization/GenericServiceLocalizer.cs | 10 ---------- .../Localization/IGenericControllerLocalizer.cs | 11 ++++++++--- .../Helpers/Localization/GenericServiceLocalizer.cs | 10 ---------- .../Localization/IGenericControllerLocalizer.cs | 11 ++++++++--- 6 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/GenericControllerLocalizer.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/GenericControllerLocalizer.cs index ac2506a39..c51916eed 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/GenericControllerLocalizer.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/GenericControllerLocalizer.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Reflection; using Microsoft.Extensions.Localization; @@ -32,13 +31,6 @@ public GenericControllerLocalizer(IStringLocalizerFactory factory) _localizer = factory.Create(baseName, assemblyName); } - /// - public virtual IStringLocalizer WithCulture(CultureInfo culture) - { - return _localizer.WithCulture(culture); - } - - /// public virtual LocalizedString this[string name] { get @@ -49,7 +41,6 @@ public virtual LocalizedString this[string name] } } - /// public virtual LocalizedString this[string name, params object[] arguments] { get @@ -60,7 +51,6 @@ public virtual LocalizedString this[string name] } } - /// public IEnumerable GetAllStrings(bool includeParentCultures) { return _localizer.GetAllStrings(includeParentCultures); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/IGenericControllerLocalizer.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/IGenericControllerLocalizer.cs index 1635c46a9..20bf4a325 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/IGenericControllerLocalizer.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/Localization/IGenericControllerLocalizer.cs @@ -1,9 +1,14 @@ -using Microsoft.Extensions.Localization; +using System.Collections.Generic; +using Microsoft.Extensions.Localization; namespace Skoruba.IdentityServer4.Admin.Api.Helpers.Localization { - public interface IGenericControllerLocalizer : IStringLocalizer + public interface IGenericControllerLocalizer { + LocalizedString this[string name] { get; } + LocalizedString this[string name, params object[] arguments] { get; } + + IEnumerable GetAllStrings(bool includeParentCultures); } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/GenericServiceLocalizer.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/GenericServiceLocalizer.cs index f2fe80cec..05976bf30 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/GenericServiceLocalizer.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/GenericServiceLocalizer.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Reflection; using Microsoft.Extensions.Localization; @@ -32,13 +31,6 @@ public GenericControllerLocalizer(IStringLocalizerFactory factory) _localizer = factory.Create(baseName, assemblyName); } - /// - public virtual IStringLocalizer WithCulture(CultureInfo culture) - { - return _localizer.WithCulture(culture); - } - - /// public virtual LocalizedString this[string name] { get @@ -49,7 +41,6 @@ public virtual LocalizedString this[string name] } } - /// public virtual LocalizedString this[string name, params object[] arguments] { get @@ -60,7 +51,6 @@ public virtual LocalizedString this[string name] } } - /// public IEnumerable GetAllStrings(bool includeParentCultures) { return _localizer.GetAllStrings(includeParentCultures); diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/IGenericControllerLocalizer.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/IGenericControllerLocalizer.cs index f84efbc47..5419cb4e4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/IGenericControllerLocalizer.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Localization/IGenericControllerLocalizer.cs @@ -1,9 +1,14 @@ -using Microsoft.Extensions.Localization; +using System.Collections.Generic; +using Microsoft.Extensions.Localization; namespace Skoruba.IdentityServer4.Admin.Helpers.Localization { - public interface IGenericControllerLocalizer : IStringLocalizer + public interface IGenericControllerLocalizer { - + LocalizedString this[string name] { get; } + + LocalizedString this[string name, params object[] arguments] { get; } + + IEnumerable GetAllStrings(bool includeParentCultures); } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs index d31450b76..985f47588 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Reflection; using Microsoft.Extensions.Localization; @@ -32,13 +31,6 @@ public GenericControllerLocalizer(IStringLocalizerFactory factory) _localizer = factory.Create(baseName, assemblyName); } - /// - public virtual IStringLocalizer WithCulture(CultureInfo culture) - { - return _localizer.WithCulture(culture); - } - - /// public virtual LocalizedString this[string name] { get @@ -49,7 +41,6 @@ public virtual LocalizedString this[string name] } } - /// public virtual LocalizedString this[string name, params object[] arguments] { get @@ -60,7 +51,6 @@ public virtual LocalizedString this[string name] } } - /// public IEnumerable GetAllStrings(bool includeParentCultures) { return _localizer.GetAllStrings(includeParentCultures); diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs index 80f417cba..0b24c3571 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs @@ -1,9 +1,14 @@ -using Microsoft.Extensions.Localization; +using System.Collections.Generic; +using Microsoft.Extensions.Localization; namespace Skoruba.IdentityServer4.STS.Identity.Helpers.Localization { - public interface IGenericControllerLocalizer : IStringLocalizer + public interface IGenericControllerLocalizer { - + LocalizedString this[string name] { get; } + + LocalizedString this[string name, params object[] arguments] { get; } + + IEnumerable GetAllStrings(bool includeParentCultures); } } \ No newline at end of file From b6ae3357ff4329eff8eda1a1a370645e8ef80ac4 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Tue, 12 Nov 2019 16:59:23 +0100 Subject: [PATCH 217/338] Polish CultureConfiguration --- .../Configuration/CultureConfiguration.cs | 7 +- .../Helpers/StartupHelpers.cs | 15 +- .../appsettings.json | 392 +++++++++--------- .../Configuration/CultureConfiguration.cs | 7 +- .../Helpers/StartupHelpers.cs | 17 +- .../appsettings.json | 16 +- 6 files changed, 223 insertions(+), 231 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs index 1d13c56f8..c359ec868 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs @@ -1,13 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; namespace Skoruba.IdentityServer4.Admin.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "es" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "es", "da" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index abfa9d8c8..f1ca89d10 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -421,18 +421,17 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) // otherwise use all the available cultures var supportedCultureCodes = (cultureConfiguration?.Cultures?.Count > 0 ? cultureConfiguration.Cultures.Intersect(CultureConfiguration.AvailableCultures) : - CultureConfiguration.AvailableCultures); - if (supportedCultureCodes.Count() == 0) - supportedCultureCodes = CultureConfiguration.AvailableCultures; - var supportedCultures = supportedCultureCodes - .Select(c => new CultureInfo(c)).ToList(); + CultureConfiguration.AvailableCultures).ToArray(); + + if (!supportedCultureCodes.Any()) supportedCultureCodes = CultureConfiguration.AvailableCultures; + var supportedCultures = supportedCultureCodes.Select(c => new CultureInfo(c)).ToList(); // If the default culture is specified use it, otherwise use CultureConfiguration.DefaultRequestCulture ("en") - string defaultCultureCode = string.IsNullOrEmpty(cultureConfiguration?.DefaultCulture) ? + var defaultCultureCode = string.IsNullOrEmpty(cultureConfiguration?.DefaultCulture) ? CultureConfiguration.DefaultRequestCulture : cultureConfiguration?.DefaultCulture; + // If the default culture is not among the supported cultures, use the first supported culture as default - if (!supportedCultureCodes.Contains(defaultCultureCode)) - defaultCultureCode = supportedCultureCodes.FirstOrDefault(); + if (!supportedCultureCodes.Contains(defaultCultureCode)) defaultCultureCode = supportedCultureCodes.FirstOrDefault(); opts.DefaultRequestCulture = new RequestCulture(defaultCultureCode); opts.SupportedCultures = supportedCultures; diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 510fabbdf..2f4cb05c1 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -1,213 +1,213 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" - }, - "AdminConfiguration": { - "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", - "IdentityServerBaseUrl": "http://localhost:5000", - "IdentityAdminCookieName": "IdentityServerAdmin", - "IdentityAdminCookieExpiresUtcHours": 12, - "RequireHttpsMetadata": false, - "TokenValidationClaimName": "name", - "TokenValidationClaimRole": "role", - "ClientId": "skoruba_identity_admin", - "ClientSecret": "skoruba_admin_client_secret", - "OidcResponseType": "code id_token", - "Scopes": [ - "openid", - "profile", - "email", - "roles" - ], - "AdministrationRole": "SkorubaIdentityAdminAdministrator" + }, + "AdminConfiguration": { + "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", + "IdentityServerBaseUrl": "http://localhost:5000", + "IdentityAdminCookieName": "IdentityServerAdmin", + "IdentityAdminCookieExpiresUtcHours": 12, + "RequireHttpsMetadata": false, + "TokenValidationClaimName": "name", + "TokenValidationClaimRole": "role", + "ClientId": "skoruba_identity_admin", + "ClientSecret": "skoruba_admin_client_secret", + "OidcResponseType": "code id_token", + "Scopes": [ + "openid", + "profile", + "email", + "roles" + ], + "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, "AuditLoggingConfiguration": { "Source": "IdentityServer.Admin.Web", "SubjectIdentifierClaim": "sub", "SubjectNameClaim": "name", "IncludeFormVariables": false - }, - "CultureConfiguration": { - "Cultures": [], - "DefaultCulture": null - }, - "Serilog": { - "MinimumLevel": { - "Default": "Error", - "Override": { - "Skoruba": "Information" - } }, - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Log\\skoruba_admin.txt", - "rollingInterval": "Day" - } - }, - { - "Name": "MSSqlServer", - "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "tableName": "Log", - "columnOptionsSection": { - "addStandardColumns": [ "LogEvent" ], - "removeStandardColumns": [ "Properties" ] - } - } - } - ] - }, - "IdentityData": { - "Roles": [ - { - "Name": "SkorubaIdentityAdminAdministrator" - } - ], - "Users": [ - { - "Username": "admin", - "Password": "Pa$$word123", - "Email": "admin@skoruba.com", - "Roles": [ - "SkorubaIdentityAdminAdministrator" - ], - "Claims": [ - { - "Type": "name", - "Value": "admin" - } - ] - } - ] - }, - "IdentityServerData": { - "IdentityResources": [ - { - "Name": "roles", - "Enabled": true, - "DisplayName": "Roles", - "UserClaims": [ - "role" - ] - }, - { - "Name": "openid", - "Enabled": true, - "Required": true, - "DisplayName": "Your user identifier", - "UserClaims": [ - "sub" - ] - }, - { - "Name": "profile", - "Enabled": true, - "DisplayName": "User profile", - "Description": "Your user profile information (first name, last name, etc.)", - "Emphasize": true, - "UserClaims": [ - "name", - "family_name", - "given_name", - "middle_name", - "nickname", - "preferred_username", - "profile", - "picture", - "website", - "gender", - "birthdate", - "zoneinfo", - "locale", - "updated_at" - ] - }, - { - "Name": "email", - "Enabled": true, - "DisplayName": "Your email address", - "Emphasize": true, - "UserClaims": [ - "email", - "email_verified" - ] - }, - { - "Name": "address", - "Enabled": true, - "DisplayName": "Your address", - "Emphasize": true, - "UserClaims": [ - "address" - ] - } - ], - "ApiResources": [ - { - "Name": "skoruba_identity_admin_api", - "Scopes": [ - { - "Name": "skoruba_identity_admin_api", - "DisplayName": "skoruba_identity_admin_api", - "Required": true, - "UserClaims": [ - "role" - ] - } + "CultureConfiguration": { + "Cultures": [ "en", "fa", "fr", "ru", "sv", "zh", "es", "da" ], + "DefaultCulture": "en" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Error", + "Override": { + "Skoruba": "Information" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Log\\skoruba_admin.txt", + "rollingInterval": "Day" + } + }, + { + "Name": "MSSqlServer", + "Args": { + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], + "removeStandardColumns": [ "Properties" ] + } + } + } ] - } - ], - "Clients": [ - { - "ClientId": "skoruba_identity_admin", - "ClientName": "skoruba_identity_admin", - "ClientUri": "http://localhost:9000", - "AllowedGrantTypes": [ - "hybrid" - ], - "ClientSecrets": [ - { - "Value": "skoruba_admin_client_secret" - } - ], - "RedirectUris": [ - "http://localhost:9000/signin-oidc" - ], - "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", - "PostLogoutRedirectUris": [ - "http://localhost:9000/signout-callback-oidc" - ], - "AllowedCorsOrigins": [ - "http://localhost:9000" + }, + "IdentityData": { + "Roles": [ + { + "Name": "SkorubaIdentityAdminAdministrator" + } ], - "AllowedScopes": [ - "openid", - "email", - "profile", - "roles" + "Users": [ + { + "Username": "admin", + "Password": "Pa$$word123", + "Email": "admin@skoruba.com", + "Roles": [ + "SkorubaIdentityAdminAdministrator" + ], + "Claims": [ + { + "Type": "name", + "Value": "admin" + } + ] + } ] - }, - { - "ClientId": "skoruba_identity_admin_api_swaggerui", - "ClientName": "skoruba_identity_admin_api_swaggerui", - "AllowedGrantTypes": [ - "implicit" - ], - "RedirectUris": [ - "http://localhost:5001/swagger/oauth2-redirect.html" + }, + "IdentityServerData": { + "IdentityResources": [ + { + "Name": "roles", + "Enabled": true, + "DisplayName": "Roles", + "UserClaims": [ + "role" + ] + }, + { + "Name": "openid", + "Enabled": true, + "Required": true, + "DisplayName": "Your user identifier", + "UserClaims": [ + "sub" + ] + }, + { + "Name": "profile", + "Enabled": true, + "DisplayName": "User profile", + "Description": "Your user profile information (first name, last name, etc.)", + "Emphasize": true, + "UserClaims": [ + "name", + "family_name", + "given_name", + "middle_name", + "nickname", + "preferred_username", + "profile", + "picture", + "website", + "gender", + "birthdate", + "zoneinfo", + "locale", + "updated_at" + ] + }, + { + "Name": "email", + "Enabled": true, + "DisplayName": "Your email address", + "Emphasize": true, + "UserClaims": [ + "email", + "email_verified" + ] + }, + { + "Name": "address", + "Enabled": true, + "DisplayName": "Your address", + "Emphasize": true, + "UserClaims": [ + "address" + ] + } ], - "AllowedScopes": [ - "skoruba_identity_admin_api" + "ApiResources": [ + { + "Name": "skoruba_identity_admin_api", + "Scopes": [ + { + "Name": "skoruba_identity_admin_api", + "DisplayName": "skoruba_identity_admin_api", + "Required": true, + "UserClaims": [ + "role" + ] + } + ] + } ], - "AllowAccessTokensViaBrowser": true + "Clients": [ + { + "ClientId": "skoruba_identity_admin", + "ClientName": "skoruba_identity_admin", + "ClientUri": "http://localhost:9000", + "AllowedGrantTypes": [ + "hybrid" + ], + "ClientSecrets": [ + { + "Value": "skoruba_admin_client_secret" + } + ], + "RedirectUris": [ + "http://localhost:9000/signin-oidc" + ], + "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", + "PostLogoutRedirectUris": [ + "http://localhost:9000/signout-callback-oidc" + ], + "AllowedCorsOrigins": [ + "http://localhost:9000" + ], + "AllowedScopes": [ + "openid", + "email", + "profile", + "roles" + ] + }, + { + "ClientId": "skoruba_identity_admin_api_swaggerui", + "ClientName": "skoruba_identity_admin_api_swaggerui", + "AllowedGrantTypes": [ + "implicit" + ], + "RedirectUris": [ + "http://localhost:5001/swagger/oauth2-redirect.html" + ], + "AllowedScopes": [ + "skoruba_identity_admin_api" + ], + "AllowAccessTokensViaBrowser": true - } - ] - } + } + ] + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs index cf96c3fa5..b604ab3f9 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs @@ -1,13 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; namespace Skoruba.IdentityServer4.STS.Identity.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "da" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index ec454350f..e2865c91e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -44,7 +44,7 @@ public static void AddMvcWithLocalization(this IServiceCollection s services.AddLocalization(opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }); services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - + services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); @@ -66,18 +66,17 @@ public static void AddMvcWithLocalization(this IServiceCollection s // otherwise use all the available cultures var supportedCultureCodes = (cultureConfiguration?.Cultures?.Count > 0 ? cultureConfiguration.Cultures.Intersect(CultureConfiguration.AvailableCultures) : - CultureConfiguration.AvailableCultures); - if (supportedCultureCodes.Count() == 0) - supportedCultureCodes = CultureConfiguration.AvailableCultures; - var supportedCultures = supportedCultureCodes - .Select(c => new CultureInfo(c)).ToList(); + CultureConfiguration.AvailableCultures).ToArray(); + + if (!supportedCultureCodes.Any()) supportedCultureCodes = CultureConfiguration.AvailableCultures; + var supportedCultures = supportedCultureCodes.Select(c => new CultureInfo(c)).ToList(); // If the default culture is specified use it, otherwise use CultureConfiguration.DefaultRequestCulture ("en") - string defaultCultureCode = string.IsNullOrEmpty(cultureConfiguration?.DefaultCulture) ? + var defaultCultureCode = string.IsNullOrEmpty(cultureConfiguration?.DefaultCulture) ? CultureConfiguration.DefaultRequestCulture : cultureConfiguration?.DefaultCulture; + // If the default culture is not among the supported cultures, use the first supported culture as default - if (!supportedCultureCodes.Contains(defaultCultureCode)) - defaultCultureCode = supportedCultureCodes.FirstOrDefault(); + if (!supportedCultureCodes.Contains(defaultCultureCode)) defaultCultureCode = supportedCultureCodes.FirstOrDefault(); opts.DefaultRequestCulture = new RequestCulture(defaultCultureCode); opts.SupportedCultures = supportedCultures; diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index e3acab361..35a9eced2 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -71,12 +71,12 @@ "LoginConfiguration": { "ResolutionPolicy": "Username" }, - "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" - }, - "CultureConfiguration": { - "Cultures": [ ], - "DefaultCulture": null - } + "AdminConfiguration": { + "IdentityAdminBaseUrl": "http://localhost:9000", + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + }, + "CultureConfiguration": { + "Cultures": [ "en", "fa", "fr", "ru", "sv", "zh", "es", "da" ], + "DefaultCulture": "en" + } } \ No newline at end of file From 56ce0600e76d4563bef12db4bd33f5cd68f0ff82 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 13 Nov 2019 10:28:28 +0100 Subject: [PATCH 218/338] Reset default all cultures and defaultculture. --- src/Skoruba.IdentityServer4.Admin/appsettings.json | 4 ++-- src/Skoruba.IdentityServer4.STS.Identity/appsettings.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 2f4cb05c1..2a9514718 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -32,8 +32,8 @@ "IncludeFormVariables": false }, "CultureConfiguration": { - "Cultures": [ "en", "fa", "fr", "ru", "sv", "zh", "es", "da" ], - "DefaultCulture": "en" + "Cultures": [ ], + "DefaultCulture": null }, "Serilog": { "MinimumLevel": { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 35a9eced2..e637d8bd0 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -76,7 +76,7 @@ "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, "CultureConfiguration": { - "Cultures": [ "en", "fa", "fr", "ru", "sv", "zh", "es", "da" ], - "DefaultCulture": "en" + "Cultures": [ ], + "DefaultCulture": null } } \ No newline at end of file From 00bf5eb36e546a2cfe95a39e1d9eceac7fe37855 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 13 Nov 2019 15:54:18 +0100 Subject: [PATCH 219/338] Add support for SqlServer and PostgreSQL, including generating of migrations --- Skoruba.IdentityServer4.Admin.sln | 34 +- build/add-migrations.ps1 | 31 + .../Extensions/DatabaseExtensions.cs | 63 ++ .../20191113134327_DbInit.Designer.cs | 68 ++ .../AuditLogging/20191113134327_DbInit.cs | 40 + .../AdminAuditLogDbContextModelSnapshot.cs | 66 ++ .../20191113134204_DbInit.Designer.cs | 271 ++++++ .../Identity/20191113134204_DbInit.cs | 218 +++++ .../AdminIdentityDbContextModelSnapshot.cs | 269 ++++++ .../20191113134246_DbInit.Designer.cs | 835 ++++++++++++++++++ .../20191113134246_DbInit.cs | 608 +++++++++++++ ...rverConfigurationDbContextModelSnapshot.cs | 833 +++++++++++++++++ .../20191113134308_DbInit.Designer.cs | 108 +++ .../20191113134308_DbInit.cs | 75 ++ ...verPersistedGrantDbContextModelSnapshot.cs | 106 +++ .../Logging/20191113134224_DbInit.Designer.cs | 60 ++ .../Logging/20191113134224_DbInit.cs | 37 + .../Logging/AdminLogDbContextModelSnapshot.cs | 58 ++ ...r4.Admin.EntityFramework.PostgreSQL.csproj | 29 + .../DatabaseProviderConfiguration.cs | 7 + .../Configuration/DatabaseProviderType.cs | 8 + .../Extensions/DatabaseExtensions.cs | 53 ++ .../20191113134141_DbInit.Designer.cs | 68 ++ .../AuditLogging/20191113134141_DbInit.cs | 39 + .../AdminAuditLogDbContextModelSnapshot.cs | 66 ++ .../20191113134015_DbInit.Designer.cs | 273 ++++++ .../Identity/20191113134015_DbInit.cs | 219 +++++ .../AdminIdentityDbContextModelSnapshot.cs | 271 ++++++ .../20191113134059_DbInit.Designer.cs | 835 ++++++++++++++++++ .../20191113134059_DbInit.cs | 607 +++++++++++++ ...rverConfigurationDbContextModelSnapshot.cs | 833 +++++++++++++++++ .../20191113134119_DbInit.Designer.cs | 108 +++ .../20191113134119_DbInit.cs | 75 ++ ...verPersistedGrantDbContextModelSnapshot.cs | 106 +++ .../Logging/20191113134038_DbInit.Designer.cs | 60 ++ .../Logging/20191113134038_DbInit.cs | 36 + .../Logging/AdminLogDbContextModelSnapshot.cs | 58 ++ ...er4.Admin.EntityFramework.SqlServer.csproj | 29 + .../Helpers/StartupHelpers.cs | 51 +- .../Skoruba.IdentityServer4.Admin.csproj | 2 + .../appsettings.json | 3 + 41 files changed, 7577 insertions(+), 39 deletions(-) create mode 100644 build/add-migrations.ps1 create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/AdminLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/AdminLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj diff --git a/Skoruba.IdentityServer4.Admin.sln b/Skoruba.IdentityServer4.Admin.sln index 9ca903f33..866cf5903 100644 --- a/Skoruba.IdentityServer4.Admin.sln +++ b/Skoruba.IdentityServer4.Admin.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28803.452 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{588205D4-3A30-4DA4-849D-C7422C396DAA}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin", "admin", "{588205D4-3A30-4DA4-849D-C7422C396DAA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5}" EndProject @@ -37,6 +37,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Adm EndProject Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{F817047F-018D-4F93-BDA5-58602073B634}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer", "src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj", "{8230366D-81F9-4FA5-8F5D-8546B527F54F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL", "src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj", "{3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "database", "database", "{2A514C8F-6A53-41CA-AB41-B644E7BC92A7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "business", "business", "{EE588CE5-51D0-4E98-A2B3-40EC8E655931}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -99,6 +107,14 @@ Global {F817047F-018D-4F93-BDA5-58602073B634}.Debug|Any CPU.Build.0 = Debug|Any CPU {F817047F-018D-4F93-BDA5-58602073B634}.Release|Any CPU.ActiveCfg = Release|Any CPU {F817047F-018D-4F93-BDA5-58602073B634}.Release|Any CPU.Build.0 = Release|Any CPU + {8230366D-81F9-4FA5-8F5D-8546B527F54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8230366D-81F9-4FA5-8F5D-8546B527F54F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8230366D-81F9-4FA5-8F5D-8546B527F54F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8230366D-81F9-4FA5-8F5D-8546B527F54F}.Release|Any CPU.Build.0 = Release|Any CPU + {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -107,16 +123,18 @@ Global {E3713598-3375-4E81-9EC7-58DC090789BD} = {588205D4-3A30-4DA4-849D-C7422C396DAA} {BFF10ECC-B02A-4660-A82B-AADFDE0C0EBF} = {0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5} {92405E00-759C-4A20-A736-E21E7EF771C2} = {0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5} - {D9F5B8B1-01F5-4996-8E75-A41532CF32CD} = {588205D4-3A30-4DA4-849D-C7422C396DAA} - {491B30A8-D4A1-42E8-8DEE-4093E0E45C36} = {588205D4-3A30-4DA4-849D-C7422C396DAA} + {D9F5B8B1-01F5-4996-8E75-A41532CF32CD} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {491B30A8-D4A1-42E8-8DEE-4093E0E45C36} = {EE588CE5-51D0-4E98-A2B3-40EC8E655931} {72F17B1A-88D9-47FD-AA35-1C700E51CD0E} = {63D44665-AC4C-45F4-A2C7-A7DB394F44C4} - {2FAECDE3-8D21-4C36-BFF1-3F7C1A56F0D4} = {588205D4-3A30-4DA4-849D-C7422C396DAA} - {C360A0D5-1671-4738-BC5D-BED0E8A24D66} = {588205D4-3A30-4DA4-849D-C7422C396DAA} - {CA63CC7B-BE27-4737-AE91-42E43F729A1E} = {588205D4-3A30-4DA4-849D-C7422C396DAA} + {2FAECDE3-8D21-4C36-BFF1-3F7C1A56F0D4} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {C360A0D5-1671-4738-BC5D-BED0E8A24D66} = {EE588CE5-51D0-4E98-A2B3-40EC8E655931} + {CA63CC7B-BE27-4737-AE91-42E43F729A1E} = {EE588CE5-51D0-4E98-A2B3-40EC8E655931} {83319150-92D2-408C-A944-52DBE6AB8B37} = {0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5} {8F112368-2E45-4C3A-922E-85AB6056F559} = {588205D4-3A30-4DA4-849D-C7422C396DAA} - {E18F8C70-7448-4039-9D78-1369D7F498EF} = {588205D4-3A30-4DA4-849D-C7422C396DAA} - {2DD3CB7D-462E-4039-B684-81B1E88C7C6A} = {588205D4-3A30-4DA4-849D-C7422C396DAA} + {E18F8C70-7448-4039-9D78-1369D7F498EF} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {2DD3CB7D-462E-4039-B684-81B1E88C7C6A} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {8230366D-81F9-4FA5-8F5D-8546B527F54F} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B3166EDE-037B-4C68-BEBA-5DE9C5E3DB82} diff --git a/build/add-migrations.ps1 b/build/add-migrations.ps1 new file mode 100644 index 000000000..6995e178d --- /dev/null +++ b/build/add-migrations.ps1 @@ -0,0 +1,31 @@ +param([string] $migrations = 'DbInit') +$currentPath = Get-Location +Set-Location ../src/Skoruba.IdentityServer4.Admin + +Copy-Item appsettings.json -Destination appsettings-backup.json +$settings = Get-Content appsettings.json -raw + +# SQL Server Migration +$settings = $settings -replace '"ProviderType".*', '"ProviderType": "SqlServer",' +$settings | set-content appsettings.json + +dotnet ef migrations add $migrations -c AdminIdentityDbContext -o Migrations/Identity -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +dotnet ef migrations add $migrations -c AdminLogDbContext -o Migrations/Logging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +dotnet ef migrations add $migrations -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +dotnet ef migrations add $migrations -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +dotnet ef migrations add $migrations -c AdminAuditLogDbContext -o Migrations/AuditLogging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj + +# Postgre Migration +$settings = $settings -replace '"ProviderType".*', '"ProviderType": "PostgreSQL"' +$settings | set-content appsettings.json + +dotnet ef migrations add $migrations -c AdminIdentityDbContext -o Migrations/Identity -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj +dotnet ef migrations add $migrations -c AdminLogDbContext -o Migrations/Logging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj +dotnet ef migrations add $migrations -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj +dotnet ef migrations add $migrations -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj +dotnet ef migrations add $migrations -c AdminAuditLogDbContext -o Migrations/AuditLogging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj + +Remove-Item appsettings.json +Copy-Item appsettings-backup.json -Destination appsettings.json +Remove-Item appsettings-backup.json +Set-Location $currentPath \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs new file mode 100644 index 000000000..87120f910 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs @@ -0,0 +1,63 @@ +using System.Reflection; +using IdentityServer4.EntityFramework.Storage; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions +{ + public static class DatabaseExtensions + { + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterNpgSqlDbContexts(this IServiceCollection services, + string identityConnectionString, string configurationConnectionString, + string persistedGrantConnectionString, string errorLoggingConnectionString, + string auditLoggingConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => + options.UseNpgsql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => + options.ConfigureDbContext = b => + b.UseNpgsql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => + b.UseNpgsql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Log DB from existing connection + services.AddDbContext(options => options.UseNpgsql(errorLoggingConnectionString, + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + + // Audit logging connection + services.AddDbContext(options => options.UseNpgsql(auditLoggingConnectionString, + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs new file mode 100644 index 000000000..e34139ca6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs @@ -0,0 +1,68 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + [Migration("20191113134327_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Action") + .HasColumnType("text"); + + b.Property("Category") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("Event") + .HasColumnType("text"); + + b.Property("Source") + .HasColumnType("text"); + + b.Property("SubjectAdditionalData") + .HasColumnType("text"); + + b.Property("SubjectIdentifier") + .HasColumnType("text"); + + b.Property("SubjectName") + .HasColumnType("text"); + + b.Property("SubjectType") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs new file mode 100644 index 000000000..872d157b9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.AuditLogging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AuditLog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Event = table.Column(nullable: true), + Source = table.Column(nullable: true), + Category = table.Column(nullable: true), + SubjectIdentifier = table.Column(nullable: true), + SubjectName = table.Column(nullable: true), + SubjectType = table.Column(nullable: true), + SubjectAdditionalData = table.Column(nullable: true), + Action = table.Column(nullable: true), + Data = table.Column(nullable: true), + Created = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AuditLog", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AuditLog"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..d15e56bb9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs @@ -0,0 +1,66 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + partial class AdminAuditLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Action") + .HasColumnType("text"); + + b.Property("Category") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .HasColumnType("text"); + + b.Property("Event") + .HasColumnType("text"); + + b.Property("Source") + .HasColumnType("text"); + + b.Property("SubjectAdditionalData") + .HasColumnType("text"); + + b.Property("SubjectIdentifier") + .HasColumnType("text"); + + b.Property("SubjectName") + .HasColumnType("text"); + + b.Property("SubjectType") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs new file mode 100644 index 000000000..6a11b39c2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs @@ -0,0 +1,271 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + [Migration("20191113134204_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs new file mode 100644 index 000000000..d4f64d334 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs @@ -0,0 +1,218 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Identity +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_RoleClaims_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogins_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_UserRoles_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserRoles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RoleClaims_RoleId", + table: "RoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "Roles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogins_UserId", + table: "UserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserRoles_RoleId", + table: "UserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "Users", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "Users", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RoleClaims"); + + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "UserLogins"); + + migrationBuilder.DropTable( + name: "UserRoles"); + + migrationBuilder.DropTable( + name: "UserTokens"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs new file mode 100644 index 000000000..fc05e24c9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs @@ -0,0 +1,269 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + partial class AdminIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Email") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("character varying(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs new file mode 100644 index 000000000..7b952b7db --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs @@ -0,0 +1,835 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + [Migration("20191113134246_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("LastAccessed") + .HasColumnType("timestamp without time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiScopeId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("integer"); + + b.Property("AccessTokenLifetime") + .HasColumnType("integer"); + + b.Property("AccessTokenType") + .HasColumnType("integer"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("boolean"); + + b.Property("AllowOfflineAccess") + .HasColumnType("boolean"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("boolean"); + + b.Property("AllowRememberConsent") + .HasColumnType("boolean"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("boolean"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("boolean"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("integer"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("boolean"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("integer"); + + b.Property("EnableLocalLogin") + .HasColumnType("boolean"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("boolean"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("integer"); + + b.Property("IncludeJwtId") + .HasColumnType("boolean"); + + b.Property("LastAccessed") + .HasColumnType("timestamp without time zone"); + + b.Property("LogoUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("integer"); + + b.Property("RefreshTokenUsage") + .HasColumnType("integer"); + + b.Property("RequireClientSecret") + .HasColumnType("boolean"); + + b.Property("RequireConsent") + .HasColumnType("boolean"); + + b.Property("RequirePkce") + .HasColumnType("boolean"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("integer"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.Property("UserCodeType") + .HasColumnType("character varying(100)") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("character varying(150)") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("IdentityResourceId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("boolean"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("IdentityResourceId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs new file mode 100644 index 000000000..755b7ec59 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs @@ -0,0 +1,608 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerConfiguration +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ApiResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Enabled = table.Column(nullable: false), + ClientId = table.Column(maxLength: 200, nullable: false), + ProtocolType = table.Column(maxLength: 200, nullable: false), + RequireClientSecret = table.Column(nullable: false), + ClientName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + ClientUri = table.Column(maxLength: 2000, nullable: true), + LogoUri = table.Column(maxLength: 2000, nullable: true), + RequireConsent = table.Column(nullable: false), + AllowRememberConsent = table.Column(nullable: false), + AlwaysIncludeUserClaimsInIdToken = table.Column(nullable: false), + RequirePkce = table.Column(nullable: false), + AllowPlainTextPkce = table.Column(nullable: false), + AllowAccessTokensViaBrowser = table.Column(nullable: false), + FrontChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + FrontChannelLogoutSessionRequired = table.Column(nullable: false), + BackChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + BackChannelLogoutSessionRequired = table.Column(nullable: false), + AllowOfflineAccess = table.Column(nullable: false), + IdentityTokenLifetime = table.Column(nullable: false), + AccessTokenLifetime = table.Column(nullable: false), + AuthorizationCodeLifetime = table.Column(nullable: false), + ConsentLifetime = table.Column(nullable: true), + AbsoluteRefreshTokenLifetime = table.Column(nullable: false), + SlidingRefreshTokenLifetime = table.Column(nullable: false), + RefreshTokenUsage = table.Column(nullable: false), + UpdateAccessTokenClaimsOnRefresh = table.Column(nullable: false), + RefreshTokenExpiration = table.Column(nullable: false), + AccessTokenType = table.Column(nullable: false), + EnableLocalLogin = table.Column(nullable: false), + IncludeJwtId = table.Column(nullable: false), + AlwaysSendClientClaims = table.Column(nullable: false), + ClientClaimsPrefix = table.Column(maxLength: 200, nullable: true), + PairWiseSubjectSalt = table.Column(maxLength: 200, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + UserSsoLifetime = table.Column(nullable: true), + UserCodeType = table.Column(maxLength: 100, nullable: true), + DeviceCodeLifetime = table.Column(nullable: false), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "IdentityResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ApiClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Type = table.Column(maxLength: 200, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiClaims_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiProperties", x => x.Id); + table.ForeignKey( + name: "FK_ApiProperties_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopes", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopes_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Description = table.Column(maxLength: 1000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ApiSecrets_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Type = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientClaims", x => x.Id); + table.ForeignKey( + name: "FK_ClientClaims_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientCorsOrigins", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Origin = table.Column(maxLength: 150, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id); + table.ForeignKey( + name: "FK_ClientCorsOrigins_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientGrantTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + GrantType = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientGrantTypes", x => x.Id); + table.ForeignKey( + name: "FK_ClientGrantTypes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientIdPRestrictions", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Provider = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id); + table.ForeignKey( + name: "FK_ClientIdPRestrictions_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientPostLogoutRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PostLogoutRedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientProperties", x => x.Id); + table.ForeignKey( + name: "FK_ClientProperties_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Scope = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientScopes", x => x.Id); + table.ForeignKey( + name: "FK_ClientScopes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Description = table.Column(maxLength: 2000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ClientSecrets_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Type = table.Column(maxLength: 200, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityClaims", x => x.Id); + table.ForeignKey( + name: "FK_IdentityClaims_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityProperties", x => x.Id); + table.ForeignKey( + name: "FK_IdentityProperties_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopeClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Type = table.Column(maxLength: 200, nullable: false), + ApiScopeId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopeClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopeClaims_ApiScopes_ApiScopeId", + column: x => x.ApiScopeId, + principalTable: "ApiScopes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiClaims_ApiResourceId", + table: "ApiClaims", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiProperties_ApiResourceId", + table: "ApiProperties", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiResources_Name", + table: "ApiResources", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopeClaims_ApiScopeId", + table: "ApiScopeClaims", + column: "ApiScopeId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_ApiResourceId", + table: "ApiScopes", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_Name", + table: "ApiScopes", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiSecrets_ApiResourceId", + table: "ApiSecrets", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientClaims_ClientId", + table: "ClientClaims", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientCorsOrigins_ClientId", + table: "ClientCorsOrigins", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientGrantTypes_ClientId", + table: "ClientGrantTypes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientIdPRestrictions_ClientId", + table: "ClientIdPRestrictions", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientPostLogoutRedirectUris_ClientId", + table: "ClientPostLogoutRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientProperties_ClientId", + table: "ClientProperties", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientRedirectUris_ClientId", + table: "ClientRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Clients_ClientId", + table: "Clients", + column: "ClientId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ClientScopes_ClientId", + table: "ClientScopes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientSecrets_ClientId", + table: "ClientSecrets", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityClaims_IdentityResourceId", + table: "IdentityClaims", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityProperties_IdentityResourceId", + table: "IdentityProperties", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityResources_Name", + table: "IdentityResources", + column: "Name", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApiClaims"); + + migrationBuilder.DropTable( + name: "ApiProperties"); + + migrationBuilder.DropTable( + name: "ApiScopeClaims"); + + migrationBuilder.DropTable( + name: "ApiSecrets"); + + migrationBuilder.DropTable( + name: "ClientClaims"); + + migrationBuilder.DropTable( + name: "ClientCorsOrigins"); + + migrationBuilder.DropTable( + name: "ClientGrantTypes"); + + migrationBuilder.DropTable( + name: "ClientIdPRestrictions"); + + migrationBuilder.DropTable( + name: "ClientPostLogoutRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientProperties"); + + migrationBuilder.DropTable( + name: "ClientRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientScopes"); + + migrationBuilder.DropTable( + name: "ClientSecrets"); + + migrationBuilder.DropTable( + name: "IdentityClaims"); + + migrationBuilder.DropTable( + name: "IdentityProperties"); + + migrationBuilder.DropTable( + name: "ApiScopes"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "IdentityResources"); + + migrationBuilder.DropTable( + name: "ApiResources"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs new file mode 100644 index 000000000..ada2e9c39 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs @@ -0,0 +1,833 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + partial class IdentityServerConfigurationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("LastAccessed") + .HasColumnType("timestamp without time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiScopeId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiResourceId") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("integer"); + + b.Property("AccessTokenLifetime") + .HasColumnType("integer"); + + b.Property("AccessTokenType") + .HasColumnType("integer"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("boolean"); + + b.Property("AllowOfflineAccess") + .HasColumnType("boolean"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("boolean"); + + b.Property("AllowRememberConsent") + .HasColumnType("boolean"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("boolean"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("boolean"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("integer"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("boolean"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("integer"); + + b.Property("EnableLocalLogin") + .HasColumnType("boolean"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("boolean"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("integer"); + + b.Property("IncludeJwtId") + .HasColumnType("boolean"); + + b.Property("LastAccessed") + .HasColumnType("timestamp without time zone"); + + b.Property("LogoUri") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("integer"); + + b.Property("RefreshTokenUsage") + .HasColumnType("integer"); + + b.Property("RequireClientSecret") + .HasColumnType("boolean"); + + b.Property("RequireConsent") + .HasColumnType("boolean"); + + b.Property("RequirePkce") + .HasColumnType("boolean"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("integer"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.Property("UserCodeType") + .HasColumnType("character varying(100)") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("character varying(150)") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("IdentityResourceId") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Description") + .HasColumnType("character varying(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("boolean"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("boolean"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("IdentityResourceId") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("character varying(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs new file mode 100644 index 000000000..c303ddad3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs @@ -0,0 +1,108 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + [Migration("20191113134308_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("character varying(50000)") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("timestamp without time zone"); + + b.Property("SubjectId") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("character varying(50000)") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("SubjectId") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(50)") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs new file mode 100644 index 000000000..112c72744 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerGrants +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DeviceCodes", + columns: table => new + { + UserCode = table.Column(maxLength: 200, nullable: false), + DeviceCode = table.Column(maxLength: 200, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: false), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DeviceCodes", x => x.UserCode); + }); + + migrationBuilder.CreateTable( + name: "PersistedGrants", + columns: table => new + { + Key = table.Column(maxLength: 200, nullable: false), + Type = table.Column(maxLength: 50, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: true), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistedGrants", x => x.Key); + }); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_DeviceCode", + table: "DeviceCodes", + column: "DeviceCode", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_Expiration", + table: "DeviceCodes", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_Expiration", + table: "PersistedGrants", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_SubjectId_ClientId_Type", + table: "PersistedGrants", + columns: new[] { "SubjectId", "ClientId", "Type" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DeviceCodes"); + + migrationBuilder.DropTable( + name: "PersistedGrants"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs new file mode 100644 index 000000000..cae5bb065 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs @@ -0,0 +1,106 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + partial class IdentityServerPersistedGrantDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("character varying(50000)") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("timestamp without time zone"); + + b.Property("SubjectId") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Data") + .IsRequired() + .HasColumnType("character varying(50000)") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("timestamp without time zone"); + + b.Property("SubjectId") + .HasColumnType("character varying(200)") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("character varying(50)") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs new file mode 100644 index 000000000..4cbb7166f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs @@ -0,0 +1,60 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + [Migration("20191113134224_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Exception") + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("character varying(128)") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("text"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("MessageTemplate") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("TimeStamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs new file mode 100644 index 000000000..5888cb3ff --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Logging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Log", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Message = table.Column(nullable: true), + MessageTemplate = table.Column(nullable: true), + Level = table.Column(maxLength: 128, nullable: true), + TimeStamp = table.Column(nullable: false), + Exception = table.Column(nullable: true), + LogEvent = table.Column(nullable: true), + Properties = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Log", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Log"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/AdminLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/AdminLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..66de01cb1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/AdminLogDbContextModelSnapshot.cs @@ -0,0 +1,58 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + partial class AdminLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Exception") + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("character varying(128)") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("text"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("MessageTemplate") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("TimeStamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj new file mode 100644 index 000000000..c62b6f399 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.0 + 1.0.0-beta7 + Jan Škoruba + IdentityServer4 Admin OpenIDConnect OAuth2 Identity + Entity Framework library for support PostrgreSQL + https://github.com/skoruba/IdentityServer4.Admin/blob/master/LICENSE.md + https://github.com/skoruba/IdentityServer4.Admin + https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png + + + + + + + + + + + + + + + + + + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs new file mode 100644 index 000000000..4d222f7a2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs @@ -0,0 +1,7 @@ +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration +{ + public class DatabaseProviderConfiguration + { + public string ProviderType { get; set; } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs new file mode 100644 index 000000000..ee5ae94e2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs @@ -0,0 +1,8 @@ +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration +{ + public enum DatabaseProviderType + { + SqlServer, + PostgreSQL + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs new file mode 100644 index 000000000..6f55a1a4e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs @@ -0,0 +1,53 @@ +using System.Reflection; +using IdentityServer4.EntityFramework.Storage; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions +{ + public static class DatabaseExtensions + { + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterSqlServerDbContexts(this IServiceCollection services, string identityConnectionString, string configurationConnectionString, string persistedGrantConnectionString, string errorLoggingConnectionString, string auditLoggingConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => options.UseSqlServer(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => options.ConfigureDbContext = b => b.UseSqlServer(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => b.UseSqlServer(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Log DB from existing connection + services.AddDbContext(options => options.UseSqlServer(errorLoggingConnectionString, optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + + // Audit logging connection + services.AddDbContext(options => options.UseSqlServer(auditLoggingConnectionString, optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs new file mode 100644 index 000000000..c62b46781 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs @@ -0,0 +1,68 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + [Migration("20191113134141_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Action") + .HasColumnType("nvarchar(max)"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("Event") + .HasColumnType("nvarchar(max)"); + + b.Property("Source") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectAdditionalData") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectName") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectType") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs new file mode 100644 index 000000000..46cecfe5d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.AuditLogging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AuditLog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Event = table.Column(nullable: true), + Source = table.Column(nullable: true), + Category = table.Column(nullable: true), + SubjectIdentifier = table.Column(nullable: true), + SubjectName = table.Column(nullable: true), + SubjectType = table.Column(nullable: true), + SubjectAdditionalData = table.Column(nullable: true), + Action = table.Column(nullable: true), + Data = table.Column(nullable: true), + Created = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AuditLog", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AuditLog"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..62c16f36c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs @@ -0,0 +1,66 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + partial class AdminAuditLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Action") + .HasColumnType("nvarchar(max)"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Data") + .HasColumnType("nvarchar(max)"); + + b.Property("Event") + .HasColumnType("nvarchar(max)"); + + b.Property("Source") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectAdditionalData") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectName") + .HasColumnType("nvarchar(max)"); + + b.Property("SubjectType") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs new file mode 100644 index 000000000..60d3d98ee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs @@ -0,0 +1,273 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + [Migration("20191113134015_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs new file mode 100644 index 000000000..74a3761e4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs @@ -0,0 +1,219 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Identity +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_RoleClaims_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogins_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_UserRoles_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserRoles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RoleClaims_RoleId", + table: "RoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "Roles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogins_UserId", + table: "UserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserRoles_RoleId", + table: "UserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "Users", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "Users", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RoleClaims"); + + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "UserLogins"); + + migrationBuilder.DropTable( + name: "UserRoles"); + + migrationBuilder.DropTable( + name: "UserTokens"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs new file mode 100644 index 000000000..c11aaaf86 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs @@ -0,0 +1,271 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + partial class AdminIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs new file mode 100644 index 000000000..3115f92d5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs @@ -0,0 +1,835 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + [Migration("20191113134059_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiScopeId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("LogoUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("UserCodeType") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("nvarchar(150)") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs new file mode 100644 index 000000000..023c4d6a6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs @@ -0,0 +1,607 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerConfiguration +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ApiResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Enabled = table.Column(nullable: false), + ClientId = table.Column(maxLength: 200, nullable: false), + ProtocolType = table.Column(maxLength: 200, nullable: false), + RequireClientSecret = table.Column(nullable: false), + ClientName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + ClientUri = table.Column(maxLength: 2000, nullable: true), + LogoUri = table.Column(maxLength: 2000, nullable: true), + RequireConsent = table.Column(nullable: false), + AllowRememberConsent = table.Column(nullable: false), + AlwaysIncludeUserClaimsInIdToken = table.Column(nullable: false), + RequirePkce = table.Column(nullable: false), + AllowPlainTextPkce = table.Column(nullable: false), + AllowAccessTokensViaBrowser = table.Column(nullable: false), + FrontChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + FrontChannelLogoutSessionRequired = table.Column(nullable: false), + BackChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + BackChannelLogoutSessionRequired = table.Column(nullable: false), + AllowOfflineAccess = table.Column(nullable: false), + IdentityTokenLifetime = table.Column(nullable: false), + AccessTokenLifetime = table.Column(nullable: false), + AuthorizationCodeLifetime = table.Column(nullable: false), + ConsentLifetime = table.Column(nullable: true), + AbsoluteRefreshTokenLifetime = table.Column(nullable: false), + SlidingRefreshTokenLifetime = table.Column(nullable: false), + RefreshTokenUsage = table.Column(nullable: false), + UpdateAccessTokenClaimsOnRefresh = table.Column(nullable: false), + RefreshTokenExpiration = table.Column(nullable: false), + AccessTokenType = table.Column(nullable: false), + EnableLocalLogin = table.Column(nullable: false), + IncludeJwtId = table.Column(nullable: false), + AlwaysSendClientClaims = table.Column(nullable: false), + ClientClaimsPrefix = table.Column(maxLength: 200, nullable: true), + PairWiseSubjectSalt = table.Column(maxLength: 200, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + UserSsoLifetime = table.Column(nullable: true), + UserCodeType = table.Column(maxLength: 100, nullable: true), + DeviceCodeLifetime = table.Column(nullable: false), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "IdentityResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ApiClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Type = table.Column(maxLength: 200, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiClaims_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiProperties", x => x.Id); + table.ForeignKey( + name: "FK_ApiProperties_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopes", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopes_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Description = table.Column(maxLength: 1000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ApiSecrets_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Type = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientClaims", x => x.Id); + table.ForeignKey( + name: "FK_ClientClaims_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientCorsOrigins", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Origin = table.Column(maxLength: 150, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id); + table.ForeignKey( + name: "FK_ClientCorsOrigins_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientGrantTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + GrantType = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientGrantTypes", x => x.Id); + table.ForeignKey( + name: "FK_ClientGrantTypes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientIdPRestrictions", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Provider = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id); + table.ForeignKey( + name: "FK_ClientIdPRestrictions_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientPostLogoutRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + PostLogoutRedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientProperties", x => x.Id); + table.ForeignKey( + name: "FK_ClientProperties_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Scope = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientScopes", x => x.Id); + table.ForeignKey( + name: "FK_ClientScopes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Description = table.Column(maxLength: 2000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ClientSecrets_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Type = table.Column(maxLength: 200, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityClaims", x => x.Id); + table.ForeignKey( + name: "FK_IdentityClaims_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityProperties", x => x.Id); + table.ForeignKey( + name: "FK_IdentityProperties_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopeClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Type = table.Column(maxLength: 200, nullable: false), + ApiScopeId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopeClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopeClaims_ApiScopes_ApiScopeId", + column: x => x.ApiScopeId, + principalTable: "ApiScopes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiClaims_ApiResourceId", + table: "ApiClaims", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiProperties_ApiResourceId", + table: "ApiProperties", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiResources_Name", + table: "ApiResources", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopeClaims_ApiScopeId", + table: "ApiScopeClaims", + column: "ApiScopeId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_ApiResourceId", + table: "ApiScopes", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_Name", + table: "ApiScopes", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiSecrets_ApiResourceId", + table: "ApiSecrets", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientClaims_ClientId", + table: "ClientClaims", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientCorsOrigins_ClientId", + table: "ClientCorsOrigins", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientGrantTypes_ClientId", + table: "ClientGrantTypes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientIdPRestrictions_ClientId", + table: "ClientIdPRestrictions", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientPostLogoutRedirectUris_ClientId", + table: "ClientPostLogoutRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientProperties_ClientId", + table: "ClientProperties", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientRedirectUris_ClientId", + table: "ClientRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Clients_ClientId", + table: "Clients", + column: "ClientId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ClientScopes_ClientId", + table: "ClientScopes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientSecrets_ClientId", + table: "ClientSecrets", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityClaims_IdentityResourceId", + table: "IdentityClaims", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityProperties_IdentityResourceId", + table: "IdentityProperties", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityResources_Name", + table: "IdentityResources", + column: "Name", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApiClaims"); + + migrationBuilder.DropTable( + name: "ApiProperties"); + + migrationBuilder.DropTable( + name: "ApiScopeClaims"); + + migrationBuilder.DropTable( + name: "ApiSecrets"); + + migrationBuilder.DropTable( + name: "ClientClaims"); + + migrationBuilder.DropTable( + name: "ClientCorsOrigins"); + + migrationBuilder.DropTable( + name: "ClientGrantTypes"); + + migrationBuilder.DropTable( + name: "ClientIdPRestrictions"); + + migrationBuilder.DropTable( + name: "ClientPostLogoutRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientProperties"); + + migrationBuilder.DropTable( + name: "ClientRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientScopes"); + + migrationBuilder.DropTable( + name: "ClientSecrets"); + + migrationBuilder.DropTable( + name: "IdentityClaims"); + + migrationBuilder.DropTable( + name: "IdentityProperties"); + + migrationBuilder.DropTable( + name: "ApiScopes"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "IdentityResources"); + + migrationBuilder.DropTable( + name: "ApiResources"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs new file mode 100644 index 000000000..da2d4654d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs @@ -0,0 +1,833 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + partial class IdentityServerConfigurationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiScopeId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("LogoUri") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("UserCodeType") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("nvarchar(150)") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(1000)") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("bit"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("nvarchar(250)") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(2000)") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs new file mode 100644 index 000000000..c58dae863 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs @@ -0,0 +1,108 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + [Migration("20191113134119_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("SubjectId") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("SubjectId") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs new file mode 100644 index 000000000..3b64da15f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerGrants +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DeviceCodes", + columns: table => new + { + UserCode = table.Column(maxLength: 200, nullable: false), + DeviceCode = table.Column(maxLength: 200, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: false), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DeviceCodes", x => x.UserCode); + }); + + migrationBuilder.CreateTable( + name: "PersistedGrants", + columns: table => new + { + Key = table.Column(maxLength: 200, nullable: false), + Type = table.Column(maxLength: 50, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: true), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistedGrants", x => x.Key); + }); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_DeviceCode", + table: "DeviceCodes", + column: "DeviceCode", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_Expiration", + table: "DeviceCodes", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_Expiration", + table: "PersistedGrants", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_SubjectId_ClientId_Type", + table: "PersistedGrants", + columns: new[] { "SubjectId", "ClientId", "Type" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DeviceCodes"); + + migrationBuilder.DropTable( + name: "PersistedGrants"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs new file mode 100644 index 000000000..5e089b1f6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs @@ -0,0 +1,106 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + partial class IdentityServerPersistedGrantDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("SubjectId") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("SubjectId") + .HasColumnType("nvarchar(200)") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs new file mode 100644 index 000000000..3d9f0dc15 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs @@ -0,0 +1,60 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + [Migration("20191113134038_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Exception") + .HasColumnType("nvarchar(max)"); + + b.Property("Level") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("nvarchar(max)"); + + b.Property("Message") + .HasColumnType("nvarchar(max)"); + + b.Property("MessageTemplate") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("TimeStamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs new file mode 100644 index 000000000..dcf066cef --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs @@ -0,0 +1,36 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Logging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Log", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Message = table.Column(nullable: true), + MessageTemplate = table.Column(nullable: true), + Level = table.Column(maxLength: 128, nullable: true), + TimeStamp = table.Column(nullable: false), + Exception = table.Column(nullable: true), + LogEvent = table.Column(nullable: true), + Properties = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Log", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Log"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/AdminLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/AdminLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..776db4c9d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/AdminLogDbContextModelSnapshot.cs @@ -0,0 +1,58 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + partial class AdminLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Exception") + .HasColumnType("nvarchar(max)"); + + b.Property("Level") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("nvarchar(max)"); + + b.Property("Message") + .HasColumnType("nvarchar(max)"); + + b.Property("MessageTemplate") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("TimeStamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj new file mode 100644 index 000000000..27aa31d47 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.0 + 1.0.0-beta7 + Jan Škoruba + IdentityServer4 Admin OpenIDConnect OAuth2 Identity + Entity Framework library for support SqlServer + https://github.com/skoruba/IdentityServer4.Admin/blob/master/LICENSE.md + https://github.com/skoruba/IdentityServer4.Admin + https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png + + + + + + + + + + + + + + + + + + diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index bd858d3bc..129c8e779 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -44,6 +44,9 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; using Skoruba.IdentityServer4.Admin.Helpers.Localization; using Microsoft.Extensions.Hosting; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; +using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; namespace Skoruba.IdentityServer4.Admin.Helpers { @@ -136,40 +139,26 @@ public static void RegisterDbContexts { - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; - - // Config DB for identity - services.AddDbContext(options => - options.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly))); + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); - // Config DB from existing connection - services.AddConfigurationDbContext(options => - { - options.ConfigureDbContext = b => - b.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var errorLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); + var auditLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); - // Operational DB from existing connection - services.AddOperationalDbContext(options => + switch (databaseProviderType) { - options.ConfigureDbContext = b => - b.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - // Log DB from existing connection - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey), - optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); - - // Audit logging connection - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey), - optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + case DatabaseProviderType.SqlServer: + services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; + case DatabaseProviderType.PostgreSQL: + services.RegisterNpgSqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; + default: + throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + } } /// diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index 2a5525976..39c858afb 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -105,7 +105,9 @@ + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 50757ec11..03f728d49 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -6,6 +6,9 @@ "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, + "DatabaseProviderConfiguration": { + "ProviderType": "SqlServer" + }, "AdminConfiguration": { "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", "IdentityServerBaseUrl": "http://localhost:5000", From ec7a4e9884e98690576d56018d42275d35da4891 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Wed, 13 Nov 2019 16:06:54 +0100 Subject: [PATCH 220/338] . --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4255d6756..f8d0df898 100644 --- a/.gitignore +++ b/.gitignore @@ -278,4 +278,5 @@ __pycache__/ !/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ !/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/ !/src/Skoruba.IdentityServer4.Admin/Views/Log/ -!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/ \ No newline at end of file +!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/ +/src/Skoruba.IdentityServer4.Admin.Api/appsettings.Production.json From d7d60030f1a204c4402543e9147fa635847c3d78 Mon Sep 17 00:00:00 2001 From: Nelson Reis Date: Thu, 14 Nov 2019 16:26:02 +0000 Subject: [PATCH 221/338] Fix commands for migrations of AuditLogging DbContext --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b62d8e89..a5e90a649 100644 --- a/README.md +++ b/README.md @@ -151,8 +151,8 @@ Update-Database -context IdentityServerPersistedGrantDbContext #### Migrations for AuditLogging DbContext: ```powershell -Add-Migration AuditLoggingDbInit -context AuditLoggingDbContext -output Data/Migrations/AuditLogging -Update-Database -context AuditLoggingDbContext +Add-Migration AdminAuditLogDbInit -context AdminAuditLogDbContext -output Data/Migrations/AuditLogging +Update-Database -context AdminAuditLogDbContext ``` ### Or via `dotnet CLI`: @@ -188,8 +188,8 @@ dotnet ef database update -c IdentityServerPersistedGrantDbContext #### Migrations for AuditLogging DbContext: ```powershell -dotnet ef migrations add AuditLoggingDbInit -c AuditLoggingDbContext -o Data/Migrations/AuditLogging -dotnet ef database update -c AuditLoggingDbContext +dotnet ef migrations add AdminAuditLogDbInit -c AdminAuditLogDbContext -o Data/Migrations/AuditLogging +dotnet ef database update -c AdminAuditLogDbContext ``` Migrations are not a part of the repository - they are ignored in `.gitignore`. From ec95bf3155299fe431a1dd5bf8f62dfcc0e919fb Mon Sep 17 00:00:00 2001 From: Andrew Godfroy Date: Thu, 14 Nov 2019 23:46:45 -0500 Subject: [PATCH 222/338] Added certificate configuration change --- .../Configuration/CertificateConfiguration.cs | 3 +++ .../IdentityServerBuilderExtensions.cs | 22 +++++++++++++++++-- .../appsettings.json | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CertificateConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CertificateConfiguration.cs index 775151770..99e8f00c1 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CertificateConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CertificateConfiguration.cs @@ -4,6 +4,9 @@ public class CertificateConfiguration { public bool UseTemporarySigningKeyForDevelopment { get; set; } + public string CertificateStoreLocation { get; set; } + public bool CertificateValidOnly { get; set; } + public bool UseSigningCertificateThumbprint { get; set; } public string SigningCertificateThumbprint { get; set; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs index 0f1f40b97..70d36d1b7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs @@ -36,10 +36,28 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe throw new Exception(SigningCertificateThumbprintNotFound); } - var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); + StoreLocation storeLocation = StoreLocation.LocalMachine; + bool validOnly = certificateConfiguration.CertificateValidOnly; + + // Parse the Certificate StoreLocation + string certStoreLocationLower = certificateConfiguration.CertificateStoreLocation.ToLower(); + if (certStoreLocationLower == StoreLocation.CurrentUser.ToString().ToLower() || + certificateConfiguration.CertificateStoreLocation == ((int)StoreLocation.CurrentUser).ToString()) + { + storeLocation = StoreLocation.CurrentUser; + } + else if (certStoreLocationLower == StoreLocation.LocalMachine.ToString().ToLower() || + certStoreLocationLower == ((int)StoreLocation.LocalMachine).ToString()) + { + storeLocation = StoreLocation.LocalMachine; + } + else { storeLocation = StoreLocation.LocalMachine; validOnly = true; } + + // Open Certificate + var certStore = new X509Store(StoreName.My, storeLocation); certStore.Open(OpenFlags.ReadOnly); - var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, true); + var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, validOnly); if (certCollection.Count == 0) { throw new Exception(CertificateNotFound); diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 91e08e29f..354763037 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -36,6 +36,9 @@ "UseTemporarySigningKeyForDevelopment": true, + "CertificateStoreLocation": "LocalMachine", + "CertificateValidOnly": true, + "UseSigningCertificateThumbprint": false, "SigningCertificateThumbprint": "", From dd6f9d75f06c9984d77a18cafc474b0a6b14eb0a Mon Sep 17 00:00:00 2001 From: Andrew Godfroy Date: Fri, 15 Nov 2019 00:03:50 -0500 Subject: [PATCH 223/338] Update Configure-Azure-Deploy.md Updated Azure documentation to use new CertificateConfiguration --- docs/Configure-Azure-Deploy.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/docs/Configure-Azure-Deploy.md b/docs/Configure-Azure-Deploy.md index 791812ac1..82026a8b2 100644 --- a/docs/Configure-Azure-Deploy.md +++ b/docs/Configure-Azure-Deploy.md @@ -69,27 +69,23 @@ While we're at it we can allow only https traffic to our STS and admin: ![Always https](Images/https_always.PNG) +Then head to "Application Settings" section within your Azure App Service and create a new Application setting with the following parameters: + +``` +Name: WEBSITE_LOAD_CERTIFICATES +Value: * +``` + Last step before deploy - we need to update `src/Skoruba.IdentityServer4.STS.Identity/appsettings.json` and modify following lines: ```json "CertificateConfiguration": { "UseTemporarySigningKeyForDevelopment": false, + "CertificateStoreLocation": "CurrentUser", + "CertificateValidOnly": false, "UseSigningCertificateThumbprint": true, "SigningCertificateThumbprint": "" } ``` -In `src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs` - change loading certificates from `StoreLocation.LocalMachine` to `StoreLocation.CurrentUser`. - -And change in method: `AddCustomSigningCredential` -from: -``` -var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, true); -``` -to: -``` -var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, false); -``` - - Now we can (re)deploy both apps to Azure. From 3eca9fb504009adc598c13dc73be04a1e4bec22f Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 16 Nov 2019 10:35:29 +0100 Subject: [PATCH 224/338] polish migration script --- build/add-migrations.ps1 | 32 +++++++++---------- docker-compose.yml | 1 + ...r4.Admin.EntityFramework.PostgreSQL.csproj | 4 --- ...er4.Admin.EntityFramework.SqlServer.csproj | 4 --- .../Dockerfile | 7 ++-- 5 files changed, 19 insertions(+), 29 deletions(-) diff --git a/build/add-migrations.ps1 b/build/add-migrations.ps1 index 6995e178d..7c6eb088c 100644 --- a/build/add-migrations.ps1 +++ b/build/add-migrations.ps1 @@ -1,29 +1,27 @@ -param([string] $migrations = 'DbInit') +param([string] $migration = 'DbInit') $currentPath = Get-Location Set-Location ../src/Skoruba.IdentityServer4.Admin Copy-Item appsettings.json -Destination appsettings-backup.json $settings = Get-Content appsettings.json -raw -# SQL Server Migration -$settings = $settings -replace '"ProviderType".*', '"ProviderType": "SqlServer",' -$settings | set-content appsettings.json +$dbProviders = @{ } -dotnet ef migrations add $migrations -c AdminIdentityDbContext -o Migrations/Identity -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj -dotnet ef migrations add $migrations -c AdminLogDbContext -o Migrations/Logging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj -dotnet ef migrations add $migrations -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj -dotnet ef migrations add $migrations -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj -dotnet ef migrations add $migrations -c AdminAuditLogDbContext -o Migrations/AuditLogging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +$dbProviders.Add("SqlServer", "..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj") +$dbProviders.Add("PostgreSQL", "..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj") -# Postgre Migration -$settings = $settings -replace '"ProviderType".*', '"ProviderType": "PostgreSQL"' -$settings | set-content appsettings.json +foreach ($key in $dbProviders.Keys) { + Write-Host $dbProviders[$key] -dotnet ef migrations add $migrations -c AdminIdentityDbContext -o Migrations/Identity -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj -dotnet ef migrations add $migrations -c AdminLogDbContext -o Migrations/Logging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj -dotnet ef migrations add $migrations -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj -dotnet ef migrations add $migrations -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj -dotnet ef migrations add $migrations -c AdminAuditLogDbContext -o Migrations/AuditLogging -p ..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj + $settings = $settings -replace '"ProviderType".*', '"ProviderType": "' + $key + '",' + $settings | set-content appsettings.json + + dotnet ef migrations add $migration -c AdminIdentityDbContext -o Migrations/Identity -p $dbProviders[$key] + dotnet ef migrations add $migration -c AdminLogDbContext -o Migrations/Logging -p $dbProviders[$key] + dotnet ef migrations add $migration -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p $dbProviders[$key] + dotnet ef migrations add $migration -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p $dbProviders[$key] + dotnet ef migrations add $migration -c AdminAuditLogDbContext -o Migrations/AuditLogging -p $dbProviders[$key] +} Remove-Item appsettings.json Copy-Item appsettings-backup.json -Destination appsettings.json diff --git a/docker-compose.yml b/docker-compose.yml index c662c2dfe..ddcb61e35 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,6 +46,7 @@ services: - "ConnectionStrings__PersistedGrantDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings__IdentityDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" - "ConnectionStrings__AdminLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" + - "ConnectionStrings__AdminAuditLogDbConnection=Server=db;Database=IdentityServer4Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true" container_name: skoruba-identityserver4-admin-api skoruba.identityserver4.sts.identity: diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj index c62b6f399..c9f245ac7 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj @@ -11,10 +11,6 @@ https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png - - - - diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj index 27aa31d47..f8254f128 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj @@ -11,10 +11,6 @@ https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png - - - - diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile index 127e992c1..8ffe80f09 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile +++ b/src/Skoruba.IdentityServer4.STS.Identity/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base +FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base WORKDIR /app EXPOSE 80 -FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build +FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build WORKDIR /src COPY ["src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj", "src/Skoruba.IdentityServer4.STS.Identity/"] COPY ["src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/Skoruba.IdentityServer4.Admin.EntityFramework.Identity.csproj", "src/Skoruba.IdentityServer4.Admin.EntityFramework.Identity/"] @@ -20,5 +20,4 @@ RUN dotnet publish "Skoruba.IdentityServer4.STS.Identity.csproj" -c Release -o / FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true -ENTRYPOINT ["dotnet", "Skoruba.IdentityServer4.STS.Identity.dll"] +ENTRYPOINT ["dotnet", "Skoruba.IdentityServer4.STS.Identity.dll"] \ No newline at end of file From d5858f0d09566bb73524f50e35ee0711e2ef2ba5 Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 11:00:04 +0200 Subject: [PATCH 225/338] initial finnish translation with google translator --- .../Configuration/CultureConfiguration.cs | 2 +- .../ConfigurationController.fi.resx | 189 +++++++ .../Controllers/GrantController.fi.resx | 129 +++++ .../Controllers/IdentityController.fi.resx | 162 ++++++ .../Services/ApiResourceService.fi.resx | 150 ++++++ .../Resources/Services/ClientService.fi.resx | 138 ++++++ .../Services/IdentityResourceService.fi.resx | 135 +++++ .../Services/IdentityService.fi.resx | 180 +++++++ .../Services/PersistedGrantService.fi.resx | 126 +++++ .../Views/Account/AccessDenied.fi.resx | 129 +++++ .../Views/Configuration/ApiResource.fi.resx | 165 +++++++ .../ApiResource/Section/Label.fi.resx | 192 ++++++++ .../Configuration/ApiResourceDelete.fi.resx | 132 +++++ .../ApiResourceProperties.fi.resx | 147 ++++++ .../ApiResourcePropertyDelete.fi.resx | 135 +++++ .../Views/Configuration/ApiResources.fi.resx | 135 +++++ .../Configuration/ApiScopeDelete.fi.resx | 135 +++++ .../Views/Configuration/ApiScopes.fi.resx | 165 +++++++ .../Configuration/ApiSecretDelete.fi.resx | 135 +++++ .../Views/Configuration/ApiSecrets.fi.resx | 162 ++++++ .../Views/Configuration/Client.fi.resx | 129 +++++ .../Client/Section/ActionButtons.fi.resx | 129 +++++ .../Client/Section/Authentication.fi.resx | 144 ++++++ .../Client/Section/Basics.fi.resx | 150 ++++++ .../Client/Section/Consent.fi.resx | 123 +++++ .../Client/Section/Label.fi.resx | 462 ++++++++++++++++++ .../Configuration/Client/Section/Name.fi.resx | 159 ++++++ .../Client/Section/Token.fi.resx | 147 ++++++ .../Configuration/Client/Settings.fi.resx | 141 ++++++ .../Configuration/ClientClaimDelete.fi.resx | 135 +++++ .../Views/Configuration/ClientClaims.fi.resx | 171 +++++++ .../Views/Configuration/ClientClone.fi.resx | 162 ++++++ .../Views/Configuration/ClientDelete.fi.resx | 129 +++++ .../Configuration/ClientProperties.fi.resx | 147 ++++++ .../ClientPropertyDelete.fi.resx | 135 +++++ .../Configuration/ClientSecretDelete.fi.resx | 135 +++++ .../Views/Configuration/ClientSecrets.fi.resx | 162 ++++++ .../Views/Configuration/Clients.fi.resx | 135 +++++ .../Configuration/IdentityResource.fi.resx | 159 ++++++ .../IdentityResource/Section/Label.fi.resx | 186 +++++++ .../IdentityResourceDelete.fi.resx | 132 +++++ .../IdentityResourceProperties.fi.resx | 147 ++++++ .../IdentityResourcePropertyDelete.fi.resx | 135 +++++ .../Configuration/IdentityResources.fi.resx | 132 +++++ .../Views/Grant/PersistedGrant.fi.resx | 156 ++++++ .../Views/Grant/PersistedGrantDelete.fi.resx | 144 ++++++ .../Views/Grant/PersistedGrants.fi.resx | 132 +++++ .../Resources/Views/Home/Index.fi.resx | 147 ++++++ .../Resources/Views/Identity/Role.fi.resx | 138 ++++++ .../Views/Identity/Role/Section/Label.fi.resx | 138 ++++++ .../Views/Identity/RoleClaims.fi.resx | 168 +++++++ .../Views/Identity/RoleClaimsDelete.fi.resx | 135 +++++ .../Views/Identity/RoleDelete.fi.resx | 129 +++++ .../Views/Identity/RoleUsers.fi.resx | 141 ++++++ .../Resources/Views/Identity/Roles.fi.resx | 135 +++++ .../Views/Identity/User/Section/Label.fi.resx | 234 +++++++++ .../Views/Identity/UserChangePassword.fi.resx | 132 +++++ .../Views/Identity/UserClaims.fi.resx | 168 +++++++ .../Views/Identity/UserClaimsDelete.fi.resx | 135 +++++ .../Views/Identity/UserDelete.fi.resx | 129 +++++ .../Views/Identity/UserProfile.fi.resx | 150 ++++++ .../Views/Identity/UserProviders.fi.resx | 138 ++++++ .../Identity/UserProvidersDelete.fi.resx | 135 +++++ .../Views/Identity/UserRoles.fi.resx | 141 ++++++ .../Views/Identity/UserRolesDelete.fi.resx | 135 +++++ .../Resources/Views/Identity/Users.fi.resx | 138 ++++++ .../Resources/Views/Log/AuditLog.fi.resx | 171 +++++++ .../Resources/Views/Log/ErrorsLog.fi.resx | 150 ++++++ .../Views/Shared/Common/ErrorPage.fi.resx | 123 +++++ .../Views/Shared/Common/Pager.fi.resx | 126 +++++ .../Views/Shared/Common/PagerDynamic.fi.resx | 126 +++++ .../Views/Shared/Common/Search.fi.resx | 126 +++++ .../Shared/Common/SelectLanguage.fi.resx | 123 +++++ .../IdentityServerLink/Default.fi.resx | 123 +++++ .../Resources/Views/Shared/_Layout.fi.resx | 162 ++++++ .../Configuration/CultureConfiguration.cs | 2 +- .../Controllers/AccountController.fi.resx | 147 ++++++ .../Controllers/ManageController.fi.resx | 207 ++++++++ .../Views/Account/ConfirmEmail.fi.resx | 126 +++++ .../Account/ExternalLoginConfirmation.fi.resx | 140 ++++++ .../Account/ExternalLoginFailure.fi.resx | 126 +++++ .../Views/Account/ForgotPassword.fi.resx | 132 +++++ .../ForgotPasswordConfirmation.fi.resx | 126 +++++ .../Resources/Views/Account/Lockout.fi.resx | 126 +++++ .../Resources/Views/Account/LoggedOut.fi.resx | 135 +++++ .../Resources/Views/Account/Login.fi.resx | 159 ++++++ .../Views/Account/LoginWith2fa.fi.resx | 141 ++++++ .../Account/LoginWithRecoveryCode.fi.resx | 133 +++++ .../Resources/Views/Account/Logout.fi.resx | 129 +++++ .../Resources/Views/Account/Register.fi.resx | 141 ++++++ .../Views/Account/ResetPassword.fi.resx | 138 ++++++ .../Account/ResetPasswordConfirmation.fi.resx | 129 +++++ .../Resources/Views/Consent/Index.fi.resx | 141 ++++++ .../Resources/Views/Device/Success.fi.resx | 126 +++++ .../Views/Device/UserCodeCapture.fi.resx | 129 +++++ .../Views/Device/UserCodeConfirmation.fi.resx | 144 ++++++ .../Resources/Views/Diagnostics/Index.fi.resx | 132 +++++ .../Resources/Views/Grants/Index.fi.resx | 144 ++++++ .../Resources/Views/Home/Index.fi.resx | 156 ++++++ .../Views/Manage/ChangePassword.fi.resx | 135 +++++ .../Views/Manage/DeletePersonalData.fi.resx | 132 +++++ .../Resources/Views/Manage/Disable2fa.fi.resx | 135 +++++ .../Views/Manage/DownloadPersonalData.fi.resx | 123 +++++ .../Views/Manage/EnableAuthenticator.fi.resx | 148 ++++++ .../Views/Manage/ExternalLogins.fi.resx | 132 +++++ .../Manage/GenerateRecoveryCodes.fi.resx | 138 ++++++ .../Resources/Views/Manage/Index.fi.resx | 162 ++++++ .../Views/Manage/LinkLoginFailure.fi.resx | 126 +++++ .../Views/Manage/PersonalData.fi.resx | 135 +++++ .../Views/Manage/ResetAuthenticator.fi.resx | 133 +++++ .../Views/Manage/SetPassword.fi.resx | 138 ++++++ .../Views/Manage/ShowRecoveryCodes.fi.resx | 129 +++++ .../Manage/TwoFactorAuthentication.fi.resx | 171 +++++++ .../Shared/Common/SelectLanguage.fi.resx | 123 +++++ .../IdentityServerAdminLink/Default.fi.resx | 123 +++++ .../Resources/Views/Shared/Error.fi.resx | 129 +++++ .../Resources/Views/Shared/Redirect.fi.resx | 126 +++++ .../Resources/Views/Shared/_Layout.fi.resx | 159 ++++++ .../Views/Shared/_ScopeListItem.fi.resx | 123 +++++ .../Views/Shared/_ValidationSummary.fi.resx | 123 +++++ 120 files changed, 17107 insertions(+), 2 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.fi.resx create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs index c359ec868..0d2f6a55e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/CultureConfiguration.cs @@ -4,7 +4,7 @@ namespace Skoruba.IdentityServer4.Admin.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "es", "da" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "es", "da", "fi" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx new file mode 100644 index 000000000..5a1e569e2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Api-resurssi {0} on tallennettu onnistuneesti! + + + Api-resurssin {0} apiresurssin {1} tallennus onnistui! + + + Api Scope {0} on tallennettu onnistuneesti! + + + Api Secret on luotu onnistuneesti! + + + Asiakkaan {0} luominen onnistui! + + + Asiakasvaatimus {0} asiakkaalle {1} tallennettiin onnistuneesti! + + + Asiakkaan {1} asiakasominaisuus {0} on tallennettu onnistuneesti! + + + Asiakkaan {0} asiakassalaisuus on tallennettu onnistuneesti! + + + Henkilöllisyysresurssi {0} on tallennettu onnistuneesti! + + + Api-resurssin {1} henkilöllisyysresurssin ominaisuus {0} on tallennettu onnistuneesti! + + + Asiakas {0} kloonattiin onnistuneesti! + + + Asiakas on poistettu onnistuneesti! + + + Api-resurssi on poistettu onnistuneesti! + + + Api-resurssiominaisuus on poistettu onnistuneesti! + + + Api-laajuus on poistettu onnistuneesti! + + + Api Secret on poistettu onnistuneesti! + + + Asiakasvaatimus on poistettu onnistuneesti! + + + Asiakasomaisuus on poistettu onnistuneesti! + + + Asiakassalaisuus on poistettu onnistuneesti! + + + Henkilöllisyysresurssi on poistettu onnistuneesti! + + + Henkilöllisyysresurssin ominaisuus on poistettu onnistuneesti! + + + Menestys + + + Asiakkaan {0} päivitys onnistui! + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx new file mode 100644 index 000000000..30e1f02c5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Jatkuva apuraha on poistettu onnistuneesti! + + + Jatkuvat apurahat poistetaan onnistuneesti! + + + Menestys + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx new file mode 100644 index 000000000..707bdb410 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Et voi poistaa itseäsi. Jos haluat poistaa tämän tilin, luo ensin uusi järjestelmänvalvojan tili, vaihda sitten siihen ja poista tämä tili sieltä. + + + Rooli {0} on tallennettu onnistuneesti! + + + Vaatimus {0} - {1} on tallennettu onnistuneesti! + + + Käyttäjän {0} tallennus onnistui! + + + Vaatimus {0} - {1} on tallennettu onnistuneesti! + + + Roolin tallennus onnistui! + + + Roolin poisto onnistui! + + + Vaatimus on onnistuneesti poistettu! + + + Käyttäjä on poistettu onnistuneesti! + + + Vaatimus on onnistuneesti poistettu! + + + Käyttäjätarjoaja on onnistuneesti poistettu! + + + Roolin poisto onnistui! + + + Menestys + + + Uuden salasanan vaihto onnistui! + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.fi.resx new file mode 100644 index 000000000..275c96ef2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ApiResourceService.fi.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Api-resurssia, jonka tunnus on {0}, ei ole + + + Api-resurssi on jo olemassa + + + Api-resurssi ({0}) on jo olemassa + + + Api-resurssiominaisuutta, jonka tunnus on {0}, ei ole + + + Api-resurssiominaisuus on jo olemassa + + + Api-resurssiominaisuus avaimella ({0}) on jo olemassa + + + Api-laajuutta, jonka tunnus on {0}, ei ole + + + Api-laajuus on jo olemassa + + + Api-laajuus ({0}) on jo olemassa + + + Api-salaisuutta, jonka tunnus on {0}, ei ole + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx new file mode 100644 index 000000000..52084b915 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Asiakasvaatimusta tunnuksella {0} ei ole + + + Asiakasta, jonka tunnus on {0}, ei ole + + + Asiakas on jo olemassa + + + Asiakastunnus ({0}) on jo olemassa + + + Asiakasomaisuutta, jonka tunnus on {0}, ei ole + + + Asiakassalaisuutta, jonka tunnus on {0}, ei ole + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx new file mode 100644 index 000000000..ea2f0745e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Henkilöllisyysresurssi {0} on jo olemassa + + + Henkilöllisyysresurssi {0} on jo olemassa + + + Henkilöllisyysresurssiominaisuutta, jonka tunnus on {0}, ei ole + + + Identity Resource Property on jo olemassa + + + Identiteettiresurssiominaisuus avaimella ({0}) on jo olemassa + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx new file mode 100644 index 000000000..b8b1b2750 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Virhe + + + Roolivastausta tunnuksella {0} ei ole + + + Rooliväittämien luominen epäonnistui + + + Rooliväitteiden poistaminen epäonnistui + + + Roolin luominen epäonnistui + + + Roolin poistaminen epäonnistui + + + Roolia tunnuksella {0} ei ole + + + Roolin päivitys epäonnistui + + + Käyttäjän vaihto-salasana epäonnistui + + + Käyttäjävaatimusta tunnuksella {0} ei ole + + + Käyttäjävaatimusten luominen epäonnistui + + + Käyttäjävaatimusten poistaminen epäonnistui + + + Käyttäjän luominen epäonnistui + + + Käyttäjän poistaminen epäonnistui + + + Käyttäjää, jonka tunnus on {0}, ei ole + + + Käyttäjätarjoajan poistaminen epäonnistui + + + Käyttäjätoimittajaa, jonka tunnus on {0}, ei ole + + + Käyttäjäroolin luominen epäonnistui + + + Käyttäjäroolin poistaminen epäonnistui + + + Käyttäjän päivitys epäonnistui + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx new file mode 100644 index 000000000..5795a0750 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Jatkuvaa apurahaa, jonka tunnus on {0}, ei ole + + + Pysyvää apurahaa tälle aiheen tunnukselle {0} ei ole + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.fi.resx new file mode 100644 index 000000000..ed387a84f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Account/AccessDenied.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kirjaudu ulos + + + Pääsy evätty! + + + Palaa takaisin IdentityServeriin + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx new file mode 100644 index 000000000..7f4f34bfc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista Api-resurssi + + + Hallitse Api-resurssiominaisuuksia + + + Hallitse Api-laajuuksia + + + Hallitse Api-salaisuuksia + + + Tallenna Api-resurssi + + + Api-resurssit + + + Api-resurssi + + + Api-resurssi + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx new file mode 100644 index 000000000..38d4aea76 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tätä arvoa voidaan käyttää esimerkiksi suostumusnäytöllä. + + + Kuvaus + + + Tätä arvoa voidaan käyttää esimerkiksi suostumusnäytöllä. + + + Näyttönimi + + + Osoittaa, onko tämä resurssi käytössä ja voidaanko sitä pyytää. Oletusarvo totta. + + + käytössä + + + päättyminen + + + päättyminen + + + Sovellusliittymän yksilöivä nimi. Tätä arvoa käytetään autentikointiin itsehavainnolla, ja se lisätään lähtevän käyttöoikeustunnuksen yleisölle. + + + Nimi + + + Sanakirja pitää tarvittavat mukautetut api-resurssikohtaiset arvot. + + + ominaisuudet + + + avain + + + avain + + + Arvo + + + Arvo + + + Sovellusliittymällä on oltava ainakin yksi laajuus. Jokaisella laajuudella voi olla erilaisia asetuksia. + + + laajuudet + + + Kuvaus + + + Kuvaus + + + API-salaisuutta käytetään itsetutkimuksen päätepisteeseen. Sovellusliittymä voi todentaa itsetutkimuksella käyttämällä API-nimeä ja salaisuutta. + + + Secrets + + + Luettelo liittyvistä käyttäjän vaatimustyypeistä, jotka tulisi sisällyttää käyttöoikeustunnukseen. + + + Käyttäjän vaatimukset + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.fi.resx new file mode 100644 index 000000000..4273b7fd3 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceDelete.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista Api-resurssi + + + Api-resurssit + + + Poista Api-resurssi + + + Poista Api-resurssi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx new file mode 100644 index 000000000..133ac68b8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää Api Resource Property + + + Api-resurssin ominaisuudet + + + Api-resurssit + + + Api-resurssin ominaisuudet + + + Api-resurssin ominaisuudet + + + Api-resurssiomaisuus + + + Poistaa + + + avain + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.fi.resx new file mode 100644 index 000000000..371b90429 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourcePropertyDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista Api-resurssiominaisuus + + + Api-resurssin ominaisuudet + + + Api-resurssit + + + Poista Api-resurssiominaisuus + + + Poista Api-resurssiominaisuus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.fi.resx new file mode 100644 index 000000000..fe54fd75d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResources.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää Api-resurssi + + + Api-resurssit + + + Api-resurssit + + + Muokkaa + + + Nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.fi.resx new file mode 100644 index 000000000..2fe38a806 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopeDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista Api-laajuus + + + Api-resurssit + + + Api-laajuudet + + + Poista Api-laajuus + + + Poista Api-laajuus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx new file mode 100644 index 000000000..22fd57d16 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Säästä Api-laajuus + + + Api-resurssit + + + Api-laajuudet + + + Api-laajuudet + + + Api-laajuus + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + + Muokkaa + + + Poistaa + + + Nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx new file mode 100644 index 000000000..b3c749ae9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista Api Secret + + + Api-resurssit + + + Api-salaisuudet + + + Poista Api Secret + + + Poista Api Secret + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx new file mode 100644 index 000000000..e99821ef4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää Api Secret + + + HashType on käytettävissä vain SharedSecret-tyypille. + + + Tiedot: + + + Api-resurssit + + + Api-salaisuudet + + + Api-salaisuudet + + + Api-salaisuus + + + Api-salaisuudet + + + Poistaa + + + Luotu + + + Kuvaus + + + päättyminen + + + Tyyppi + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx new file mode 100644 index 000000000..16d58416c --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + asiakkaat + + + Asiakas + + + Asiakas - + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx new file mode 100644 index 000000000..de5a960b5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kloonausasiakas + + + Poista asiakas + + + Tallenna asiakas + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx new file mode 100644 index 000000000..197401756 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authentication / ulos + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx new file mode 100644 index 000000000..bf73728f9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hallitse asiakasominaisuuksia + + + Hallitse asiakassalaisuuksia + + + Perusasiat + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx new file mode 100644 index 000000000..6d10cbc97 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Suostumusnäyttö + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx new file mode 100644 index 000000000..a34075edd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Päivitysmerkin enimmäiskesto sekunneissa. Oletusarvo on 2592000 sekuntia / 30 päivää + + + Absoluuttinen päivitysmerkin käyttöikä + + + Käyttöoikeustunnuksen elinikä sekunneissa (oletusarvo on 3600 sekuntia / 1 tunti) + + + Access Token Lifetime + + + Määrittää, onko käyttöoikeustunnus viitetunniste vai itsenäinen JWT-tunnus (oletusarvo on Jwt). + + + Käyttöoikeustyyppi + + + Määrittää, sallitaanko tämän asiakkaan vastaanottaa käyttöoikeuksia selaimen kautta. Tämä on hyödyllistä kovettaa vuoita, jotka sallivat useita vastaustyyppejä (esim. Estämällä hybridivirtausasiakas, jonka oletetaan käyttävän koodia id_token lisätäkseen tokenin vastaustyypin ja vuotaen siten tokenin selaimeen. + + + Salli Access Token selaimen kautta + + + Määrittää, voiko tämä asiakas pyytää päivitystunnuksia (pyytää offline_access-laajuutta) + + + Salli offline-käyttö + + + Määrittää, voivatko PKCE: tä käyttävät asiakkaat käyttää tekstitekstin haastetta (ei suositella - ja oletusarvo on väärä) + + + Salli pelkkää tekstiä + + + Määrittää, voiko käyttäjä tallentaa suostumuspäätökset. Oletusarvo totta. + + + Salli Muista suostumus + + + + + + Sisällytä käyttäjän vaatimukset aina IdTokeniin + + + Jos asetettu, asiakasvaatimukset lähetetään jokaisesta vuoista. Jos ei, vain asiakkaan käyttöoikeustiedot -virta (oletus on väärä) + + + Lähetä asiakasvaatimukset aina + + + Valtuutuskoodin elinikä sekunneissa (oletusarvo 300 sekuntia / 5 minuuttia) + + + Valtuutuskoodin käyttöikä + + + Asiakkaan yksilöivä tunnus + + + Asiakastunnus + + + Asiakkaan näyttönimi (käytetään kirjautumiseen ja suostumusnäyttöön) + + + Asiakkaan Nimi + + + URI lisätietoja asiakkaasta (käytetään suostumusnäytössä) + + + Asiakas Uri + + + Määrittää, onko asiakas käytössä. Oletusarvo totta. + + + käytössä + + + Määrittää, pystyykö tämä asiakas käyttämään paikallisia tilejä vai vain ulkoisia IdP: tä. Oletusarvo totta. + + + Ota paikallinen sisäänkirjautuminen käyttöön + + + Elinikä identiteettitunnukseen sekunneissa (oletusarvo 300 sekuntia / 5 minuuttia) + + + Identity Token Lifetime + + + Määrittää, onko JWT-käyttöoikeustunnuksilla oltava upotettu yksilöllinen tunnus (jti-vaatimuksen kautta). + + + Sisällytä Jwt-tunnus + + + URI asiakkaan logoon (käytetään suostumusnäytössä) + + + Logo Uri + + + Absoluuttinen päivitystunnus vanhenee kiinteänä ajankohtana (määritelty AbsoluteRefreshTokenLifetime) + +Liukusäädintä päivitettäessä merkkiä, päivityksen tokenin käyttöikä uusitaan (SlidingRefreshTokenLifetime-kohdassa määritetyn määrän verran). Elinikä ei ylitä AbsoluteRefreshTokenLifetime -aikaa. + + + Päivitä tokenin vanheneminen + + + Uudelleenkäyttö Päivitä merkinnän kahva pysyy samana päivitettäessä merkkejä + +Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä + + + Päivitä Token-käyttö + + + Uudelleenkäyttö Päivitä merkinnän kahva pysyy samana päivitettäessä merkkejä + +Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä + + + Päivitä Token-käyttö + + + Määrittää, tarvitseeko tämä asiakas salaisuuden tokenien pyytämiseen tokenin päätepisteestä (oletusarvo on tosi) + + + Vaadi asiakassalaisuus + + + Määrittää, tarvitaanko suostumusnäyttö. Oletusarvo totta. + + + Vaatii suostumus + + + Määrittää, onko valtuuskoodipohjaista avustustyyppiä käyttävien asiakkaiden lähetettävä todisteavain + + + Vaadi Pkce + + + Päivitysmerkin liukuva käyttöikä sekunneissa. Oletusarvo on 1296000 sekuntia / 15 päivää + + + Liukuva päivitysmerkin käyttöikä + + + Hanki tai asettaa arvon, joka ilmaisee, onko käyttöoikeustunnus (ja sen vaatimukset) päivitettävä päivitystunnuspyynnössä. + + + Päivitä Access Token -vaatimukset päivitettäessä + + + Jos määritetään, sitä käytetään oletus CORS-käytäntöpalvelun toteutuksissa (muistissa ja EF) rakentamaan CORS-käytäntö JavaScript-asiakkaille. + + + Sallittujen korsien alkuperä + + + Määrittää avustyypit, joita asiakkaan sallitaan käyttää. Käytä GrantTypes-luokkaa yleisiin yhdistelmiin. Oletusapurahojen luettelo: implisiittinen apuraha - (implisiittinen), asiakastodistusten myöntäminen - (asiakas_koodit), käyttöoikeuskoodin myöntäminen - (valtuuskoodi), yhdistelmäapu - (hybridi), resurssin omistajan salasanan käyttöoikeudet - (salasana) + + + Sallitut avustuslajit + + + Oletuksena asiakkaalla ei ole pääsyä resursseihin - määritä sallitut resurssit lisäämällä vastaavat laajuusnimet + + + Sallitut laajuudet + + + Sallii asiakasasetuksia koskevat vaatimukset (sisällytetään käyttöoikeustunnukseen). + + + väittää + + + Luettelo asiakassalaisuuksista - käyttöoikeustiedot avataksesi token-päätepiste. + + + Asiakassalaisuudet + + + Määrittää, mitä ulkoisia IdP: itä voidaan käyttää tämän asiakkaan kanssa (jos luettelo on tyhjä, kaikki IdP: t ovat sallittuja). Oletusasetus on tyhjä. + + + Henkilöllisyyden tarjoajan rajoitukset + + + Määrittää sallitut URI: t uudelleenohjautua uloskirjautumisen jälkeen + + + Uloskirjautumisen uudelleenohjaus Uris + + + Määrittää sallitut URI: t, joihin palautetaan tokenit tai valtuuskoodit + + + Ohjaa Uris + + + + + + Vaatimuksen tyyppi + + + + + + Vaatimuksen arvo + + + + + + Salainen tyyppi + + + + + + Salainen arvo + + + + + + Hash-tyyppi + + + Normalisoitu roolinimi + + + Normalisoitu nimi + + + Määrittää, lähetetäänkö käyttäjän istunnon tunnus pyynnössä BackChannelLogoutUri -sivulle. Oletusarvo totta. + + + Takaisin kanavan uloskirjautumisistunto vaaditaan + + + Määrittää uloskirjautumisen URI: n asiakkaassa HTTP-pohjaisen takakanavan uloskirjautumisen yhteydessä. Katso lisätietoja OIDC-takakanavan teknisistä tiedoista. + + + Takaisin kanavan uloskirjautuminen Uri + + + Jos asetettu, etuliiteasiakkaan vaatimustyypit etuliitetetään. Oletusarvot asiakas_. Tarkoituksena on varmistaa, etteivät ne törmää vahingossa käyttäjän vaatimuksiin. + + + Asiakasvaatimusten etuliite + + + Asiakkaan kuvaus + + + Kuvaus + + + Määrittää, onko käyttäjän istunnon tunnus lähetettävä FrontChannelLogoutUri -sovellukseen. Oletusarvo totta. + + + Etuskanavan uloskirjautumisistunto vaaditaan + + + Määrittää uloskirjautumisen URI asiakasohjelmassa HTTP-pohjaisen etukanavan uloskirjautumisen yhteydessä. Katso lisätietoja OIDC Front Channel -spesifikaatiosta. + + + Front Channel Logout Uri + + + Suola-arvo, jota käytetään parinpohjaisessa subjektien luonnissa tämän asiakkaan käyttäjille. + + + Yhdistä viisas aiheinen suola + + + Sanakirja pitää tarvittavat mukautetut asiakaskohtaiset arvot. + + + ominaisuudet + + + avain + + + avain + + + Arvo + + + Arvo + + + Oletus on OpenID Connect -protokolla + + + Protokollan tyyppi + + + Enimmäiskesto (sekunteina) viimeisimmästä käyttäjän todennuksesta. Oletusarvo on nolla + + + User Sso Lifetime + + + Laitekoodin käyttöikä sekunneissa (oletusarvo 300 sekuntia / 5 minuuttia) + + + Laitekoodin käyttöikä + + + Määrittää asiakaskoodin tyypin, jota asiakas käyttää. Muutoin palaa takaisin oletusasetukseen. + + + Käyttäjätunnuksen tyyppi + + + päättyminen + + + päättyminen + + + Kuvaus + + + Kuvaus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx new file mode 100644 index 000000000..377d1d875 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nimi + + + Valtuutuskoodivirta PKCE: llä + + + TV- ja rajoitetun tulon laitesovellus + + + Laitteen virtaus + + + Tyhjä - oletus + + + Hybridi virtaus + + + Implisiittinen virtaus + + + Kone / Robot + + + Alkuperäinen sovellus - mobiili / työpöytä + + + Resurssien omistajan salasana ja asiakkaan käyttöoikeustiedot kulkevat + + + Yhden sivun sovellus - Javascript + + + Verkkosovellus - palvelinpuoli + + + Verkkosovellus - palvelinpuoli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx new file mode 100644 index 000000000..974952e66 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hallinnoi asiakasvaatimuksia + + + symbolinen + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx new file mode 100644 index 000000000..549041a55 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authentication / ulos + + + Perusasiat + + + Suostumusnäyttö + + + Laitevirta + + + Nimi + + + symbolinen + + + asetukset + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx new file mode 100644 index 000000000..9a1c42a93 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista asiakasvaatimus + + + Asiakasvaatimukset + + + asiakkaat + + + Poista asiakasvaatimus + + + Poista asiakasvaatimus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx new file mode 100644 index 000000000..6eae02320 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää asiakasvaatimus + + + Asiakasvaatimukset + + + asiakkaat + + + Asiakasvaatimukset + + + Asiakkaan vaatimus + + + Asiakasvaatimukset + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Tyyppi vaaditaan + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + + Poistaa + + + Tyyppi + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx new file mode 100644 index 000000000..4b199373a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kloonausasiakas + + + Asiakassalaisuuksia ei kloonata. + + + Tiedot: + + + Asiakasvaatimukset + + + Asiakaskorien alkuperä + + + Asiakkaiden avustustyypit + + + Client IdP -rajoitukset + + + Asiakkaan lähettämisen uloskirjautumisen uudelleenohjaus Uris + + + Asiakkaan ominaisuudet + + + Asiakasohjaaja Uris + + + Asiakasalueet + + + asiakkaat + + + Kloonausasiakas + + + Asiakas + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx new file mode 100644 index 000000000..1c1b20300 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista asiakas + + + asiakkaat + + + Poista asiakas + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx new file mode 100644 index 000000000..8292207da --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää asiakasominaisuus + + + Asiakkaan ominaisuudet + + + asiakkaat + + + Asiakkaan ominaisuudet + + + Asiakkaan ominaisuudet + + + Asiakkaan omaisuus + + + Poistaa + + + avain + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx new file mode 100644 index 000000000..7e9b6d008 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista asiakasominaisuus + + + Asiakkaan ominaisuudet + + + asiakkaat + + + Poista asiakasominaisuus + + + Poista asiakasominaisuus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx new file mode 100644 index 000000000..9914832a1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista asiakassalaisuus + + + asiakkaat + + + Asiakassalaisuudet + + + Poista asiakassalaisuus + + + Poista asiakassalaisuus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx new file mode 100644 index 000000000..88db99d9e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää asiakassalaisuus + + + HashType on käytettävissä vain SharedSecret-tyypille. + + + Tiedot: + + + asiakkaat + + + Asiakassalaisuudet + + + Asiakassalaisuudet + + + Asiakassalaisuudet + + + Asiakassalaisuus + + + Poistaa + + + Tyyppi + + + Arvo + + + Luotu + + + Kuvaus + + + päättyminen + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx new file mode 100644 index 000000000..1ff1513b7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää asiakas + + + asiakkaat + + + Muokkaa + + + Asiakastunnus + + + Asiakkaan Nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx new file mode 100644 index 000000000..22ac988d6 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista henkilöllisyysresurssi + + + Hallitse henkilöllisyysresurssien ominaisuuksia + + + Tallenna henkilöllisyysresurssi + + + Henkilöllisyysresurssit + + + Henkilöllisyysresurssi + + + Henkilöllisyysresurssi + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx new file mode 100644 index 000000000..d730c7078 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tätä arvoa käytetään esimerkiksi suostumusnäytöllä. + + + Kuvaus + + + Tätä arvoa käytetään esimerkiksi suostumusnäytöllä. + + + Näyttönimi + + + Määrittää, korostaako suostumusnäyttö tätä laajuutta (jos suostumusnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Käytä tätä asetusta herkille tai tärkeille alueille. Oletusarvo on väärä. + + + painottaa + + + Osoittaa, onko tämä resurssi käytössä ja voidaanko sitä pyytää. Oletusarvo totta. + + + käytössä + + + Henkilöllisyysresurssin yksilöllinen nimi. Tämä on arvo, jota asiakas käyttää laajuusparametrissa valtuutuspyynnössä. + + + Nimi + + + Sanakirja, jolla voidaan pitää tarvittavat mukautetut identiteettiresurssikohtaiset arvot. + + + ominaisuudet + + + avain + + + avain + + + Arvo + + + Arvo + + + Määrittää, voiko käyttäjä poistaa valinnan laajuudesta suostumusnäytössä (jos suostumusnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Oletusarvo on väärä. + + + Vaaditaan + + + Määrittää, näkyykö tämä laajuus Konfiguraation dokumenttssa. Oletusarvo totta. + + + Näytä Konfiguraation dokumenttssa + + + Luettelo liittyvistä käyttäjän vaatimustyypeistä, jotka tulisi sisällyttää identiteettitunnisteeseen. + + + Käyttäjän vaatimukset + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx new file mode 100644 index 000000000..775ca1ace --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista henkilöllisyysresurssi + + + Henkilöllisyysresurssit + + + Poista henkilöllisyysresurssi + + + Poista henkilöllisyysresurssi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx new file mode 100644 index 000000000..41c59418d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää henkilöllisyysresurssien omaisuus + + + Henkilöllisyysresurssien ominaisuudet + + + Henkilöllisyysresurssit + + + Henkilöllisyysresurssien ominaisuudet + + + Henkilöllisyysresurssien ominaisuudet + + + Henkilöllisyysresurssien omaisuus + + + Poistaa + + + avain + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.fi.resx new file mode 100644 index 000000000..8dc13d822 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourcePropertyDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista henkilöllisyysresurssien omaisuus + + + Henkilöllisyysresurssien ominaisuudet + + + Henkilöllisyysresurssit + + + Poista henkilöllisyysresurssien omaisuus + + + Poista henkilöllisyysresurssien omaisuus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx new file mode 100644 index 000000000..333906860 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää henkilöllisyysresurssi + + + Henkilöllisyysresurssit + + + Muokkaa + + + Nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx new file mode 100644 index 000000000..4cf60ed7b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista kaikki + + + Oletko varma? Kaikki tähän aiheeseen liittyvät pysyvät apurahat poistetaan. + + + Ei - sulje + + + Varoitus + + + Kyllä - poista + + + Pysyvät oikeudet + + + Jatkoi apurahaa + + + Asiakas + + + data + + + päättyminen + + + Aiheen tunnus + + + Tyyppi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx new file mode 100644 index 000000000..dcc838fef --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista pysyvä apuraha + + + Pysyvät oikeudet + + + Poista pysyvä apuraha + + + Asiakas + + + data + + + päättyminen + + + Aiheen tunnus + + + Tyyppi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.fi.resx new file mode 100644 index 000000000..18a6feaee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrants.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Pysyvät oikeudet + + + Yksityiskohta + + + Aiheen tunnus + + + Aiheen nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx new file mode 100644 index 000000000..8cfd0df77 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Api-resurssit + + + asiakkaat + + + Henkilöllisyysresurssit + + + Hallinnoi + + + Pysyvät oikeudet + + + roolit + + + käyttäjät + + + IdentityServer4: n ja Asp.Net Core Identity: n hallinto + + + Skoruba IdentityServer4 Järjestelmänvalvoja + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx new file mode 100644 index 000000000..7f45d1183 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää roolivaatimukset + + + Poista rooli + + + käyttäjät + + + Tallenna rooli + + + roolit + + + Rooli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.fi.resx new file mode 100644 index 000000000..6ade5daa2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role/Section/Label.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Roolin nimi + + + Roolinimi + + + + + + Vaatimuksen tyyppi + + + + + + Vaatimuksen arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx new file mode 100644 index 000000000..2e8a58972 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää roolivaatimus + + + roolit + + + Roolivaatimukset + + + Roolivaatimukset + + + vaatimus + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Tyyppi vaaditaan + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + + Poistaa + + + Tyyppi + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx new file mode 100644 index 000000000..b026c5228 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista rooliväite + + + Roolivaatimukset + + + roolit + + + Poista rooliväite + + + Poista rooliväite + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx new file mode 100644 index 000000000..469b60508 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista rooli + + + roolit + + + Poista rooli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx new file mode 100644 index 000000000..1baa025e2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hae + + + Sähköposti + + + Hae + + + roolit + + + Roolin käyttäjät + + + Käyttäjätunnus + + + Käyttäjänimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx new file mode 100644 index 000000000..dd8b66b2e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää rooli + + + roolit + + + Muokkaa + + + käyttäjät + + + Nimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx new file mode 100644 index 000000000..830339fcd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Roolin nimi + + + Roolinimi + + + Rooli + + + Rooli + + + + + + Vaatimuksen tyyppi + + + Käyttäjän käyttö epäonnistui + + + Käyttäjän käyttö epäonnistui + + + Vahvista salasana + + + Vahvista salasana + + + Salasana + + + Salasana + + + Käyttäjätunnus + + + Käyttäjätunnus + + + Käyttäjän sähköposti vahvistettu + + + Käyttäjän sähköposti vahvistettu + + + Sähköposti + + + Sähköposti + + + Käyttäjän lukitus käytössä + + + Käyttäjän lukitus käytössä + + + Käyttäjän lukitus loppuu + + + Käyttäjän lukitus loppuu + + + Käyttäjän puhelinnumero vahvistettu + + + Käyttäjän puhelinnumero vahvistettu + + + Käyttäjän puhelinnumero + + + Käyttäjän puhelinnumero + + + Sisäänkirjautumisen tarjoaja + + + Sisäänkirjautumisen tarjoaja + + + Näyttönimi + + + Näyttönimi + + + Palveluntarjoaja-avain + + + Palveluntarjoaja-avain + + + Käyttäjän kaksi tekijää käytössä + + + Käyttäjän kaksi tekijää käytössä + + + Käyttäjätunnus + + + Käyttäjätunnus + + + + + + Vaatimuksen arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx new file mode 100644 index 000000000..c0422a4d5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vaihda salasana + + + käyttäjät + + + Käyttäjän vaihto salasana + + + Vaihda salasana + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx new file mode 100644 index 000000000..9ce6d298b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää käyttäjän vaatimus + + + käyttäjät + + + Käyttäjän vaatimukset + + + Käyttäjän vaatimukset + + + Käyttäjän vaatimus + + + kohde on jo valittu + + + Kohteita ei ole valittu + + + Tyyppi vaaditaan + + + Kirjoita vähintään 2 merkkiä + + + Hakutulos: (napsauta tuotetta valitaksesi) + + + Valitut kohteet: + + + lisää + + + Ehdotetut tuotteet: + + + Poistaa + + + Tyyppi + + + Arvo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx new file mode 100644 index 000000000..370ca67cc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista käyttäjän vaatimus + + + Käyttäjän vaatimukset + + + käyttäjät + + + Poista käyttäjän vaatimus + + + Poista käyttäjän vaatimus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx new file mode 100644 index 000000000..8cdbe0ffe --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista käyttäjä + + + käyttäjät + + + Poista käyttäjä + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx new file mode 100644 index 000000000..ee59216d2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tarkastusloki + + + Vaihda salasana + + + Poista käyttäjä + + + Hallinnoi käyttäjän vaatimuksia + + + Hallinnoi käyttäjän ulkoisia palveluntarjoajia + + + Hallinnoi käyttäjärooleja + + + Tallenna käyttäjä + + + käyttäjät + + + käyttäjä + + + käyttäjä + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx new file mode 100644 index 000000000..f900c692e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + käyttäjät + + + Käyttäjätarjoajat + + + Poistaa + + + Sisäänkirjautumisen tarjoaja + + + Palveluntarjoajan näyttönimi + + + Palveluntarjoaja-avain + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx new file mode 100644 index 000000000..c85fb7734 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista käyttäjän palveluntarjoaja + + + Käyttäjätarjoajat + + + käyttäjät + + + Poista käyttäjän palveluntarjoaja + + + Poista käyttäjän palveluntarjoaja + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx new file mode 100644 index 000000000..7f6dcff04 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää rooli + + + Poistaa + + + käyttäjät + + + Nimi + + + Käyttäjän rooli + + + Käyttäjäroolit + + + roolit + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx new file mode 100644 index 000000000..41c8de5ee --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista rooli + + + Käyttäjäroolit + + + käyttäjät + + + Poista rooli + + + Käyttäjän rooli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx new file mode 100644 index 000000000..e7321c065 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää käyttäjä + + + Muokkaa + + + Sähköposti + + + käyttäjät + + + Käyttäjätunnus + + + Käyttäjänimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx new file mode 100644 index 000000000..54de81680 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Toiminta + + + Oletko varma? + + + Tarkastusloki + + + Kategoria + + + Luotu + + + Poista lokit, jotka ovat vanhempia + + + Yksityiskohta + + + Tapahtuma + + + Ei - sulje + + + Hae + + + Näytä yksityiskohdat + + + Lähde + + + aihe + + + Aiheen tunniste + + + Aiheen nimi + + + Varoitus + + + Kyllä - poista + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx new file mode 100644 index 000000000..065898fea --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista lokit, jotka ovat vanhempia + + + Oletko varma? + + + Ei - sulje + + + Varoitus + + + Kyllä - poista + + + lokit + + + Taso + + + kirjautunut + + + Viesti + + + Näytä yksityiskohdat + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.fi.resx new file mode 100644 index 000000000..9aed0cd74 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/ErrorPage.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Virhe + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.fi.resx new file mode 100644 index 000000000..7f4cab4d9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Pager.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ensimmäinen + + + Viimeinen + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fi.resx new file mode 100644 index 000000000..7f4cab4d9 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/PagerDynamic.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ensimmäinen + + + Viimeinen + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.fi.resx new file mode 100644 index 000000000..ee6d02b2a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/Search.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hae + + + Hae + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.fi.resx new file mode 100644 index 000000000..4f91d16b5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Common/SelectLanguage.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kieli: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.fi.resx new file mode 100644 index 000000000..27ad81e9d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/Components/IdentityServerLink/Default.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx new file mode 100644 index 000000000..73e1de289 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + &kopio; 2018 + + + Skoruba IdentityServer4 Järjestelmänvalvoja + + + Api-resurssit + + + asiakkaat + + + Henkilöllisyysresurssit + + + Kirjaudu ulos + + + Pysyvät oikeudet + + + roolit + + + käyttäjät + + + valikko + + + Skoruba IdentityServer4 Järjestelmänvalvoja + + + Asiakkaat / Resurssit + + + lokit + + + Käyttäjät / roolit + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs index b604ab3f9..a8505a635 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/CultureConfiguration.cs @@ -4,7 +4,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.Configuration { public class CultureConfiguration { - public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "da" }; + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "da", "fi" }; public static readonly string DefaultRequestCulture = "en"; public List Cultures { get; set; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.fi.resx new file mode 100644 index 000000000..c0cc2e150 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/AccountController.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista tilisi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + vahvista sähköpostiosoitteesi + + + Käyttäjää ei ole tai sitä ei ole vahvistettu + + + Ulkoisen palveluntarjoajan virhe: {0} + + + Virheellinen todennuskoodi. + + + Annettu virheellinen palautuskoodi. + + + Palauta salasanasi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + Nollaa salasana + + + Kahden tekijän todennuksen käyttäjää ei voi ladata. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fi.resx new file mode 100644 index 000000000..518caf788 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Controllers/ManageController.fi.resx @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Käyttäjä, jonka tunnus '{0}', pyysi henkilökohtaisia tietojaan. + + + Autentikaattorisovelluksesi on vahvistettu. + + + Vahvista tilisi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + vahvista sähköpostiosoitteesi + + + Käyttäjä, jonka tunnus '{0}', poisti itsensä. + + + Palautuskoodeja ei voi luoda käyttäjälle, jonka tunnus on {0}, koska heillä ei ole 2FA: ta käytössä. + + + Koodi + + + Käyttäjän, jolla on tunnus {0}, poistamisessa tapahtui odottamaton virhe. + + + Odottamaton virhe tapahtui poistamalla 2FA käytöstä käyttäjälle, jolla on tunnus {0}. + + + Palautuskoodeja ei voi luoda käyttäjälle, koska heillä ei ole 2FA: ta käytössä. + + + Odottamaton virhe ladattaessa ulkoista kirjautumistietoa käyttäjälle, jolla on tunnus {0}. + + + Odottamaton virhe ulkoisen kirjautumisen poistamisessa käyttäjälle, jolla on tunnus {0}. + + + Asettamalla odottamaton virhe sähköpostin asettamisessa käyttäjälle, jolla on tunnus {0}. + + + Asettamalla odottamaton virhe puhelinnumeron asettamisessa käyttäjälle, jolla on tunnus {0}. + + + Ulkoinen kirjautuminen lisättiin. + + + Ulkoinen sisäänkirjautuminen poistettiin. + + + Vahvistuskoodi on virheellinen. + + + Salasanasi on vaihdettu. + + + Käyttäjä {0} vaihtoi salasanansa onnistuneesti. + + + Salasana ei ole oikea. + + + Salasanasi on asetettu. + + + Profiilisi on päivitetty + + + Käyttäjätunnuksella {0} on poistettu 2fa käytöstä. + + + Nykyinen selain on unohdettu. Kun kirjaudut sisään uudelleen tästä selaimesta, sinulta kysytään 2fa-koodiasi. + + + Käyttäjä, jonka tunnus on {0}, on nollannut todennussovelluksen avaimen. + + + Käyttäjä, jonka tunnus on {0}, on ottanut käyttöön 2FA: n todennussovelluksella. + + + Käyttäjä, jonka tunnus on {0}, on luonut uusia 2FA-palautuskoodeja. + + + Käyttäjää, jolla on tunnus {0}, ei voi ladata. + + + Varmennusviesti lähetetty. Ole hyvä ja tarkista sähköpostisi. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx new file mode 100644 index 000000000..dbe9d059d --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kiitos sähköpostiviestisi vahvistamisesta. + + + Vahvista sähköposti + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx new file mode 100644 index 000000000..bb20d998a --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sähköposti + + + Olet todennut {0} onnistuneesti. +        Kirjoita tämän sivuston sähköpostiosoite alle ja napsauta Rekisteröi-painiketta viimeistelläksesi +        Kirjaudu sisään. + + + Rekisteröidy + + + Yhdistä {0} -tilisi. + + + Rekisteröidy + + + Käyttäjänimi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx new file mode 100644 index 000000000..742fb61e1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Epäonnistunut kirjautuminen palveluun. + + + Kirjautuminen epäonnistui + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx new file mode 100644 index 000000000..621f15286 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lähetä + + + Syötä sähköpostiosoitteesi. + + + Unohditko salasanasi? + + + Sähköposti + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx new file mode 100644 index 000000000..fd4ad8b6c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tarkista salasanasi tarkistamalla sähköpostiosoitteesi. + + + Unohtunut salasanan vahvistus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.fi.resx new file mode 100644 index 000000000..bad3dc307 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Lockout.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tämä tili on lukittu, yritä myöhemmin uudelleen. + + + Lukittu + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx new file mode 100644 index 000000000..e034ef8fb --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Klikkaus + + + tässä + + + palata + + + Olet nyt kirjautunut ulos + + + Kirjaudu ulos + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fi.resx new file mode 100644 index 000000000..3ea20a2f7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Login.fi.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Peruuttaa + + + Sähköposti + + + Ulkoinen kirjautuminen + + + Unohtuiko salasana + + + Virheellinen sisäänkirjauspyyntö + + + Paikallinen kirjautuminen + + + Kirjaudu sisään + + + Tätä asiakasohjelmaa varten ei ole määritetty kirjautumismalleja. + + + Salasana + + + Rekisteröidy + + + Muista kirjautumiseni + + + Kirjaudu sisään + + + Käyttäjätunnus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx new file mode 100644 index 000000000..82a0a38a4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authenticator-koodi + + + Kirjautumistunnuksesi on suojattu todennussovelluksella. Kirjoita todennuskoodi alla. + + + Kirjaudu sisään + + + kirjaudu sisään palautuskoodilla + + + Eikö sinulla ole pääsyä todennuslaitteeseesi? Sinä pystyt + + + Muista tämä kone + + + Kaksivaiheinen todennus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx new file mode 100644 index 000000000..ccca2c11c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Palautuskoodi + + + Olet pyytänyt Kirjaudu sisään palautuskoodilla. Tätä sisäänkirjautumista ei muisteta, ennen kuin annat +    todennussovelluksen koodi kirjautumisen yhteydessä tai poista 2FA käytöstä ja kirjaudu sisään uudelleen. + + + Kirjaudu sisään + + + Palautuskoodin varmennus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx new file mode 100644 index 000000000..58682bf5e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Haluatko Kirjaudu ulos IdentityServeristä? + + + Kirjaudu ulos + + + Joo + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fi.resx new file mode 100644 index 000000000..ee84b61b5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Register.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Rekisteröidy + + + Vahvista salasana + + + Sähköposti + + + Salasana + + + Luo uusi tili. + + + Rekisteröidy + + + Käyttäjätunnus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx new file mode 100644 index 000000000..7d85d9136 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + Sähköposti + + + Salasana + + + Nollaa + + + Nollaa salasana. + + + Nollaa salasana + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx new file mode 100644 index 000000000..fdd93a4ec --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Salasanasi on nollattu. Ole kiltti + + + kirjaudu sisään napsauttamalla tätä + + + Nollaa salasanan vahvistus + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.fi.resx new file mode 100644 index 000000000..e3d94f966 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Consent/Index.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sovelluksen käyttö + + + Ei, älä salli + + + Henkilökohtaisia tietoja + + + Muista päätökseni + + + pyytää lupaa + + + Poista valinnat, joita et halua myöntää. + + + Kyllä, salli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx new file mode 100644 index 000000000..9cac83997 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Menestys + + + Olet valtuuttanut laitteen onnistuneesti + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx new file mode 100644 index 000000000..25dfcbaed --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Anna laitteellasi näkyvä koodi + + + Lähetä + + + Käyttäjäkoodi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx new file mode 100644 index 000000000..914e93915 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sovelluksen käyttö + + + Vahvista, että valtuutuspyynnössä on mainittu koodi: + + + Ei, älä salli + + + Henkilökohtaisia tietoja + + + Muista päätökseni + + + pyytää lupaa + + + Poista valinnat, joita et halua myöntää. + + + Kyllä, salli + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx new file mode 100644 index 000000000..b16883806 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + väittää + + + asiakkaat + + + ominaisuudet + + + Todennus eväste + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fi.resx new file mode 100644 index 000000000..a1fab30cc --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Grants/Index.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + API-tuet + + + Luotu: + + + Erääntyy: + + + Henkilöllisyystodistukset + + + Et ole antanut käyttöoikeutta mihinkään sovelluksiin + + + Peruuta käyttöoikeus + + + Alla on luettelo sovelluksista, joille olet saanut pääsyn, ja resurssien nimet, joihin heillä on pääsy. + + + Asiakassovelluksen käyttöoikeudet + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx new file mode 100644 index 000000000..209f24da7 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kaksivaiheinen todennus + + + Vaihda salasana + + + Konfiguraation dokumentt + + + Pysyvät oikeudet + + + käyttövalmiita näytteitä + + + lähdekoodien arkisto + + + Tässä on linkit + + + Kirjaudu sisään + + + Henkilökohtaiset tietoni + + + Profiilini + + + Tervetuloa Skoruba IdentityServer4: een + + + Skoruba IdentityServer4 + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx new file mode 100644 index 000000000..01d3c0841 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + uusi salasana + + + vanha salasana + + + Vaihda salasana + + + Päivitä salasana + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx new file mode 100644 index 000000000..e4036781f --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tietojen poistaminen poistaa tilisi pysyvästi, eikä sitä voida palauttaa. + + + Poista tiedot ja sulje tilini + + + Salasana + + + Poista henkilökohtaiset tiedot + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx new file mode 100644 index 000000000..4fd4bea72 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista 2FA käytöstä + + + 2FA: n poistaminen käytöstä ei muuta todentajasovelluksissa käytettyjä näppäimiä. Jos haluat vaihtaa todennussovelluksessa käytetyn avaimen, sinun pitäisi tehdä + + + nollaa todennusavaimet + + + Tämä toiminta poistaa vain 2FA: n. + + + Poista kaksifaktorinen todennus (2FA) käytöstä + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx new file mode 100644 index 000000000..f09d1f51b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lataa tietosi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx new file mode 100644 index 000000000..4e2cdf3ed --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvistuskoodi + + + Lataa kaksifaktorinen todennussovellus, kuten Microsoft Authenticator + + + Google Authenticator verkkotunnukselle + + + Kun olet skannannut QR-koodin tai syöttänyt yllä olevan avaimen, kaksifaktorinen todennussovellus antaa sinulle +                ainutlaatuisella koodilla. Kirjoita koodi alla olevaan vahvistuskenttään. + + + Skannaa QR-koodi tai kirjoita tämä avain + + + kahden tekijän todennussovellukseesi. Väleillä ja kotelolla ei ole merkitystä. + + + Voit käyttää todennussovellusta seuraavien vaiheiden avulla: + + + Määritä todennussovellus + + + tarkistaa + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx new file mode 100644 index 000000000..078956450 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poistaa + + + Rekisteröidyt kirjautumiset + + + Hallitse ulkoisia kirjautumistietoja + + + Lisää toinen palvelu Kirjauduksesi sisään. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx new file mode 100644 index 000000000..5494c4edc --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Luo palautuskoodit + + + Uusien palautuskoodien luominen ei muuta todentajasovelluksissa käytettyjä avaimia. Jos haluat vaihtaa todennussovelluksessa käytetyn avaimen, sinun pitäisi tehdä + + + Jos kadotat laitteen ja sinulla ei ole palautuskoodeja, menetät pääsyn tilillesi. + + + nollaa todennusavaimet. + + + Aseta nämä koodit turvalliseen paikkaan. + + + Luo kahden tekijän todennuksen (2FA) palautuskoodit + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx new file mode 100644 index 000000000..096208e1b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Maa + + + Sähköposti + + + Kaupunki + + + Koko nimi + + + Puhelinnumero + + + Postinumero + + + profiili-URL + + + alue + + + Tallentaa + + + Lähetä vahvistusviesti + + + Katuosoite + + + Profiili + + + Käyttäjänimi + + + Nettisivun URL + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx new file mode 100644 index 000000000..742fb61e1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Epäonnistunut kirjautuminen palveluun. + + + Kirjautuminen epäonnistui + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx new file mode 100644 index 000000000..9d7cbce21 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poistaa + + + ladata + + + Tilisi sisältää henkilökohtaisia tietoja, jotka olet antanut meille. Tällä sivulla voit ladata tai poistaa kyseisiä tietoja. + + + Henkilökohtaiset tiedot + + + Tietojen poistaminen poistaa tilisi pysyvästi, eikä sitä voida palauttaa. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx new file mode 100644 index 000000000..7e3d0632c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tämä prosessi poistaa 2FA: n käytöstä, kunnes olet todennut todentajasovelluksesi. +        Jos et suorita todennussovelluksen määrityksiä, saatat menettää pääsyn tilillesi. + + + Nollaa todennusavain + + + Jos nollaat todennusavaimen, todennussovellus ei toimi, ennen kuin olet määrittänyt sen uudelleen. + + + Nollaa todennusavain + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx new file mode 100644 index 000000000..147171346 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + Sinulla ei ole paikallista käyttäjänimeä / salasanaa tälle sivustolle. Lisää paikallinen tili, jotta voit Kirjaudu sisään ilman ulkoista kirjautumista. + + + uusi salasana + + + Aseta salasana + + + Aseta salasanasi + + + Aseta salasana + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx new file mode 100644 index 000000000..87d662c9f --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Jos kadotat laitteen ja sinulla ei ole palautuskoodeja, menetät pääsyn tilillesi. + + + Aseta nämä koodit turvalliseen paikkaan. + + + Palautuskoodit + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx new file mode 100644 index 000000000..b2132fbb1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää todennussovellus + + + Authenticator-sovellus + + + ennen kuin voit Kirjaudu sisään palautuskoodilla + + + Poista 2FA käytöstä + + + Unohda tämä selain + + + luo uusi joukko palautuskoodeja + + + Sinulla ei ole palautuskoodeja jäljellä + + + Sinulla on 1 palautuskoodi jäljellä + + + palautuskoodit jäljellä + + + Nollaa todennussovellus + + + Palauta palautuskoodit + + + Aseta todennussovellus + + + Kaksivaiheinen todennus (2FA) + + + Voit luoda uuden palautuskoodijoukon + + + Sinulla on + + + Sinun täytyy + + + Sinun pitäisi + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx new file mode 100644 index 000000000..4f91d16b5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kieli: + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx new file mode 100644 index 000000000..5138ded0c --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer-järjestelmänvalvoja + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.fi.resx new file mode 100644 index 000000000..ce3d8093b --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Error.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Valitettavasti tapahtui virhe + + + Pyydä tunnusta: + + + Virhe + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.fi.resx new file mode 100644 index 000000000..e3526e954 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/Redirect.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kun olet valmis, voit sulkea tämän välilehden + + + Palaatte nyt sovellukseen. + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx new file mode 100644 index 000000000..8adc9743e --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kaksivaiheinen todennus + + + Vaihda salasana + + + Omat ulkoiset kirjautumiset + + + Skoruba IdentityServer4 + + + © 2019 + + + Apurahat + + + Henkilökohtaiset tietoni + + + Profiilini + + + valikko + + + IdentityServer4 + + + asetukset + + + Kirjaudu ulos + + + Skoruba IdentityServer4 + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx new file mode 100644 index 000000000..fb2088702 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (vaaditaan) + + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx new file mode 100644 index 000000000..a1ffe2eeb --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Virhe + + \ No newline at end of file From 88fdf42743fd6eab0d981fe9d8f1e738c88ca348 Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 11:21:52 +0200 Subject: [PATCH 226/338] sanity check part for the translations --- .../ConfigurationController.fi.resx | 24 +++++++------- .../Controllers/GrantController.fi.resx | 6 ++-- .../Controllers/IdentityController.fi.resx | 2 +- .../Resources/Services/ClientService.fi.resx | 2 +- .../Configuration/ApiSecretDelete.fi.resx | 6 ++-- .../Views/Configuration/ApiSecrets.fi.resx | 2 +- .../Views/Configuration/Client.fi.resx | 4 +-- .../Client/Section/ActionButtons.fi.resx | 4 +-- .../Client/Section/Label.fi.resx | 32 +++++++++---------- .../Configuration/Client/Section/Name.fi.resx | 2 +- .../Configuration/ClientClaimDelete.fi.resx | 6 ++-- .../Views/Configuration/ClientClaims.fi.resx | 4 +-- .../Views/Configuration/ClientClone.fi.resx | 6 ++-- .../Views/Configuration/ClientDelete.fi.resx | 4 +-- .../Configuration/ClientProperties.fi.resx | 10 +++--- .../ClientPropertyDelete.fi.resx | 8 ++--- .../Views/Configuration/Clients.fi.resx | 4 +-- .../IdentityResource/Section/Label.fi.resx | 2 +- .../Views/Grant/PersistedGrant.fi.resx | 4 +-- .../Views/Grant/PersistedGrantDelete.fi.resx | 6 ++-- .../Resources/Views/Device/Success.fi.resx | 2 +- .../Resources/Views/Shared/_Layout.fi.resx | 2 +- .../appsettings.json | 8 ++--- 23 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx index 5a1e569e2..128476f5c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx @@ -124,22 +124,22 @@ Api-resurssin {0} apiresurssin {1} tallennus onnistui! - Api Scope {0} on tallennettu onnistuneesti! + Api näkyvyysalue {0} on tallennettu onnistuneesti! - Api Secret on luotu onnistuneesti! + Api salaus on luotu onnistuneesti! - Asiakkaan {0} luominen onnistui! + Sovelluksen {0} luominen onnistui! - Asiakasvaatimus {0} asiakkaalle {1} tallennettiin onnistuneesti! + Sovellusvaatimus {0} asiakkaalle {1} tallennettiin onnistuneesti! - Asiakkaan {1} asiakasominaisuus {0} on tallennettu onnistuneesti! + Sovelluksen {1} sominaisuus {0} on tallennettu onnistuneesti! - Asiakkaan {0} asiakassalaisuus on tallennettu onnistuneesti! + Sovelluksen {0} asiakassalaisuus on tallennettu onnistuneesti! Henkilöllisyysresurssi {0} on tallennettu onnistuneesti! @@ -148,10 +148,10 @@ Api-resurssin {1} henkilöllisyysresurssin ominaisuus {0} on tallennettu onnistuneesti! - Asiakas {0} kloonattiin onnistuneesti! + Sovellus {0} kloonattiin onnistuneesti! - Asiakas on poistettu onnistuneesti! + Sovellus on poistettu onnistuneesti! Api-resurssi on poistettu onnistuneesti! @@ -163,10 +163,10 @@ Api-laajuus on poistettu onnistuneesti! - Api Secret on poistettu onnistuneesti! + Api salaus on poistettu onnistuneesti! - Asiakasvaatimus on poistettu onnistuneesti! + Sovellusvaatimus on poistettu onnistuneesti! Asiakasomaisuus on poistettu onnistuneesti! @@ -181,9 +181,9 @@ Henkilöllisyysresurssin ominaisuus on poistettu onnistuneesti! - Menestys + Onnistui - Asiakkaan {0} päivitys onnistui! + Sovelluksen {0} päivitys onnistui! \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx index 30e1f02c5..1aa823194 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx @@ -118,12 +118,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Jatkuva apuraha on poistettu onnistuneesti! + Jatkuva käyttöoikeus on poistettu onnistuneesti! - Jatkuvat apurahat poistetaan onnistuneesti! + Jatkuvat käyttöoikeudet poistetaan onnistuneesti! - Menestys + Onnistui \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx index 707bdb410..1fe969a6e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/IdentityController.fi.resx @@ -154,7 +154,7 @@ Roolin poisto onnistui! - Menestys + Onnistui Uuden salasanan vaihto onnistui! diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx index 52084b915..e39cc7437 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/ClientService.fi.resx @@ -124,7 +124,7 @@ Asiakasta, jonka tunnus on {0}, ei ole - Asiakas on jo olemassa + Sovellus on jo olemassa Asiakastunnus ({0}) on jo olemassa diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx index b3c749ae9..316ea2a38 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecretDelete.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista Api Secret + Poista Api salaus Api-resurssit @@ -127,9 +127,9 @@ Api-salaisuudet - Poista Api Secret + Poista Api salaus - Poista Api Secret + Poista Api salaus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx index e99821ef4..74c8c5486 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää Api Secret + Lisää Api salaus HashType on käytettävissä vain SharedSecret-tyypille. diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx index 16d58416c..ef093bf79 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx @@ -121,9 +121,9 @@ asiakkaat - Asiakas + Sovellus - Asiakas - + Sovellus - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx index de5a960b5..58bfe564f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx @@ -121,9 +121,9 @@ Kloonausasiakas - Poista asiakas + Poista Sovellus - Tallenna asiakas + Tallenna Sovellus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx index a34075edd..243557018 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx @@ -136,13 +136,13 @@ Käyttöoikeustyyppi - Määrittää, sallitaanko tämän asiakkaan vastaanottaa käyttöoikeuksia selaimen kautta. Tämä on hyödyllistä kovettaa vuoita, jotka sallivat useita vastaustyyppejä (esim. Estämällä hybridivirtausasiakas, jonka oletetaan käyttävän koodia id_token lisätäkseen tokenin vastaustyypin ja vuotaen siten tokenin selaimeen. + Määrittää, sallitaanko tämän Sovelluksen vastaanottaa käyttöoikeuksia selaimen kautta. Tämä on hyödyllistä kovettaa vuoita, jotka sallivat useita vastaustyyppejä (esim. Estämällä hybridivirtausasiakas, jonka oletetaan käyttävän koodia id_token lisätäkseen tokenin vastaustyypin ja vuotaen siten tokenin selaimeen. Salli Access Token selaimen kautta - Määrittää, voiko tämä asiakas pyytää päivitystunnuksia (pyytää offline_access-laajuutta) + Määrittää, voiko tämä Sovellus pyytää päivitystunnuksia (pyytää offline_access-laajuutta) Salli offline-käyttö @@ -166,7 +166,7 @@ Sisällytä käyttäjän vaatimukset aina IdTokeniin - Jos asetettu, asiakasvaatimukset lähetetään jokaisesta vuoista. Jos ei, vain asiakkaan käyttöoikeustiedot -virta (oletus on väärä) + Jos asetettu, asiakasvaatimukset lähetetään jokaisesta vuoista. Jos ei, vain Sovelluksen käyttöoikeustiedot -virta (oletus on väärä) Lähetä asiakasvaatimukset aina @@ -178,31 +178,31 @@ Valtuutuskoodin käyttöikä - Asiakkaan yksilöivä tunnus + Sovelluksen yksilöivä tunnus Asiakastunnus - Asiakkaan näyttönimi (käytetään kirjautumiseen ja suostumusnäyttöön) + Sovelluksen näyttönimi (käytetään kirjautumiseen ja suostumusnäyttöön) - Asiakkaan Nimi + Sovelluksen Nimi URI lisätietoja asiakkaasta (käytetään suostumusnäytössä) - Asiakas Uri + Sovellus Uri - Määrittää, onko asiakas käytössä. Oletusarvo totta. + Määrittää, onko Sovellus käytössä. Oletusarvo totta. käytössä - Määrittää, pystyykö tämä asiakas käyttämään paikallisia tilejä vai vain ulkoisia IdP: tä. Oletusarvo totta. + Määrittää, pystyykö tämä Sovellus käyttämään paikallisia tilejä vai vain ulkoisia IdP: tä. Oletusarvo totta. Ota paikallinen sisäänkirjautuminen käyttöön @@ -220,7 +220,7 @@ Sisällytä Jwt-tunnus - URI asiakkaan logoon (käytetään suostumusnäytössä) + URI Sovelluksen logoon (käytetään suostumusnäytössä) Logo Uri @@ -250,7 +250,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Päivitä Token-käyttö - Määrittää, tarvitseeko tämä asiakas salaisuuden tokenien pyytämiseen tokenin päätepisteestä (oletusarvo on tosi) + Määrittää, tarvitseeko tämä Sovellus salaisuuden tokenien pyytämiseen tokenin päätepisteestä (oletusarvo on tosi) Vaadi asiakassalaisuus @@ -286,7 +286,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Sallittujen korsien alkuperä - Määrittää avustyypit, joita asiakkaan sallitaan käyttää. Käytä GrantTypes-luokkaa yleisiin yhdistelmiin. Oletusapurahojen luettelo: implisiittinen apuraha - (implisiittinen), asiakastodistusten myöntäminen - (asiakas_koodit), käyttöoikeuskoodin myöntäminen - (valtuuskoodi), yhdistelmäapu - (hybridi), resurssin omistajan salasanan käyttöoikeudet - (salasana) + Määrittää avustyypit, joita Sovelluksen sallitaan käyttää. Käytä GrantTypes-luokkaa yleisiin yhdistelmiin. Oletusapurahojen luettelo: implisiittinen käyttöoikeus - (implisiittinen), asiakastodistusten myöntäminen - (asiakas_koodit), käyttöoikeuskoodin myöntäminen - (valtuuskoodi), yhdistelmäapu - (hybridi), resurssin omistajan salasanan käyttöoikeudet - (salasana) Sallitut avustuslajit @@ -310,7 +310,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Asiakassalaisuudet - Määrittää, mitä ulkoisia IdP: itä voidaan käyttää tämän asiakkaan kanssa (jos luettelo on tyhjä, kaikki IdP: t ovat sallittuja). Oletusasetus on tyhjä. + Määrittää, mitä ulkoisia IdP: itä voidaan käyttää tämän Sovelluksen kanssa (jos luettelo on tyhjä, kaikki IdP: t ovat sallittuja). Oletusasetus on tyhjä. Henkilöllisyyden tarjoajan rajoitukset @@ -382,7 +382,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Asiakasvaatimusten etuliite - Asiakkaan kuvaus + Sovelluksen kuvaus Kuvaus @@ -400,7 +400,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Front Channel Logout Uri - Suola-arvo, jota käytetään parinpohjaisessa subjektien luonnissa tämän asiakkaan käyttäjille. + Suola-arvo, jota käytetään parinpohjaisessa subjektien luonnissa tämän Sovelluksen käyttäjille. Yhdistä viisas aiheinen suola @@ -442,7 +442,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Laitekoodin käyttöikä - Määrittää asiakaskoodin tyypin, jota asiakas käyttää. Muutoin palaa takaisin oletusasetukseen. + Määrittää asiakaskoodin tyypin, jota Sovellus käyttää. Muutoin palaa takaisin oletusasetukseen. Käyttäjätunnuksen tyyppi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx index 377d1d875..f92d4f334 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx @@ -145,7 +145,7 @@ Alkuperäinen sovellus - mobiili / työpöytä - Resurssien omistajan salasana ja asiakkaan käyttöoikeustiedot kulkevat + Resurssien omistajan salasana ja Sovelluksen käyttöoikeustiedot kulkevat Yhden sivun sovellus - Javascript diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx index 9a1c42a93..a031e1be3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista asiakasvaatimus + Poista Sovellusvaatimus Asiakasvaatimukset @@ -127,9 +127,9 @@ asiakkaat - Poista asiakasvaatimus + Poista Sovellusvaatimus - Poista asiakasvaatimus + Poista Sovellusvaatimus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx index 6eae02320..6b821b908 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää asiakasvaatimus + Lisää Sovellusvaatimus Asiakasvaatimukset @@ -130,7 +130,7 @@ Asiakasvaatimukset - Asiakkaan vaatimus + Sovelluksen vaatimus Asiakasvaatimukset diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx index 4b199373a..094e36081 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx @@ -139,10 +139,10 @@ Client IdP -rajoitukset - Asiakkaan lähettämisen uloskirjautumisen uudelleenohjaus Uris + Sovelluksen lähettämisen uloskirjautumisen uudelleenohjaus Uris - Asiakkaan ominaisuudet + Sovelluksen ominaisuudet Asiakasohjaaja Uris @@ -157,6 +157,6 @@ Kloonausasiakas - Asiakas + Sovellus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx index 1c1b20300..f3d9e2940 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx @@ -118,12 +118,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista asiakas + Poista Sovellus asiakkaat - Poista asiakas + Poista Sovellus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx index 8292207da..f7c2ad4fc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx @@ -118,22 +118,22 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää asiakasominaisuus + Lisää sominaisuus - Asiakkaan ominaisuudet + Sovelluksen ominaisuudet asiakkaat - Asiakkaan ominaisuudet + Sovelluksen ominaisuudet - Asiakkaan ominaisuudet + Sovelluksen ominaisuudet - Asiakkaan omaisuus + Sovelluksen omaisuus Poistaa diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx index 7e9b6d008..a74f3ef5e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx @@ -118,18 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista asiakasominaisuus + Poista sominaisuus - Asiakkaan ominaisuudet + Sovelluksen ominaisuudet asiakkaat - Poista asiakasominaisuus + Poista sominaisuus - Poista asiakasominaisuus + Poista sominaisuus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx index 1ff1513b7..5f29c90d7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää asiakas + Lisää Sovellus asiakkaat @@ -130,6 +130,6 @@ Asiakastunnus - Asiakkaan Nimi + Sovelluksen Nimi \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx index d730c7078..895646d74 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx @@ -142,7 +142,7 @@ käytössä - Henkilöllisyysresurssin yksilöllinen nimi. Tämä on arvo, jota asiakas käyttää laajuusparametrissa valtuutuspyynnössä. + Henkilöllisyysresurssin yksilöllinen nimi. Tämä on arvo, jota Sovellus käyttää laajuusparametrissa valtuutuspyynnössä. Nimi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx index 4cf60ed7b..3c55ca583 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx @@ -121,7 +121,7 @@ Poista kaikki - Oletko varma? Kaikki tähän aiheeseen liittyvät pysyvät apurahat poistetaan. + Oletko varma? Kaikki tähän aiheeseen liittyvät pysyvät käyttöoikeudet poistetaan. Ei - sulje @@ -139,7 +139,7 @@ Jatkoi apurahaa - Asiakas + Sovellus data diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx index dcc838fef..f583fe517 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx @@ -118,16 +118,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista pysyvä apuraha + Poista pysyvä käyttöoikeus Pysyvät oikeudet - Poista pysyvä apuraha + Poista pysyvä käyttöoikeus - Asiakas + Sovellus data diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx index 9cac83997..4613435f0 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Device/Success.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Menestys + Onnistui Olet valtuuttanut laitteen onnistuneesti diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx index 8adc9743e..690f68067 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx @@ -133,7 +133,7 @@ © 2019 - Apurahat + käyttöoikeudet Henkilökohtaiset tietoni diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 294071781..964472552 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -1,8 +1,8 @@ { "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "ConfigurationDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, "Serilog": { "MinimumLevel": { @@ -22,7 +22,7 @@ { "Name": "MSSqlServer", "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "connectionString": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "tableName": "Log", "columnOptionsSection": { "addStandardColumns": [ "LogEvent" ], From 060b9255422b96ce66ec7884b231fe7fccecbc4f Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 12:11:59 +0200 Subject: [PATCH 227/338] translation sanity check part2 --- .../ConfigurationController.fi.resx | 4 ++-- .../Controllers/GrantController.fi.resx | 2 +- .../Services/IdentityResourceService.fi.resx | 6 ++--- .../Services/IdentityService.fi.resx | 14 +++++------ .../Services/PersistedGrantService.fi.resx | 4 ++-- .../Views/Configuration/ApiResource.fi.resx | 6 ++--- .../ApiResource/Section/Label.fi.resx | 24 +++++++++---------- .../ApiResourceProperties.fi.resx | 6 ++--- .../Views/Configuration/ApiScopes.fi.resx | 6 ++--- .../Views/Configuration/ApiSecrets.fi.resx | 6 ++--- .../Views/Configuration/Client.fi.resx | 2 +- .../Client/Section/ActionButtons.fi.resx | 2 +- .../Client/Section/Authentication.fi.resx | 6 ++--- .../Client/Section/Basics.fi.resx | 6 ++--- .../Client/Section/Consent.fi.resx | 2 +- .../Client/Section/Label.fi.resx | 16 ++++++------- .../Configuration/Client/Section/Name.fi.resx | 12 +++++----- .../Client/Section/Token.fi.resx | 4 ++-- .../Configuration/Client/Settings.fi.resx | 8 +++---- .../Configuration/ClientClaimDelete.fi.resx | 2 +- .../Views/Configuration/ClientClaims.fi.resx | 8 +++---- .../Views/Configuration/ClientClone.fi.resx | 18 +++++++------- .../Views/Configuration/ClientDelete.fi.resx | 2 +- .../Configuration/ClientProperties.fi.resx | 6 ++--- .../ClientPropertyDelete.fi.resx | 2 +- .../Configuration/ClientSecretDelete.fi.resx | 2 +- .../Views/Configuration/ClientSecrets.fi.resx | 8 +++---- .../Views/Configuration/Clients.fi.resx | 2 +- .../Configuration/IdentityResource.fi.resx | 12 +++++----- .../IdentityResource/Section/Label.fi.resx | 20 ++++++++-------- .../IdentityResourceDelete.fi.resx | 6 ++--- .../IdentityResourceProperties.fi.resx | 4 ++-- .../Configuration/IdentityResources.fi.resx | 2 +- .../Views/Grant/PersistedGrant.fi.resx | 2 +- .../Views/Grant/PersistedGrantDelete.fi.resx | 2 +- .../Resources/Views/Home/Index.fi.resx | 2 +- .../Views/Identity/RoleClaims.fi.resx | 6 ++--- .../Views/Identity/UserClaims.fi.resx | 14 +++++------ .../Views/Identity/UserClaimsDelete.fi.resx | 8 +++---- .../Views/Identity/UserProviders.fi.resx | 2 +- .../Views/Identity/UserRoles.fi.resx | 2 +- .../Resources/Views/Shared/_Layout.fi.resx | 4 ++-- .../Resources/Views/Diagnostics/Index.fi.resx | 4 ++-- .../Views/Manage/ExternalLogins.fi.resx | 2 +- .../Views/Manage/PersonalData.fi.resx | 2 +- 45 files changed, 140 insertions(+), 140 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx index 128476f5c..8fd184d87 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/ConfigurationController.fi.resx @@ -142,7 +142,7 @@ Sovelluksen {0} asiakassalaisuus on tallennettu onnistuneesti! - Henkilöllisyysresurssi {0} on tallennettu onnistuneesti! + Identiteettiresurssi {0} on tallennettu onnistuneesti! Api-resurssin {1} henkilöllisyysresurssin ominaisuus {0} on tallennettu onnistuneesti! @@ -175,7 +175,7 @@ Asiakassalaisuus on poistettu onnistuneesti! - Henkilöllisyysresurssi on poistettu onnistuneesti! + Identiteettiresurssi on poistettu onnistuneesti! Henkilöllisyysresurssin ominaisuus on poistettu onnistuneesti! diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx index 1aa823194..6b46d24d3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Controllers/GrantController.fi.resx @@ -121,7 +121,7 @@ Jatkuva käyttöoikeus on poistettu onnistuneesti! - Jatkuvat käyttöoikeudet poistetaan onnistuneesti! + Jatkuvat käyttöoikeudet poistettiin onnistuneesti! Onnistui diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx index ea2f0745e..28ab10ea7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityResourceService.fi.resx @@ -118,16 +118,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Henkilöllisyysresurssi {0} on jo olemassa + Identiteettiresurssi {0} on jo olemassa - Henkilöllisyysresurssi {0} on jo olemassa + Identiteettiresurssi {0} on jo olemassa Henkilöllisyysresurssiominaisuutta, jonka tunnus on {0}, ei ole - Identity Resource Property on jo olemassa + Henkilöllisyysresurssiominaisuus on jo olemassa Identiteettiresurssiominaisuus avaimella ({0}) on jo olemassa diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx index b8b1b2750..4387ed7e4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/IdentityService.fi.resx @@ -121,10 +121,10 @@ Virhe - Roolivastausta tunnuksella {0} ei ole + Rooliominaisuutta tunnuksella {0} ei ole - Rooliväittämien luominen epäonnistui + Rooliominaisuuksien luominen epäonnistui Rooliväitteiden poistaminen epäonnistui @@ -142,16 +142,16 @@ Roolin päivitys epäonnistui - Käyttäjän vaihto-salasana epäonnistui + Käyttäjän salasanan päivitys epäonnistui - Käyttäjävaatimusta tunnuksella {0} ei ole + Käyttäjäominaisuutta tunnuksella {0} ei ole - Käyttäjävaatimusten luominen epäonnistui + Käyttäjäominaisuuksien luominen epäonnistui - Käyttäjävaatimusten poistaminen epäonnistui + Käyttäjäominaisuuksien poistaminen epäonnistui Käyttäjän luominen epäonnistui @@ -166,7 +166,7 @@ Käyttäjätarjoajan poistaminen epäonnistui - Käyttäjätoimittajaa, jonka tunnus on {0}, ei ole + Käyttäjätarjoajaa, jonka tunnus on {0}, ei ole Käyttäjäroolin luominen epäonnistui diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx index 5795a0750..c55300d0c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Services/PersistedGrantService.fi.resx @@ -118,9 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Jatkuvaa apurahaa, jonka tunnus on {0}, ei ole + Pysyvää oikeutta, jonka tunnus on {0}, ei ole - Pysyvää apurahaa tälle aiheen tunnukselle {0} ei ole + Pysyvää oikeutta tälle aiheen tunnukselle {0} ei ole \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx index 7f4f34bfc..4914813ed 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource.fi.resx @@ -124,7 +124,7 @@ Hallitse Api-resurssiominaisuuksia - Hallitse Api-laajuuksia + Hallitse Api-ominaisuuksi Hallitse Api-salaisuuksia @@ -142,7 +142,7 @@ Api-resurssi - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -157,7 +157,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx index 38d4aea76..f8d66b835 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResource/Section/Label.fi.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Tätä arvoa voidaan käyttää esimerkiksi suostumusnäytöllä. + Tätä arvoa voidaan käyttää esimerkiksi oikeuksien myöntämisnäytöllä. Kuvaus - Tätä arvoa voidaan käyttää esimerkiksi suostumusnäytöllä. + Tätä arvoa voidaan käyttää esimerkiksi oikeuksien myöntämisnäytöllä. Näyttönimi @@ -133,13 +133,13 @@ Osoittaa, onko tämä resurssi käytössä ja voidaanko sitä pyytää. Oletusarvo totta. - käytössä + Käytössä - päättyminen + Päättyminen - päättyminen + Päättyminen Sovellusliittymän yksilöivä nimi. Tätä arvoa käytetään autentikointiin itsehavainnolla, ja se lisätään lähtevän käyttöoikeustunnuksen yleisölle. @@ -151,13 +151,13 @@ Sanakirja pitää tarvittavat mukautetut api-resurssikohtaiset arvot. - ominaisuudet + Ominaisuudet - avain + Avain - avain + Avain Arvo @@ -169,7 +169,7 @@ Sovellusliittymällä on oltava ainakin yksi laajuus. Jokaisella laajuudella voi olla erilaisia asetuksia. - laajuudet + Laajuudet Kuvaus @@ -181,12 +181,12 @@ API-salaisuutta käytetään itsetutkimuksen päätepisteeseen. Sovellusliittymä voi todentaa itsetutkimuksella käyttämällä API-nimeä ja salaisuutta. - Secrets + Suojatut avaimet - Luettelo liittyvistä käyttäjän vaatimustyypeistä, jotka tulisi sisällyttää käyttöoikeustunnukseen. + Luettelo liittyvistä käyttäjän ominaisuuksista, jotka tulisi sisällyttää käyttöoikeustunnukseen. - Käyttäjän vaatimukset + Käyttäjän ominaisuudet \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx index 133ac68b8..bac63fc3c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiResourceProperties.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää Api Resource Property + Lisää Api-resurssin ominaisuus Api-resurssin ominaisuudet @@ -136,10 +136,10 @@ Api-resurssiomaisuus - Poistaa + Poista - avain + Avain Arvo diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx index 22fd57d16..f68e05b60 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiScopes.fi.resx @@ -133,7 +133,7 @@ Api-laajuus - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -148,7 +148,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: @@ -157,7 +157,7 @@ Muokkaa - Poistaa + Poista Nimi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx index 74c8c5486..8f576af6d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ApiSecrets.fi.resx @@ -121,7 +121,7 @@ Lisää Api salaus - HashType on käytettävissä vain SharedSecret-tyypille. + HashType on käytettävissä vain jaetuille salausavaintyypeille. Tiedot: @@ -142,7 +142,7 @@ Api-salaisuudet - Poistaa + Poista Luotu @@ -151,7 +151,7 @@ Kuvaus - päättyminen + Päättyminen Tyyppi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx index ef093bf79..cbc43f497 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - asiakkaat + Sovellukset Sovellus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx index 58bfe564f..1690fb332 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/ActionButtons.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Kloonausasiakas + Kopioi sovellus Poista Sovellus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx index 197401756..8876b9f4c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Authentication.fi.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Authentication / ulos + Kirjautuminen / ulos - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -136,7 +136,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx index bf73728f9..2a41b17ab 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Basics.fi.resx @@ -124,10 +124,10 @@ Hallitse asiakassalaisuuksia - Perusasiat + Perustiedot - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -142,7 +142,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx index 6d10cbc97..3d3925707 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Consent.fi.resx @@ -118,6 +118,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Suostumusnäyttö + Oikeuksien myöntämisnäyttö \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx index 243557018..160c097d3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx @@ -163,7 +163,7 @@ - Sisällytä käyttäjän vaatimukset aina IdTokeniin + Sisällytä Käyttäjän ominaisuudet aina IdTokeniin Jos asetettu, asiakasvaatimukset lähetetään jokaisesta vuoista. Jos ei, vain Sovelluksen käyttöoikeustiedot -virta (oletus on väärä) @@ -199,7 +199,7 @@ Määrittää, onko Sovellus käytössä. Oletusarvo totta. - käytössä + Käytössä Määrittää, pystyykö tämä Sovellus käyttämään paikallisia tilejä vai vain ulkoisia IdP: tä. Oletusarvo totta. @@ -256,7 +256,7 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Vaadi asiakassalaisuus - Määrittää, tarvitaanko suostumusnäyttö. Oletusarvo totta. + Määrittää, tarvitaanko oikeuksien myöntämisnäyttö. Oletusarvo totta. Vaatii suostumus @@ -409,13 +409,13 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Sanakirja pitää tarvittavat mukautetut asiakaskohtaiset arvot. - ominaisuudet + Ominaisuudet - avain + Avain - avain + Avain Arvo @@ -448,10 +448,10 @@ Yhden kerran päivitysmerkin kahva päivitetään, kun päivitetään merkkejä< Käyttäjätunnuksen tyyppi - päättyminen + Päättyminen - päättyminen + Päättyminen Kuvaus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx index f92d4f334..2322d0525 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Name.fi.resx @@ -121,7 +121,7 @@ Nimi - Valtuutuskoodivirta PKCE: llä + Valtuutuskoodi PKCE:llä TV- ja rajoitetun tulon laitesovellus @@ -133,22 +133,22 @@ Tyhjä - oletus - Hybridi virtaus + Hybridi - Implisiittinen virtaus + Implisiittinen - Kone / Robot + Kone / Robotti Alkuperäinen sovellus - mobiili / työpöytä - Resurssien omistajan salasana ja Sovelluksen käyttöoikeustiedot kulkevat + Resurssien omistajan salasana ja Sovelluksen käyttöoikeustiedot - Yhden sivun sovellus - Javascript + Spa-sovellus - Javascript Verkkosovellus - palvelinpuoli diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx index 974952e66..3be43e602 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Token.fi.resx @@ -124,7 +124,7 @@ symbolinen - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -139,7 +139,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx index 549041a55..18c3804d0 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Settings.fi.resx @@ -118,16 +118,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Authentication / ulos + Kirjautuminen / ulos - Perusasiat + Perustiedot - Suostumusnäyttö + Oikeuksien myöntämisnäyttö - Laitevirta + Deviceflow Nimi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx index a031e1be3..913e3daf1 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaimDelete.fi.resx @@ -124,7 +124,7 @@ Asiakasvaatimukset - asiakkaat + Sovellukset Poista Sovellusvaatimus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx index 6b821b908..9896fc930 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClaims.fi.resx @@ -124,7 +124,7 @@ Asiakasvaatimukset - asiakkaat + Sovellukset Asiakasvaatimukset @@ -136,7 +136,7 @@ Asiakasvaatimukset - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -154,13 +154,13 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: - Poistaa + Poista Tyyppi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx index 094e36081..0719c1cc9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientClone.fi.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Kloonausasiakas + Kopioi sovellus - Asiakassalaisuuksia ei kloonata. + Asiakassalaisuuksia ei kopioida. Tiedot: @@ -130,31 +130,31 @@ Asiakasvaatimukset - Asiakaskorien alkuperä + Sovelluksen sallitut lähteet - Asiakkaiden avustustyypit + Sovellusten oikeustyypit Client IdP -rajoitukset - Sovelluksen lähettämisen uloskirjautumisen uudelleenohjaus Uris + Sovelluksen uloskirjautumisen uudelleenohjausosoitteet Sovelluksen ominaisuudet - Asiakasohjaaja Uris + Sovelluksen uudelleenohjausosoitteet - Asiakasalueet + Sovellukset ominaisuudet - asiakkaat + Sovellukset - Kloonausasiakas + Kopioi sovellus Sovellus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx index f3d9e2940..ab8851d79 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientDelete.fi.resx @@ -121,7 +121,7 @@ Poista Sovellus - asiakkaat + Sovellukset Poista Sovellus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx index f7c2ad4fc..4292d23d3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientProperties.fi.resx @@ -124,7 +124,7 @@ Sovelluksen ominaisuudet - asiakkaat + Sovellukset Sovelluksen ominaisuudet @@ -136,10 +136,10 @@ Sovelluksen omaisuus - Poistaa + Poista - avain + Avain Arvo diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx index a74f3ef5e..4eccade93 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientPropertyDelete.fi.resx @@ -124,7 +124,7 @@ Sovelluksen ominaisuudet - asiakkaat + Sovellukset Poista sominaisuus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx index 9914832a1..76d747522 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecretDelete.fi.resx @@ -121,7 +121,7 @@ Poista asiakassalaisuus - asiakkaat + Sovellukset Asiakassalaisuudet diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx index 88db99d9e..877bdf3a0 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/ClientSecrets.fi.resx @@ -121,13 +121,13 @@ Lisää asiakassalaisuus - HashType on käytettävissä vain SharedSecret-tyypille. + HashType on käytettävissä vain jaetuille salausavaintyypeille. Tiedot: - asiakkaat + Sovellukset Asiakassalaisuudet @@ -142,7 +142,7 @@ Asiakassalaisuus - Poistaa + Poista Tyyppi @@ -157,6 +157,6 @@ Kuvaus - päättyminen + Päättyminen \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx index 5f29c90d7..304f28397 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Clients.fi.resx @@ -121,7 +121,7 @@ Lisää Sovellus - asiakkaat + Sovellukset Muokkaa diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx index 22ac988d6..79becdb84 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource.fi.resx @@ -118,25 +118,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista henkilöllisyysresurssi + Poista Identiteettiresurssi Hallitse henkilöllisyysresurssien ominaisuuksia - Tallenna henkilöllisyysresurssi + Tallenna Identiteettiresurssi Henkilöllisyysresurssit - Henkilöllisyysresurssi + Identiteettiresurssi - Henkilöllisyysresurssi + Identiteettiresurssi - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -151,7 +151,7 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx index 895646d74..17add7f56 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx @@ -118,19 +118,19 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Tätä arvoa käytetään esimerkiksi suostumusnäytöllä. + Tätä arvoa käytetään esimerkiksi oikeuksien myöntämisnäytöllä. Kuvaus - Tätä arvoa käytetään esimerkiksi suostumusnäytöllä. + Tätä arvoa käytetään esimerkiksi oikeuksien myöntämisnäytöllä. Näyttönimi - Määrittää, korostaako suostumusnäyttö tätä laajuutta (jos suostumusnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Käytä tätä asetusta herkille tai tärkeille alueille. Oletusarvo on väärä. + Määrittää, korostaako oikeuksien myöntämisnäyttö tätä laajuutta (jos oikeuksien myöntämisnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Käytä tätä asetusta herkille tai tärkeille alueille. Oletusarvo on väärä. painottaa @@ -139,7 +139,7 @@ Osoittaa, onko tämä resurssi käytössä ja voidaanko sitä pyytää. Oletusarvo totta. - käytössä + Käytössä Henkilöllisyysresurssin yksilöllinen nimi. Tämä on arvo, jota Sovellus käyttää laajuusparametrissa valtuutuspyynnössä. @@ -151,13 +151,13 @@ Sanakirja, jolla voidaan pitää tarvittavat mukautetut identiteettiresurssikohtaiset arvot. - ominaisuudet + Ominaisuudet - avain + Avain - avain + Avain Arvo @@ -166,7 +166,7 @@ Arvo - Määrittää, voiko käyttäjä poistaa valinnan laajuudesta suostumusnäytössä (jos suostumusnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Oletusarvo on väärä. + Määrittää, voiko käyttäjä poistaa valinnan laajuudesta suostumusnäytössä (jos oikeuksien myöntämisnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Oletusarvo on väärä. Vaaditaan @@ -178,9 +178,9 @@ Näytä Konfiguraation dokumenttssa - Luettelo liittyvistä käyttäjän vaatimustyypeistä, jotka tulisi sisällyttää identiteettitunnisteeseen. + Luettelo liittyvistä käyttäjän ominaisuuksista, jotka tulisi sisällyttää identiteettitunnisteeseen. - Käyttäjän vaatimukset + Käyttäjän ominaisuudet \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx index 775ca1ace..20061ebff 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceDelete.fi.resx @@ -118,15 +118,15 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista henkilöllisyysresurssi + Poista Identiteettiresurssi Henkilöllisyysresurssit - Poista henkilöllisyysresurssi + Poista Identiteettiresurssi - Poista henkilöllisyysresurssi + Poista Identiteettiresurssi \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx index 41c59418d..f4b456076 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResourceProperties.fi.resx @@ -136,10 +136,10 @@ Henkilöllisyysresurssien omaisuus - Poistaa + Poista - avain + Avain Arvo diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx index 333906860..08b4710e7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResources.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää henkilöllisyysresurssi + Lisää Identiteettiresurssi Henkilöllisyysresurssit diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx index 3c55ca583..e2aa30efc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx @@ -145,7 +145,7 @@ data - päättyminen + Päättyminen Aiheen tunnus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx index f583fe517..1a92c40bc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrantDelete.fi.resx @@ -133,7 +133,7 @@ data - päättyminen + Päättyminen Aiheen tunnus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx index 8cfd0df77..5718d9661 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx @@ -121,7 +121,7 @@ Api-resurssit - asiakkaat + Sovellukset Henkilöllisyysresurssit diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx index 2e8a58972..536ca2b25 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx @@ -133,7 +133,7 @@ vaatimus - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -151,13 +151,13 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: - Poistaa + Poista Tyyppi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx index 9ce6d298b..8f23a0d1c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx @@ -118,22 +118,22 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Lisää käyttäjän vaatimus + Lisää Käyttäjän ominaisuus käyttäjät - Käyttäjän vaatimukset + Käyttäjän ominaisuudet - Käyttäjän vaatimukset + Käyttäjän ominaisuudet - Käyttäjän vaatimus + Käyttäjän ominaisuus - kohde on jo valittu + Kohde on jo valittu Kohteita ei ole valittu @@ -151,13 +151,13 @@ Valitut kohteet: - lisää + Lisää Ehdotetut tuotteet: - Poistaa + Poista Tyyppi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx index 370ca67cc..d5d098053 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx @@ -118,18 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poista käyttäjän vaatimus + Poista Käyttäjän ominaisuus - Käyttäjän vaatimukset + Käyttäjän ominaisuudet käyttäjät - Poista käyttäjän vaatimus + Poista Käyttäjän ominaisuus - Poista käyttäjän vaatimus + Poista Käyttäjän ominaisuus \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx index f900c692e..52d1b21c6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx @@ -124,7 +124,7 @@ Käyttäjätarjoajat - Poistaa + Poista Sisäänkirjautumisen tarjoaja diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx index 7f6dcff04..dc5951143 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx @@ -121,7 +121,7 @@ Lisää rooli - Poistaa + Poista käyttäjät diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx index 73e1de289..f25b84d85 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx @@ -127,7 +127,7 @@ Api-resurssit - asiakkaat + Sovellukset Henkilöllisyysresurssit @@ -151,7 +151,7 @@ Skoruba IdentityServer4 Järjestelmänvalvoja - Asiakkaat / Resurssit + Sovellukset / Resurssit lokit diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx index b16883806..920e593a7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx @@ -121,10 +121,10 @@ väittää - asiakkaat + Sovellukset - ominaisuudet + Ominaisuudet Todennus eväste diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx index 078956450..742e12a92 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poistaa + Poista Rekisteröidyt kirjautumiset diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx index 9d7cbce21..9ed12f6f7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Poistaa + Poista ladata From 7464486ba652911cac17f1822cfbafe66c22a41f Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 12:20:20 +0200 Subject: [PATCH 228/338] revert apsettings. --- .../appsettings.json.rej | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej new file mode 100644 index 000000000..b8b0553a8 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej @@ -0,0 +1,22 @@ +diff a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json (rejected hunks) +@@ -1,8 +1,8 @@ + { + "ConnectionStrings": { +- "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", +- "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", +- "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" ++ "ConfigurationDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", ++ "PersistedGrantDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", ++ "IdentityDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, + "Serilog": { + "MinimumLevel": { +@@ -22,7 +22,7 @@ + { + "Name": "MSSqlServer", + "Args": { +- "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", ++ "connectionString": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], From bd487c3ac86b7333ec2adae25bf8d53e91ba0e85 Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 12:21:39 +0200 Subject: [PATCH 229/338] revert --- src/Skoruba.IdentityServer4.STS.Identity/appsettings.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 964472552..294071781 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -1,8 +1,8 @@ { "ConnectionStrings": { - "ConfigurationDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, "Serilog": { "MinimumLevel": { @@ -22,7 +22,7 @@ { "Name": "MSSqlServer", "Args": { - "connectionString": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "tableName": "Log", "columnOptionsSection": { "addStandardColumns": [ "LogEvent" ], From ba10e7c25f1f4bd69dafa53d346802a103fb2c69 Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 12:22:48 +0200 Subject: [PATCH 230/338] cleanup --- .../appsettings.json.rej | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej deleted file mode 100644 index b8b0553a8..000000000 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json.rej +++ /dev/null @@ -1,22 +0,0 @@ -diff a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json (rejected hunks) -@@ -1,8 +1,8 @@ - { - "ConnectionStrings": { -- "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", -- "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", -- "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" -+ "ConfigurationDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", -+ "PersistedGrantDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", -+ "IdentityDbConnection": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" - }, - "Serilog": { - "MinimumLevel": { -@@ -22,7 +22,7 @@ - { - "Name": "MSSqlServer", - "Args": { -- "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", -+ "connectionString": "Server=LW-DELL170\\SQLEXPRESS;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "tableName": "Log", - "columnOptionsSection": { - "addStandardColumns": [ "LogEvent" ], From 4e624216a825ae2ade9afa8a04e88a3c90c4886d Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 12:43:48 +0200 Subject: [PATCH 231/338] Finalization of translation, fi --- .../Configuration/IdentityResource/Section/Label.fi.resx | 8 ++++---- .../Resources/Views/Grant/PersistedGrant.fi.resx | 2 +- .../Resources/Views/Home/Index.fi.resx | 4 ++-- .../Resources/Views/Identity/Role.fi.resx | 4 ++-- .../Resources/Views/Identity/RoleClaims.fi.resx | 4 ++-- .../Resources/Views/Identity/RoleClaimsDelete.fi.resx | 2 +- .../Resources/Views/Identity/RoleDelete.fi.resx | 2 +- .../Resources/Views/Identity/RoleUsers.fi.resx | 2 +- .../Resources/Views/Identity/Roles.fi.resx | 4 ++-- .../Resources/Views/Identity/User/Section/Label.fi.resx | 8 ++++---- .../Resources/Views/Identity/UserChangePassword.fi.resx | 4 ++-- .../Resources/Views/Identity/UserClaims.fi.resx | 2 +- .../Resources/Views/Identity/UserClaimsDelete.fi.resx | 2 +- .../Resources/Views/Identity/UserDelete.fi.resx | 2 +- .../Resources/Views/Identity/UserProfile.fi.resx | 2 +- .../Resources/Views/Identity/UserProviders.fi.resx | 2 +- .../Resources/Views/Identity/UserProvidersDelete.fi.resx | 2 +- .../Resources/Views/Identity/UserRoles.fi.resx | 4 ++-- .../Resources/Views/Identity/UserRolesDelete.fi.resx | 2 +- .../Resources/Views/Identity/Users.fi.resx | 2 +- .../Resources/Views/Shared/_Layout.fi.resx | 4 ++-- .../Resources/Views/Shared/_Layout.fi.resx | 2 +- 22 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx index 17add7f56..2285e853d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/IdentityResource/Section/Label.fi.resx @@ -133,7 +133,7 @@ Määrittää, korostaako oikeuksien myöntämisnäyttö tätä laajuutta (jos oikeuksien myöntämisnäyttö haluaa ottaa käyttöön tällaisen ominaisuuden). Käytä tätä asetusta herkille tai tärkeille alueille. Oletusarvo on väärä. - painottaa + Painotus Osoittaa, onko tämä resurssi käytössä ja voidaanko sitä pyytää. Oletusarvo totta. @@ -148,7 +148,7 @@ Nimi - Sanakirja, jolla voidaan pitää tarvittavat mukautetut identiteettiresurssikohtaiset arvot. + Ominaisuudet, jolla voidaan pitää tarvittavat mukautetut identiteettiresurssikohtaiset arvot. Ominaisuudet @@ -172,10 +172,10 @@ Vaaditaan - Määrittää, näkyykö tämä laajuus Konfiguraation dokumenttssa. Oletusarvo totta. + Määrittää, näkyykö tämä ominaisuus discovery-dokumentissa. Oletusarvo totta. - Näytä Konfiguraation dokumenttssa + Näytä discovery-dokumentissa Luettelo liittyvistä käyttäjän ominaisuuksista, jotka tulisi sisällyttää identiteettitunnisteeseen. diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx index e2aa30efc..8f7a6505d 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Grant/PersistedGrant.fi.resx @@ -136,7 +136,7 @@ Pysyvät oikeudet - Jatkoi apurahaa + Pysyvät oikeudet Sovellus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx index 5718d9661..de611a4ac 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx @@ -133,10 +133,10 @@ Pysyvät oikeudet - roolit + Roolit - käyttäjät + Käyttäjät IdentityServer4: n ja Asp.Net Core Identity: n hallinto diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx index 7f45d1183..b553bf0c3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Role.fi.resx @@ -124,13 +124,13 @@ Poista rooli - käyttäjät + Käyttäjät Tallenna rooli - roolit + Roolit Rooli diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx index 536ca2b25..f30218c91 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaims.fi.resx @@ -121,7 +121,7 @@ Lisää roolivaatimus - roolit + Roolit Roolivaatimukset @@ -130,7 +130,7 @@ Roolivaatimukset - vaatimus + Vaatimus Kohde on jo valittu diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx index b026c5228..995a31a86 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleClaimsDelete.fi.resx @@ -124,7 +124,7 @@ Roolivaatimukset - roolit + Roolit Poista rooliväite diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx index 469b60508..f990ce5fd 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleDelete.fi.resx @@ -121,7 +121,7 @@ Poista rooli - roolit + Roolit Poista rooli diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx index 1baa025e2..e589026d0 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/RoleUsers.fi.resx @@ -127,7 +127,7 @@ Hae - roolit + Roolit Roolin käyttäjät diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx index dd8b66b2e..a7ddfaf61 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Roles.fi.resx @@ -121,13 +121,13 @@ Lisää rooli - roolit + Roolit Muokkaa - käyttäjät + Käyttäjät Nimi diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx index 830339fcd..f480318c2 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/User/Section/Label.fi.resx @@ -136,10 +136,10 @@ Vaatimuksen tyyppi - Käyttäjän käyttö epäonnistui + Käyttäjän kirjautuminen epäonnistui - Käyttäjän käyttö epäonnistui + Käyttäjän kirjautuminen epäonnistui Vahvista salasana @@ -214,10 +214,10 @@ Palveluntarjoaja-avain - Käyttäjän kaksi tekijää käytössä + Käyttäjän kaksivaiheinen kirjautuminen käytössä - Käyttäjän kaksi tekijää käytössä + Käyttäjän kaksivaiheinen kirjautuminen käytössä Käyttäjätunnus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx index c0422a4d5..6b10430ca 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserChangePassword.fi.resx @@ -121,10 +121,10 @@ Vaihda salasana - käyttäjät + Käyttäjät - Käyttäjän vaihto salasana + Käyttäjän salasanan vaihto Vaihda salasana diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx index 8f23a0d1c..00cc69b41 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaims.fi.resx @@ -121,7 +121,7 @@ Lisää Käyttäjän ominaisuus - käyttäjät + Käyttäjät Käyttäjän ominaisuudet diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx index d5d098053..0ac74e709 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserClaimsDelete.fi.resx @@ -124,7 +124,7 @@ Käyttäjän ominaisuudet - käyttäjät + Käyttäjät Poista Käyttäjän ominaisuus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx index 8cdbe0ffe..20c6c8823 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserDelete.fi.resx @@ -121,7 +121,7 @@ Poista käyttäjä - käyttäjät + Käyttäjät Poista käyttäjä diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx index ee59216d2..d6bdf1a5b 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx @@ -139,7 +139,7 @@ Tallenna käyttäjä - käyttäjät + Käyttäjät käyttäjä diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx index 52d1b21c6..6cb59a74f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProviders.fi.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - käyttäjät + Käyttäjät Käyttäjätarjoajat diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx index c85fb7734..da152706f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProvidersDelete.fi.resx @@ -124,7 +124,7 @@ Käyttäjätarjoajat - käyttäjät + Käyttäjät Poista käyttäjän palveluntarjoaja diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx index dc5951143..6a4176a3a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRoles.fi.resx @@ -124,7 +124,7 @@ Poista - käyttäjät + Käyttäjät Nimi @@ -136,6 +136,6 @@ Käyttäjäroolit - roolit + Roolit \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx index 41c8de5ee..d51085b80 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserRolesDelete.fi.resx @@ -124,7 +124,7 @@ Käyttäjäroolit - käyttäjät + Käyttäjät Poista rooli diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx index e7321c065..f5da5dcdd 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/Users.fi.resx @@ -127,7 +127,7 @@ Sähköposti - käyttäjät + Käyttäjät Käyttäjätunnus diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx index f25b84d85..f9018b543 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx @@ -139,10 +139,10 @@ Pysyvät oikeudet - roolit + Roolit - käyttäjät + Käyttäjät valikko diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx index 690f68067..07782079c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx @@ -133,7 +133,7 @@ © 2019 - käyttöoikeudet + Käyttöoikeudet Henkilökohtaiset tietoni From 4149555a9c86141675981f488fc8c8b1f946b502 Mon Sep 17 00:00:00 2001 From: tapmui Date: Sun, 17 Nov 2019 13:01:10 +0200 Subject: [PATCH 232/338] review check fixes --- .../Resources/Views/Home/Index.fi.resx | 2 +- .../Resources/Views/Identity/UserProfile.fi.resx | 2 +- .../Resources/Views/Log/AuditLog.fi.resx | 2 +- .../Resources/Views/Log/ErrorsLog.fi.resx | 2 +- .../Resources/Views/Shared/_Layout.fi.resx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx index de611a4ac..d0ccbfb3f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Home/Index.fi.resx @@ -139,7 +139,7 @@ Käyttäjät - IdentityServer4: n ja Asp.Net Core Identity: n hallinto + IdentityServer4:n ja Asp.Net Core Identityn hallinta Skoruba IdentityServer4 Järjestelmänvalvoja diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx index d6bdf1a5b..8d16c622a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Identity/UserProfile.fi.resx @@ -117,7 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Tarkastusloki diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx index 54de81680..4bd44b782 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/AuditLog.fi.resx @@ -123,7 +123,7 @@ Oletko varma? - + Tarkastusloki diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx index 065898fea..f3e4f8ed9 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ErrorsLog.fi.resx @@ -133,7 +133,7 @@ Kyllä - poista - lokit + Lokit Taso diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx index f9018b543..7ef2e64df 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Shared/_Layout.fi.resx @@ -154,7 +154,7 @@ Sovellukset / Resurssit - lokit + Lokit Käyttäjät / roolit From f539ef9313ac619636e833b4942e1374c78951ab Mon Sep 17 00:00:00 2001 From: tapmui Date: Mon, 18 Nov 2019 07:18:28 +0200 Subject: [PATCH 233/338] Test findings --- .../Views/Configuration/Client/Section/Label.fi.resx | 2 +- .../Resources/Views/Account/Logout.fi.resx | 4 ++-- .../Resources/Views/Home/Index.fi.resx | 2 +- .../Resources/Views/Manage/Index.fi.resx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx index 160c097d3..2f72b147e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/Label.fi.resx @@ -154,7 +154,7 @@ Salli pelkkää tekstiä - Määrittää, voiko käyttäjä tallentaa suostumuspäätökset. Oletusarvo totta. + Määrittää, voiko käyttäjä Tallenna suostumuspäätökset. Oletusarvo totta. Salli Muista suostumus diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx index 58682bf5e..d51a62d66 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Account/Logout.fi.resx @@ -118,12 +118,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Haluatko Kirjaudu ulos IdentityServeristä? + Haluatko kirjautua ulos IdentityServeristä? Kirjaudu ulos - Joo + Kyllä \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx index 209f24da7..43f2dc79f 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx @@ -124,7 +124,7 @@ Vaihda salasana - Konfiguraation dokumentt + Konfiguraation dokumentti Pysyvät oikeudet diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx index 096208e1b..4d87a59cc 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Manage/Index.fi.resx @@ -142,7 +142,7 @@ alue - Tallentaa + Tallenna Lähetä vahvistusviesti From dcf67e06a560bc69d63f8ad09fa751efbf330ead Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Tue, 19 Nov 2019 11:29:54 +0100 Subject: [PATCH 234/338] SqlServer, DbContext and IdentityServer health checks added to IdentityServer, Admin and Admin.Api projects. --- .../Helpers/StartupHelpers.cs | 37 ++ .../Skoruba.IdentityServer4.Admin.Api.csproj | 5 + .../Startup.cs | 17 +- .../appsettings.json | 108 ++--- .../healthchecksdb | Bin 0 -> 45056 bytes .../Helpers/StartupHelpers.cs | 37 ++ .../Properties/launchSettings.json | 2 - .../Skoruba.IdentityServer4.Admin.csproj | 7 +- src/Skoruba.IdentityServer4.Admin/Startup.cs | 17 +- .../appsettings.json | 415 +++++++++--------- .../healthchecksdb | Bin 0 -> 45056 bytes .../Helpers/StartupHelpers.cs | 22 + ...koruba.IdentityServer4.STS.Identity.csproj | 4 + .../Startup.cs | 19 +- .../appsettings.json | 16 +- .../healthchecksdb | Bin 0 -> 45056 bytes 16 files changed, 441 insertions(+), 265 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb create mode 100644 src/Skoruba.IdentityServer4.Admin/healthchecksdb create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 9127c864e..331c73701 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -2,6 +2,7 @@ using System.Reflection; using IdentityModel; using IdentityServer4.AccessTokenValidation; +using IdentityServer4.EntityFramework.Interfaces; using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Identity; @@ -205,5 +206,41 @@ public static void AddAuthorizationPolicies(this IServiceCollection services) )); }); } + + public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration, AdminApiConfiguration adminApiConfiguration) + where TConfigurationDbContext : DbContext, IConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TIdentityDbContext : DbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var configurationDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var identityDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var logDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); + var auditLogDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); + + var identityServerUri = adminApiConfiguration.IdentityServerBaseUrl; + services.AddHealthChecks() + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddDbContextCheck("ConfigurationDbContext") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddDbContextCheck("PersistedGrantsDbContext") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddDbContextCheck("IdentityDbContext") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddDbContextCheck("LogDbContext") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog") + .AddDbContextCheck("AuditLogDbContext") + + .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); + + services.AddHealthChecksUI(); + } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index 21faa0e85..4a6783938 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -10,11 +10,16 @@ + + + + + diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 5503c086f..8cfd801f6 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using HealthChecks.UI.Client; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -99,6 +101,8 @@ public void ConfigureServices(IServiceCollection services) }); services.AddAuditEventLogging(Configuration); + + services.AddIdSHealthChecks(Configuration, adminApiConfiguration); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApiConfiguration adminApiConfiguration) @@ -122,7 +126,18 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi app.UseRouting(); app.UseAuthorization(); - app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); + app.UseEndpoints(endpoints => + { + endpoints.MapDefaultControllerRoute(); + endpoints.MapHealthChecks("/health", new HealthCheckOptions + { + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + endpoints.MapHealthChecksUI(setup => + { + setup.UIPath = "/health-ui"; + }); + }); } } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 644f04951..1a9b23a6f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -1,53 +1,61 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, + "AdminApiConfiguration": { + "ApiName": "Skoruba IdentityServer4 Admin Api", + "ApiVersion": "v1", + "ApiBaseUrl": "http://localhost:5001", + "IdentityServerBaseUrl": "http://localhost:5000", + "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", + "OidcApiName": "skoruba_identity_admin_api", + "AdministrationRole": "SkorubaIdentityAdminAdministrator", + "RequireHttpsMetadata": false + }, + "AuditLoggingConfiguration": { + "Source": "IdentityServer.Admin.Api", + "SubjectIdentifierClaim": "sub", + "SubjectNameClaim": "name", + "ClientIdClaim": "client_id" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Error", + "Override": { + "Skoruba": "Information" + } }, - "AdminApiConfiguration": { - "ApiName": "Skoruba IdentityServer4 Admin Api", - "ApiVersion": "v1", - "ApiBaseUrl": "http://localhost:5001", - "IdentityServerBaseUrl": "http://localhost:5000", - "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "OidcApiName": "skoruba_identity_admin_api", - "AdministrationRole": "SkorubaIdentityAdminAdministrator", - "RequireHttpsMetadata": false - }, - "AuditLoggingConfiguration": { - "Source": "IdentityServer.Admin.Api", - "SubjectIdentifierClaim": "sub", - "SubjectNameClaim": "name", - "ClientIdClaim": "client_id" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Error", - "Override": { - "Skoruba": "Information" - } - }, - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Log\\skoruba_admin_api.txt", - "rollingInterval": "Day" - } - }, - { - "Name": "MSSqlServer", - "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "tableName": "Log", - "columnOptionsSection": { - "addStandardColumns": [ "LogEvent" ], - "removeStandardColumns": [ "Properties" ] - } - } - } - ] - } + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Log\\skoruba_admin_api.txt", + "rollingInterval": "Day" + } + }, + { + "Name": "MSSqlServer", + "Args": { + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], + "removeStandardColumns": [ "Properties" ] + } + } + } + ] + }, + "HealthChecks-UI": { + "HealthChecks": [ + { + "Name": "Identity Server Admin API Health Checks", + "Uri": "http://localhost:5001/health" + } + ] + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb b/src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb new file mode 100644 index 0000000000000000000000000000000000000000..2be0fbfc89a3196bd722a6c6c04793b6a84c9abf GIT binary patch literal 45056 zcmeI*&2QUe90%~nNmDn;62oDNI24|SjV*L*?YyUAf{?mdv@9uUiaJeGlqGI!kvd!K zY@Mb_w42zOe}M}pBrc5qfx{382@n!OLPA{Nzy*YM;BnrQ=ja8rM!)GY;6wRu0D#wQ+p$qg&X@H?Dp6PR#J0WRkm|G>TU% z%2=nd3+=6zdiX0myjSx={FBAZ#u=i+QW^{!qR8akc8 z^3v5@>S8>1iC&N|(fE2ko64}7T$D5UGp%)GiaUyz=H-oM@$K2mie9Rz*UT^-vUJTT z8g>2g%C&Q6JDFOwZZ8;y)YnSZ!dBYecCJilXQ8uCjoO#IbS0aUQ^`z2Vsu2)oV+6E zXfx=^8TTTjs@gcNauN8ZvYoPF9P){Eyt@i%QVY0V7&3k5Nxx0x*n5-1l zO1-A&?PtC}0NS%z=pA5dcXLhLv^~VV2Z4bNkuK^+rfR60s=|&&&Ev#Cl9axFEv}Vw zbxl*Xt;dfFY!BH_+j!619CxqOXnJ?Y>P}7fH@~~!U;w@OCK5~v;jCt+P*!Tyoe^y} zd77&n$+KQlM`RwuzO3q{>J6oKYfY)$P)ogsXvVoZHSL+7=Porc_3IVZB`fI4^}3>! zl!2GFKGuPSr!{u;Kf`kR_HJ5vkI%>5^)<>&RJBcYtF?>j{ja9_O7!+GJlMt>%sX*| z{R5VJ8yxS6M7aIt!Mjk9S1zhs&4ZKPd?&p%bf%@>VQ88zN2g5lDAut>nTV>XPbR{vp-K< z?7;~?5cY=w0uX=z1Rwwb2tWV=5P$##AOL|QD)1s_jd}c{6q6(=AVvfJV5p#Ks-YGu zfdz3vbg*`D!cT<#VSoSxAOHafKmY;|fB*y_009U<;7AL+V2#;_e+bb0{{I0H9vtZg zqVf=c00bZa0SG_<0uX=z1Rwx`|DeEm&PL?RWZN*VEiEoqs- zi0~;JVSoSxAOHafKmY;|fB*y_009U<;1C3o78|*ous`9s`2#)w#zz97KsXi-g_7(7 zfXj)Qr!B}Yvd1&hdy~z^009U<00Izz z00bZa0SG_<0!LZEn4j5u`RrgfG*hLes-`I=^JhHSWW7?RR~5QbEGz7}RIKX?HMZHK zSldzzHotVr$&-1GJXVrL6qg!*3z8HJ1jV4w!IMQZVZ2^ejdXQu`6@dN-B5OoZc@?D z`lF$k*Upo<{-ix=qO4Es_p@K|B`3`^BTI?|0?}EXC!S8Ko4s8H){2^;4=ptk3W>p2tvr!>b7)38 zOK<7XXe1n3u<#^irtLd>e^}YUm_HVfPI0X*GmyTg;HW5uL$T)h{||}q@F)i~>J9-2 zKmY;|fB*y_009U<00I#BKM9Ctx1U{6F!<5V=&K9N-~V$8pAq4a@VoFEy9?mY!jHoD z!neX#!sl!@1_(d^0uX=z1Rwwb2tWV=5P$##o+*JTtDSS2BZoP%o1+(this IServiceCollection services, IConfiguration configuration, IAdminConfiguration adminConfiguration) + where TConfigurationDbContext : DbContext, IConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TIdentityDbContext : DbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var configurationDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var identityDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var logDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); + var auditLogDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); + + var identityServerUri = adminConfiguration.IdentityServerBaseUrl; + services.AddHealthChecks() + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddDbContextCheck("ConfigurationDbContext") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddDbContextCheck("PersistedGrantsDbContext") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddDbContextCheck("IdentityDbContext") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddDbContextCheck("LogDbContext") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog") + .AddDbContextCheck("AuditLogDbContext") + + .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); + + services.AddHealthChecksUI(); + } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Properties/launchSettings.json b/src/Skoruba.IdentityServer4.Admin/Properties/launchSettings.json index 4e0b77f48..262a1304b 100644 --- a/src/Skoruba.IdentityServer4.Admin/Properties/launchSettings.json +++ b/src/Skoruba.IdentityServer4.Admin/Properties/launchSettings.json @@ -10,7 +10,6 @@ "profiles": { "IIS Express": { "commandName": "IISExpress", - "commandLineArgs": "/seed", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -28,7 +27,6 @@ "commandName": "Docker", "launchBrowser": true, "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", - "environmentVariables": {}, "httpPort": 10000 } } diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index 2a5525976..754099b11 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -10,6 +10,9 @@ + + + @@ -18,7 +21,9 @@ - + + + diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 863033111..dc644b5f6 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -1,5 +1,7 @@ using System.IdentityModel.Tokens.Jwt; +using HealthChecks.UI.Client; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -82,6 +84,8 @@ public void ConfigureServices(IServiceCollection services) // Add audit logging services.AddAuditEventLogging(Configuration); + + services.AddIdSHealthChecks(Configuration, rootConfiguration.AdminConfiguration); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) @@ -110,7 +114,18 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseRouting(); app.UseAuthorization(); - app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); + app.UseEndpoints(endpoint => + { + endpoint.MapDefaultControllerRoute(); + endpoint.MapHealthChecks("/health", new HealthCheckOptions + { + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + endpoint.MapHealthChecksUI(setup => + { + setup.UIPath = "/health-ui"; + }); + }); } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 2a9514718..e8c3c2428 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -1,213 +1,220 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, + "AdminConfiguration": { + "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", + "IdentityServerBaseUrl": "http://localhost:5000", + "IdentityAdminCookieName": "IdentityServerAdmin", + "IdentityAdminCookieExpiresUtcHours": 12, + "RequireHttpsMetadata": false, + "TokenValidationClaimName": "name", + "TokenValidationClaimRole": "role", + "ClientId": "skoruba_identity_admin", + "ClientSecret": "skoruba_admin_client_secret", + "OidcResponseType": "code id_token", + "Scopes": [ + "openid", + "profile", + "email", + "roles" + ], + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + }, + "AuditLoggingConfiguration": { + "Source": "IdentityServer.Admin.Web", + "SubjectIdentifierClaim": "sub", + "SubjectNameClaim": "name", + "IncludeFormVariables": false + }, + "CultureConfiguration": { + "Cultures": [], + "DefaultCulture": null + }, + "Serilog": { + "MinimumLevel": { + "Default": "Error", + "Override": { + "Skoruba": "Information" + } }, - "AdminConfiguration": { - "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", - "IdentityServerBaseUrl": "http://localhost:5000", - "IdentityAdminCookieName": "IdentityServerAdmin", - "IdentityAdminCookieExpiresUtcHours": 12, - "RequireHttpsMetadata": false, - "TokenValidationClaimName": "name", - "TokenValidationClaimRole": "role", - "ClientId": "skoruba_identity_admin", - "ClientSecret": "skoruba_admin_client_secret", - "OidcResponseType": "code id_token", - "Scopes": [ - "openid", - "profile", - "email", - "roles" - ], - "AdministrationRole": "SkorubaIdentityAdminAdministrator" - }, - "AuditLoggingConfiguration": { - "Source": "IdentityServer.Admin.Web", - "SubjectIdentifierClaim": "sub", - "SubjectNameClaim": "name", - "IncludeFormVariables": false - }, - "CultureConfiguration": { - "Cultures": [ ], - "DefaultCulture": null - }, - "Serilog": { - "MinimumLevel": { - "Default": "Error", - "Override": { - "Skoruba": "Information" - } - }, - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Log\\skoruba_admin.txt", - "rollingInterval": "Day" - } - }, - { - "Name": "MSSqlServer", - "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "tableName": "Log", - "columnOptionsSection": { - "addStandardColumns": [ "LogEvent" ], - "removeStandardColumns": [ "Properties" ] - } - } - } - ] - }, - "IdentityData": { + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Log\\skoruba_admin.txt", + "rollingInterval": "Day" + } + }, + { + "Name": "MSSqlServer", + "Args": { + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], + "removeStandardColumns": [ "Properties" ] + } + } + } + ] + }, + "IdentityData": { + "Roles": [ + { + "Name": "SkorubaIdentityAdminAdministrator" + } + ], + "Users": [ + { + "Username": "admin", + "Password": "Pa$$word123", + "Email": "admin@skoruba.com", "Roles": [ - { - "Name": "SkorubaIdentityAdminAdministrator" - } + "SkorubaIdentityAdminAdministrator" ], - "Users": [ - { - "Username": "admin", - "Password": "Pa$$word123", - "Email": "admin@skoruba.com", - "Roles": [ - "SkorubaIdentityAdminAdministrator" - ], - "Claims": [ - { - "Type": "name", - "Value": "admin" - } - ] - } + "Claims": [ + { + "Type": "name", + "Value": "admin" + } ] - }, - "IdentityServerData": { - "IdentityResources": [ - { - "Name": "roles", - "Enabled": true, - "DisplayName": "Roles", - "UserClaims": [ - "role" - ] - }, - { - "Name": "openid", - "Enabled": true, - "Required": true, - "DisplayName": "Your user identifier", - "UserClaims": [ - "sub" - ] - }, - { - "Name": "profile", - "Enabled": true, - "DisplayName": "User profile", - "Description": "Your user profile information (first name, last name, etc.)", - "Emphasize": true, - "UserClaims": [ - "name", - "family_name", - "given_name", - "middle_name", - "nickname", - "preferred_username", - "profile", - "picture", - "website", - "gender", - "birthdate", - "zoneinfo", - "locale", - "updated_at" - ] - }, - { - "Name": "email", - "Enabled": true, - "DisplayName": "Your email address", - "Emphasize": true, - "UserClaims": [ - "email", - "email_verified" - ] - }, - { - "Name": "address", - "Enabled": true, - "DisplayName": "Your address", - "Emphasize": true, - "UserClaims": [ - "address" - ] - } + } + ] + }, + "IdentityServerData": { + "IdentityResources": [ + { + "Name": "roles", + "Enabled": true, + "DisplayName": "Roles", + "UserClaims": [ + "role" + ] + }, + { + "Name": "openid", + "Enabled": true, + "Required": true, + "DisplayName": "Your user identifier", + "UserClaims": [ + "sub" + ] + }, + { + "Name": "profile", + "Enabled": true, + "DisplayName": "User profile", + "Description": "Your user profile information (first name, last name, etc.)", + "Emphasize": true, + "UserClaims": [ + "name", + "family_name", + "given_name", + "middle_name", + "nickname", + "preferred_username", + "profile", + "picture", + "website", + "gender", + "birthdate", + "zoneinfo", + "locale", + "updated_at" + ] + }, + { + "Name": "email", + "Enabled": true, + "DisplayName": "Your email address", + "Emphasize": true, + "UserClaims": [ + "email", + "email_verified" + ] + }, + { + "Name": "address", + "Enabled": true, + "DisplayName": "Your address", + "Emphasize": true, + "UserClaims": [ + "address" + ] + } + ], + "ApiResources": [ + { + "Name": "skoruba_identity_admin_api", + "Scopes": [ + { + "Name": "skoruba_identity_admin_api", + "DisplayName": "skoruba_identity_admin_api", + "Required": true, + "UserClaims": [ + "role" + ] + } + ] + } + ], + "Clients": [ + { + "ClientId": "skoruba_identity_admin", + "ClientName": "skoruba_identity_admin", + "ClientUri": "http://localhost:9000", + "AllowedGrantTypes": [ + "hybrid" + ], + "ClientSecrets": [ + { + "Value": "skoruba_admin_client_secret" + } ], - "ApiResources": [ - { - "Name": "skoruba_identity_admin_api", - "Scopes": [ - { - "Name": "skoruba_identity_admin_api", - "DisplayName": "skoruba_identity_admin_api", - "Required": true, - "UserClaims": [ - "role" - ] - } - ] - } + "RedirectUris": [ + "http://localhost:9000/signin-oidc" ], - "Clients": [ - { - "ClientId": "skoruba_identity_admin", - "ClientName": "skoruba_identity_admin", - "ClientUri": "http://localhost:9000", - "AllowedGrantTypes": [ - "hybrid" - ], - "ClientSecrets": [ - { - "Value": "skoruba_admin_client_secret" - } - ], - "RedirectUris": [ - "http://localhost:9000/signin-oidc" - ], - "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", - "PostLogoutRedirectUris": [ - "http://localhost:9000/signout-callback-oidc" - ], - "AllowedCorsOrigins": [ - "http://localhost:9000" - ], - "AllowedScopes": [ - "openid", - "email", - "profile", - "roles" - ] - }, - { - "ClientId": "skoruba_identity_admin_api_swaggerui", - "ClientName": "skoruba_identity_admin_api_swaggerui", - "AllowedGrantTypes": [ - "implicit" - ], - "RedirectUris": [ - "http://localhost:5001/swagger/oauth2-redirect.html" - ], - "AllowedScopes": [ - "skoruba_identity_admin_api" - ], - "AllowAccessTokensViaBrowser": true - - } + "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", + "PostLogoutRedirectUris": [ + "http://localhost:9000/signout-callback-oidc" + ], + "AllowedCorsOrigins": [ + "http://localhost:9000" + ], + "AllowedScopes": [ + "openid", + "email", + "profile", + "roles" ] - } + }, + { + "ClientId": "skoruba_identity_admin_api_swaggerui", + "ClientName": "skoruba_identity_admin_api_swaggerui", + "AllowedGrantTypes": [ + "implicit" + ], + "RedirectUris": [ + "http://localhost:5001/swagger/oauth2-redirect.html" + ], + "AllowedScopes": [ + "skoruba_identity_admin_api" + ], + "AllowAccessTokensViaBrowser": true + } + ] + }, + "HealthChecks-UI": { + "HealthChecks": [ + { + "Name": "Identity Admin Health Checks", + "Uri": "http://localhost:9000/health" + } + ] + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/healthchecksdb b/src/Skoruba.IdentityServer4.Admin/healthchecksdb new file mode 100644 index 0000000000000000000000000000000000000000..bd763fffd097c87f1ff961802abb1f6ebea5b31d GIT binary patch literal 45056 zcmeI*&2QUe90%~nNm}QH)Z;Kk912gv1`Ay?+iBXQ+9X2icG0q=q$%nSQ^VBc= zNxTzpk*RNlPyOHfKYC@+chPft^7qLpmWTlY5P-n37C2D7eBkaXcX(RU%j#Zgvv650 zR;-=mj#~Oq*;7k3ORMUaHPfmZnraT5n<|ei<4fk0L|&n(%(AjcgU`5#AkAiIaO8r5 z^xVJHcNQ_RU1cFKfHy_a--UJ|BRattgdnoR;}WV ziaOG1SGeFuE9VtBe`f^+lj1HmYno;bIuD;3#K|On*G~4@v!{lIZk`GKzbN7<7r?6s+P8;scdi5*iZCjNtqir6M8vU z({)YXetNIKwvfa01Rt20;qI5}P48@2ovF#*=67Zs4WPT+Sb}jOoYn0d>WWd_9nyB2 zr?JSPJR62Kr0@v#Wz8&AZ>z@sx@z3kO5M9?#<}L249w1Q*Xo$&tqMCNE12r7nyQ!7 zzPA%StbH@j>1^+Ro|Oz8+;Q@OP>8!1s@IvU>RZ}&a}zat-?@5f4ED}ET4(i_9ou35 zgXO^{#|IV{xx>cJyHHS8u4>zjos-%4B;6mF=;(DAn5V>auBl znywkua;;>2pc-b^=X7)HWMPtWOa`tma-{ypS+nblHLF^GUl_QYf;2GMKDM`y=ZT*^ zIpHy34-62100bZa0SG_<0uX=z1Rwwb2%J!X*EwfAAd6C5lB9?ji^%iQf~IShR;)zA zVp#ODc5%Wlggr1o00Izz00bZa0SG_<0uX=z1R!vt1zvN;J%j%V&^Z79hzO5PbOW*S z5P$##AOHafKmY;|fB*y_0D+fV;1V}M6ou?q*3G307b?|Kv9eP&t);jqiWhe3SE;7T zs%~l4K24N&HJvuD6QcENS55o)-z9uTgx`e6!q;p90|X!d0SG_<0uX=z1Rwwb2tWV= zFI?aamov$A-RYx!dyM8SQG9-w7HGK}}w5N3wkyklq$kTg|hQ|5-heUYz!kdN_ zfB*y_009U<00Izz00bZa0SLVO0yWM}+=(PRm2ZDhe@>F-q&SttB}rZq7s89t1&Lj} z-#=$Q5{@rQvKU=>p7Z~l@C9KH3=n_-1Rwwb2tWV=5P$##AOHaf99w~l_5}b*_oy%V zKlOhD_8*04G#-_un0@}==YK+k?}Sf;yFyAhJN4Jpk5ivdeLS_rk}*I40uX=z1Rwwb z2tWV=5P-mm6)=2mGV4BgbI#K~WVC;iP&G1DTB_>0TC#t}lTFqtWqL!UyT!7~UQ5NA zsZwi)J&VS+YO(avj;5=$$nxJ-EBn+?w^)`k)vT~6F4+$`EJb8?>N*ng^5g1A|K!w(4Q8x31Rwwb2tWV=5P$##AOHafKmY>&Lcsq0KcDa=5&jnb z5T3BR0RAfcEc_(=Abcx)#gZ{V00Izz00bZa0SG_<0uX=z1R!v%1YAxJ=d(v%d*rc4 zZhOSrqe*)-VUJw)$Z3xpPN&CXAOGY0|FP;wtPBJo009U<00Izz00bZa0SG|gKNt81 DJ}-o$ literal 0 HcmV?d00001 diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index e2865c91e..0adc93b28 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -441,5 +441,27 @@ public static void AddAuthorizationPolicies(this IServiceCollection services, policy => policy.RequireRole(rootConfiguration.AdminConfiguration.AdministrationRole)); }); } + + public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration) + where TConfigurationDbContext : DbContext, IConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TIdentityDbContext : DbContext + { + var configurationDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var identityDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + + services.AddHealthChecks() + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddDbContextCheck("ConfigurationDbContext") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddDbContextCheck("PersistedGrantsDbContext") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddDbContextCheck("IdentityDbContext"); + services.AddHealthChecksUI(); + } } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 6eda6cd72..820b27676 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -9,11 +9,15 @@ + + + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 2f537bcb1..056451dd5 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -1,4 +1,6 @@ -using Microsoft.AspNetCore.Builder; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -56,6 +58,8 @@ public void ConfigureServices(IServiceCollection services) // Add authorization policies for MVC var rootConfiguration = services.BuildServiceProvider().GetService(); services.AddAuthorizationPolicies(rootConfiguration); + + services.AddIdSHealthChecks(Configuration); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) @@ -76,7 +80,18 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseRouting(); app.UseAuthorization(); - app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); + app.UseEndpoints(endpoint => + { + endpoint.MapDefaultControllerRoute(); + endpoint.MapHealthChecks("/health", new HealthCheckOptions + { + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + endpoint.MapHealthChecksUI(setup => + { + setup.UIPath = "/health-ui"; + }); + }); } } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index e637d8bd0..6594512c6 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -75,8 +75,16 @@ "IdentityAdminBaseUrl": "http://localhost:9000", "AdministrationRole": "SkorubaIdentityAdminAdministrator" }, - "CultureConfiguration": { - "Cultures": [ ], - "DefaultCulture": null - } + "CultureConfiguration": { + "Cultures": [], + "DefaultCulture": null + }, + "HealthChecks-UI": { + "HealthChecks": [ + { + "Name": "Identity Server Health Checks", + "Uri": "http://localhost:5000/health" + } + ] + } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb b/src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb new file mode 100644 index 0000000000000000000000000000000000000000..90c18ed79d0a1455c1d01f73b2d6b3414e647320 GIT binary patch literal 45056 zcmeI*PjA~~90%~naT_-snc*-+90pIV0SntwJ8hPx0z`4$ELxV7G)3KEin7FQEiz}b zovqVO?WXOeaN;E(?KNI-P5_ywEBIHv_2_Zato?*}aFvmX3^hek`=leYFBTrJxG%o&0=4an0 zXTKG{j(;D2`bPH5N3nC!-=b&PL<|ss00drZfkS;>NIc4ON9PQ)sUH+}YS;97%h^}= z^~RUlf!^piM%%n**iPFrbUSozp*gY68MUIVRW({Dt!q0}ddWpdv|OUn#05$8VrYRv zQ%WA*iV2AaDt8p06sKl7$BfdeG5@b(oZS5Q2)%lf;(KyoPDteQ+_St>zunR&I!&Az z^CGFPeOA<_gU9D78ze@|`nRg(wF)hjtF*LTEK;>x+NxI8*mNpwUJp&3L1IaCvr@RR zR=G*9Yd7iIcC}n6u{F7&m8zG$Wt8f7bct5AonG_($?Lk^u#CHInug5Xa_UaUesSgc zwabG_-dgu(gdqi@WD$C0{c&zgiL*A?rp9ec65S|Qv_ihrl^CDVw4!Zj6|JOdTT~jh z>L!Vs@b2cat`#-5;Z-!&4F$CtpHDuyAP5On<(`$triqtqVexyj=BB5}Fk@daK?V&S zD?LW~a#|8hPNDUVRrhDtNaJBpFP|u0y#I5W93Di4#QF2wW3`(m8+D`Av2?rtE(8;x zKbfW8F?xGgYiif}i2XZ(k&YC3NuwM3aKjpYiUz|U&Nv=`zur`WX(?Pb-4gnS)xI+(c9*BO$gw=zmNBOC z1om~qZnW>~*268`x^Fc6yJ*I_ITKA>y2Rb=V%qmw?2xQx>-Rdk+0aKuX9KJwGcTHK z?|+%qOddYqg+wyRJx+GpRNLmRvFB}~c5rMa(4rKadA!aVtvj{D{sYUy9ZpDOv)oZ{ z=UuC58#j!--p4F7a-{o@Gq3CG9jDzLuZ1qBri4y*kL}&#c@k$&PW+Lu2L=d000Izz z00bZa0SG_<0uX=z1Wu^HI~<=&q-78009U<00Izz00bZa0SG_<0uXrJ1m5L&mGj;9V{oqw z@BS#!c!Xbw4W`;}aeOisyhlUt{QpxTK7HMS!}>q~0uX=z1Rwwb2tWV=5P$##PMg31 zH%B;CWhe3@?$7kED9RNjM-_QBy|TKzoXRQkaxSNg%*w6GnN&KL&SrDjS33XCZu*Y_ z0uX=z1Rwwb2tWV=5P$##AOL|=Ea0C1kDmRDh~J4{iI2pB_#PX<009U<00Izz00bZa z0SG_<0uVSg0?DXA7CCYy*1tY}{Wkk)yrUmD5m{dCK2q!=`rOr(v@|P_g^ZzHUOR>HXfB*y_009U<00Izz00bZaf#V7M0}X~DH~;_u literal 0 HcmV?d00001 From 7d13245031f9115a017f72121582b093a80e15b6 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 20 Nov 2019 11:29:20 +0100 Subject: [PATCH 235/338] Add support for MySQL database --- Skoruba.IdentityServer4.Admin.sln | 11 +- build/add-migrations.ps1 | 25 +- .../Helpers/StartupHelpers.cs | 62 +- .../Skoruba.IdentityServer4.Admin.Api.csproj | 3 + .../Extensions/DatabaseExtensions.cs | 94 ++ .../20191120085753_DbInit.Designer.cs | 65 ++ .../AuditLogging/20191120085753_DbInit.cs | 40 + .../AdminAuditLogDbContextModelSnapshot.cs | 63 ++ .../20191120085611_DbInit.Designer.cs | 267 ++++++ .../Identity/20191120085611_DbInit.cs | 218 +++++ .../AdminIdentityDbContextModelSnapshot.cs | 265 ++++++ .../20191120085701_DbInit.Designer.cs | 814 ++++++++++++++++++ .../20191120085701_DbInit.cs | 608 +++++++++++++ ...rverConfigurationDbContextModelSnapshot.cs | 812 +++++++++++++++++ .../20191120085729_DbInit.Designer.cs | 106 +++ .../20191120085729_DbInit.cs | 75 ++ ...verPersistedGrantDbContextModelSnapshot.cs | 104 +++ .../Logging/20191120085635_DbInit.Designer.cs | 57 ++ .../Logging/20191120085635_DbInit.cs | 37 + .../Logging/AdminLogDbContextModelSnapshot.cs | 55 ++ ...Server4.Admin.EntityFramework.MySql.csproj | 26 + .../Extensions/DatabaseExtensions.cs | 36 +- ...r.cs => 20191120100220_DbInit.Designer.cs} | 2 +- ...327_DbInit.cs => 20191120100220_DbInit.cs} | 0 ...r.cs => 20191120100035_DbInit.Designer.cs} | 2 +- ...204_DbInit.cs => 20191120100035_DbInit.cs} | 0 ...r.cs => 20191120100129_DbInit.Designer.cs} | 2 +- ...246_DbInit.cs => 20191120100129_DbInit.cs} | 0 ...r.cs => 20191120100155_DbInit.Designer.cs} | 2 +- ...308_DbInit.cs => 20191120100155_DbInit.cs} | 0 ...r.cs => 20191120100104_DbInit.Designer.cs} | 2 +- ...224_DbInit.cs => 20191120100104_DbInit.cs} | 0 .../Configuration/DatabaseProviderType.cs | 3 +- .../Extensions/DatabaseExtensions.cs | 31 + ...r.cs => 20191119164022_DbInit.Designer.cs} | 2 +- ...141_DbInit.cs => 20191119164022_DbInit.cs} | 0 ...r.cs => 20191119163918_DbInit.Designer.cs} | 2 +- ...015_DbInit.cs => 20191119163918_DbInit.cs} | 0 ...r.cs => 20191119163952_DbInit.Designer.cs} | 2 +- ...059_DbInit.cs => 20191119163952_DbInit.cs} | 0 ...r.cs => 20191119164007_DbInit.Designer.cs} | 2 +- ...119_DbInit.cs => 20191119164007_DbInit.cs} | 0 ...r.cs => 20191119163936_DbInit.Designer.cs} | 2 +- ...038_DbInit.cs => 20191119163936_DbInit.cs} | 0 .../Helpers/StartupHelpers.cs | 4 + .../Skoruba.IdentityServer4.Admin.csproj | 1 + .../Helpers/StartupHelpers.cs | 255 +++--- ...koruba.IdentityServer4.STS.Identity.csproj | 3 + .../Startup.cs | 6 +- 49 files changed, 3959 insertions(+), 207 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Extensions/DatabaseExtensions.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.Designer.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/AdminLogDbContextModelSnapshot.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/{20191113134327_DbInit.Designer.cs => 20191120100220_DbInit.Designer.cs} (98%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/{20191113134327_DbInit.cs => 20191120100220_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/{20191113134204_DbInit.Designer.cs => 20191120100035_DbInit.Designer.cs} (99%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/{20191113134204_DbInit.cs => 20191120100035_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/{20191113134246_DbInit.Designer.cs => 20191120100129_DbInit.Designer.cs} (99%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/{20191113134246_DbInit.cs => 20191120100129_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/{20191113134308_DbInit.Designer.cs => 20191120100155_DbInit.Designer.cs} (99%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/{20191113134308_DbInit.cs => 20191120100155_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/{20191113134224_DbInit.Designer.cs => 20191120100104_DbInit.Designer.cs} (98%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/{20191113134224_DbInit.cs => 20191120100104_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/{20191113134141_DbInit.Designer.cs => 20191119164022_DbInit.Designer.cs} (98%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/{20191113134141_DbInit.cs => 20191119164022_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/{20191113134015_DbInit.Designer.cs => 20191119163918_DbInit.Designer.cs} (99%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/{20191113134015_DbInit.cs => 20191119163918_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/{20191113134059_DbInit.Designer.cs => 20191119163952_DbInit.Designer.cs} (99%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/{20191113134059_DbInit.cs => 20191119163952_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/{20191113134119_DbInit.Designer.cs => 20191119164007_DbInit.Designer.cs} (98%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/{20191113134119_DbInit.cs => 20191119164007_DbInit.cs} (100%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/{20191113134038_DbInit.Designer.cs => 20191119163936_DbInit.Designer.cs} (98%) rename src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/{20191113134038_DbInit.cs => 20191119163936_DbInit.cs} (100%) diff --git a/Skoruba.IdentityServer4.Admin.sln b/Skoruba.IdentityServer4.Admin.sln index 866cf5903..c3efadb7c 100644 --- a/Skoruba.IdentityServer4.Admin.sln +++ b/Skoruba.IdentityServer4.Admin.sln @@ -37,14 +37,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Adm EndProject Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{F817047F-018D-4F93-BDA5-58602073B634}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer", "src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj", "{8230366D-81F9-4FA5-8F5D-8546B527F54F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer", "src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj", "{8230366D-81F9-4FA5-8F5D-8546B527F54F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL", "src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj", "{3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL", "src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj", "{3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "database", "database", "{2A514C8F-6A53-41CA-AB41-B644E7BC92A7}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "business", "business", "{EE588CE5-51D0-4E98-A2B3-40EC8E655931}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.MySql", "src\Skoruba.IdentityServer4.Admin.EntityFramework.MySql\Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj", "{0A8A0DB7-0509-4DFB-9201-74398511B481}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -115,6 +117,10 @@ Global {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Debug|Any CPU.Build.0 = Debug|Any CPU {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Release|Any CPU.ActiveCfg = Release|Any CPU {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D}.Release|Any CPU.Build.0 = Release|Any CPU + {0A8A0DB7-0509-4DFB-9201-74398511B481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A8A0DB7-0509-4DFB-9201-74398511B481}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A8A0DB7-0509-4DFB-9201-74398511B481}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A8A0DB7-0509-4DFB-9201-74398511B481}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -135,6 +141,7 @@ Global {2DD3CB7D-462E-4039-B684-81B1E88C7C6A} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} {8230366D-81F9-4FA5-8F5D-8546B527F54F} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {0A8A0DB7-0509-4DFB-9201-74398511B481} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B3166EDE-037B-4C68-BEBA-5DE9C5E3DB82} diff --git a/build/add-migrations.ps1 b/build/add-migrations.ps1 index 7c6eb088c..cae143845 100644 --- a/build/add-migrations.ps1 +++ b/build/add-migrations.ps1 @@ -1,4 +1,4 @@ -param([string] $migration = 'DbInit') +param([string] $migration = 'DbInit', [string] $migrationProviderName = 'All') $currentPath = Get-Location Set-Location ../src/Skoruba.IdentityServer4.Admin @@ -9,18 +9,25 @@ $dbProviders = @{ } $dbProviders.Add("SqlServer", "..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer\Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.csproj") $dbProviders.Add("PostgreSQL", "..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL\Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.csproj") +$dbProviders.Add("MySql", "..\..\src\Skoruba.IdentityServer4.Admin.EntityFramework.MySql\Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj") foreach ($key in $dbProviders.Keys) { - Write-Host $dbProviders[$key] - $settings = $settings -replace '"ProviderType".*', '"ProviderType": "' + $key + '",' - $settings | set-content appsettings.json + if ($migrationProviderName -eq 'All' -or $migrationProviderName -eq $key) { + + Write-Host "Generate migration for db provider:" $key ", for project path - " $dbProviders[$key] - dotnet ef migrations add $migration -c AdminIdentityDbContext -o Migrations/Identity -p $dbProviders[$key] - dotnet ef migrations add $migration -c AdminLogDbContext -o Migrations/Logging -p $dbProviders[$key] - dotnet ef migrations add $migration -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p $dbProviders[$key] - dotnet ef migrations add $migration -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p $dbProviders[$key] - dotnet ef migrations add $migration -c AdminAuditLogDbContext -o Migrations/AuditLogging -p $dbProviders[$key] + $providerName = '"ProviderType": "' + $key + '"' + + $settings = $settings -replace '"ProviderType".*', $providerName + $settings | set-content appsettings.json + + dotnet ef migrations add $migration -c AdminIdentityDbContext -o Migrations/Identity -p $dbProviders[$key] + dotnet ef migrations add $migration -c AdminLogDbContext -o Migrations/Logging -p $dbProviders[$key] + dotnet ef migrations add $migration -c IdentityServerConfigurationDbContext -o Migrations/IdentityServerConfiguration -p $dbProviders[$key] + dotnet ef migrations add $migration -c IdentityServerPersistedGrantDbContext -o Migrations/IdentityServerGrants -p $dbProviders[$key] + dotnet ef migrations add $migration -c AdminAuditLogDbContext -o Migrations/AuditLogging -p $dbProviders[$key] + } } Remove-Item appsettings.json diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 9127c864e..04de92586 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -5,19 +5,16 @@ using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; using Serilog; using Skoruba.AuditLogging.EntityFramework.DbContexts; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.AuditLogging.EntityFramework.Extensions; using Skoruba.AuditLogging.EntityFramework.Repositories; using Skoruba.AuditLogging.EntityFramework.Services; -using Skoruba.AuditLogging.Events.Http; using Skoruba.IdentityServer4.Admin.Api.AuditLogging; using Skoruba.IdentityServer4.Admin.Api.Configuration; using Skoruba.IdentityServer4.Admin.Api.Configuration.ApplicationParts; @@ -25,6 +22,10 @@ using Skoruba.IdentityServer4.Admin.Api.Helpers.Localization; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; +using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; +using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; namespace Skoruba.IdentityServer4.Admin.Api.Helpers { @@ -114,6 +115,7 @@ public static void AddLogging(this IApplicationBuilder app, IConfiguration confi /// /// /// + /// /// /// public static void AddDbContexts { - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); - // Config DB for identity - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly))); + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var errorLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); + var auditLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); - // Config DB from existing connection - services.AddConfigurationDbContext(options => + switch (databaseProviderType) { - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - // Operational DB from existing connection - services.AddOperationalDbContext(options => - { - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - // Log DB from existing connection - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey), - optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); - - // Audit logging connection - services.AddDbContext(options => - options.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey), - optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + case DatabaseProviderType.SqlServer: + services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; + case DatabaseProviderType.PostgreSQL: + services.RegisterNpgSqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; + case DatabaseProviderType.MySql: + services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; + default: + throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + } } /// diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index 21faa0e85..db235afb6 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -30,7 +30,10 @@ + + + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Extensions/DatabaseExtensions.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Extensions/DatabaseExtensions.cs new file mode 100644 index 000000000..d8f979018 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Extensions/DatabaseExtensions.cs @@ -0,0 +1,94 @@ +using System.Reflection; +using IdentityServer4.EntityFramework.Storage; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.AuditLogging.EntityFramework.DbContexts; +using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions +{ + public static class DatabaseExtensions + { + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterMySqlDbContexts(this IServiceCollection services, + string identityConnectionString, string configurationConnectionString, + string persistedGrantConnectionString, string errorLoggingConnectionString, + string auditLoggingConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => + options.UseMySql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => + options.ConfigureDbContext = b => + b.UseMySql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => + b.UseMySql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Log DB from existing connection + services.AddDbContext(options => options.UseMySql(errorLoggingConnectionString, + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + + // Audit logging connection + services.AddDbContext(options => options.UseMySql(auditLoggingConnectionString, + optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); + } + + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterMySqlDbContexts(this IServiceCollection services, + string identityConnectionString, string configurationConnectionString, + string persistedGrantConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => options.UseMySql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => options.ConfigureDbContext = b => b.UseMySql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => b.UseMySql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.Designer.cs new file mode 100644 index 000000000..b3f4e156a --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.Designer.cs @@ -0,0 +1,65 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + [Migration("20191120085753_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Action") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Event") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Source") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectAdditionalData") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectIdentifier") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.cs new file mode 100644 index 000000000..7ae662c73 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/20191120085753_DbInit.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.AuditLogging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AuditLog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Event = table.Column(nullable: true), + Source = table.Column(nullable: true), + Category = table.Column(nullable: true), + SubjectIdentifier = table.Column(nullable: true), + SubjectName = table.Column(nullable: true), + SubjectType = table.Column(nullable: true), + SubjectAdditionalData = table.Column(nullable: true), + Action = table.Column(nullable: true), + Data = table.Column(nullable: true), + Created = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AuditLog", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AuditLog"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..91079b7ed --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/AuditLogging/AdminAuditLogDbContextModelSnapshot.cs @@ -0,0 +1,63 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.AuditLogging +{ + [DbContext(typeof(AdminAuditLogDbContext))] + partial class AdminAuditLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.AuditLogging.EntityFramework.Entities.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Action") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Event") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Source") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectAdditionalData") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectIdentifier") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SubjectType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("AuditLog"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.Designer.cs new file mode 100644 index 000000000..24aab9ec4 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.Designer.cs @@ -0,0 +1,267 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + [Migration("20191120085611_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.cs new file mode 100644 index 000000000..b8693e043 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/20191120085611_DbInit.cs @@ -0,0 +1,218 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Identity +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "RoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_RoleClaims_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogins_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_UserRoles_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserRoles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RoleClaims_RoleId", + table: "RoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "Roles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogins_UserId", + table: "UserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserRoles_RoleId", + table: "UserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "Users", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "Users", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RoleClaims"); + + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "UserLogins"); + + migrationBuilder.DropTable( + name: "UserRoles"); + + migrationBuilder.DropTable( + name: "UserTokens"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs new file mode 100644 index 000000000..7f2b9fd8f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Identity/AdminIdentityDbContextModelSnapshot.cs @@ -0,0 +1,265 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Identity +{ + [DbContext(typeof(AdminIdentityDbContext))] + partial class AdminIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens"); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRoleClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserClaim", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserLogin", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserRole", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentityUserToken", b => + { + b.HasOne("Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity.UserIdentity", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.Designer.cs new file mode 100644 index 000000000..fea85ef1f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.Designer.cs @@ -0,0 +1,814 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + [Migration("20191120085701_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastAccessed") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiScopeId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("tinyint(1)"); + + b.Property("AllowOfflineAccess") + .HasColumnType("tinyint(1)"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("tinyint(1)"); + + b.Property("AllowRememberConsent") + .HasColumnType("tinyint(1)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("tinyint(1)"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("tinyint(1)"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("tinyint(1)"); + + b.Property("LastAccessed") + .HasColumnType("datetime(6)"); + + b.Property("LogoUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("tinyint(1)"); + + b.Property("RequireConsent") + .HasColumnType("tinyint(1)"); + + b.Property("RequirePkce") + .HasColumnType("tinyint(1)"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.Property("UserCodeType") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("varchar(150) CHARACTER SET utf8mb4") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.cs new file mode 100644 index 000000000..61ef1af35 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/20191120085701_DbInit.cs @@ -0,0 +1,608 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerConfiguration +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ApiResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Enabled = table.Column(nullable: false), + ClientId = table.Column(maxLength: 200, nullable: false), + ProtocolType = table.Column(maxLength: 200, nullable: false), + RequireClientSecret = table.Column(nullable: false), + ClientName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + ClientUri = table.Column(maxLength: 2000, nullable: true), + LogoUri = table.Column(maxLength: 2000, nullable: true), + RequireConsent = table.Column(nullable: false), + AllowRememberConsent = table.Column(nullable: false), + AlwaysIncludeUserClaimsInIdToken = table.Column(nullable: false), + RequirePkce = table.Column(nullable: false), + AllowPlainTextPkce = table.Column(nullable: false), + AllowAccessTokensViaBrowser = table.Column(nullable: false), + FrontChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + FrontChannelLogoutSessionRequired = table.Column(nullable: false), + BackChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + BackChannelLogoutSessionRequired = table.Column(nullable: false), + AllowOfflineAccess = table.Column(nullable: false), + IdentityTokenLifetime = table.Column(nullable: false), + AccessTokenLifetime = table.Column(nullable: false), + AuthorizationCodeLifetime = table.Column(nullable: false), + ConsentLifetime = table.Column(nullable: true), + AbsoluteRefreshTokenLifetime = table.Column(nullable: false), + SlidingRefreshTokenLifetime = table.Column(nullable: false), + RefreshTokenUsage = table.Column(nullable: false), + UpdateAccessTokenClaimsOnRefresh = table.Column(nullable: false), + RefreshTokenExpiration = table.Column(nullable: false), + AccessTokenType = table.Column(nullable: false), + EnableLocalLogin = table.Column(nullable: false), + IncludeJwtId = table.Column(nullable: false), + AlwaysSendClientClaims = table.Column(nullable: false), + ClientClaimsPrefix = table.Column(maxLength: 200, nullable: true), + PairWiseSubjectSalt = table.Column(maxLength: 200, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + UserSsoLifetime = table.Column(nullable: true), + UserCodeType = table.Column(maxLength: 100, nullable: true), + DeviceCodeLifetime = table.Column(nullable: false), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "IdentityResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ApiClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 200, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiClaims_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiProperties", x => x.Id); + table.ForeignKey( + name: "FK_ApiProperties_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopes", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopes_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Description = table.Column(maxLength: 1000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ApiSecrets_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientClaims", x => x.Id); + table.ForeignKey( + name: "FK_ClientClaims_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientCorsOrigins", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Origin = table.Column(maxLength: 150, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id); + table.ForeignKey( + name: "FK_ClientCorsOrigins_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientGrantTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + GrantType = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientGrantTypes", x => x.Id); + table.ForeignKey( + name: "FK_ClientGrantTypes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientIdPRestrictions", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Provider = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id); + table.ForeignKey( + name: "FK_ClientIdPRestrictions_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientPostLogoutRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + PostLogoutRedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientProperties", x => x.Id); + table.ForeignKey( + name: "FK_ClientProperties_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Scope = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientScopes", x => x.Id); + table.ForeignKey( + name: "FK_ClientScopes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Description = table.Column(maxLength: 2000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ClientSecrets_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 200, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityClaims", x => x.Id); + table.ForeignKey( + name: "FK_IdentityClaims_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityProperties", x => x.Id); + table.ForeignKey( + name: "FK_IdentityProperties_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopeClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 200, nullable: false), + ApiScopeId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopeClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopeClaims_ApiScopes_ApiScopeId", + column: x => x.ApiScopeId, + principalTable: "ApiScopes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiClaims_ApiResourceId", + table: "ApiClaims", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiProperties_ApiResourceId", + table: "ApiProperties", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiResources_Name", + table: "ApiResources", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopeClaims_ApiScopeId", + table: "ApiScopeClaims", + column: "ApiScopeId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_ApiResourceId", + table: "ApiScopes", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_Name", + table: "ApiScopes", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiSecrets_ApiResourceId", + table: "ApiSecrets", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientClaims_ClientId", + table: "ClientClaims", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientCorsOrigins_ClientId", + table: "ClientCorsOrigins", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientGrantTypes_ClientId", + table: "ClientGrantTypes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientIdPRestrictions_ClientId", + table: "ClientIdPRestrictions", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientPostLogoutRedirectUris_ClientId", + table: "ClientPostLogoutRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientProperties_ClientId", + table: "ClientProperties", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientRedirectUris_ClientId", + table: "ClientRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Clients_ClientId", + table: "Clients", + column: "ClientId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ClientScopes_ClientId", + table: "ClientScopes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientSecrets_ClientId", + table: "ClientSecrets", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityClaims_IdentityResourceId", + table: "IdentityClaims", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityProperties_IdentityResourceId", + table: "IdentityProperties", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityResources_Name", + table: "IdentityResources", + column: "Name", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApiClaims"); + + migrationBuilder.DropTable( + name: "ApiProperties"); + + migrationBuilder.DropTable( + name: "ApiScopeClaims"); + + migrationBuilder.DropTable( + name: "ApiSecrets"); + + migrationBuilder.DropTable( + name: "ClientClaims"); + + migrationBuilder.DropTable( + name: "ClientCorsOrigins"); + + migrationBuilder.DropTable( + name: "ClientGrantTypes"); + + migrationBuilder.DropTable( + name: "ClientIdPRestrictions"); + + migrationBuilder.DropTable( + name: "ClientPostLogoutRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientProperties"); + + migrationBuilder.DropTable( + name: "ClientRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientScopes"); + + migrationBuilder.DropTable( + name: "ClientSecrets"); + + migrationBuilder.DropTable( + name: "IdentityClaims"); + + migrationBuilder.DropTable( + name: "IdentityProperties"); + + migrationBuilder.DropTable( + name: "ApiScopes"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "IdentityResources"); + + migrationBuilder.DropTable( + name: "ApiResources"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs new file mode 100644 index 000000000..daaf9173e --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerConfiguration/IdentityServerConfigurationDbContextModelSnapshot.cs @@ -0,0 +1,812 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerConfiguration +{ + [DbContext(typeof(IdentityServerConfigurationDbContext))] + partial class IdentityServerConfigurationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastAccessed") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiScopeId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApiResourceId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("tinyint(1)"); + + b.Property("AllowOfflineAccess") + .HasColumnType("tinyint(1)"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("tinyint(1)"); + + b.Property("AllowRememberConsent") + .HasColumnType("tinyint(1)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("tinyint(1)"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("tinyint(1)"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("tinyint(1)"); + + b.Property("LastAccessed") + .HasColumnType("datetime(6)"); + + b.Property("LogoUri") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("tinyint(1)"); + + b.Property("RequireConsent") + .HasColumnType("tinyint(1)"); + + b.Property("RequirePkce") + .HasColumnType("tinyint(1)"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.Property("UserCodeType") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("varchar(150) CHARACTER SET utf8mb4") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("varchar(1000) CHARACTER SET utf8mb4") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("tinyint(1)"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("IdentityResourceId") + .HasColumnType("int"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(250) CHARACTER SET utf8mb4") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(2000) CHARACTER SET utf8mb4") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.Designer.cs new file mode 100644 index 000000000..b00bebacf --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.Designer.cs @@ -0,0 +1,106 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + [Migration("20191120085729_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("SubjectId") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("SubjectId") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.cs new file mode 100644 index 000000000..b6f6c0697 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/20191120085729_DbInit.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerGrants +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DeviceCodes", + columns: table => new + { + UserCode = table.Column(maxLength: 200, nullable: false), + DeviceCode = table.Column(maxLength: 200, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: false), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DeviceCodes", x => x.UserCode); + }); + + migrationBuilder.CreateTable( + name: "PersistedGrants", + columns: table => new + { + Key = table.Column(maxLength: 200, nullable: false), + Type = table.Column(maxLength: 50, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: true), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersistedGrants", x => x.Key); + }); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_DeviceCode", + table: "DeviceCodes", + column: "DeviceCode", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_DeviceCodes_Expiration", + table: "DeviceCodes", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_Expiration", + table: "PersistedGrants", + column: "Expiration"); + + migrationBuilder.CreateIndex( + name: "IX_PersistedGrants_SubjectId_ClientId_Type", + table: "PersistedGrants", + columns: new[] { "SubjectId", "ClientId", "Type" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DeviceCodes"); + + migrationBuilder.DropTable( + name: "PersistedGrants"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs new file mode 100644 index 000000000..9f33655e2 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/IdentityServerGrants/IdentityServerPersistedGrantDbContextModelSnapshot.cs @@ -0,0 +1,104 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.IdentityServerGrants +{ + [DbContext(typeof(IdentityServerPersistedGrantDbContext))] + partial class IdentityServerPersistedGrantDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b => + { + b.Property("UserCode") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("SubjectId") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.HasKey("UserCode"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.ToTable("DeviceCodes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b => + { + b.Property("Key") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("SubjectId") + .HasColumnType("varchar(200) CHARACTER SET utf8mb4") + .HasMaxLength(200); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.ToTable("PersistedGrants"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.Designer.cs new file mode 100644 index 000000000..aaaeb025f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.Designer.cs @@ -0,0 +1,57 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + [Migration("20191120085635_DbInit")] + partial class DbInit + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Exception") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Level") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Message") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("MessageTemplate") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Properties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TimeStamp") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.cs new file mode 100644 index 000000000..e390205cb --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/20191120085635_DbInit.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Logging +{ + public partial class DbInit : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Log", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Message = table.Column(nullable: true), + MessageTemplate = table.Column(nullable: true), + Level = table.Column(maxLength: 128, nullable: true), + TimeStamp = table.Column(nullable: false), + Exception = table.Column(nullable: true), + LogEvent = table.Column(nullable: true), + Properties = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Log", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Log"); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/AdminLogDbContextModelSnapshot.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/AdminLogDbContextModelSnapshot.cs new file mode 100644 index 000000000..7f75145eb --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Migrations/Logging/AdminLogDbContextModelSnapshot.cs @@ -0,0 +1,55 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Migrations.Logging +{ + [DbContext(typeof(AdminLogDbContext))] + partial class AdminLogDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Skoruba.IdentityServer4.Admin.EntityFramework.Entities.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Exception") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Level") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("LogEvent") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Message") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("MessageTemplate") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Properties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TimeStamp") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("Log"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj new file mode 100644 index 000000000..d06b0ed57 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.MySql/Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.0 + 1.0.0-beta7 + Jan Škoruba + IdentityServer4 Admin OpenIDConnect OAuth2 Identity + Entity Framework library for support MySql + https://github.com/skoruba/IdentityServer4.Admin/blob/master/LICENSE.md + https://github.com/skoruba/IdentityServer4.Admin + https://raw.githubusercontent.com/skoruba/IdentityServer4.Admin/master/docs/Images/Skoruba.IdentityServer4.Admin-Logo-Nuget.png + + + + + + + + + + + + + + + diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs index 87120f910..007817528 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Extensions/DatabaseExtensions.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using IdentityServer4.EntityFramework.Storage; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -59,5 +60,36 @@ public static class DatabaseExtensions services.AddDbContext(options => options.UseNpgsql(auditLoggingConnectionString, optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); } + + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterNpgSqlDbContexts(this IServiceCollection services, + string identityConnectionString, string configurationConnectionString, + string persistedGrantConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => options.UseNpgsql(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => options.ConfigureDbContext = b => b.UseNpgsql(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => b.UseNpgsql(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + } } -} +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191120100220_DbInit.Designer.cs similarity index 98% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191120100220_DbInit.Designer.cs index e34139ca6..80e9b52c0 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191120100220_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.AuditLogging { [DbContext(typeof(AdminAuditLogDbContext))] - [Migration("20191113134327_DbInit")] + [Migration("20191120100220_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191120100220_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191113134327_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/AuditLogging/20191120100220_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191120100035_DbInit.Designer.cs similarity index 99% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191120100035_DbInit.Designer.cs index 6a11b39c2..83de728c9 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191120100035_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Identity { [DbContext(typeof(AdminIdentityDbContext))] - [Migration("20191113134204_DbInit")] + [Migration("20191120100035_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191120100035_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191113134204_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Identity/20191120100035_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191120100129_DbInit.Designer.cs similarity index 99% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191120100129_DbInit.Designer.cs index 7b952b7db..1cbba5018 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191120100129_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerConfiguration { [DbContext(typeof(IdentityServerConfigurationDbContext))] - [Migration("20191113134246_DbInit")] + [Migration("20191120100129_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191120100129_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191113134246_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerConfiguration/20191120100129_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191120100155_DbInit.Designer.cs similarity index 99% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191120100155_DbInit.Designer.cs index c303ddad3..79c719e1b 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191120100155_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.IdentityServerGrants { [DbContext(typeof(IdentityServerPersistedGrantDbContext))] - [Migration("20191113134308_DbInit")] + [Migration("20191120100155_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191120100155_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191113134308_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/IdentityServerGrants/20191120100155_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191120100104_DbInit.Designer.cs similarity index 98% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191120100104_DbInit.Designer.cs index 4cbb7166f..00e6a2803 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191120100104_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Migrations.Logging { [DbContext(typeof(AdminLogDbContext))] - [Migration("20191113134224_DbInit")] + [Migration("20191120100104_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191120100104_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191113134224_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL/Migrations/Logging/20191120100104_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs index ee5ae94e2..3e7cd9e6c 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderType.cs @@ -3,6 +3,7 @@ public enum DatabaseProviderType { SqlServer, - PostgreSQL + PostgreSQL, + MySql } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs index 6f55a1a4e..3ef917703 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Extensions/DatabaseExtensions.cs @@ -49,5 +49,36 @@ public static void RegisterSqlServerDbContexts(options => options.UseSqlServer(auditLoggingConnectionString, optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); } + + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + /// + public static void RegisterSqlServerDbContexts(this IServiceCollection services, + string identityConnectionString, string configurationConnectionString, + string persistedGrantConnectionString) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var migrationsAssembly = typeof(DatabaseExtensions).GetTypeInfo().Assembly.GetName().Name; + + // Config DB for identity + services.AddDbContext(options => options.UseSqlServer(identityConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Config DB from existing connection + services.AddConfigurationDbContext(options => options.ConfigureDbContext = b => b.UseSqlServer(configurationConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + + // Operational DB from existing connection + services.AddOperationalDbContext(options => options.ConfigureDbContext = b => b.UseSqlServer(persistedGrantConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly))); + } } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191119164022_DbInit.Designer.cs similarity index 98% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191119164022_DbInit.Designer.cs index c62b46781..cc393c821 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191119164022_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.AuditLogging { [DbContext(typeof(AdminAuditLogDbContext))] - [Migration("20191113134141_DbInit")] + [Migration("20191119164022_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191119164022_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191113134141_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/AuditLogging/20191119164022_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191119163918_DbInit.Designer.cs similarity index 99% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191119163918_DbInit.Designer.cs index 60d3d98ee..74ed6bbf2 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191119163918_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Identity { [DbContext(typeof(AdminIdentityDbContext))] - [Migration("20191113134015_DbInit")] + [Migration("20191119163918_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191119163918_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191113134015_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Identity/20191119163918_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191119163952_DbInit.Designer.cs similarity index 99% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191119163952_DbInit.Designer.cs index 3115f92d5..12fc1bec9 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191119163952_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerConfiguration { [DbContext(typeof(IdentityServerConfigurationDbContext))] - [Migration("20191113134059_DbInit")] + [Migration("20191119163952_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191119163952_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191113134059_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerConfiguration/20191119163952_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191119164007_DbInit.Designer.cs similarity index 98% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191119164007_DbInit.Designer.cs index c58dae863..3e8082727 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191119164007_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.IdentityServerGrants { [DbContext(typeof(IdentityServerPersistedGrantDbContext))] - [Migration("20191113134119_DbInit")] + [Migration("20191119164007_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191119164007_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191113134119_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/IdentityServerGrants/20191119164007_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191119163936_DbInit.Designer.cs similarity index 98% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191119163936_DbInit.Designer.cs index 3d9f0dc15..0445557ec 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.Designer.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191119163936_DbInit.Designer.cs @@ -10,7 +10,7 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Migrations.Logging { [DbContext(typeof(AdminLogDbContext))] - [Migration("20191113134038_DbInit")] + [Migration("20191119163936_DbInit")] partial class DbInit { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191119163936_DbInit.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191113134038_DbInit.cs rename to src/Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer/Migrations/Logging/20191119163936_DbInit.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 129c8e779..e13da9b6c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -44,6 +44,7 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; using Skoruba.IdentityServer4.Admin.Helpers.Localization; using Microsoft.Extensions.Hosting; +using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; @@ -156,6 +157,9 @@ public static void RegisterDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); break; + case DatabaseProviderType.MySql: + services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); + break; default: throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); } diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index 39c858afb..083b38455 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -105,6 +105,7 @@ + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 5b332bbba..4f7a941d2 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -1,7 +1,6 @@ using System; using System.Globalization; -using System.Reflection; -using IdentityServer4.EntityFramework.Interfaces; +using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -9,7 +8,6 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Localization; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -27,6 +25,11 @@ using Skoruba.IdentityServer4.STS.Identity.Services; using ILogger = Microsoft.Extensions.Logging.ILogger; using Microsoft.Extensions.Hosting; +using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; +using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; +using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; namespace Skoruba.IdentityServer4.STS.Identity.Helpers { @@ -43,7 +46,7 @@ public static void AddMvcWithLocalization(this IServiceCollection s services.AddLocalization(opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }); services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - + services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); @@ -120,6 +123,100 @@ public static void AddEmailSenders(this IServiceCollection services, IConfigurat } } + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + /// + public static void RegisterDbContexts(this IServiceCollection services, IWebHostEnvironment environment, IConfiguration configuration) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + if (environment.IsStaging()) + { + services.RegisterDbContextsInMemory(); + } + else + { + services.RegisterDbContexts(configuration); + } + } + + + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + public static void RegisterDbContexts(this IServiceCollection services, IConfiguration configuration) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); + + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + + switch (databaseProviderType) + { + case DatabaseProviderType.SqlServer: + services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + case DatabaseProviderType.PostgreSQL: + services.RegisterNpgSqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + case DatabaseProviderType.MySql: + services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + default: + throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + } + } + + /// + /// Register InMemory DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + public static void RegisterDbContextsInMemory( + this IServiceCollection services) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var identityDatabaseName = Guid.NewGuid().ToString(); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(identityDatabaseName)); + + var configurationDatabaseName = Guid.NewGuid().ToString(); + var operationalDatabaseName = Guid.NewGuid().ToString(); + + services.AddConfigurationDbContext(options => + { + options.ConfigureDbContext = b => b.UseInMemoryDatabase(configurationDatabaseName); + }); + + services.AddOperationalDbContext(options => + { + options.ConfigureDbContext = b => b.UseInMemoryDatabase(operationalDatabaseName); + }); + } + /// /// Add services for authentication, including Identity model, IdentityServer4 and external providers /// @@ -129,13 +226,11 @@ public static void AddEmailSenders(this IServiceCollection services, IConfigurat /// /// /// - /// /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfiguration configuration, ILogger logger) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - where TIdentityDbContext : DbContext + public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration, ILogger logger) where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TUserIdentity : class where TUserIdentityRole : class { @@ -163,7 +258,7 @@ public static void AddAuthenticationServices(services, configuration, logger, hostingEnvironment); + AddIdentityServer(services, configuration, logger); } /// @@ -229,13 +324,12 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect /// /// /// - /// private static void AddIdentityServer( IServiceCollection services, - IConfiguration configuration, ILogger logger, IWebHostEnvironment hostingEnvironment) + IConfiguration configuration, ILogger logger) + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TUserIdentity : class - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext { var builder = services.AddIdentityServer(options => { @@ -244,8 +338,9 @@ private static void AddIdentityServer() - .AddIdentityServerStoresWithDbContexts(configuration, hostingEnvironment); + .AddConfigurationStore() + .AddOperationalStore() + .AddAspNetIdentity(); builder.AddCustomSigningCredential(configuration, logger); builder.AddCustomValidationKey(configuration, logger); @@ -272,133 +367,6 @@ private static void AddExternalProviders(AuthenticationBuilder authenticationBui } } - /// - /// Add DbContext for Identity - /// - /// - /// - /// - /// - public static void AddIdentityDbContext(this IServiceCollection services, - IConfiguration configuration, IWebHostEnvironment hostingEnvironment) - where TContext : DbContext - { - if (hostingEnvironment.IsStaging()) - { - RegisterIdentityDbContextStaging(services); - } - else - { - RegisterIdentityDbContext(services, configuration); - } - } - - private static void RegisterIdentityDbContextStaging(IServiceCollection services) where TContext : DbContext - { - var identityDatabaseName = Guid.NewGuid().ToString(); - - services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(identityDatabaseName)); - } - - private static void RegisterIdentityDbContext(IServiceCollection services, IConfiguration configuration) - where TContext : DbContext - { - var connectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); - services.AddDbContext(options => options.UseSqlServer(connectionString)); - } - - /// - /// Add shared DbContext for Identity and IdentityServer4 stores - /// - /// - /// - /// - public static void AddDbContexts(this IServiceCollection services, IConfiguration configuration) - where TContext : DbContext - { - var connectionString = configuration.GetConnectionString(ConfigurationConsts.AdminConnectionStringKey); - services.AddDbContext(options => options.UseSqlServer(connectionString)); - } - - /// - /// Register DbContexts and configure stores for IdentityServer4 - /// - /// - /// - /// - /// - /// - public static IIdentityServerBuilder AddIdentityServerStoresWithDbContexts(this IIdentityServerBuilder builder, IConfiguration configuration, - IWebHostEnvironment hostingEnvironment) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - if (hostingEnvironment.IsStaging()) - { - return RegisterIdentityServerStoresWithDbContextsStaging(builder, configuration); - } - else - { - return RegisterIdentityServerStoresWithDbContexts(builder, configuration); - } - } - - private static IIdentityServerBuilder - RegisterIdentityServerStoresWithDbContextsStaging( - IIdentityServerBuilder builder, IConfiguration configuration) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - var configurationDatabaseName = Guid.NewGuid().ToString(); - var operationalDatabaseName = Guid.NewGuid().ToString(); - - builder.AddConfigurationStore(options => - { - options.ConfigureDbContext = b => b.UseInMemoryDatabase(configurationDatabaseName); - }); - - builder.AddOperationalStore(options => - { - options.ConfigureDbContext = b => b.UseInMemoryDatabase(operationalDatabaseName); - }); - - return builder; - } - - private static IIdentityServerBuilder - RegisterIdentityServerStoresWithDbContexts( - IIdentityServerBuilder builder, IConfiguration configuration) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; - - // Config DB from existing connection - builder.AddConfigurationStore(options => - { - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - // Operational DB from existing connection - builder.AddOperationalStore(options => - { - options.EnableTokenCleanup = true; -#if DEBUG - options.TokenCleanupInterval = 15; -#endif - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - return builder; - } - /// /// Register middleware for localization /// @@ -426,6 +394,7 @@ public static void AddLogging(this IApplicationBuilder app, ILoggerFactory logge /// Add authorization policies /// /// + /// public static void AddAuthorizationPolicies(this IServiceCollection services, IRootConfiguration rootConfiguration) { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 6eda6cd72..73c55b5aa 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -30,7 +30,10 @@ + + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 0d46bcb47..e6487b65b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -39,14 +39,14 @@ public void ConfigureServices(IServiceCollection services) { services.ConfigureRootConfiguration(Configuration); - // Add DbContext for Asp.Net Core Identity - services.AddIdentityDbContext(Configuration, Environment); + // Register DbContexts for IdentityServer and Identity + services.RegisterDbContexts(Environment, Configuration); // Add email senders which is currently setup for SendGrid and SMTP services.AddEmailSenders(Configuration); // Add services for authentication, including Identity model, IdentityServer4 and external providers - services.AddAuthenticationServices(Environment, Configuration, Logger); + services.AddAuthenticationServices(Configuration, Logger); // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization From 6ec0aae1e8a390826ead5cf591c86a76de798ae0 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 20 Nov 2019 11:30:17 +0100 Subject: [PATCH 236/338] Add DatabaseProviderConfiguration configuration --- .../appsettings.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 91e08e29f..0497dcfc5 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -4,6 +4,9 @@ "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" }, + "DatabaseProviderConfiguration": { + "ProviderType": "SqlServer" + }, "Serilog": { "MinimumLevel": { "Default": "Error", @@ -71,8 +74,8 @@ "LoginConfiguration": { "ResolutionPolicy": "Username" }, - "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000", - "AdministrationRole": "SkorubaIdentityAdminAdministrator" - } + "AdminConfiguration": { + "IdentityAdminBaseUrl": "http://localhost:9000", + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + } } \ No newline at end of file From 82217d5464824ff36867662ae559f6168f4fa60a Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 20 Nov 2019 13:14:22 +0100 Subject: [PATCH 237/338] Change string to Enum --- .../Helpers/StartupHelpers.cs | 7 +++---- .../Configuration/DatabaseProviderConfiguration.cs | 2 +- .../Helpers/StartupHelpers.cs | 7 +++---- .../Helpers/StartupHelpers.cs | 7 +++---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 04de92586..fba1be226 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -127,15 +127,14 @@ public static void AddLogging(this IApplicationBuilder app, IConfiguration confi where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext { var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); - Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); - + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); var errorLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); var auditLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); - switch (databaseProviderType) + switch (databaseProvider.ProviderType) { case DatabaseProviderType.SqlServer: services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); @@ -147,7 +146,7 @@ public static void AddLogging(this IApplicationBuilder app, IConfiguration confi services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs index 4d222f7a2..8622bea8d 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework.Shared/Configuration/DatabaseProviderConfiguration.cs @@ -2,6 +2,6 @@ { public class DatabaseProviderConfiguration { - public string ProviderType { get; set; } + public DatabaseProviderType ProviderType { get; set; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index b85e2dfea..b693f3865 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -142,15 +142,14 @@ public static void RegisterDbContexts { var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); - Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); - + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); var errorLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminLogDbConnectionStringKey); var auditLoggingConnectionString = configuration.GetConnectionString(ConfigurationConsts.AdminAuditLogDbConnectionStringKey); - switch (databaseProviderType) + switch (databaseProvider.ProviderType) { case DatabaseProviderType.SqlServer: services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); @@ -162,7 +161,7 @@ public static void RegisterDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index f8c0c7cc5..1e0696c2c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -170,13 +170,12 @@ public static void RegisterDbContexts(); - Enum.TryParse(databaseProvider.ProviderType, out DatabaseProviderType databaseProviderType); - + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); - switch (databaseProviderType) + switch (databaseProvider.ProviderType) { case DatabaseProviderType.SqlServer: services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); @@ -188,7 +187,7 @@ public static void RegisterDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); } } From 0fe01c9096565d3b747117546226f73c114a7cc9 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Wed, 20 Nov 2019 14:14:12 +0100 Subject: [PATCH 238/338] Add name of recommended values for dbprovider --- src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs | 2 +- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 2 +- .../Helpers/StartupHelpers.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index fba1be226..45a4fe7ed 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -146,7 +146,7 @@ public static void AddLogging(this IApplicationBuilder app, IConfiguration confi services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}."); } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index b693f3865..931589086 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -161,7 +161,7 @@ public static void RegisterDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString, errorLoggingConnectionString, auditLoggingConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}."); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 1e0696c2c..8df71f705 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -187,7 +187,7 @@ public static void RegisterDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); break; default: - throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType)); + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}."); } } From ac5c72492dbcc1765acb45e438f2782f65e4f1b8 Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Tue, 22 Oct 2019 14:31:11 +0200 Subject: [PATCH 239/338] Added Created HTTP response code for Role and User post methods --- .../Controllers/RolesController.cs | 13 ++++++++----- .../Controllers/UsersController.cs | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs index 38023511a..49dd6529a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs @@ -19,7 +19,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class RolesController> Get(string searchText, int page = 1, } [HttpPost] - public async Task Post([FromBody]TRoleDto role) + [ProducesResponseType(201)] + [ProducesResponseType(400)] + public async Task> Post([FromBody]TRoleDto role) { if (!EqualityComparer.Default.Equals(role.Id, default)) { return BadRequest(_errorResources.CannotSetId()); } + + var (identityResult, roleId) = await _identityService.CreateRoleAsync(role); + var createdRole = await _identityService.GetRoleAsync(roleId.ToString()); - await _identityService.CreateRoleAsync(role); - - return Ok(); + return CreatedAtAction(nameof(Get), new { id = createdRole.Id }, createdRole); } [HttpPut] diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index f57ca1f10..f0fe252ad 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -20,7 +20,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class UsersController> Get(string searchText, int page = 1, } [HttpPost] - public async Task Post([FromBody]TUserDto user) + [ProducesResponseType(201)] + [ProducesResponseType(400)] + public async Task> Post([FromBody]TUserDto user) { if (!EqualityComparer.Default.Equals(user.Id, default)) { return BadRequest(_errorResources.CannotSetId()); } - await _identityService.CreateUserAsync(user); + var (identityResult, userId) = await _identityService.CreateUserAsync(user); + var createdUser = await _identityService.GetUserAsync(userId.ToString()); - return Ok(); + return CreatedAtAction(nameof(Get), new { id = createdUser.Id }, createdUser); } [HttpPut] From 965d844c6b9651adc045f2edf5ca1d83eb4e662a Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 20 Nov 2019 16:57:27 +0100 Subject: [PATCH 240/338] returns 201 Created for all Post actions in ApiResourcesController --- .../Controllers/ApiResourcesController.cs | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs index b7855ef91..926135c7b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs @@ -15,7 +15,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class ApiResourcesController : ControllerBase { @@ -46,7 +46,9 @@ public async Task> Get(int id) return Ok(apiResourceApiDto); } - [HttpPost] + [HttpPost] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task Post([FromBody]ApiResourceApiDto apiResourceApi) { var apiResourceDto = apiResourceApi.ToApiResourceApiModel(); @@ -56,9 +58,10 @@ public async Task Post([FromBody]ApiResourceApiDto apiResourceApi return BadRequest(_errorResources.CannotSetId()); } - await _apiResourceService.AddApiResourceAsync(apiResourceDto); + var apiResourceId = await _apiResourceService.AddApiResourceAsync(apiResourceDto); + apiResourceApi.Id = apiResourceId; - return Ok(); + return CreatedAtAction(nameof(Get), new { id = apiResourceId }, apiResourceApi); } [HttpPut] @@ -101,7 +104,9 @@ public async Task> GetScope(int id, int scopeId) return Ok(apiScopeApiDto); } - [HttpPost("{id}/Scopes")] + [HttpPost("{id}/Scopes")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostScope(int id, [FromBody]ApiScopeApiDto apiScopeApi) { var apiScope = apiScopeApi.ToApiResourceApiModel(); @@ -113,9 +118,10 @@ public async Task PostScope(int id, [FromBody]ApiScopeApiDto apiS } await _apiResourceService.GetApiResourceAsync(apiScope.ApiResourceId); - await _apiResourceService.AddApiScopeAsync(apiScope); - - return Ok(); + var scopeId = await _apiResourceService.AddApiScopeAsync(apiScope); + apiScope.ApiScopeId = scopeId; + + return CreatedAtAction(nameof(GetScope), new { id, scopeId }, apiScope); } [HttpPut("{id}/Scopes")] @@ -163,7 +169,9 @@ public async Task> GetSecret(int secretId) return Ok(apiSecretApiDto); } - [HttpPost("{id}/Secrets")] + [HttpPost("{id}/Secrets")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostSecret(int id, [FromBody]ApiSecretApiDto clientSecretApi) { var secretsDto = clientSecretApi.ToApiResourceApiModel(); @@ -174,9 +182,10 @@ public async Task PostSecret(int id, [FromBody]ApiSecretApiDto cl return BadRequest(_errorResources.CannotSetId()); } - await _apiResourceService.AddApiSecretAsync(secretsDto); - - return Ok(); + var secretId = await _apiResourceService.AddApiSecretAsync(secretsDto); + clientSecretApi.Id = secretId; + + return CreatedAtAction(nameof(GetSecret), new { secretId }, clientSecretApi); } [HttpDelete("Secrets/{secretId}")] @@ -208,7 +217,9 @@ public async Task> GetProperty(int prope return Ok(apiResourcePropertyApiDto); } - [HttpPost("{id}/Properties")] + [HttpPost("{id}/Properties")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostProperty(int id, [FromBody]ApiResourcePropertyApiDto apiPropertyApi) { var apiResourcePropertiesDto = apiPropertyApi.ToApiResourceApiModel(); @@ -219,9 +230,10 @@ public async Task PostProperty(int id, [FromBody]ApiResourcePrope return BadRequest(_errorResources.CannotSetId()); } - await _apiResourceService.AddApiResourcePropertyAsync(apiResourcePropertiesDto); - - return Ok(); + var propertyId = await _apiResourceService.AddApiResourcePropertyAsync(apiResourcePropertiesDto); + apiPropertyApi.Id = propertyId; + + return CreatedAtAction(nameof(GetProperty), new { propertyId }, apiPropertyApi); } [HttpDelete("Properties/{propertyId}")] From 18f1918c035e2f438548e7d9f1ea07d43188d866 Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 20 Nov 2019 17:18:07 +0100 Subject: [PATCH 241/338] returns 201 Created for all Post actions in ClientsController --- .../Controllers/ClientsController.cs | 56 ++++++++++++------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs index 7c3ac3dc0..e13a32eba 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Runtime.InteropServices.ComTypes; +using System.Threading.Tasks; using IdentityServer4.AccessTokenValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -15,7 +16,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class ClientsController : ControllerBase { @@ -46,7 +47,9 @@ public async Task> Get(int id) return Ok(clientApiDto); } - [HttpPost] + [HttpPost] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task Post([FromBody]ClientApiDto client) { var clientDto = client.ToClientApiModel(); @@ -56,11 +59,12 @@ public async Task Post([FromBody]ClientApiDto client) return BadRequest(_errorResources.CannotSetId()); } - await _clientService.AddClientAsync(clientDto); + var id = await _clientService.AddClientAsync(clientDto); + client.Id = id; - return Ok(); - } - + return CreatedAtAction(nameof(Get), new { id }, client); + } + [HttpPut] public async Task Put([FromBody]ClientApiDto client) { @@ -83,15 +87,18 @@ public async Task Delete(int id) return Ok(); } - [HttpPost("Clone")] + [HttpPost("Clone")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostClientClone([FromBody]ClientCloneApiDto client) { var clientCloneDto = client.ToClientApiModel(); - await _clientService.GetClientAsync(clientCloneDto.Id); - await _clientService.CloneClientAsync(clientCloneDto); + var originalClient = await _clientService.GetClientAsync(clientCloneDto.Id); + var id = await _clientService.CloneClientAsync(clientCloneDto); + originalClient.Id = id; - return Ok(); + return CreatedAtAction(nameof(Get), new { id }, originalClient); } [HttpGet("{id}/Secrets")] @@ -112,7 +119,9 @@ public async Task> GetSecret(int secretId) return Ok(clientSecretDto); } - [HttpPost("{id}/Secrets")] + [HttpPost("{id}/Secrets")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostSecret(int id, [FromBody]ClientSecretApiDto clientSecretApi) { var secretsDto = clientSecretApi.ToClientApiModel(); @@ -123,9 +132,10 @@ public async Task PostSecret(int id, [FromBody]ClientSecretApiDto return BadRequest(_errorResources.CannotSetId()); } - await _clientService.AddClientSecretAsync(secretsDto); + var secretId = await _clientService.AddClientSecretAsync(secretsDto); + clientSecretApi.Id = secretId; - return Ok(); + return CreatedAtAction(nameof(GetSecret), new { secretId }, clientSecretApi); } [HttpDelete("Secrets/{secretId}")] @@ -157,7 +167,9 @@ public async Task> GetProperty(int propertyId return Ok(clientPropertyApiDto); } - [HttpPost("{id}/Properties")] + [HttpPost("{id}/Properties")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostProperty(int id, [FromBody]ClientPropertyApiDto clientPropertyApi) { var clientPropertiesDto = clientPropertyApi.ToClientApiModel(); @@ -168,9 +180,10 @@ public async Task PostProperty(int id, [FromBody]ClientPropertyAp return BadRequest(_errorResources.CannotSetId()); } - await _clientService.AddClientPropertyAsync(clientPropertiesDto); + var propertyId = await _clientService.AddClientPropertyAsync(clientPropertiesDto); + clientPropertyApi.Id = propertyId; - return Ok(); + return CreatedAtAction(nameof(GetProperty), new { propertyId }, clientPropertyApi); } [HttpDelete("Properties/{propertyId}")] @@ -202,7 +215,9 @@ public async Task> GetClaim(int claimId) return Ok(clientClaimApiDto); } - [HttpPost("{id}/Claims")] + [HttpPost("{id}/Claims")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostClaim(int id, [FromBody]ClientClaimApiDto clientClaimApiDto) { var clientClaimsDto = clientClaimApiDto.ToClientApiModel(); @@ -213,9 +228,10 @@ public async Task PostClaim(int id, [FromBody]ClientClaimApiDto c return BadRequest(_errorResources.CannotSetId()); } - await _clientService.AddClientClaimAsync(clientClaimsDto); + var claimId = await _clientService.AddClientClaimAsync(clientClaimsDto); + clientClaimApiDto.Id = claimId; - return Ok(); + return CreatedAtAction(nameof(GetClaim), new { claimId }, clientClaimApiDto); } [HttpDelete("Claims/{claimId}")] From b8dd083bb292f8238dd8b36336d43bbe7af561e0 Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 20 Nov 2019 17:25:16 +0100 Subject: [PATCH 242/338] returns 201 Created for all Post actions in IdentityResourcesController --- .../IdentityResourcesController.cs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs index 91a29886c..6b4c9c292 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs @@ -15,7 +15,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [Route("api/[controller]")] [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] - [Produces("application/json")] + [Produces("application/json", "application/problem+json")] [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] public class IdentityResourcesController : ControllerBase { @@ -46,7 +46,9 @@ public async Task> Get(int id) return Ok(identityResourceApiModel); } - [HttpPost] + [HttpPost] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task Post([FromBody]IdentityResourceApiDto identityResourceApi) { var identityResourceDto = identityResourceApi.ToIdentityResourceApiModel(); @@ -56,9 +58,10 @@ public async Task Post([FromBody]IdentityResourceApiDto identityR return BadRequest(_errorResources.CannotSetId()); } - await _identityResourceService.AddIdentityResourceAsync(identityResourceDto); + var id = await _identityResourceService.AddIdentityResourceAsync(identityResourceDto); + identityResourceApi.Id = id; - return Ok(); + return CreatedAtAction(nameof(Get), new { id }, identityResourceApi); } [HttpPut] @@ -101,7 +104,9 @@ public async Task> GetProperty(int return Ok(identityResourcePropertyApiDto); } - [HttpPost("{id}/Properties")] + [HttpPost("{id}/Properties")] + [ProducesResponseType(201)] + [ProducesResponseType(400)] public async Task PostProperty(int id, [FromBody]IdentityResourcePropertyApiDto identityResourcePropertyApi) { var identityResourcePropertiesDto = identityResourcePropertyApi.ToIdentityResourceApiModel(); @@ -112,9 +117,10 @@ public async Task PostProperty(int id, [FromBody]IdentityResource return BadRequest(_errorResources.CannotSetId()); } - await _identityResourceService.AddIdentityResourcePropertyAsync(identityResourcePropertiesDto); + var propertyId = await _identityResourceService.AddIdentityResourcePropertyAsync(identityResourcePropertiesDto); + identityResourcePropertyApi.Id = propertyId; - return Ok(); + return CreatedAtAction(nameof(GetProperty), new { propertyId }, identityResourcePropertyApi); } [HttpDelete("Properties/{propertyId}")] From 8d780dcf9eebd73265d1c5fc7e07813218599dfc Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Fri, 22 Nov 2019 17:36:30 +0300 Subject: [PATCH 243/338] Remove extra configuration interfaces and service provider --- .../Configuration/AdminConfiguration.cs | 6 ++-- .../IdentityDataConfiguration.cs | 3 +- .../IdentityServerDataConfiguration.cs | 3 +- .../Interfaces/IAdminConfiguration.cs | 18 ---------- .../Interfaces/IIdentityDataConfiguration.cs | 11 ------ .../IIdentityServerDataConfiguration.cs | 13 ------- .../Interfaces/IRootConfiguration.cs | 6 ++-- .../Configuration/RootConfiguration.cs | 17 +++------ .../Helpers/DbMigrationHelpers.cs | 5 +-- .../Helpers/StartupHelpers.cs | 29 +++------------ src/Skoruba.IdentityServer4.Admin/Startup.cs | 35 +++++++++---------- 11 files changed, 35 insertions(+), 111 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs delete mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs index 3b046107f..d0fbbcdfb 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/AdminConfiguration.cs @@ -1,8 +1,6 @@ -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; - -namespace Skoruba.IdentityServer4.Admin.Configuration +namespace Skoruba.IdentityServer4.Admin.Configuration { - public class AdminConfiguration : IAdminConfiguration + public class AdminConfiguration { public string IdentityAdminRedirectUri { get; set; } public string[] Scopes { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs index 561fb7bb6..4dafd44c7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityDataConfiguration.cs @@ -1,10 +1,9 @@ using Skoruba.IdentityServer4.Admin.Configuration.Identity; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using System.Collections.Generic; namespace Skoruba.IdentityServer4.Admin.Configuration { - public class IdentityDataConfiguration : IIdentityDataConfiguration + public class IdentityDataConfiguration { public List Roles { get; set; } public List Users { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs index fa20f64d4..4b002875e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/IdentityServerDataConfiguration.cs @@ -1,11 +1,10 @@ using IdentityServer4.Models; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using System.Collections.Generic; using Client = Skoruba.IdentityServer4.Admin.Configuration.IdentityServer.Client; namespace Skoruba.IdentityServer4.Admin.Configuration { - public class IdentityServerDataConfiguration : IIdentityServerDataConfiguration + public class IdentityServerDataConfiguration { public List Clients { get; set; } = new List(); public List IdentityResources { get; set; } = new List(); diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs deleted file mode 100644 index 3647a16ba..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IAdminConfiguration.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces -{ - public interface IAdminConfiguration - { - string IdentityAdminRedirectUri { get; } - string IdentityServerBaseUrl { get; } - string ClientId { get; } - string ClientSecret { get; } - string OidcResponseType { get; } - string[] Scopes { get; } - string AdministrationRole { get; } - bool RequireHttpsMetadata { get; } - string IdentityAdminCookieName { get; } - double IdentityAdminCookieExpiresUtcHours { get; } - string TokenValidationClaimName { get; } - string TokenValidationClaimRole { get; } - } -} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs deleted file mode 100644 index ee98b9dc6..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityDataConfiguration.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Skoruba.IdentityServer4.Admin.Configuration.Identity; -using System.Collections.Generic; - -namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces -{ - public interface IIdentityDataConfiguration - { - List Roles { get; } - List Users { get; } - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs deleted file mode 100644 index 6886105f4..000000000 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IIdentityServerDataConfiguration.cs +++ /dev/null @@ -1,13 +0,0 @@ -using IdentityServer4.Models; -using System.Collections.Generic; -using Client = Skoruba.IdentityServer4.Admin.Configuration.IdentityServer.Client; - -namespace Skoruba.IdentityServer4.Admin.Configuration.Interfaces -{ - public interface IIdentityServerDataConfiguration - { - List Clients { get; } - List IdentityResources { get; } - List ApiResources { get; } - } -} diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs index 8edca3601..708348978 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Interfaces/IRootConfiguration.cs @@ -2,8 +2,8 @@ { public interface IRootConfiguration { - IAdminConfiguration AdminConfiguration { get; } - IIdentityDataConfiguration IdentityDataConfiguration { get; } - IIdentityServerDataConfiguration IdentityServerDataConfiguration { get; } + AdminConfiguration AdminConfiguration { get; } + IdentityDataConfiguration IdentityDataConfiguration { get; } + IdentityServerDataConfiguration IdentityServerDataConfiguration { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs index 7a56dbbcb..069472cb7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/RootConfiguration.cs @@ -1,20 +1,11 @@ -using Microsoft.Extensions.Options; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; namespace Skoruba.IdentityServer4.Admin.Configuration { public class RootConfiguration : IRootConfiguration { - public IAdminConfiguration AdminConfiguration { get; set; } - public IIdentityDataConfiguration IdentityDataConfiguration { get; set; } - public IIdentityServerDataConfiguration IdentityServerDataConfiguration { get; set; } - - public RootConfiguration(IOptions adminConfiguration, IOptions clientConfiguration, - IOptions userConfiguration) - { - AdminConfiguration = adminConfiguration.Value; - IdentityDataConfiguration = userConfiguration.Value; - IdentityServerDataConfiguration = clientConfiguration.Value; - } + public AdminConfiguration AdminConfiguration { get; set; } = new AdminConfiguration(); + public IdentityDataConfiguration IdentityDataConfiguration { get; set; } = new IdentityDataConfiguration(); + public IdentityServerDataConfiguration IdentityServerDataConfiguration { get; set; } = new IdentityServerDataConfiguration(); } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs index 1f486831f..20a3b2cfa 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/DbMigrationHelpers.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Hosting; using Skoruba.AuditLogging.EntityFramework.DbContexts; using Skoruba.AuditLogging.EntityFramework.Entities; +using Skoruba.IdentityServer4.Admin.Configuration; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; @@ -95,7 +96,7 @@ public static async Task EnsureSeedData( /// Generate default admin user / role /// private static async Task EnsureSeedIdentityData(UserManager userManager, - RoleManager roleManager, IIdentityDataConfiguration identityDataConfiguration) + RoleManager roleManager, IdentityDataConfiguration identityDataConfiguration) where TUser : IdentityUser, new() where TRole : IdentityRole, new() { @@ -161,7 +162,7 @@ private static async Task EnsureSeedIdentityData(UserManager /// Generate default clients, identity and api resources /// - private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IIdentityServerDataConfiguration identityServerDataConfiguration) + private static async Task EnsureSeedIdentityServerData(TIdentityServerDbContext context, IdentityServerDataConfiguration identityServerDataConfiguration) where TIdentityServerDbContext : DbContext, IAdminConfigurationDbContext { if (!context.IdentityResources.Any()) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 931589086..87006facc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -134,7 +134,7 @@ public static void RegisterDbContextsStaging(this IServiceCollection s /// /// /// - public static void RegisterDbContexts(this IServiceCollection services, IConfigurationRoot configuration) + public static void RegisterDbContexts(this IServiceCollection services, IConfiguration configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext @@ -316,7 +316,7 @@ public static void AddDbContexts(this IServiceCollection services, IWe /// /// /// - public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfigurationRoot configuration) + public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfiguration configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext @@ -442,7 +442,7 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) /// /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IAdminConfiguration adminConfiguration) + public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, AdminConfiguration adminConfiguration) where TContext : DbContext where TUserIdentity : class where TUserIdentityRole : class { services.AddIdentity(options => @@ -523,26 +523,7 @@ public static void AddAuthenticationServices - /// Configuration root configuration - /// - /// - /// - /// - public static IServiceCollection ConfigureRootConfiguration(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - - services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.IdentityDataConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.IdentityServerDataConfigurationKey)); - - services.TryAddSingleton(); - - return services; - } - - private static Task OnMessageReceived(MessageReceivedContext context, IAdminConfiguration adminConfiguration) + private static Task OnMessageReceived(MessageReceivedContext context, AdminConfiguration adminConfiguration) { context.Properties.IsPersistent = true; context.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddHours(adminConfiguration.IdentityAdminCookieExpiresUtcHours)); @@ -550,7 +531,7 @@ private static Task OnMessageReceived(MessageReceivedContext context, IAdminConf return Task.FromResult(0); } - private static Task OnRedirectToIdentityProvider(RedirectContext n, IAdminConfiguration adminConfiguration) + private static Task OnRedirectToIdentityProvider(RedirectContext n, AdminConfiguration adminConfiguration) { n.ProtocolMessage.RedirectUri = adminConfiguration.IdentityAdminRedirectUri; diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 863033111..88076605a 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -11,40 +11,28 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; using Skoruba.IdentityServer4.Admin.Helpers; +using Skoruba.IdentityServer4.Admin.Configuration; +using Skoruba.IdentityServer4.Admin.Configuration.Constants; namespace Skoruba.IdentityServer4.Admin { public class Startup { - public Startup(IWebHostEnvironment env) + public Startup(IWebHostEnvironment env, IConfiguration configuration) { JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - - var builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); - - if (env.IsDevelopment()) - { - builder.AddUserSecrets(); - } - - Configuration = builder.Build(); - HostingEnvironment = env; + Configuration = configuration; } - public IConfigurationRoot Configuration { get; } + public IConfiguration Configuration { get; } public IWebHostEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { - // Get Configuration - services.ConfigureRootConfiguration(Configuration); - var rootConfiguration = services.BuildServiceProvider().GetService(); + var rootConfiguration = CreateRootConfiguration(); + services.AddSingleton(rootConfiguration); // Add DbContexts for Asp.Net Core Identity, Logging and IdentityServer - Configuration store and Operational store services.AddDbContexts(HostingEnvironment, Configuration); @@ -112,5 +100,14 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseAuthorization(); app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } + + private IRootConfiguration CreateRootConfiguration() + { + var rootConfiguration = new RootConfiguration(); + Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration); + Configuration.GetSection(ConfigurationConsts.IdentityDataConfigurationKey).Bind(rootConfiguration.IdentityDataConfiguration); + Configuration.GetSection(ConfigurationConsts.IdentityServerDataConfigurationKey).Bind(rootConfiguration.IdentityServerDataConfiguration); + return rootConfiguration; + } } } \ No newline at end of file From 264b2c3a91e4b037753590aea773766cd1a12bd5 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Fri, 22 Nov 2019 17:52:11 +0300 Subject: [PATCH 244/338] Separate logging configuration from service configuration --- .../Helpers/StartupHelpers.cs | 13 ------------- src/Skoruba.IdentityServer4.Admin/Program.cs | 6 ++++++ src/Skoruba.IdentityServer4.Admin/Startup.cs | 2 -- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 87006facc..3a2a935f1 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -272,19 +272,6 @@ public static void ConfigureLocalization(this IApplicationBuilder app) app.UseRequestLocalization(options.Value); } - /// - /// Add logging configuration - /// - /// - /// - /// - public static void AddLogging(this IApplicationBuilder app, ILoggerFactory loggerFactory, IConfigurationRoot configuration) - { - Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(configuration) - .CreateLogger(); - } - /// /// Register shared DbContext /// diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index 162a8b6e2..127bb2282 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Hosting; using Serilog; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; @@ -33,6 +34,11 @@ public static async Task Main(string[] args) public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .ConfigureLogging((hostingContext, logging) => { + logging.ClearProviders(); + var logger = new LoggerConfiguration().ReadFrom.Configuration(hostingContext.Configuration).CreateLogger(); + logging.AddSerilog(logger); + }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseContentRoot(Directory.GetCurrentDirectory()); diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 88076605a..e014a5d25 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -74,8 +74,6 @@ public void ConfigureServices(IServiceCollection services) public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { - app.AddLogging(loggerFactory, Configuration); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); From 58fe8c77b2d1b244c8e15dddab04b8ac7480e55c Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Fri, 22 Nov 2019 17:53:32 +0300 Subject: [PATCH 245/338] Remove some default code --- src/Skoruba.IdentityServer4.Admin/Program.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index 127bb2282..4cf0bcc1f 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -41,9 +41,7 @@ public static IHostBuilder CreateHostBuilder(string[] args) => }) .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseContentRoot(Directory.GetCurrentDirectory()); webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); - webBuilder.UseIISIntegration(); webBuilder.UseStartup(); webBuilder.UseSerilog(); }); From 2ab6bc0cf6f9346c997900e3761b96a4f7ceaf86 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 23 Nov 2019 17:15:22 +0100 Subject: [PATCH 246/338] Add missing DatabaseProviderConfiguration in Api --- src/Skoruba.IdentityServer4.Admin.Api/appsettings.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 644f04951..183be5d5a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -16,6 +16,9 @@ "AdministrationRole": "SkorubaIdentityAdminAdministrator", "RequireHttpsMetadata": false }, + "DatabaseProviderConfiguration": { + "ProviderType": "SqlServer" + }, "AuditLoggingConfiguration": { "Source": "IdentityServer.Admin.Api", "SubjectIdentifierClaim": "sub", From 76f82dd1be2c2de2b7d75f7929efa2f40d2480d8 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 25 Nov 2019 15:56:33 +0100 Subject: [PATCH 247/338] Removed health checks UI endpoint --- .../Helpers/StartupHelpers.cs | 2 -- .../Startup.cs | 4 ---- .../appsettings.json | 8 -------- .../healthchecksdb | Bin 45056 -> 0 bytes .../Helpers/StartupHelpers.cs | 2 -- src/Skoruba.IdentityServer4.Admin/Startup.cs | 6 +----- .../appsettings.json | 8 -------- .../healthchecksdb | Bin 45056 -> 0 bytes .../Helpers/StartupHelpers.cs | 2 +- .../Startup.cs | 8 ++------ .../appsettings.json | 8 -------- .../healthchecksdb | Bin 45056 -> 0 bytes 12 files changed, 4 insertions(+), 44 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb delete mode 100644 src/Skoruba.IdentityServer4.Admin/healthchecksdb delete mode 100644 src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 331c73701..695990277 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -239,8 +239,6 @@ public static void AddIdSHealthChecks("AuditLogDbContext") .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); - - services.AddHealthChecksUI(); } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 8cfd801f6..65b9bbe69 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -133,10 +133,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi { ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); - endpoints.MapHealthChecksUI(setup => - { - setup.UIPath = "/health-ui"; - }); }); } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json index 1a9b23a6f..d710e688e 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin.Api/appsettings.json @@ -49,13 +49,5 @@ } } ] - }, - "HealthChecks-UI": { - "HealthChecks": [ - { - "Name": "Identity Server Admin API Health Checks", - "Uri": "http://localhost:5001/health" - } - ] } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb b/src/Skoruba.IdentityServer4.Admin.Api/healthchecksdb deleted file mode 100644 index 2be0fbfc89a3196bd722a6c6c04793b6a84c9abf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 zcmeI*&2QUe90%~nNmDn;62oDNI24|SjV*L*?YyUAf{?mdv@9uUiaJeGlqGI!kvd!K zY@Mb_w42zOe}M}pBrc5qfx{382@n!OLPA{Nzy*YM;BnrQ=ja8rM!)GY;6wRu0D#wQ+p$qg&X@H?Dp6PR#J0WRkm|G>TU% z%2=nd3+=6zdiX0myjSx={FBAZ#u=i+QW^{!qR8akc8 z^3v5@>S8>1iC&N|(fE2ko64}7T$D5UGp%)GiaUyz=H-oM@$K2mie9Rz*UT^-vUJTT z8g>2g%C&Q6JDFOwZZ8;y)YnSZ!dBYecCJilXQ8uCjoO#IbS0aUQ^`z2Vsu2)oV+6E zXfx=^8TTTjs@gcNauN8ZvYoPF9P){Eyt@i%QVY0V7&3k5Nxx0x*n5-1l zO1-A&?PtC}0NS%z=pA5dcXLhLv^~VV2Z4bNkuK^+rfR60s=|&&&Ev#Cl9axFEv}Vw zbxl*Xt;dfFY!BH_+j!619CxqOXnJ?Y>P}7fH@~~!U;w@OCK5~v;jCt+P*!Tyoe^y} zd77&n$+KQlM`RwuzO3q{>J6oKYfY)$P)ogsXvVoZHSL+7=Porc_3IVZB`fI4^}3>! zl!2GFKGuPSr!{u;Kf`kR_HJ5vkI%>5^)<>&RJBcYtF?>j{ja9_O7!+GJlMt>%sX*| z{R5VJ8yxS6M7aIt!Mjk9S1zhs&4ZKPd?&p%bf%@>VQ88zN2g5lDAut>nTV>XPbR{vp-K< z?7;~?5cY=w0uX=z1Rwwb2tWV=5P$##AOL|QD)1s_jd}c{6q6(=AVvfJV5p#Ks-YGu zfdz3vbg*`D!cT<#VSoSxAOHafKmY;|fB*y_009U<;7AL+V2#;_e+bb0{{I0H9vtZg zqVf=c00bZa0SG_<0uX=z1Rwx`|DeEm&PL?RWZN*VEiEoqs- zi0~;JVSoSxAOHafKmY;|fB*y_009U<;1C3o78|*ous`9s`2#)w#zz97KsXi-g_7(7 zfXj)Qr!B}Yvd1&hdy~z^009U<00Izz z00bZa0SG_<0!LZEn4j5u`RrgfG*hLes-`I=^JhHSWW7?RR~5QbEGz7}RIKX?HMZHK zSldzzHotVr$&-1GJXVrL6qg!*3z8HJ1jV4w!IMQZVZ2^ejdXQu`6@dN-B5OoZc@?D z`lF$k*Upo<{-ix=qO4Es_p@K|B`3`^BTI?|0?}EXC!S8Ko4s8H){2^;4=ptk3W>p2tvr!>b7)38 zOK<7XXe1n3u<#^irtLd>e^}YUm_HVfPI0X*GmyTg;HW5uL$T)h{||}q@F)i~>J9-2 zKmY;|fB*y_009U<00I#BKM9Ctx1U{6F!<5V=&K9N-~V$8pAq4a@VoFEy9?mY!jHoD z!neX#!sl!@1_(d^0uX=z1Rwwb2tWV=5P$##o+*JTtDSS2BZoP%o1+("AuditLogDbContext") .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); - - services.AddHealthChecksUI(); } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index dc644b5f6..9ee5f4ecc 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -120,11 +120,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF endpoint.MapHealthChecks("/health", new HealthCheckOptions { ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - endpoint.MapHealthChecksUI(setup => - { - setup.UIPath = "/health-ui"; - }); + }); }); } } diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index e8c3c2428..762c10404 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -208,13 +208,5 @@ "AllowAccessTokensViaBrowser": true } ] - }, - "HealthChecks-UI": { - "HealthChecks": [ - { - "Name": "Identity Admin Health Checks", - "Uri": "http://localhost:9000/health" - } - ] } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/healthchecksdb b/src/Skoruba.IdentityServer4.Admin/healthchecksdb deleted file mode 100644 index bd763fffd097c87f1ff961802abb1f6ebea5b31d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 zcmeI*&2QUe90%~nNm}QH)Z;Kk912gv1`Ay?+iBXQ+9X2icG0q=q$%nSQ^VBc= zNxTzpk*RNlPyOHfKYC@+chPft^7qLpmWTlY5P-n37C2D7eBkaXcX(RU%j#Zgvv650 zR;-=mj#~Oq*;7k3ORMUaHPfmZnraT5n<|ei<4fk0L|&n(%(AjcgU`5#AkAiIaO8r5 z^xVJHcNQ_RU1cFKfHy_a--UJ|BRattgdnoR;}WV ziaOG1SGeFuE9VtBe`f^+lj1HmYno;bIuD;3#K|On*G~4@v!{lIZk`GKzbN7<7r?6s+P8;scdi5*iZCjNtqir6M8vU z({)YXetNIKwvfa01Rt20;qI5}P48@2ovF#*=67Zs4WPT+Sb}jOoYn0d>WWd_9nyB2 zr?JSPJR62Kr0@v#Wz8&AZ>z@sx@z3kO5M9?#<}L249w1Q*Xo$&tqMCNE12r7nyQ!7 zzPA%StbH@j>1^+Ro|Oz8+;Q@OP>8!1s@IvU>RZ}&a}zat-?@5f4ED}ET4(i_9ou35 zgXO^{#|IV{xx>cJyHHS8u4>zjos-%4B;6mF=;(DAn5V>auBl znywkua;;>2pc-b^=X7)HWMPtWOa`tma-{ypS+nblHLF^GUl_QYf;2GMKDM`y=ZT*^ zIpHy34-62100bZa0SG_<0uX=z1Rwwb2%J!X*EwfAAd6C5lB9?ji^%iQf~IShR;)zA zVp#ODc5%Wlggr1o00Izz00bZa0SG_<0uX=z1R!vt1zvN;J%j%V&^Z79hzO5PbOW*S z5P$##AOHafKmY;|fB*y_0D+fV;1V}M6ou?q*3G307b?|Kv9eP&t);jqiWhe3SE;7T zs%~l4K24N&HJvuD6QcENS55o)-z9uTgx`e6!q;p90|X!d0SG_<0uX=z1Rwwb2tWV= zFI?aamov$A-RYx!dyM8SQG9-w7HGK}}w5N3wkyklq$kTg|hQ|5-heUYz!kdN_ zfB*y_009U<00Izz00bZa0SLVO0yWM}+=(PRm2ZDhe@>F-q&SttB}rZq7s89t1&Lj} z-#=$Q5{@rQvKU=>p7Z~l@C9KH3=n_-1Rwwb2tWV=5P$##AOHaf99w~l_5}b*_oy%V zKlOhD_8*04G#-_un0@}==YK+k?}Sf;yFyAhJN4Jpk5ivdeLS_rk}*I40uX=z1Rwwb z2tWV=5P-mm6)=2mGV4BgbI#K~WVC;iP&G1DTB_>0TC#t}lTFqtWqL!UyT!7~UQ5NA zsZwi)J&VS+YO(avj;5=$$nxJ-EBn+?w^)`k)vT~6F4+$`EJb8?>N*ng^5g1A|K!w(4Q8x31Rwwb2tWV=5P$##AOHafKmY>&Lcsq0KcDa=5&jnb z5T3BR0RAfcEc_(=Abcx)#gZ{V00Izz00bZa0SG_<0uX=z1R!v%1YAxJ=d(v%d*rc4 zZhOSrqe*)-VUJw)$Z3xpPN&CXAOGY0|FP;wtPBJo009U<00Izz00bZa0SG|gKNt81 DJ}-o$ diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 0adc93b28..1690f9a3b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -461,7 +461,7 @@ public static void AddIdSHealthChecks("IdentityDbContext"); - services.AddHealthChecksUI(); + //services.AddHealthChecksUI(); } } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 056451dd5..507b9bc44 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -62,7 +62,7 @@ public void ConfigureServices(IServiceCollection services) services.AddIdSHealthChecks(Configuration); } - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, Microsoft.Extensions.Hosting.IHostApplicationLifetime applicationLifetime) { app.AddLogging(loggerFactory, Configuration); @@ -87,11 +87,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF { ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); - endpoint.MapHealthChecksUI(setup => - { - setup.UIPath = "/health-ui"; - }); - }); + }); } } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json index 6594512c6..56e2c166c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json +++ b/src/Skoruba.IdentityServer4.STS.Identity/appsettings.json @@ -78,13 +78,5 @@ "CultureConfiguration": { "Cultures": [], "DefaultCulture": null - }, - "HealthChecks-UI": { - "HealthChecks": [ - { - "Name": "Identity Server Health Checks", - "Uri": "http://localhost:5000/health" - } - ] } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb b/src/Skoruba.IdentityServer4.STS.Identity/healthchecksdb deleted file mode 100644 index 90c18ed79d0a1455c1d01f73b2d6b3414e647320..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 zcmeI*PjA~~90%~naT_-snc*-+90pIV0SntwJ8hPx0z`4$ELxV7G)3KEin7FQEiz}b zovqVO?WXOeaN;E(?KNI-P5_ywEBIHv_2_Zato?*}aFvmX3^hek`=leYFBTrJxG%o&0=4an0 zXTKG{j(;D2`bPH5N3nC!-=b&PL<|ss00drZfkS;>NIc4ON9PQ)sUH+}YS;97%h^}= z^~RUlf!^piM%%n**iPFrbUSozp*gY68MUIVRW({Dt!q0}ddWpdv|OUn#05$8VrYRv zQ%WA*iV2AaDt8p06sKl7$BfdeG5@b(oZS5Q2)%lf;(KyoPDteQ+_St>zunR&I!&Az z^CGFPeOA<_gU9D78ze@|`nRg(wF)hjtF*LTEK;>x+NxI8*mNpwUJp&3L1IaCvr@RR zR=G*9Yd7iIcC}n6u{F7&m8zG$Wt8f7bct5AonG_($?Lk^u#CHInug5Xa_UaUesSgc zwabG_-dgu(gdqi@WD$C0{c&zgiL*A?rp9ec65S|Qv_ihrl^CDVw4!Zj6|JOdTT~jh z>L!Vs@b2cat`#-5;Z-!&4F$CtpHDuyAP5On<(`$triqtqVexyj=BB5}Fk@daK?V&S zD?LW~a#|8hPNDUVRrhDtNaJBpFP|u0y#I5W93Di4#QF2wW3`(m8+D`Av2?rtE(8;x zKbfW8F?xGgYiif}i2XZ(k&YC3NuwM3aKjpYiUz|U&Nv=`zur`WX(?Pb-4gnS)xI+(c9*BO$gw=zmNBOC z1om~qZnW>~*268`x^Fc6yJ*I_ITKA>y2Rb=V%qmw?2xQx>-Rdk+0aKuX9KJwGcTHK z?|+%qOddYqg+wyRJx+GpRNLmRvFB}~c5rMa(4rKadA!aVtvj{D{sYUy9ZpDOv)oZ{ z=UuC58#j!--p4F7a-{o@Gq3CG9jDzLuZ1qBri4y*kL}&#c@k$&PW+Lu2L=d000Izz z00bZa0SG_<0uX=z1Wu^HI~<=&q-78009U<00Izz00bZa0SG_<0uXrJ1m5L&mGj;9V{oqw z@BS#!c!Xbw4W`;}aeOisyhlUt{QpxTK7HMS!}>q~0uX=z1Rwwb2tWV=5P$##PMg31 zH%B;CWhe3@?$7kED9RNjM-_QBy|TKzoXRQkaxSNg%*w6GnN&KL&SrDjS33XCZu*Y_ z0uX=z1Rwwb2tWV=5P$##AOL|=Ea0C1kDmRDh~J4{iI2pB_#PX<009U<00Izz00bZa z0SG_<0uVSg0?DXA7CCYy*1tY}{Wkk)yrUmD5m{dCK2q!=`rOr(v@|P_g^ZzHUOR>HXfB*y_009U<00Izz00bZaf#V7M0}X~DH~;_u From 467a374c7be30d35f8325c6a8de37c1b3b7850d0 Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Mon, 25 Nov 2019 18:26:19 +0100 Subject: [PATCH 248/338] DB healthchecks now target the correct type of db provider according to the DatabaseProviderConfiguration.ProviderType setting --- .../Helpers/StartupHelpers.cs | 58 ++++++++++++++----- .../Skoruba.IdentityServer4.Admin.Api.csproj | 2 + .../Helpers/StartupHelpers.cs | 57 +++++++++++++----- .../Skoruba.IdentityServer4.Admin.csproj | 2 + .../Helpers/StartupHelpers.cs | 43 +++++++++++--- ...koruba.IdentityServer4.STS.Identity.csproj | 2 + 6 files changed, 124 insertions(+), 40 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index a049eb4cf..307d0c68c 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -2,8 +2,6 @@ using System.Reflection; using IdentityModel; using IdentityServer4.AccessTokenValidation; -using IdentityServer4.EntityFramework.Interfaces; -using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -195,8 +193,8 @@ public static void AddAuthorizationPolicies(this IServiceCollection services) } public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration, AdminApiConfiguration adminApiConfiguration) - where TConfigurationDbContext : DbContext, IConfigurationDbContext - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TIdentityDbContext : DbContext where TLogDbContext : DbContext, IAdminLogDbContext where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext @@ -208,24 +206,52 @@ public static void AddIdSHealthChecks("ConfigurationDbContext") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") .AddDbContextCheck("PersistedGrantsDbContext") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") .AddDbContextCheck("IdentityDbContext") - .AddSqlServer(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") .AddDbContextCheck("LogDbContext") - .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog") .AddDbContextCheck("AuditLogDbContext") .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder.AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddNpgSql(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb") + .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); + break; + } } } -} \ No newline at end of file +} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj index dbfc12936..2ab557f4e 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj +++ b/src/Skoruba.IdentityServer4.Admin.Api/Skoruba.IdentityServer4.Admin.Api.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 75592e5bb..b079aafc4 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -49,7 +49,6 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; -using IdentityServer4.EntityFramework.Interfaces; namespace Skoruba.IdentityServer4.Admin.Helpers { @@ -559,8 +558,8 @@ private static Task OnRedirectToIdentityProvider(RedirectContext n, IAdminConfig } public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration, IAdminConfiguration adminConfiguration) - where TConfigurationDbContext : DbContext, IConfigurationDbContext - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TIdentityDbContext : DbContext where TLogDbContext : DbContext, IAdminLogDbContext where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext @@ -572,24 +571,52 @@ public static void AddIdSHealthChecks("ConfigurationDbContext") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") .AddDbContextCheck("PersistedGrantsDbContext") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") .AddDbContextCheck("IdentityDbContext") - .AddSqlServer(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") .AddDbContextCheck("LogDbContext") - .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog") .AddDbContextCheck("AuditLogDbContext") - + .AddIdentityServer(new Uri(identityServerUri), "Identity Server"); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder.AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users") + .AddNpgSql(logDbConnectionString, name: "LogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Log") + .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb") + .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); + break; + } } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj index 47702dfbc..e51f70ff5 100644 --- a/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj +++ b/src/Skoruba.IdentityServer4.Admin/Skoruba.IdentityServer4.Admin.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 68c6898cc..2a1940545 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -411,24 +411,49 @@ public static void AddAuthorizationPolicies(this IServiceCollection services, } public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration) - where TConfigurationDbContext : DbContext, IConfigurationDbContext - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TIdentityDbContext : DbContext { var configurationDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); var persistedGrantsDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); var identityDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); - services.AddHealthChecks() - .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + var healthChecksBuilder = services.AddHealthChecks() .AddDbContextCheck("ConfigurationDbContext") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") .AddDbContextCheck("PersistedGrantsDbContext") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") .AddDbContextCheck("IdentityDbContext"); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users"); + + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Clients") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: "SELECT TOP 1 * FROM dbo.Users"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb"); + break; + } + //services.AddHealthChecksUI(); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj index 90b856513..0b840e30f 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj +++ b/src/Skoruba.IdentityServer4.STS.Identity/Skoruba.IdentityServer4.STS.Identity.csproj @@ -9,6 +9,8 @@ + + From 845e1aa6598815d80f8df7dd0ffa8096845f8076 Mon Sep 17 00:00:00 2001 From: Dusan K Date: Mon, 25 Nov 2019 21:30:02 +0100 Subject: [PATCH 249/338] Initial IStringLocalizer based localization of ASP.NET Core Identity --- .../Helpers/Identity/IdentityErrorMessages.cs | 231 +++++++++++++++++- .../Identity/IdentityErrorMessages.en.resx | 228 +++++++++++++++++ 2 files changed, 458 insertions(+), 1 deletion(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.en.resx diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs index dcb7562f4..f8ba7f829 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Localization; namespace Skoruba.IdentityServer4.Admin.Helpers.Identity { @@ -9,7 +10,235 @@ namespace Skoruba.IdentityServer4.Admin.Helpers.Identity /// Or install package with specific language - https://www.nuget.org/packages?q=Microsoft.AspNet.Identity.Core /// public class IdentityErrorMessages : IdentityErrorDescriber - { + { + private readonly IStringLocalizer _stringLocalizer; + public IdentityErrorMessages(IStringLocalizer stringLocalizer) + { + _stringLocalizer = stringLocalizer; + } + + /// + /// Returns an indicating a concurrency failure. + /// + /// An indicating a concurrency failure. + public override IdentityError ConcurrencyFailure() + { + return CreateNamedError(nameof(ConcurrencyFailure)); + } + + /// + /// Returns the default . + /// + /// The default . + public override IdentityError DefaultError() + { + return CreateNamedError(nameof(DefaultError)); + } + + /// + /// Returns an indicating the specified is already associated with an account. + /// + /// The email that is already associated with an account. + /// An indicating the specified is already associated with an account. + public override IdentityError DuplicateEmail(string email) + { + return CreateNamedError(nameof(DuplicateEmail)); + } + + /// + /// Returns an indicating the specified name already exists. + /// + /// The duplicate role. + /// An indicating the specific role name already exists. + public override IdentityError DuplicateRoleName(string role) + { + return CreateNamedError(nameof(DuplicateRoleName)); + } + + /// + /// Returns an indicating the specified already exists. + /// + /// The user name that already exists. + /// An indicating the specified already exists. + public override IdentityError DuplicateUserName(string userName) + { + return CreateNamedError(nameof(DuplicateUserName)); + } + + /// + /// Returns an indicating the specified is invalid. + /// + /// The email that is invalid. + /// An indicating the specified is invalid. + public override IdentityError InvalidEmail(string email) + { + return CreateNamedError(nameof(InvalidEmail)); + } + + /// + /// Returns an indicating the specified name is invalid. + /// + /// The invalid role. + /// An indicating the specific role name is invalid. + public override IdentityError InvalidRoleName(string role) + { + return CreateNamedError(nameof(InvalidRoleName)); + } + + /// + /// Returns an indicating an invalid token. + /// + /// An indicating an invalid token. + public override IdentityError InvalidToken() + { + return CreateNamedError(nameof(InvalidToken)); + } + + /// + /// Returns an indicating the specified user is invalid. + /// + /// The user name that is invalid. + /// An indicating the specified user is invalid. + public override IdentityError InvalidUserName(string userName) + { + return CreateNamedError(nameof(InvalidUserName)); + } + + /// + /// Returns an indicating an external login is already associated with an account. + /// + /// An indicating an external login is already associated with an account. + public override IdentityError LoginAlreadyAssociated() + { + return CreateNamedError(nameof(LoginAlreadyAssociated)); + } + + /// + /// Returns an indicating a password mismatch. + /// + /// An indicating a password mismatch. + public override IdentityError PasswordMismatch() + { + return CreateNamedError(nameof(PasswordMismatch)); + } + + /// + /// Returns an indicating a password entered does not contain a numeric character, which is required by the password policy. + /// + /// An indicating a password entered does not contain a numeric character. + public override IdentityError PasswordRequiresDigit() + { + return CreateNamedError(nameof(PasswordRequiresDigit)); + } + + /// + /// Returns an indicating a password entered does not contain a lower case letter, which is required by the password policy. + /// + /// An indicating a password entered does not contain a lower case letter. + public override IdentityError PasswordRequiresLower() + { + return CreateNamedError(nameof(PasswordRequiresLower)); + } + + /// + /// Returns an indicating a password entered does not contain a non-alphanumeric character, which is required by the password policy. + /// + /// An indicating a password entered does not contain a non-alphanumeric character. + public override IdentityError PasswordRequiresNonAlphanumeric() + { + return CreateNamedError(nameof(PasswordRequiresNonAlphanumeric)); + } + + /// + /// Returns an indicating a password does not meet the minimum number of unique chars. + /// + /// The number of different chars that must be used. + /// An indicating a password does not meet the minimum number of unique chars. + public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) + { + return CreateNamedError(nameof(PasswordRequiresUniqueChars)); + } + + /// + /// Returns an indicating a password entered does not contain an upper case letter, which is required by the password policy. + /// + /// An indicating a password entered does not contain an upper case letter. + public override IdentityError PasswordRequiresUpper() + { + return CreateNamedError(nameof(PasswordRequiresUpper)); + } + + /// + /// Returns an indicating a password of the specified does not meet the minimum length requirements. + /// + /// The length that is not long enough. + /// An indicating a password of the specified does not meet the minimum length requirements. + public override IdentityError PasswordTooShort(int length) + { + return CreateNamedError(nameof(PasswordTooShort)); + } + + /// + /// Returns an indicating a recovery code was not redeemed. + /// + /// An indicating a recovery code was not redeemed. + public override IdentityError RecoveryCodeRedemptionFailed() + { + return CreateNamedError(nameof(RecoveryCodeRedemptionFailed)); + } + + /// + /// Returns an indicating a user already has a password. + /// + /// An indicating a user already has a password. + public override IdentityError UserAlreadyHasPassword() + { + return CreateNamedError(nameof(UserAlreadyHasPassword)); + } + + /// + /// Returns an indicating a user is already in the specified . + /// + /// The duplicate role. + /// An indicating a user is already in the specified . + public override IdentityError UserAlreadyInRole(string role) + { + return CreateNamedError(nameof(UserAlreadyInRole)); + } + + /// + /// Returns an indicating user lockout is not enabled. + /// + /// An indicating user lockout is not enabled. + public override IdentityError UserLockoutNotEnabled() + { + return CreateNamedError(nameof(UserLockoutNotEnabled)); + } + + /// + /// Returns an indicating a user is not in the specified . + /// + /// The duplicate role. + /// An indicating a user is not in the specified . + public override IdentityError UserNotInRole(string role) + { + return CreateNamedError(nameof(UserNotInRole)); + } + + /// + /// Generates with named as + /// And error description which uses as lookup key for + /// + /// + /// An that is used in another method return with specific indication for what this error was created + private IdentityError CreateNamedError(string name) + { + return new IdentityError + { + Code = name, + Description = _stringLocalizer.GetString(name) + }; + } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.en.resx new file mode 100644 index 000000000..767b425ff --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.en.resx @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Optimistic concurrency failure, object has been modified. + Error when optimistic concurrency fails + + + An unknown failure has occurred. + Default identity result error message + + + Email '{0}' is already taken. + Error for duplicate emails + + + Role name '{0}' is already taken. + Error for duplicate roles + + + User name '{0}' is already taken. + Error for duplicate user names + + + Email '{0}' is invalid. + Invalid email + + + The provided PasswordHasherCompatibilityMode is invalid. + Error when the password hasher doesn't understand the format it's being asked to produce. + + + The iteration count must be a positive integer. + Error when the iteration count is < 1. + + + Role name '{0}' is invalid. + Error for invalid role names + + + Invalid token. + Error when a token is not recognized + + + User name '{0}' is invalid, can only contain letters or digits. + User names can only contain letters or digits + + + A user with this login already exists. + Error when a login already linked + + + Incorrect password. + Error when a password doesn't match + + + Passwords must have at least one digit ('0'-'9'). + Error when passwords do not have a digit + + + Passwords must have at least one lowercase ('a'-'z'). + Error when passwords do not have a lowercase letter + + + Passwords must have at least one non alphanumeric character. + Error when password does not have enough non alphanumeric characters + + + Passwords must have at least one uppercase ('A'-'Z'). + Error when passwords do not have an uppercase letter + + + Passwords must be at least {0} characters. + Error message for passwords that are too short + + + Role {0} does not exist. + Error when a role does not exist + + + Recovery code redemption failed. + Error when a recovery code is not redeemed. + + + User already has a password set. + Error when AddPasswordAsync called when a user already has a password + + + User already in role '{0}'. + Error when a user is already in a role + + + User is locked out. + Error when a user is locked out + + + Lockout is not enabled for this user. + Error when lockout is not enabled + + + User {0} does not exist. + Error when a user does not exist + + + User is not in role '{0}'. + Error when a user is not in the role + + + Passwords must use at least {0} different characters. + Error message for passwords that are based on similar characters + + \ No newline at end of file From 13dff68ff2d0d38380847ed8441d83ca9f02ac57 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 11:03:24 +0300 Subject: [PATCH 250/338] Fix integration test --- .../Common/HttpClientExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs index 327c39799..fe89c0ebe 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/HttpClientExtensions.cs @@ -2,14 +2,14 @@ using System.IdentityModel.Tokens.Jwt; using System.Net.Http; using System.Security.Claims; -using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.Configuration; using Skoruba.IdentityServer4.Admin.Middlewares; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Common { public static class HttpClientExtensions { - public static void SetAdminClaimsViaHeaders(this HttpClient client, IAdminConfiguration adminConfiguration) + public static void SetAdminClaimsViaHeaders(this HttpClient client, AdminConfiguration adminConfiguration) { var claims = new[] { From 10f115568c71b3945d36e6c1bc55e3d44814d228 Mon Sep 17 00:00:00 2001 From: Dusan K Date: Tue, 26 Nov 2019 10:17:12 +0100 Subject: [PATCH 251/338] Cover ASP.NET Core Identity IdentityErrorMessages implementation with Unit Tests. --- .../Helpers/IdentityErrorDescriberTestData.cs | 184 ++++++++++++++++++ .../Helpers/IdentityErrorDescriberTests.cs | 39 ++++ 2 files changed, 223 insertions(+) create mode 100644 tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs create mode 100644 tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs new file mode 100644 index 000000000..27e2ac21e --- /dev/null +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs @@ -0,0 +1,184 @@ +using Skoruba.IdentityServer4.Admin.Helpers.Identity; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.UnitTests.Helpers +{ + public class IdentityErrorDescriberTestData : IEnumerable + { + public IEnumerator GetEnumerator() + { + #region Parameterless methods + + yield return new object[] + { + nameof(IdentityErrorMessages.ConcurrencyFailure), + nameof(IdentityErrorMessages.ConcurrencyFailure), + "ConcurrencyFailureTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DefaultError), + nameof(IdentityErrorMessages.DefaultError), + "DefaultErrorTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + "PasswordRequiresNonAlphanumericTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.LoginAlreadyAssociated), + nameof(IdentityErrorMessages.LoginAlreadyAssociated), + "LoginAlreadyAssociatedTranslated" + }; + + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidToken), + nameof(IdentityErrorMessages.InvalidToken), + "InvalidTokenTranslated", + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordMismatch), + nameof(IdentityErrorMessages.PasswordMismatch), + "PasswordMismatchTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresDigit), + nameof(IdentityErrorMessages.PasswordRequiresDigit), + "PasswordRequiresDigitTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresLower), + nameof(IdentityErrorMessages.PasswordRequiresLower), + "PasswordRequiresLowerTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + "PasswordRequiresNonAlphanumericTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.RecoveryCodeRedemptionFailed), + nameof(IdentityErrorMessages.RecoveryCodeRedemptionFailed), + "RecoveryCodeRedemptionFailedTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserAlreadyHasPassword), + nameof(IdentityErrorMessages.UserAlreadyHasPassword), + "UserAlreadyHasPasswordTranslated" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserLockoutNotEnabled), + nameof(IdentityErrorMessages.UserLockoutNotEnabled), + "UserLockoutNotEnabledTranslated" + }; + + + #endregion + + #region Methods with parameters + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidEmail), + nameof(IdentityErrorMessages.InvalidEmail), + "InvalidEmailTranslated", + "TestUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateUserName), + nameof(IdentityErrorMessages.DuplicateUserName), + "DuplicateUserNameTranslated", + "TestDuplicatedUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateRoleName), + nameof(IdentityErrorMessages.DuplicateRoleName), + "DuplicateRoleNameTranslated", + "TestRoleName" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidRoleName), + nameof(IdentityErrorMessages.InvalidRoleName), + "InvalidRoleNameTranslated", + "InvalidRoleNameTest" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordTooShort), + nameof(IdentityErrorMessages.PasswordTooShort), + "PasswordTooShortTranslated", + 4 + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserAlreadyInRole), + nameof(IdentityErrorMessages.UserAlreadyInRole), + "UserAlreadyInRoleTranslated", + "TestRole" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserNotInRole), + nameof(IdentityErrorMessages.UserNotInRole), + "UserNotInRoleTranslated", + "TestRole" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidUserName), + nameof(IdentityErrorMessages.InvalidUserName), + "InvalidUsernameTranslated", + "TestUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresUniqueChars), + nameof(IdentityErrorMessages.PasswordRequiresUniqueChars), + "PasswordRequiresUniqueCharsTranslated", + 5 + }; + + #endregion + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs new file mode 100644 index 000000000..b978eb1df --- /dev/null +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Localization; +using Moq; +using Skoruba.IdentityServer4.Admin.Helpers.Identity; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.UnitTests.Helpers +{ + public class IdentityErrorDescriberTests + { + [Theory] + [ClassData(typeof(IdentityErrorDescriberTestData))] + public void TranslationTests(string key, string methodName, string translated, params object[] args) + { + + // Arrange + var localizer = new Mock>(); + + // GetString extension method uses indexer underneath + localizer.Setup(x => x[key]) + .Returns(new LocalizedString(key, translated)); + + var describer = new IdentityErrorMessages(localizer.Object); + + // Act + var methodInfo = typeof(IdentityErrorMessages).GetMethod(methodName); // get method name dynamically + var error = methodInfo.Invoke(describer, args) as IdentityError; // invoke method on our instance + + // Assert + Assert.IsType(error); + + Assert.Equal(translated, error.Description); + Assert.Equal(key, error.Code); + } + } +} From 7b789a05067ec6f0caeb50fc3f4b79958dc5547a Mon Sep 17 00:00:00 2001 From: Dusan K Date: Tue, 26 Nov 2019 10:21:59 +0100 Subject: [PATCH 252/338] Remove duplicated test data. --- .../Helpers/IdentityErrorDescriberTestData.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs index 27e2ac21e..a7b8192c0 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs @@ -1,5 +1,4 @@ using Skoruba.IdentityServer4.Admin.Helpers.Identity; -using System; using System.Collections; using System.Collections.Generic; @@ -68,13 +67,6 @@ public IEnumerator GetEnumerator() "PasswordRequiresLowerTranslated" }; - yield return new object[] - { - nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), - nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), - "PasswordRequiresNonAlphanumericTranslated" - }; - yield return new object[] { nameof(IdentityErrorMessages.RecoveryCodeRedemptionFailed), From 7426f161e535d2c577fd108b95116a39aff2e570 Mon Sep 17 00:00:00 2001 From: Dusan K Date: Tue, 26 Nov 2019 10:28:22 +0100 Subject: [PATCH 253/338] Add missing DuplicateEmail method test. --- .../Helpers/IdentityErrorDescriberTestData.cs | 10 +++++++++- .../Helpers/IdentityErrorDescriberTests.cs | 3 --- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs index a7b8192c0..633271830 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs @@ -22,7 +22,7 @@ public IEnumerator GetEnumerator() nameof(IdentityErrorMessages.DefaultError), nameof(IdentityErrorMessages.DefaultError), "DefaultErrorTranslated" - }; + }; yield return new object[] { @@ -165,6 +165,14 @@ public IEnumerator GetEnumerator() 5 }; + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateEmail), + nameof(IdentityErrorMessages.DuplicateEmail), + "DuplicateEmailTranslated", + "testduplicateemail@email.com" + }; + #endregion } diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs index b978eb1df..84689ae52 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs @@ -2,9 +2,6 @@ using Microsoft.Extensions.Localization; using Moq; using Skoruba.IdentityServer4.Admin.Helpers.Identity; -using System; -using System.Collections.Generic; -using System.Text; using Xunit; namespace Skoruba.IdentityServer4.Admin.UnitTests.Helpers From 6a4a392cc8559cc905d1619146069dfafb6fd1bf Mon Sep 17 00:00:00 2001 From: Aiscrim Date: Tue, 26 Nov 2019 12:21:53 +0100 Subject: [PATCH 254/338] Now the table names for the sql health checks are retrieved from the DbContexts; Fixed PosgreSql queries syntax --- .../Helpers/StartupHelpers.cs | 85 +++++++++++-------- .../Helpers/DbContextHelpers.cs | 32 +++++++ .../Helpers/StartupHelpers.cs | 85 +++++++++++-------- .../Helpers/StartupHelpers.cs | 68 ++++++++------- 4 files changed, 171 insertions(+), 99 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.EntityFramework/Helpers/DbContextHelpers.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 307d0c68c..a68ccbb7f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -20,6 +20,7 @@ using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Api.Helpers.Localization; using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity; +using Skoruba.IdentityServer4.Admin.EntityFramework.Helpers; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; @@ -215,42 +216,56 @@ public static void AddIdSHealthChecks(); - switch (databaseProvider.ProviderType) + var serviceProvider = services.BuildServiceProvider(); + var scopeFactory = serviceProvider.GetRequiredService(); + using (var scope = scopeFactory.CreateScope()) { - case DatabaseProviderType.SqlServer: - healthChecksBuilder.AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") - .AddSqlServer(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") - .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); - break; - case DatabaseProviderType.PostgreSQL: - healthChecksBuilder - .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddNpgSql(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") - .AddNpgSql(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") - .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); - break; - case DatabaseProviderType.MySql: - healthChecksBuilder - .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") - .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") - .AddMySql(identityDbConnectionString, name: "IdentityDb") - .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") - .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); - break; + var configurationTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var persistedGrantTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var identityTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var logTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var auditLogTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{logTableName}]") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{auditLogTableName}]"); + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT * FROM {configurationTableName} LIMIT 1") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT * FROM {persistedGrantTableName} LIMIT 1") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT * FROM {identityTableName} LIMIT 1") + .AddNpgSql(logDbConnectionString, name: "LogDb", + healthQuery: $"SELECT * FROM {logTableName} LIMIT 1") + .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: $"SELECT * FROM {auditLogTableName} LIMIT 1"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb") + .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); + break; + default: + throw new NotImplementedException($"Health checks not defined for database provider {databaseProvider.ProviderType}"); + } } } } diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Helpers/DbContextHelpers.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Helpers/DbContextHelpers.cs new file mode 100644 index 000000000..103a13dc5 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Helpers/DbContextHelpers.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using System; +using Microsoft.Extensions.DependencyInjection; +using System.Linq; + +namespace Skoruba.IdentityServer4.Admin.EntityFramework.Helpers +{ + public static class DbContextHelpers + { + /// + /// Get the table name of an entity in the given DbContext + /// + /// + /// + /// If specified, the full name of the type of the entity. + /// Otherwise, the first entity in the DbContext will be retrieved + /// + public static string GetEntityTable(IServiceProvider serviceProvider, string entityTypeName = null) + where TDbContext : DbContext + { + var db = serviceProvider.GetService(); + if (db != null) + { + var entityType = entityTypeName != null ? db.Model.FindEntityType(entityTypeName) : db.Model.GetEntityTypes().FirstOrDefault(); + if (entityType != null) + return entityType.GetTableName(); + } + + return null; + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index b079aafc4..cb9f113e7 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -49,6 +49,7 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Helpers; namespace Skoruba.IdentityServer4.Admin.Helpers { @@ -580,42 +581,56 @@ public static void AddIdSHealthChecks(); - switch (databaseProvider.ProviderType) + var serviceProvider = services.BuildServiceProvider(); + var scopeFactory = serviceProvider.GetRequiredService(); + using (var scope = scopeFactory.CreateScope()) { - case DatabaseProviderType.SqlServer: - healthChecksBuilder.AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") - .AddSqlServer(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") - .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); - break; - case DatabaseProviderType.PostgreSQL: - healthChecksBuilder - .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddNpgSql(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users") - .AddNpgSql(logDbConnectionString, name: "LogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Log") - .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", - healthQuery: "SELECT TOP 1 * FROM dbo.AuditLog"); - break; - case DatabaseProviderType.MySql: - healthChecksBuilder - .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") - .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") - .AddMySql(identityDbConnectionString, name: "IdentityDb") - .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") - .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); - break; + var configurationTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var persistedGrantTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var identityTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var logTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var auditLogTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]") + .AddSqlServer(logDbConnectionString, name: "LogDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{logTableName}]") + .AddSqlServer(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{auditLogTableName}]"); + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT * FROM {configurationTableName} LIMIT 1") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT * FROM {persistedGrantTableName} LIMIT 1") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT * FROM {identityTableName} LIMIT 1") + .AddNpgSql(logDbConnectionString, name: "LogDb", + healthQuery: $"SELECT * FROM {logTableName} LIMIT 1") + .AddNpgSql(auditLogDbConnectionString, name: "AuditLogDb", + healthQuery: $"SELECT * FROM {auditLogTableName} LIMIT 1"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb") + .AddMySql(logDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(auditLogDbConnectionString, name: "IdentityDb"); + break; + default: + throw new NotImplementedException($"Health checks not defined for database provider {databaseProvider.ProviderType}"); + } } } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 2a1940545..61ea0f8ee 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -31,6 +31,7 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Helpers; namespace Skoruba.IdentityServer4.STS.Identity.Helpers { @@ -418,43 +419,52 @@ public static void AddIdSHealthChecks("ConfigurationDbContext") .AddDbContextCheck("PersistedGrantsDbContext") .AddDbContextCheck("IdentityDbContext"); - var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); - switch (databaseProvider.ProviderType) + var serviceProvider = services.BuildServiceProvider(); + var scopeFactory = serviceProvider.GetRequiredService(); + using (var scope = scopeFactory.CreateScope()) { - case DatabaseProviderType.SqlServer: - healthChecksBuilder - .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddSqlServer(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users"); + var configurationTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var persistedGrantTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var identityTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); - break; - case DatabaseProviderType.PostgreSQL: - healthChecksBuilder - .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Clients") - .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", - healthQuery: "SELECT TOP 1 * FROM dbo.PersistedGrants") - .AddNpgSql(identityDbConnectionString, name: "IdentityDb", - healthQuery: "SELECT TOP 1 * FROM dbo.Users"); - break; - case DatabaseProviderType.MySql: - healthChecksBuilder - .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") - .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") - .AddMySql(identityDbConnectionString, name: "IdentityDb"); - break; + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]"); + + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT * FROM {configurationTableName} LIMIT 1") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT * FROM {persistedGrantTableName} LIMIT 1") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT * FROM {identityTableName} LIMIT 1"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb"); + break; + default: + throw new NotImplementedException($"Health checks not defined for database provider {databaseProvider.ProviderType}"); + } } - - //services.AddHealthChecksUI(); } } } From 1aa3c61c71301963e65fbede67b3865e2ed5b5fd Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:20:18 +0300 Subject: [PATCH 255/338] Fix typo --- .../Configuration/AdminConfiguration.cs | 2 +- .../{Intefaces => Interfaces}/IAdminConfiguration.cs | 2 +- .../{Intefaces => Interfaces}/IRegisterConfiguration.cs | 2 +- .../{Intefaces => Interfaces}/IRootConfiguration.cs | 2 +- .../Configuration/RegisterConfiguration.cs | 2 +- .../Configuration/RootConfiguration.cs | 2 +- .../Helpers/StartupHelpers.cs | 2 +- src/Skoruba.IdentityServer4.STS.Identity/Startup.cs | 2 +- .../ViewComponents/IdentityServerAdminLinkViewComponent.cs | 2 +- .../Views/Account/Login.cshtml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) rename src/Skoruba.IdentityServer4.STS.Identity/Configuration/{Intefaces => Interfaces}/IAdminConfiguration.cs (94%) rename src/Skoruba.IdentityServer4.STS.Identity/Configuration/{Intefaces => Interfaces}/IRegisterConfiguration.cs (93%) rename src/Skoruba.IdentityServer4.STS.Identity/Configuration/{Intefaces => Interfaces}/IRootConfiguration.cs (95%) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs index e2943bd55..42fbaa11f 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs @@ -1,4 +1,4 @@ -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; namespace Skoruba.IdentityServer4.STS.Identity.Configuration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs similarity index 94% rename from src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs rename to src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs index caf9a144b..0ec74959e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs @@ -1,4 +1,4 @@ -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces +namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces { public interface IAdminConfiguration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs similarity index 93% rename from src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs rename to src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs index 37676d368..02bf41024 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs @@ -1,4 +1,4 @@ -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces +namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces { public interface IRegisterConfiguration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs similarity index 95% rename from src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs rename to src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs index 2d5a2749d..ca4c726de 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs @@ -1,4 +1,4 @@ -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces +namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces { public interface IRootConfiguration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs index e9ca8b80c..6a3354662 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs @@ -1,4 +1,4 @@ -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; namespace Skoruba.IdentityServer4.STS.Identity.Configuration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs index 25a006fd5..0a6dd98ad 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs @@ -1,5 +1,5 @@ using Microsoft.Extensions.Options; -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; namespace Skoruba.IdentityServer4.STS.Identity.Configuration { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 8df71f705..bdccac1cf 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -20,7 +20,7 @@ using Skoruba.IdentityServer4.STS.Identity.Configuration; using Skoruba.IdentityServer4.STS.Identity.Configuration.ApplicationParts; using Skoruba.IdentityServer4.STS.Identity.Configuration.Constants; -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; using Skoruba.IdentityServer4.STS.Identity.Helpers.Localization; using Skoruba.IdentityServer4.STS.Identity.Services; using ILogger = Microsoft.Extensions.Logging.ILogger; diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 5f88370dc..8f485433b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.Logging; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; using Skoruba.IdentityServer4.STS.Identity.Helpers; namespace Skoruba.IdentityServer4.STS.Identity diff --git a/src/Skoruba.IdentityServer4.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs b/src/Skoruba.IdentityServer4.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs index 27231f329..d678fbea9 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; namespace Skoruba.IdentityServer4.STS.Identity.ViewComponents { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/Login.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/Login.cshtml index 219d38a3d..1e15b117c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/Login.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Account/Login.cshtml @@ -1,5 +1,5 @@ @using Microsoft.AspNetCore.Mvc.Localization -@using Skoruba.IdentityServer4.STS.Identity.Configuration.Intefaces +@using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces @using Skoruba.IdentityServer4.STS.Identity.Helpers.Localization @inject IViewLocalizer Localizer @model Skoruba.IdentityServer4.STS.Identity.ViewModels.Account.LoginViewModel From f7b99753ce9cd31f0d19d948e363e2d384873fec Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:25:19 +0300 Subject: [PATCH 256/338] Fix typo in ConfigurationConsts --- .../Configuration/Constants/ConfigurationConsts.cs | 2 +- .../Helpers/StartupHelpers.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/ConfigurationConsts.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/ConfigurationConsts.cs index 2edf4ae29..ce21f2021 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/ConfigurationConsts.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Constants/ConfigurationConsts.cs @@ -14,6 +14,6 @@ public class ConfigurationConsts public const string AdminConfigurationKey = "AdminConfiguration"; - public const string RegisterConfiguration = "RegisterConfiguration"; + public const string RegisterConfigurationKey = "RegisterConfiguration"; } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index bdccac1cf..6a88bc375 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -313,7 +313,7 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect services.AddOptions(); services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.RegisterConfiguration)); + services.Configure(configuration.GetSection(ConfigurationConsts.RegisterConfigurationKey)); services.TryAddSingleton(); From d2352d3e4bcbe8a61542ac33d5955c2809ea7439 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:31:59 +0300 Subject: [PATCH 257/338] Remove extra configuration interfaces --- .../Configuration/AdminConfiguration.cs | 6 ++---- .../Interfaces/IAdminConfiguration.cs | 8 -------- .../Interfaces/IRegisterConfiguration.cs | 7 ------- .../Interfaces/IRootConfiguration.cs | 4 ++-- .../Configuration/RegisterConfiguration.cs | 6 ++---- .../Configuration/RootConfiguration.cs | 13 +++---------- .../Helpers/StartupHelpers.cs | 18 ------------------ .../Startup.cs | 14 ++++++++++++-- 8 files changed, 21 insertions(+), 55 deletions(-) delete mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs delete mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs index 42fbaa11f..eac3070e5 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs @@ -1,8 +1,6 @@ -using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; - -namespace Skoruba.IdentityServer4.STS.Identity.Configuration +namespace Skoruba.IdentityServer4.STS.Identity.Configuration { - public class AdminConfiguration : IAdminConfiguration + public class AdminConfiguration { public string IdentityAdminBaseUrl { get; set; } public string AdministrationRole { get; set; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs deleted file mode 100644 index 0ec74959e..000000000 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IAdminConfiguration.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces -{ - public interface IAdminConfiguration - { - string IdentityAdminBaseUrl { get; } - string AdministrationRole { get; } - } -} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs deleted file mode 100644 index 02bf41024..000000000 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRegisterConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces -{ - public interface IRegisterConfiguration - { - bool Enabled { get; } - } -} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs index ca4c726de..ba2cd2d15 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs @@ -2,8 +2,8 @@ { public interface IRootConfiguration { - IAdminConfiguration AdminConfiguration { get; } + AdminConfiguration AdminConfiguration { get; } - IRegisterConfiguration RegisterConfiguration { get; } + RegisterConfiguration RegisterConfiguration { get; } } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs index 6a3354662..fbe72909e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RegisterConfiguration.cs @@ -1,8 +1,6 @@ -using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; - -namespace Skoruba.IdentityServer4.STS.Identity.Configuration +namespace Skoruba.IdentityServer4.STS.Identity.Configuration { - public class RegisterConfiguration : IRegisterConfiguration + public class RegisterConfiguration { public bool Enabled { get; set; } = true; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs index 0a6dd98ad..c3779efaf 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/RootConfiguration.cs @@ -1,17 +1,10 @@ -using Microsoft.Extensions.Options; -using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; namespace Skoruba.IdentityServer4.STS.Identity.Configuration { public class RootConfiguration : IRootConfiguration { - public IAdminConfiguration AdminConfiguration { get; set; } - public IRegisterConfiguration RegisterConfiguration { get; } - - public RootConfiguration(IOptions adminConfiguration, IOptions registerConfiguration) - { - RegisterConfiguration = registerConfiguration.Value; - AdminConfiguration = adminConfiguration.Value; - } + public AdminConfiguration AdminConfiguration { get; } = new AdminConfiguration(); + public RegisterConfiguration RegisterConfiguration { get; } = new RegisterConfiguration(); } } \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 6a88bc375..6a7871d74 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -302,24 +302,6 @@ private static RegisterConfiguration GetRegistrationConfiguration(IConfiguration return registerConfiguration; } - /// - /// Configuration root configuration - /// - /// - /// - /// - public static IServiceCollection ConfigureRootConfiguration(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - - services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.RegisterConfigurationKey)); - - services.TryAddSingleton(); - - return services; - } - /// /// Add configuration for IdentityServer4 /// diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 8f485433b..1588d4306 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -6,6 +6,8 @@ using Microsoft.Extensions.Logging; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; +using Skoruba.IdentityServer4.STS.Identity.Configuration; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Constants; using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; using Skoruba.IdentityServer4.STS.Identity.Helpers; @@ -37,7 +39,8 @@ public Startup(IWebHostEnvironment environment, ILoggerFactory loggerFactory) public void ConfigureServices(IServiceCollection services) { - services.ConfigureRootConfiguration(Configuration); + var rootConfiguration = CreateRootConfiguration(); + services.AddSingleton(rootConfiguration); // Register DbContexts for IdentityServer and Identity services.RegisterDbContexts(Environment, Configuration); @@ -54,7 +57,6 @@ public void ConfigureServices(IServiceCollection services) services.AddMvcWithLocalization(Configuration); // Add authorization policies for MVC - var rootConfiguration = services.BuildServiceProvider().GetService(); services.AddAuthorizationPolicies(rootConfiguration); } @@ -78,5 +80,13 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseAuthorization(); app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } + + private IRootConfiguration CreateRootConfiguration() + { + var rootConfiguration = new RootConfiguration(); + Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration); + Configuration.GetSection(ConfigurationConsts.RegisterConfigurationKey).Bind(rootConfiguration.RegisterConfiguration); + return rootConfiguration; + } } } From f34c05aefd1774a55d89e1e4bd60a99577acb440 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:38:58 +0300 Subject: [PATCH 258/338] Throw exception when there is problem with specifying signing credential --- .../Helpers/IdentityServerBuilderExtensions.cs | 11 +++++++---- .../Helpers/StartupHelpers.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs index 70d36d1b7..3f1d2e9f7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs @@ -23,9 +23,8 @@ public static class IdentityServerBuilderExtensions /// /// /// - /// /// - public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentityServerBuilder builder, IConfiguration configuration, ILogger logger) + public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentityServerBuilder builder, IConfiguration configuration) { var certificateConfiguration = configuration.GetSection(nameof(CertificateConfiguration)).Get(); @@ -81,9 +80,9 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe { builder.AddSigningCredential(new X509Certificate2(certificateConfiguration.SigningCertificatePfxFilePath, certificateConfiguration.SigningCertificatePfxFilePassword)); } - catch (CryptographicException e) + catch (Exception e) { - logger.LogError($"There was an error adding the key file - during the creation of the signing key {e.Message}"); + throw new Exception("There was an error adding the key file - during the creation of the signing key", e); } } else @@ -95,6 +94,10 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe { builder.AddDeveloperSigningCredential(); } + else + { + throw new Exception("Signing credential is not specified"); + } return builder; } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 6a7871d74..e05733c8e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -329,7 +329,7 @@ private static void AddIdentityServer() .AddAspNetIdentity(); - builder.AddCustomSigningCredential(configuration, logger); + builder.AddCustomSigningCredential(configuration); builder.AddCustomValidationKey(configuration, logger); } From 5f448af88dffd6e8e2e2870b05c25f328375eab6 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:42:09 +0300 Subject: [PATCH 259/338] Throw exception when can't load user's validation key --- .../Helpers/IdentityServerBuilderExtensions.cs | 7 +++---- .../Helpers/StartupHelpers.cs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs index 3f1d2e9f7..2b9e68668 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs @@ -108,9 +108,8 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe /// /// /// - /// /// - public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServerBuilder builder, IConfiguration configuration, ILogger logger) + public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServerBuilder builder, IConfiguration configuration) { var certificateConfiguration = configuration.GetSection(nameof(CertificateConfiguration)).Get(); @@ -149,9 +148,9 @@ public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServer builder.AddValidationKey(new X509Certificate2(certificateConfiguration.ValidationCertificatePfxFilePath, certificateConfiguration.ValidationCertificatePfxFilePassword)); } - catch (CryptographicException e) + catch (Exception e) { - logger.LogError($"There was an error adding the key file - during the creation of the validation key {e.Message}"); + throw new Exception("There was an error adding the key file - during the creation of the validation key", e); } } else diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index e05733c8e..ea88f34c6 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -330,7 +330,7 @@ private static void AddIdentityServer(); builder.AddCustomSigningCredential(configuration); - builder.AddCustomValidationKey(configuration, logger); + builder.AddCustomValidationKey(configuration); } /// From 829d025b6eb97e50d5962dcda48b2100c1aa0873 Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Tue, 26 Nov 2019 15:44:34 +0300 Subject: [PATCH 260/338] Remove logger from Startup.ConfigureService --- .../Helpers/StartupHelpers.cs | 21 +++------------ .../Program.cs | 26 ++++++++++++------- .../Startup.cs | 23 +++------------- 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index ea88f34c6..0e44f1d23 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -232,8 +232,7 @@ public static void RegisterDbContextsInMemory /// /// - /// - public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration, ILogger logger) where TIdentityDbContext : DbContext + public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TUserIdentity : class @@ -263,7 +262,7 @@ public static void AddAuthenticationServices(services, configuration, logger); + AddIdentityServer(services, configuration); } /// @@ -310,10 +309,9 @@ private static RegisterConfiguration GetRegistrationConfiguration(IConfiguration /// /// /// - /// private static void AddIdentityServer( IServiceCollection services, - IConfiguration configuration, ILogger logger) + IConfiguration configuration) where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TUserIdentity : class @@ -364,19 +362,6 @@ public static void UseMvcLocalizationServices(this IApplicationBuilder app) app.UseRequestLocalization(options.Value); } - /// - /// Add configuration for logging - /// - /// - /// - /// - public static void AddLogging(this IApplicationBuilder app, ILoggerFactory loggerFactory, IConfiguration configuration) - { - Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(configuration) - .CreateLogger(); - } - /// /// Add authorization policies /// diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs index 4fe593c7f..4b86861e5 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs @@ -1,5 +1,6 @@ -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Hosting; using Serilog; namespace Skoruba.IdentityServer4.STS.Identity @@ -8,14 +9,21 @@ public class Program { public static void Main(string[] args) { - CreateWebHostBuilder(args) - .UseSerilog() - .Build().Run(); + CreateHostBuilder(args).Build().Run(); } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseIISIntegration() - .UseStartup(); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureLogging((hostingContext, logging) => { + logging.ClearProviders(); + var logger = new LoggerConfiguration().ReadFrom.Configuration(hostingContext.Configuration).CreateLogger(); + logging.AddSerilog(logger); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); + webBuilder.UseStartup(); + webBuilder.UseSerilog(); + }); } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 1588d4306..60dd0ef93 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -17,24 +17,11 @@ public class Startup { public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; } - public ILogger Logger { get; set; } - public Startup(IWebHostEnvironment environment, ILoggerFactory loggerFactory) + public Startup(IWebHostEnvironment environment, IConfiguration configuration) { - var builder = new ConfigurationBuilder() - .SetBasePath(environment.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); - - if (environment.IsDevelopment()) - { - builder.AddUserSecrets(); - } - - Configuration = builder.Build(); + Configuration = configuration; Environment = environment; - Logger = loggerFactory.CreateLogger(); } public void ConfigureServices(IServiceCollection services) @@ -49,7 +36,7 @@ public void ConfigureServices(IServiceCollection services) services.AddEmailSenders(Configuration); // Add services for authentication, including Identity model, IdentityServer4 and external providers - services.AddAuthenticationServices(Configuration, Logger); + services.AddAuthenticationServices(Configuration); // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization @@ -60,10 +47,8 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthorizationPolicies(rootConfiguration); } - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - app.AddLogging(loggerFactory, Configuration); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); From 88bf17ba0e43cd643694ec69ea593cce6084547a Mon Sep 17 00:00:00 2001 From: Carl Quirion Date: Thu, 28 Nov 2019 10:50:53 -0500 Subject: [PATCH 261/338] Fix implicit client evaluation issue with Date. --- .../Repositories/LogRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/LogRepository.cs b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/LogRepository.cs index 5f2769b86..fdbd7f178 100644 --- a/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/LogRepository.cs +++ b/src/Skoruba.IdentityServer4.Admin.EntityFramework/Repositories/LogRepository.cs @@ -23,7 +23,7 @@ public LogRepository(TDbContext dbContext) public virtual async Task DeleteLogsOlderThanAsync(DateTime deleteOlderThan) { - var logsToDelete = await DbContext.Logs.Where(x => x.TimeStamp.DateTime.Date < deleteOlderThan.Date).ToListAsync(); + var logsToDelete = await DbContext.Logs.Where(x => x.TimeStamp < deleteOlderThan.Date).ToListAsync(); if(logsToDelete.Count == 0) return; From c2d53a873c961fa36f7cff894d6e0bd310a55cdb Mon Sep 17 00:00:00 2001 From: Dmitrii Tarasov Date: Mon, 2 Dec 2019 15:23:52 +0300 Subject: [PATCH 262/338] Remove redunant code --- src/Skoruba.IdentityServer4.STS.Identity/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs index 4b86861e5..418c5214b 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Program.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Program.cs @@ -23,7 +23,6 @@ public static IHostBuilder CreateHostBuilder(string[] args) => { webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); webBuilder.UseStartup(); - webBuilder.UseSerilog(); }); } } From 76213556482930d8e19f59f76f15bddffc21299a Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 2 Dec 2019 16:44:41 +0100 Subject: [PATCH 263/338] Fix method name --- .../Controllers/UsersController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index de8d50cb9..b6ddaf9c8 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -226,7 +226,7 @@ public async Task PostChangePassword([FromBody]UserChangePassword } [HttpGet("{id}/RoleClaims")] - public async Task>> PostChangePassword(TUserDtoKey id, string claimSearchText, int page = 1, int pageSize = 10) + public async Task>> GetRoleClaims(TUserDtoKey id, string claimSearchText, int page = 1, int pageSize = 10) { var roleClaimsDto = await _identityService.GetUserRoleClaimsAsync(id.ToString(), claimSearchText, page, pageSize); var roleClaimsApiDto = _mapper.Map>(roleClaimsDto); From 4048f339f55eb7e68297d4208e627f1c0a19767f Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 2 Dec 2019 16:50:11 +0100 Subject: [PATCH 264/338] Remove redundancy serilog definition --- src/Skoruba.IdentityServer4.Admin/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Program.cs b/src/Skoruba.IdentityServer4.Admin/Program.cs index 4cf0bcc1f..79bea7a4c 100644 --- a/src/Skoruba.IdentityServer4.Admin/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin/Program.cs @@ -43,7 +43,6 @@ public static IHostBuilder CreateHostBuilder(string[] args) => { webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); webBuilder.UseStartup(); - webBuilder.UseSerilog(); }); } } \ No newline at end of file From 656fafc34b3032568c8751c5e2432a6224a1cee4 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 2 Dec 2019 17:28:32 +0100 Subject: [PATCH 265/338] Add profile scope to api, modify api startup and program.cs according to admin and sts --- .../Helpers/StartupHelpers.cs | 12 --------- .../Mappers/ClientApiMapperProfile.cs | 11 +++++--- .../Program.cs | 25 ++++++++++++------- .../Startup.cs | 18 ++----------- src/Skoruba.IdentityServer4.Admin/Startup.cs | 2 +- .../appsettings.json | 3 ++- 6 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index 45a4fe7ed..e89085558 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -95,18 +95,6 @@ public static IServiceCollection AddAuditEventLogging - /// Add configuration for logging - /// - /// - /// - public static void AddLogging(this IApplicationBuilder app, IConfiguration configuration) - { - Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(configuration) - .CreateLogger(); - } - /// /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging /// Configure the connection strings in AppSettings.json diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs b/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs index 4b6e7cadc..37a3a6275 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs @@ -25,7 +25,9 @@ public ClientApiMapperProfile() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.ClientSecretId)) .ReverseMap(); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination) + .ReverseMap(); + CreateMap(MemberList.Destination); // Client Properties @@ -33,7 +35,9 @@ public ClientApiMapperProfile() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.ClientPropertyId)) .ReverseMap(); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination) + .ReverseMap(); + CreateMap(MemberList.Destination); // Client Claims @@ -41,7 +45,8 @@ public ClientApiMapperProfile() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.ClientClaimId)) .ReverseMap(); - CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination) + .ReverseMap(); CreateMap(MemberList.Destination); } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs index e8fd12e41..445097bf7 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Program.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Program.cs @@ -1,5 +1,6 @@ -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using Serilog; namespace Skoruba.IdentityServer4.Admin.Api @@ -8,14 +9,20 @@ public class Program { public static void Main(string[] args) { - CreateWebHostBuilder(args) - .UseSerilog() - .Build().Run(); + CreateHostBuilder(args).Build().Run(); } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseIISIntegration() - .UseStartup(); + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureLogging((hostingContext, logging) => { + logging.ClearProviders(); + var logger = new LoggerConfiguration().ReadFrom.Configuration(hostingContext.Configuration).CreateLogger(); + logging.AddSerilog(logger); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); + webBuilder.UseStartup(); + }); } } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 5503c086f..7e573e2c0 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -22,22 +22,10 @@ namespace Skoruba.IdentityServer4.Admin.Api { public class Startup { - public Startup(IWebHostEnvironment env) + public Startup(IWebHostEnvironment env, IConfiguration configuration) { - var builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); - - if (env.IsDevelopment()) - { - builder.AddUserSecrets(); - } - - Configuration = builder.Build(); - HostingEnvironment = env; + Configuration = configuration; } public IConfiguration Configuration { get; } @@ -103,8 +91,6 @@ public void ConfigureServices(IServiceCollection services) public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApiConfiguration adminApiConfiguration) { - app.AddLogging(Configuration); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index e014a5d25..2df67c69b 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -32,7 +32,7 @@ public Startup(IWebHostEnvironment env, IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { var rootConfiguration = CreateRootConfiguration(); - services.AddSingleton(rootConfiguration); + services.AddSingleton(rootConfiguration); // Add DbContexts for Asp.Net Core Identity, Logging and IdentityServer - Configuration store and Operational store services.AddDbContexts(HostingEnvironment, Configuration); diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index a8cb40f22..8bd63a7ca 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -160,7 +160,8 @@ "DisplayName": "skoruba_identity_admin_api", "Required": true, "UserClaims": [ - "role" + "role", + "profile" ] } ] From 324aa0ecbe558c8ed4eb2d1d80cd53c935c3c178 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 2 Dec 2019 17:43:42 +0100 Subject: [PATCH 266/338] Remove secrets from ClientApiDto, because client secrets are handled via separated methods --- .../Dtos/Clients/ClientApiDto.cs | 2 -- .../Mappers/ClientApiMapperProfile.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Dtos/Clients/ClientApiDto.cs b/src/Skoruba.IdentityServer4.Admin.Api/Dtos/Clients/ClientApiDto.cs index 05bd8b43a..a10f11ef4 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Dtos/Clients/ClientApiDto.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Dtos/Clients/ClientApiDto.cs @@ -15,7 +15,6 @@ public ClientApiDto() AllowedCorsOrigins = new List(); AllowedGrantTypes = new List(); Claims = new List(); - ClientSecrets = new List(); Properties = new List(); } @@ -87,7 +86,6 @@ public ClientApiDto() public List AllowedScopes { get; set; } public List Claims { get; set; } - public List ClientSecrets { get; set; } public List Properties { get; set; } public DateTime? Updated { get; set; } diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs b/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs index 37a3a6275..28b56fe70 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Mappers/ClientApiMapperProfile.cs @@ -11,7 +11,6 @@ public ClientApiMapperProfile() // Client CreateMap(MemberList.Destination) .ForMember(dest => dest.ProtocolType, opt => opt.Condition(srs => srs != null)) - .ForMember(x => x.ClientSecrets, opt => opt.Ignore()) .ReverseMap(); CreateMap(MemberList.Destination) From 119b1f611ad956be50b834c19b6754e1954dd016 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Mon, 2 Dec 2019 18:00:26 +0100 Subject: [PATCH 267/338] Fix claim name --- src/Skoruba.IdentityServer4.Admin/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Skoruba.IdentityServer4.Admin/appsettings.json b/src/Skoruba.IdentityServer4.Admin/appsettings.json index 8bd63a7ca..5a727d8a8 100644 --- a/src/Skoruba.IdentityServer4.Admin/appsettings.json +++ b/src/Skoruba.IdentityServer4.Admin/appsettings.json @@ -161,7 +161,7 @@ "Required": true, "UserClaims": [ "role", - "profile" + "name" ] } ] From 51dc3788b80c93ade185de3f41a9aae52148e2d4 Mon Sep 17 00:00:00 2001 From: duki994 Date: Tue, 3 Dec 2019 10:01:14 +0100 Subject: [PATCH 268/338] Add default fallback ASP.NET Core Identity localization resource in english language. --- .../Identity/IdentityErrorMessages.resx | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.resx diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.resx new file mode 100644 index 000000000..767b425ff --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Helpers/Identity/IdentityErrorMessages.resx @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Optimistic concurrency failure, object has been modified. + Error when optimistic concurrency fails + + + An unknown failure has occurred. + Default identity result error message + + + Email '{0}' is already taken. + Error for duplicate emails + + + Role name '{0}' is already taken. + Error for duplicate roles + + + User name '{0}' is already taken. + Error for duplicate user names + + + Email '{0}' is invalid. + Invalid email + + + The provided PasswordHasherCompatibilityMode is invalid. + Error when the password hasher doesn't understand the format it's being asked to produce. + + + The iteration count must be a positive integer. + Error when the iteration count is < 1. + + + Role name '{0}' is invalid. + Error for invalid role names + + + Invalid token. + Error when a token is not recognized + + + User name '{0}' is invalid, can only contain letters or digits. + User names can only contain letters or digits + + + A user with this login already exists. + Error when a login already linked + + + Incorrect password. + Error when a password doesn't match + + + Passwords must have at least one digit ('0'-'9'). + Error when passwords do not have a digit + + + Passwords must have at least one lowercase ('a'-'z'). + Error when passwords do not have a lowercase letter + + + Passwords must have at least one non alphanumeric character. + Error when password does not have enough non alphanumeric characters + + + Passwords must have at least one uppercase ('A'-'Z'). + Error when passwords do not have an uppercase letter + + + Passwords must be at least {0} characters. + Error message for passwords that are too short + + + Role {0} does not exist. + Error when a role does not exist + + + Recovery code redemption failed. + Error when a recovery code is not redeemed. + + + User already has a password set. + Error when AddPasswordAsync called when a user already has a password + + + User already in role '{0}'. + Error when a user is already in a role + + + User is locked out. + Error when a user is locked out + + + Lockout is not enabled for this user. + Error when lockout is not enabled + + + User {0} does not exist. + Error when a user does not exist + + + User is not in role '{0}'. + Error when a user is not in the role + + + Passwords must use at least {0} different characters. + Error message for passwords that are based on similar characters + + \ No newline at end of file From 9934b1c4afee92c4cb03df3b102fe21074c8b798 Mon Sep 17 00:00:00 2001 From: duki994 Date: Tue, 3 Dec 2019 10:28:05 +0100 Subject: [PATCH 269/338] Add code fallback and 'last try' fallback to base methods of default IdentityErrorDescriber implementation in ASP.NET Core. --- .../Helpers/Identity/IdentityErrorMessages.cs | 168 +++++++++++++++--- .../IdentityErrorDescriberFallbackTestData.cs | 163 +++++++++++++++++ .../Helpers/IdentityErrorDescriberTests.cs | 33 ++++ 3 files changed, 339 insertions(+), 25 deletions(-) create mode 100644 tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs index f8ba7f829..f002b5903 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs @@ -24,7 +24,12 @@ public IdentityErrorMessages(IStringLocalizer stringLocal /// An indicating a concurrency failure. public override IdentityError ConcurrencyFailure() { - return CreateNamedError(nameof(ConcurrencyFailure)); + if (TryCreateLocalizedError(nameof(ConcurrencyFailure), out var error)) + { + return error; + } + + return base.ConcurrencyFailure(); } /// @@ -33,7 +38,12 @@ public override IdentityError ConcurrencyFailure() /// The default . public override IdentityError DefaultError() { - return CreateNamedError(nameof(DefaultError)); + if (TryCreateLocalizedError(nameof(DefaultError), out var error)) + { + return error; + } + + return base.DefaultError(); } /// @@ -43,7 +53,12 @@ public override IdentityError DefaultError() /// An indicating the specified is already associated with an account. public override IdentityError DuplicateEmail(string email) { - return CreateNamedError(nameof(DuplicateEmail)); + if (TryCreateLocalizedError(nameof(DuplicateEmail), out var error)) + { + return error; + } + + return base.DuplicateEmail(email); } /// @@ -53,7 +68,12 @@ public override IdentityError DuplicateEmail(string email) /// An indicating the specific role name already exists. public override IdentityError DuplicateRoleName(string role) { - return CreateNamedError(nameof(DuplicateRoleName)); + if (TryCreateLocalizedError(nameof(DuplicateRoleName), out var error)) + { + return error; + } + + return base.DuplicateRoleName(role); } /// @@ -63,7 +83,12 @@ public override IdentityError DuplicateRoleName(string role) /// An indicating the specified already exists. public override IdentityError DuplicateUserName(string userName) { - return CreateNamedError(nameof(DuplicateUserName)); + if (TryCreateLocalizedError(nameof(DuplicateUserName), out var error)) + { + return error; + } + + return base.DuplicateUserName(userName); } /// @@ -73,7 +98,12 @@ public override IdentityError DuplicateUserName(string userName) /// An indicating the specified is invalid. public override IdentityError InvalidEmail(string email) { - return CreateNamedError(nameof(InvalidEmail)); + if (TryCreateLocalizedError(nameof(InvalidEmail), out var error)) + { + return error; + } + + return base.InvalidEmail(email); } /// @@ -83,7 +113,12 @@ public override IdentityError InvalidEmail(string email) /// An indicating the specific role name is invalid. public override IdentityError InvalidRoleName(string role) { - return CreateNamedError(nameof(InvalidRoleName)); + if (TryCreateLocalizedError(nameof(InvalidRoleName), out var error)) + { + return error; + } + + return base.InvalidRoleName(role); } /// @@ -92,7 +127,12 @@ public override IdentityError InvalidRoleName(string role) /// An indicating an invalid token. public override IdentityError InvalidToken() { - return CreateNamedError(nameof(InvalidToken)); + if (TryCreateLocalizedError(nameof(InvalidToken), out var error)) + { + return error; + } + + return base.InvalidToken(); } /// @@ -102,7 +142,12 @@ public override IdentityError InvalidToken() /// An indicating the specified user is invalid. public override IdentityError InvalidUserName(string userName) { - return CreateNamedError(nameof(InvalidUserName)); + if (TryCreateLocalizedError(nameof(InvalidUserName), out var error)) + { + return error; + } + + return base.InvalidUserName(userName); } /// @@ -111,7 +156,12 @@ public override IdentityError InvalidUserName(string userName) /// An indicating an external login is already associated with an account. public override IdentityError LoginAlreadyAssociated() { - return CreateNamedError(nameof(LoginAlreadyAssociated)); + if (TryCreateLocalizedError(nameof(LoginAlreadyAssociated), out var error)) + { + return error; + } + + return base.LoginAlreadyAssociated(); } /// @@ -120,7 +170,12 @@ public override IdentityError LoginAlreadyAssociated() /// An indicating a password mismatch. public override IdentityError PasswordMismatch() { - return CreateNamedError(nameof(PasswordMismatch)); + if (TryCreateLocalizedError(nameof(PasswordMismatch), out var error)) + { + return error; + } + + return base.PasswordMismatch(); } /// @@ -129,7 +184,12 @@ public override IdentityError PasswordMismatch() /// An indicating a password entered does not contain a numeric character. public override IdentityError PasswordRequiresDigit() { - return CreateNamedError(nameof(PasswordRequiresDigit)); + if (TryCreateLocalizedError(nameof(PasswordRequiresDigit), out var error)) + { + return error; + } + + return base.PasswordRequiresDigit(); } /// @@ -138,7 +198,12 @@ public override IdentityError PasswordRequiresDigit() /// An indicating a password entered does not contain a lower case letter. public override IdentityError PasswordRequiresLower() { - return CreateNamedError(nameof(PasswordRequiresLower)); + if (TryCreateLocalizedError(nameof(PasswordRequiresLower), out var error)) + { + return error; + } + + return base.PasswordRequiresLower(); } /// @@ -147,7 +212,12 @@ public override IdentityError PasswordRequiresLower() /// An indicating a password entered does not contain a non-alphanumeric character. public override IdentityError PasswordRequiresNonAlphanumeric() { - return CreateNamedError(nameof(PasswordRequiresNonAlphanumeric)); + if (TryCreateLocalizedError(nameof(PasswordRequiresNonAlphanumeric), out var error)) + { + return error; + } + + return base.PasswordRequiresNonAlphanumeric(); } /// @@ -157,7 +227,12 @@ public override IdentityError PasswordRequiresNonAlphanumeric() /// An indicating a password does not meet the minimum number of unique chars. public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) { - return CreateNamedError(nameof(PasswordRequiresUniqueChars)); + if (TryCreateLocalizedError(nameof(PasswordRequiresUniqueChars), out var error)) + { + return error; + } + + return base.PasswordRequiresUniqueChars(uniqueChars); } /// @@ -166,7 +241,12 @@ public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) /// An indicating a password entered does not contain an upper case letter. public override IdentityError PasswordRequiresUpper() { - return CreateNamedError(nameof(PasswordRequiresUpper)); + if (TryCreateLocalizedError(nameof(PasswordRequiresUpper), out var error)) + { + return error; + } + + return base.PasswordRequiresUpper(); } /// @@ -176,7 +256,12 @@ public override IdentityError PasswordRequiresUpper() /// An indicating a password of the specified does not meet the minimum length requirements. public override IdentityError PasswordTooShort(int length) { - return CreateNamedError(nameof(PasswordTooShort)); + if (TryCreateLocalizedError(nameof(PasswordTooShort), out var error)) + { + return error; + } + + return base.PasswordTooShort(length); } /// @@ -185,7 +270,12 @@ public override IdentityError PasswordTooShort(int length) /// An indicating a recovery code was not redeemed. public override IdentityError RecoveryCodeRedemptionFailed() { - return CreateNamedError(nameof(RecoveryCodeRedemptionFailed)); + if (TryCreateLocalizedError(nameof(RecoveryCodeRedemptionFailed), out var error)) + { + return error; + } + + return base.RecoveryCodeRedemptionFailed(); } /// @@ -194,7 +284,12 @@ public override IdentityError RecoveryCodeRedemptionFailed() /// An indicating a user already has a password. public override IdentityError UserAlreadyHasPassword() { - return CreateNamedError(nameof(UserAlreadyHasPassword)); + if (TryCreateLocalizedError(nameof(UserAlreadyHasPassword), out var error)) + { + return error; + } + + return base.UserAlreadyHasPassword(); } /// @@ -204,7 +299,12 @@ public override IdentityError UserAlreadyHasPassword() /// An indicating a user is already in the specified . public override IdentityError UserAlreadyInRole(string role) { - return CreateNamedError(nameof(UserAlreadyInRole)); + if (TryCreateLocalizedError(nameof(UserAlreadyInRole), out var error)) + { + return error; + } + + return base.UserAlreadyInRole(role); } /// @@ -213,7 +313,12 @@ public override IdentityError UserAlreadyInRole(string role) /// An indicating user lockout is not enabled. public override IdentityError UserLockoutNotEnabled() { - return CreateNamedError(nameof(UserLockoutNotEnabled)); + if (TryCreateLocalizedError(nameof(UserLockoutNotEnabled), out var error)) + { + return error; + } + + return base.UserLockoutNotEnabled(); } /// @@ -223,7 +328,12 @@ public override IdentityError UserLockoutNotEnabled() /// An indicating a user is not in the specified . public override IdentityError UserNotInRole(string role) { - return CreateNamedError(nameof(UserNotInRole)); + if (TryCreateLocalizedError(nameof(UserNotInRole), out var error)) + { + return error; + } + + return base.UserNotInRole(role); } /// @@ -232,13 +342,21 @@ public override IdentityError UserNotInRole(string role) /// /// /// An that is used in another method return with specific indication for what this error was created - private IdentityError CreateNamedError(string name) + private bool TryCreateLocalizedError(in string name, out IdentityError error) { - return new IdentityError + LocalizedString description = _stringLocalizer.GetString(name); + if (description.ResourceNotFound) + { + error = new IdentityError(); + return false; + } + + error = new IdentityError { Code = name, - Description = _stringLocalizer.GetString(name) + Description = description }; + return true; } } } diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs new file mode 100644 index 000000000..2b03f51ab --- /dev/null +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs @@ -0,0 +1,163 @@ +using Skoruba.IdentityServer4.Admin.Helpers.Identity; +using System.Collections; +using System.Collections.Generic; + +namespace Skoruba.IdentityServer4.Admin.UnitTests.Helpers +{ + class IdentityErrorDescriberFallbackTestData : IEnumerable + { + public IEnumerator GetEnumerator() + { + #region Parameterless methods + + yield return new object[] + { + nameof(IdentityErrorMessages.ConcurrencyFailure), + nameof(IdentityErrorMessages.ConcurrencyFailure), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DefaultError), + nameof(IdentityErrorMessages.DefaultError), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + nameof(IdentityErrorMessages.PasswordRequiresNonAlphanumeric), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.LoginAlreadyAssociated), + nameof(IdentityErrorMessages.LoginAlreadyAssociated), + }; + + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidToken), + nameof(IdentityErrorMessages.InvalidToken), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordMismatch), + nameof(IdentityErrorMessages.PasswordMismatch), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresDigit), + nameof(IdentityErrorMessages.PasswordRequiresDigit), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresLower), + nameof(IdentityErrorMessages.PasswordRequiresLower), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.RecoveryCodeRedemptionFailed), + nameof(IdentityErrorMessages.RecoveryCodeRedemptionFailed), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserAlreadyHasPassword), + nameof(IdentityErrorMessages.UserAlreadyHasPassword), + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserLockoutNotEnabled), + nameof(IdentityErrorMessages.UserLockoutNotEnabled), + }; + + + #endregion + + #region Methods with parameters + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidEmail), + nameof(IdentityErrorMessages.InvalidEmail), + "TestUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateUserName), + nameof(IdentityErrorMessages.DuplicateUserName), + "TestDuplicatedUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateRoleName), + nameof(IdentityErrorMessages.DuplicateRoleName), + "TestRoleName" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidRoleName), + nameof(IdentityErrorMessages.InvalidRoleName), + "InvalidRoleNameTest" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordTooShort), + nameof(IdentityErrorMessages.PasswordTooShort), + 4 + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserAlreadyInRole), + nameof(IdentityErrorMessages.UserAlreadyInRole), + "TestRole" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.UserNotInRole), + nameof(IdentityErrorMessages.UserNotInRole), + "TestRole" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.InvalidUserName), + nameof(IdentityErrorMessages.InvalidUserName), + "TestUsername" + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresUniqueChars), + nameof(IdentityErrorMessages.PasswordRequiresUniqueChars), + 5 + }; + + yield return new object[] + { + nameof(IdentityErrorMessages.DuplicateEmail), + nameof(IdentityErrorMessages.DuplicateEmail), + "testduplicateemail@email.com" + }; + + #endregion + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs index 84689ae52..2d428df16 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Localization; using Moq; using Skoruba.IdentityServer4.Admin.Helpers.Identity; +using System.Linq; using Xunit; namespace Skoruba.IdentityServer4.Admin.UnitTests.Helpers @@ -32,5 +33,37 @@ public void TranslationTests(string key, string methodName, string translated, p Assert.Equal(translated, error.Description); Assert.Equal(key, error.Code); } + + [Theory] + [ClassData(typeof(IdentityErrorDescriberFallbackTestData))] + public void AspNetIdentity_Base_Translation_Fallback_Test(string key, string methodName, params object[] args) + { + + // Arrange + var localizer = new Mock>(); + + // GetString extension method uses indexer underneath + localizer.Setup(x => x[key]) + .Returns(new LocalizedString(key, string.Empty, resourceNotFound: true)); + + var describer = new IdentityErrorMessages(localizer.Object); + + // Act + var methodInfo = typeof(IdentityErrorMessages).GetMethod(methodName); // get method name dynamically + var error = methodInfo.Invoke(describer, args) as IdentityError; // invoke method on our instance + + // Assert + Assert.IsType(error); + + Assert.Equal(key, error.Code); + + // ASP.NET Core Identity uses arguments passed to methods to format error strings + // So it's safe to assume that Description string contains argument as string representation + // WARNING: Possible flaky test if ASP.NET Core Identity team makes some breaking changes + foreach (var argument in args) + { + Assert.Contains(argument.ToString(), error.Description); + } + } } } From 55e29e413a2e79bb367250c30df0dcec630125cb Mon Sep 17 00:00:00 2001 From: duki994 Date: Tue, 3 Dec 2019 10:32:36 +0100 Subject: [PATCH 270/338] XML Docs cleanup in EdentityErrorMessages.cs --- .../Helpers/Identity/IdentityErrorMessages.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs index f002b5903..7121bd6f5 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs @@ -337,11 +337,11 @@ public override IdentityError UserNotInRole(string role) } /// - /// Generates with named as + /// Tries to generate with named as /// And error description which uses as lookup key for /// - /// - /// An that is used in another method return with specific indication for what this error was created + /// Key used as lookup key for + /// representing that localized error was created successfully private bool TryCreateLocalizedError(in string name, out IdentityError error) { LocalizedString description = _stringLocalizer.GetString(name); From 2cb2b0e77dd32459646098bb5963b0b48f9c4921 Mon Sep 17 00:00:00 2001 From: duki994 Date: Wed, 4 Dec 2019 08:29:49 +0100 Subject: [PATCH 271/338] Add missing test data for PasswordRequiresUpper IdentityError message. --- .../Helpers/IdentityErrorDescriberFallbackTestData.cs | 6 ++++++ .../Helpers/IdentityErrorDescriberTestData.cs | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs index 2b03f51ab..502d5b19e 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberFallbackTestData.cs @@ -117,6 +117,12 @@ public IEnumerator GetEnumerator() 4 }; + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresUpper), + nameof(IdentityErrorMessages.PasswordRequiresUpper) + }; + yield return new object[] { nameof(IdentityErrorMessages.UserAlreadyInRole), diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs index 633271830..75074ef47 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTestData.cs @@ -133,6 +133,13 @@ public IEnumerator GetEnumerator() 4 }; + yield return new object[] + { + nameof(IdentityErrorMessages.PasswordRequiresUpper), + nameof(IdentityErrorMessages.PasswordRequiresUpper), + "PasswordRequiresUpperTranslated", + }; + yield return new object[] { nameof(IdentityErrorMessages.UserAlreadyInRole), From 9941717081b8a1a3b9d88af2e4c06f1db040d719 Mon Sep 17 00:00:00 2001 From: Dusan K Date: Sat, 7 Dec 2019 12:00:29 +0100 Subject: [PATCH 272/338] Fix tests to test for correct functionality --- .../Helpers/IdentityErrorDescriberTests.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs index 2d428df16..482a8c201 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs @@ -30,8 +30,15 @@ public void TranslationTests(string key, string methodName, string translated, p // Assert Assert.IsType(error); - Assert.Equal(translated, error.Description); Assert.Equal(key, error.Code); + + // ASP.NET Core Identity uses arguments passed to methods to format error strings + // So it's safe to assume that Description string contains argument as string representation + // WARNING: Possible flaky test if ASP.NET Core Identity team makes some breaking changes + foreach (var argument in args) + { + Assert.Contains(argument.ToString(), error.Description); + } } [Theory] From cff7d323229f001c97724a14b3eb5904ab7609b6 Mon Sep 17 00:00:00 2001 From: Dusan K Date: Sat, 7 Dec 2019 12:30:28 +0100 Subject: [PATCH 273/338] IdentityError messages created from IdentityErrorDescriber methods with paramteres should contain those parameters in error description. Fix localized IdentityErrorMessages class. Make tests correct. --- .../Helpers/Identity/IdentityErrorMessages.cs | 24 +++++++++---------- .../Helpers/IdentityErrorDescriberTests.cs | 13 +++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs index 7121bd6f5..84c219cca 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/Identity/IdentityErrorMessages.cs @@ -53,7 +53,7 @@ public override IdentityError DefaultError() /// An indicating the specified is already associated with an account. public override IdentityError DuplicateEmail(string email) { - if (TryCreateLocalizedError(nameof(DuplicateEmail), out var error)) + if (TryCreateLocalizedError(nameof(DuplicateEmail), out var error, email)) { return error; } @@ -68,7 +68,7 @@ public override IdentityError DuplicateEmail(string email) /// An indicating the specific role name already exists. public override IdentityError DuplicateRoleName(string role) { - if (TryCreateLocalizedError(nameof(DuplicateRoleName), out var error)) + if (TryCreateLocalizedError(nameof(DuplicateRoleName), out var error, role)) { return error; } @@ -83,7 +83,7 @@ public override IdentityError DuplicateRoleName(string role) /// An indicating the specified already exists. public override IdentityError DuplicateUserName(string userName) { - if (TryCreateLocalizedError(nameof(DuplicateUserName), out var error)) + if (TryCreateLocalizedError(nameof(DuplicateUserName), out var error, userName)) { return error; } @@ -98,7 +98,7 @@ public override IdentityError DuplicateUserName(string userName) /// An indicating the specified is invalid. public override IdentityError InvalidEmail(string email) { - if (TryCreateLocalizedError(nameof(InvalidEmail), out var error)) + if (TryCreateLocalizedError(nameof(InvalidEmail), out var error, email)) { return error; } @@ -113,7 +113,7 @@ public override IdentityError InvalidEmail(string email) /// An indicating the specific role name is invalid. public override IdentityError InvalidRoleName(string role) { - if (TryCreateLocalizedError(nameof(InvalidRoleName), out var error)) + if (TryCreateLocalizedError(nameof(InvalidRoleName), out var error, role)) { return error; } @@ -142,7 +142,7 @@ public override IdentityError InvalidToken() /// An indicating the specified user is invalid. public override IdentityError InvalidUserName(string userName) { - if (TryCreateLocalizedError(nameof(InvalidUserName), out var error)) + if (TryCreateLocalizedError(nameof(InvalidUserName), out var error, userName)) { return error; } @@ -227,7 +227,7 @@ public override IdentityError PasswordRequiresNonAlphanumeric() /// An indicating a password does not meet the minimum number of unique chars. public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) { - if (TryCreateLocalizedError(nameof(PasswordRequiresUniqueChars), out var error)) + if (TryCreateLocalizedError(nameof(PasswordRequiresUniqueChars), out var error, uniqueChars)) { return error; } @@ -256,7 +256,7 @@ public override IdentityError PasswordRequiresUpper() /// An indicating a password of the specified does not meet the minimum length requirements. public override IdentityError PasswordTooShort(int length) { - if (TryCreateLocalizedError(nameof(PasswordTooShort), out var error)) + if (TryCreateLocalizedError(nameof(PasswordTooShort), out var error, length)) { return error; } @@ -299,7 +299,7 @@ public override IdentityError UserAlreadyHasPassword() /// An indicating a user is already in the specified . public override IdentityError UserAlreadyInRole(string role) { - if (TryCreateLocalizedError(nameof(UserAlreadyInRole), out var error)) + if (TryCreateLocalizedError(nameof(UserAlreadyInRole), out var error, role)) { return error; } @@ -328,7 +328,7 @@ public override IdentityError UserLockoutNotEnabled() /// An indicating a user is not in the specified . public override IdentityError UserNotInRole(string role) { - if (TryCreateLocalizedError(nameof(UserNotInRole), out var error)) + if (TryCreateLocalizedError(nameof(UserNotInRole), out var error, role)) { return error; } @@ -342,9 +342,9 @@ public override IdentityError UserNotInRole(string role) /// /// Key used as lookup key for /// representing that localized error was created successfully - private bool TryCreateLocalizedError(in string name, out IdentityError error) + private bool TryCreateLocalizedError(in string name, out IdentityError error, params object[] formatArgs) { - LocalizedString description = _stringLocalizer.GetString(name); + LocalizedString description = _stringLocalizer.GetString(name, formatArgs); if (description.ResourceNotFound) { error = new IdentityError(); diff --git a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs index 482a8c201..422d575f4 100644 --- a/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.UnitTests/Helpers/IdentityErrorDescriberTests.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Localization; using Moq; using Skoruba.IdentityServer4.Admin.Helpers.Identity; +using System.ComponentModel.Design; using System.Linq; using Xunit; @@ -17,9 +18,15 @@ public void TranslationTests(string key, string methodName, string translated, p // Arrange var localizer = new Mock>(); + string formatString = translated; + if (args.Any()) + { + formatString = $"{formatString} {{0}}"; + } + // GetString extension method uses indexer underneath - localizer.Setup(x => x[key]) - .Returns(new LocalizedString(key, translated)); + localizer.Setup(x => x[key, args]) + .Returns(new LocalizedString(key, string.Format(formatString, args))); var describer = new IdentityErrorMessages(localizer.Object); @@ -50,7 +57,7 @@ public void AspNetIdentity_Base_Translation_Fallback_Test(string key, string met var localizer = new Mock>(); // GetString extension method uses indexer underneath - localizer.Setup(x => x[key]) + localizer.Setup(x => x[key, args]) .Returns(new LocalizedString(key, string.Empty, resourceNotFound: true)); var describer = new IdentityErrorMessages(localizer.Object); From 142bfebf014d8f16e47b0118ecc8ed5f27abf4ad Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 11 Dec 2019 21:07:45 +0100 Subject: [PATCH 274/338] expose IMvcBuilder --- .../Helpers/StartupHelpers.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 0e44f1d23..31d9528fd 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -40,7 +40,7 @@ public static class StartupHelpers /// Register services for MVC and localization including available languages /// /// - public static void AddMvcWithLocalization(this IServiceCollection services, IConfiguration configuration) + public static IMvcBuilder AddMvcWithLocalization(this IServiceCollection services, IConfiguration configuration) where TUser : IdentityUser where TKey : IEquatable { @@ -48,7 +48,7 @@ public static void AddMvcWithLocalization(this IServiceCollection s services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - services.AddControllersWithViews(o => + var mvcBuilder = services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) @@ -85,6 +85,8 @@ public static void AddMvcWithLocalization(this IServiceCollection s opts.SupportedCultures = supportedCultures; opts.SupportedUICultures = supportedCultures; }); + + return mvcBuilder; } /// From 9f712eadb7d562e22ac768c55fbe9d1ecdb68c5d Mon Sep 17 00:00:00 2001 From: aiscrim Date: Sat, 14 Dec 2019 12:12:08 +0100 Subject: [PATCH 275/338] Deviceflow panel en localization (#439) Added English localization for the Device Flow client panel --- .gitignore | 3 +- .../Client/Section/DeviceFlow.en.resx | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.en.resx diff --git a/.gitignore b/.gitignore index 4255d6756..f8d0df898 100644 --- a/.gitignore +++ b/.gitignore @@ -278,4 +278,5 @@ __pycache__/ !/src/Skoruba.IdentityServer4.Admin/Resources/Views/Log/ !/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Dtos/Log/ !/src/Skoruba.IdentityServer4.Admin/Views/Log/ -!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/ \ No newline at end of file +!/src/Skoruba.IdentityServer4.Admin.BusinessLogic/Events/Log/ +/src/Skoruba.IdentityServer4.Admin.Api/appsettings.Production.json diff --git a/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.en.resx b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.en.resx new file mode 100644 index 000000000..0bb9b8cbc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Resources/Views/Configuration/Client/Section/DeviceFlow.en.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Device Flow + + \ No newline at end of file From 24501f4ad470168dcf370b124c01649f655ffa0a Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 14 Dec 2019 12:23:22 +0100 Subject: [PATCH 276/338] Add basic API tests --- Skoruba.IdentityServer4.Admin.sln | 9 ++- .../Common/AuthenticationConsts.cs | 7 +++ .../Common/HttpClientExtensions.cs | 27 ++++++++ .../Common/WebApplicationFactoryExtensions.cs | 25 ++++++++ ...yServer4.Admin.Api.IntegrationTests.csproj | 23 +++++++ .../Tests/Base/BaseClassFixture.cs | 32 ++++++++++ .../Tests/ClientsControllerTests.cs | 44 +++++++++++++ .../AuditLogging/ApiAuditAction.cs | 0 .../AuditLogging/ApiAuditSubject.cs | 0 .../AuditLoggingConfiguration.cs | 0 .../Configuration/Test/StartupTest.cs | 47 ++++++++++++++ .../Controllers/ApiResourcesController.cs | 2 +- .../Controllers/ClientsController.cs | 2 +- .../IdentityResourcesController.cs | 2 +- .../Controllers/PersistedGrantsController.cs | 2 +- .../Controllers/RolesController.cs | 2 +- .../Controllers/UsersController.cs | 2 +- .../Helpers/StartupHelpers.cs | 40 +++++++++++- .../AuthenticatedTestRequestMiddleware.cs | 33 ++++++++++ .../Startup.cs | 35 +++++++++-- .../Helpers/StartupHelpers.cs | 61 ------------------- .../AuthenticatedTestRequestMiddleware.cs | 1 - 22 files changed, 320 insertions(+), 76 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/AuthenticationConsts.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/HttpClientExtensions.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/WebApplicationFactoryExtensions.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Skoruba.IdentityServer4.Admin.Api.IntegrationTests.csproj create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/Base/BaseClassFixture.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs rename src/Skoruba.IdentityServer4.Admin.Api/{ => Configuration}/AuditLogging/ApiAuditAction.cs (100%) rename src/Skoruba.IdentityServer4.Admin.Api/{ => Configuration}/AuditLogging/ApiAuditSubject.cs (100%) rename src/Skoruba.IdentityServer4.Admin.Api/Configuration/{ => AuditLogging}/AuditLoggingConfiguration.cs (100%) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Configuration/Test/StartupTest.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api/Middlewares/AuthenticatedTestRequestMiddleware.cs diff --git a/Skoruba.IdentityServer4.Admin.sln b/Skoruba.IdentityServer4.Admin.sln index c3efadb7c..7ce492332 100644 --- a/Skoruba.IdentityServer4.Admin.sln +++ b/Skoruba.IdentityServer4.Admin.sln @@ -45,7 +45,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "database", "database", "{2A EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "business", "business", "{EE588CE5-51D0-4E98-A2B3-40EC8E655931}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.EntityFramework.MySql", "src\Skoruba.IdentityServer4.Admin.EntityFramework.MySql\Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj", "{0A8A0DB7-0509-4DFB-9201-74398511B481}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Skoruba.IdentityServer4.Admin.EntityFramework.MySql", "src\Skoruba.IdentityServer4.Admin.EntityFramework.MySql\Skoruba.IdentityServer4.Admin.EntityFramework.MySql.csproj", "{0A8A0DB7-0509-4DFB-9201-74398511B481}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skoruba.IdentityServer4.Admin.Api.IntegrationTests", "src\Skoruba.IdentityServer4.Admin.Api.IntegrationTests\Skoruba.IdentityServer4.Admin.Api.IntegrationTests.csproj", "{4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -121,6 +123,10 @@ Global {0A8A0DB7-0509-4DFB-9201-74398511B481}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A8A0DB7-0509-4DFB-9201-74398511B481}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A8A0DB7-0509-4DFB-9201-74398511B481}.Release|Any CPU.Build.0 = Release|Any CPU + {4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -142,6 +148,7 @@ Global {8230366D-81F9-4FA5-8F5D-8546B527F54F} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} {3ECDC91E-0D3E-4E4D-A34E-D33BB714578D} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} {0A8A0DB7-0509-4DFB-9201-74398511B481} = {2A514C8F-6A53-41CA-AB41-B644E7BC92A7} + {4D123ACB-ACBD-4E40-AE6B-1B0F79D703B0} = {0BC0CC4E-A0F1-45E8-B41A-AE0FA76BF3E5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B3166EDE-037B-4C68-BEBA-5DE9C5E3DB82} diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/AuthenticationConsts.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/AuthenticationConsts.cs new file mode 100644 index 000000000..b65311010 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/AuthenticationConsts.cs @@ -0,0 +1,7 @@ +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common +{ + public class AuthenticationConsts + { + public const string AccountLoginPage = "Account/Login"; + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/HttpClientExtensions.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/HttpClientExtensions.cs new file mode 100644 index 000000000..38776b7f0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/HttpClientExtensions.cs @@ -0,0 +1,27 @@ +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; +using System.Security.Claims; +using IdentityModel; +using Skoruba.IdentityServer4.Admin.Api.Configuration; +using Skoruba.IdentityServer4.Admin.Api.Middlewares; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common +{ + public static class HttpClientExtensions + { + public static void SetAdminClaimsViaHeaders(this HttpClient client, AdminApiConfiguration adminConfiguration) + { + var claims = new[] + { + new Claim(JwtClaimTypes.Subject, Guid.NewGuid().ToString()), + new Claim(JwtClaimTypes.Name, Guid.NewGuid().ToString()), + new Claim(JwtClaimTypes.Role, adminConfiguration.AdministrationRole) + }; + + var token = new JwtSecurityToken(claims: claims); + var t = new JwtSecurityTokenHandler().WriteToken(token); + client.DefaultRequestHeaders.Add(AuthenticatedTestRequestMiddleware.TestAuthorizationHeader, t); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/WebApplicationFactoryExtensions.cs new file mode 100644 index 000000000..26ce9ac40 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -0,0 +1,25 @@ +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common +{ + public static class WebApplicationFactoryExtensions + { + public static HttpClient SetupClient(this WebApplicationFactory fixture) + { + var options = new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false + }; + + return fixture.WithWebHostBuilder( + builder => builder + .UseStartup() + .ConfigureTestServices(services => { }) + ).CreateClient(options); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Skoruba.IdentityServer4.Admin.Api.IntegrationTests.csproj b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Skoruba.IdentityServer4.Admin.Api.IntegrationTests.csproj new file mode 100644 index 000000000..cf2c4ae6d --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Skoruba.IdentityServer4.Admin.Api.IntegrationTests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp3.0 + true + false + Full + + + + + + + + + + + + + + + + diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/Base/BaseClassFixture.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/Base/BaseClassFixture.cs new file mode 100644 index 000000000..2891778dc --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -0,0 +1,32 @@ +using System.Net.Http; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.IdentityServer4.Admin.Api.Configuration; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base +{ + public class BaseClassFixture : IClassFixture> + { + protected readonly WebApplicationFactory Factory; + protected readonly HttpClient Client; + + public BaseClassFixture(WebApplicationFactory factory) + { + Factory = factory; + Client = factory.SetupClient(); + Factory.CreateClient(); + } + + protected virtual void SetupAdminClaimsViaHeaders() + { + using (var scope = Factory.Services.CreateScope()) + { + var configuration = scope.ServiceProvider.GetRequiredService(); + Client.SetAdminClaimsViaHeaders(configuration); + } + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs new file mode 100644 index 000000000..4f5899156 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs @@ -0,0 +1,44 @@ +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests +{ + public class ClientsControllerTests : BaseClassFixture + { + public ClientsControllerTests(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task GetClientsAsAdmin() + { + SetupAdminClaimsViaHeaders(); + + var response = await Client.GetAsync("api/clients"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + + [Fact] + public async Task TryGetClientsWithoutPermissions() + { + Client.DefaultRequestHeaders.Clear(); + + var response = await Client.GetAsync("api/clients"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/ApiAuditAction.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditAction.cs rename to src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/ApiAuditAction.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/ApiAuditSubject.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.Api/AuditLogging/ApiAuditSubject.cs rename to src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/ApiAuditSubject.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/AuditLoggingConfiguration.cs similarity index 100% rename from src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLoggingConfiguration.cs rename to src/Skoruba.IdentityServer4.Admin.Api/Configuration/AuditLogging/AuditLoggingConfiguration.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Test/StartupTest.cs b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Test/StartupTest.cs new file mode 100644 index 000000000..458ace69f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Configuration/Test/StartupTest.cs @@ -0,0 +1,47 @@ +using IdentityServer4.AccessTokenValidation; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.IdentityServer4.Admin.Api.Helpers; +using Skoruba.IdentityServer4.Admin.Api.Middlewares; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; + +namespace Skoruba.IdentityServer4.Admin.Api.Configuration.Test +{ + public class StartupTest : Startup + { + public StartupTest(IWebHostEnvironment env, IConfiguration configuration) : base(env, configuration) + { + } + + public override void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContextsStaging(); + } + + public override void RegisterAuthentication(IServiceCollection services) + { + services.AddIdentity(options => { options.User.RequireUniqueEmail = true; }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) + .AddCookie(IdentityServerAuthenticationDefaults.AuthenticationScheme); + } + + public override void RegisterAuthorization(IServiceCollection services) + { + services.AddAuthorizationPolicies(); + } + + public override void UseAuthentication(IApplicationBuilder app) + { + app.UseAuthentication(); + app.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs index 926135c7b..3cea3bc3c 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ApiResourcesController.cs @@ -16,7 +16,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json", "application/problem+json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class ApiResourcesController : ControllerBase { private readonly IApiResourceService _apiResourceService; diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs index e13a32eba..fd5db733b 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/ClientsController.cs @@ -17,7 +17,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json", "application/problem+json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class ClientsController : ControllerBase { private readonly IClientService _clientService; diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs index 6b4c9c292..b9fb3fdc5 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/IdentityResourcesController.cs @@ -16,7 +16,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json", "application/problem+json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class IdentityResourcesController : ControllerBase { private readonly IIdentityResourceService _identityResourceService; diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs index ef363cdbf..bb8e1cb2f 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs @@ -15,7 +15,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class PersistedGrantsController : ControllerBase { private readonly IPersistedGrantAspNetIdentityService _persistedGrantsService; diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs index 49dd6529a..947b9a094 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/RolesController.cs @@ -20,7 +20,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json", "application/problem+json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class RolesController : ControllerBase diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs index 52a1c4073..ce39c4b03 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/UsersController.cs @@ -22,7 +22,7 @@ namespace Skoruba.IdentityServer4.Admin.Api.Controllers [ApiController] [TypeFilter(typeof(ControllerExceptionFilterAttribute))] [Produces("application/json", "application/problem+json")] - [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthorizationConsts.AdministrationPolicy)] + [Authorize(Policy = AuthorizationConsts.AdministrationPolicy)] public class UsersController : ControllerBase diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs index e89085558..737b724bb 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Helpers/StartupHelpers.cs @@ -1,15 +1,13 @@ using System; -using System.Reflection; using IdentityModel; using IdentityServer4.AccessTokenValidation; -using IdentityServer4.EntityFramework.Storage; +using IdentityServer4.EntityFramework.Options; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Serilog; using Skoruba.AuditLogging.EntityFramework.DbContexts; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.AuditLogging.EntityFramework.Extensions; @@ -165,6 +163,42 @@ public static void AddApiAuthentication(this I .AddDefaultTokenProviders(); } + /// + /// Register in memory DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging + /// For testing purpose only + /// + /// + /// + /// + /// + /// + /// + public static void RegisterDbContextsStaging(this IServiceCollection services) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TLogDbContext : DbContext, IAdminLogDbContext + where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext + { + var persistedGrantsDatabaseName = Guid.NewGuid().ToString(); + var configurationDatabaseName = Guid.NewGuid().ToString(); + var logDatabaseName = Guid.NewGuid().ToString(); + var identityDatabaseName = Guid.NewGuid().ToString(); + var auditLoggingDatabaseName = Guid.NewGuid().ToString(); + + var operationalStoreOptions = new OperationalStoreOptions(); + services.AddSingleton(operationalStoreOptions); + + var storeOptions = new ConfigurationStoreOptions(); + services.AddSingleton(storeOptions); + + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(identityDatabaseName)); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(persistedGrantsDatabaseName)); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(configurationDatabaseName)); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(logDatabaseName)); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(auditLoggingDatabaseName)); + } + public static void AddAuthorizationPolicies(this IServiceCollection services) { var adminApiConfiguration = services.BuildServiceProvider().GetService(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Middlewares/AuthenticatedTestRequestMiddleware.cs b/src/Skoruba.IdentityServer4.Admin.Api/Middlewares/AuthenticatedTestRequestMiddleware.cs new file mode 100644 index 000000000..4f3e3b4f0 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api/Middlewares/AuthenticatedTestRequestMiddleware.cs @@ -0,0 +1,33 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.AccessTokenValidation; +using Microsoft.AspNetCore.Http; + +namespace Skoruba.IdentityServer4.Admin.Api.Middlewares +{ + public class AuthenticatedTestRequestMiddleware + { + private readonly RequestDelegate _next; + public static readonly string TestAuthorizationHeader = "FakeAuthorization"; + public AuthenticatedTestRequestMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + if (context.Request.Headers.Keys.Contains(TestAuthorizationHeader)) + { + var token = context.Request.Headers[TestAuthorizationHeader].Single(); + var jwt = new JwtSecurityToken(token); + var claimsIdentity = new ClaimsIdentity(jwt.Claims, IdentityServerAuthenticationDefaults.AuthenticationScheme, JwtClaimTypes.Name, JwtClaimTypes.Role); + context.User = new ClaimsPrincipal(claimsIdentity); + } + + await _next(context); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs index 7e573e2c0..9d744507a 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Startup.cs @@ -37,12 +37,17 @@ public void ConfigureServices(IServiceCollection services) var adminApiConfiguration = Configuration.GetSection(nameof(AdminApiConfiguration)).Get(); services.AddSingleton(adminApiConfiguration); - services.AddDbContexts(Configuration); + // Add DbContexts + RegisterDbContexts(services); + services.AddScoped(); services.AddScoped(); - services.AddApiAuthentication(adminApiConfiguration); - services.AddAuthorizationPolicies(); + // Add authentication services + RegisterAuthentication(services); + + // Add authorization services + RegisterAuthorization(services); var profileTypes = new HashSet { @@ -96,7 +101,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi app.UseDeveloperExceptionPage(); } - app.UseAuthentication(); + UseAuthentication(app); + app.UseSwagger(); app.UseSwaggerUI(c => { @@ -110,5 +116,26 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AdminApi app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); } + + public virtual void RegisterDbContexts(IServiceCollection services) + { + services.AddDbContexts(Configuration); + } + + public virtual void RegisterAuthentication(IServiceCollection services) + { + var adminApiConfiguration = Configuration.GetSection(nameof(AdminApiConfiguration)).Get(); + services.AddApiAuthentication(adminApiConfiguration); + } + + public virtual void RegisterAuthorization(IServiceCollection services) + { + services.AddAuthorizationPolicies(); + } + + public virtual void UseAuthentication(IApplicationBuilder app) + { + app.UseAuthentication(); + } } } diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 3a2a935f1..c4975093e 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -82,47 +82,6 @@ public static IServiceCollection AddAuditEventLogging - /// Register shared DbContext for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging - /// Configure the connection string in AppSettings.json - use AdminConnection key - /// - /// - /// - /// - public static void RegisterDbContexts(this IServiceCollection services, IConfigurationRoot configuration) - where TContext : DbContext - { - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; - - var operationalStoreOptions = new OperationalStoreOptions(); - services.AddSingleton(operationalStoreOptions); - - var storeOptions = new ConfigurationStoreOptions(); - services.AddSingleton(storeOptions); - - services.AddDbContext(options => options.UseSqlServer(configuration.GetConnectionString(ConfigurationConsts.AdminConnectionStringKey), optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly))); - } - - /// - /// Register shared in Memory DbContext for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging - /// For testing purpose only - /// - /// - /// - public static void RegisterDbContextsStaging(this IServiceCollection services) - where TContext : DbContext - { - var databaseName = Guid.NewGuid().ToString(); - - var operationalStoreOptions = new OperationalStoreOptions(); - services.AddSingleton(operationalStoreOptions); - - var storeOptions = new ConfigurationStoreOptions(); - services.AddSingleton(storeOptions); - - services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(databaseName)); - } - /// /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants, Identity and Logging /// Configure the connection strings in AppSettings.json @@ -272,26 +231,6 @@ public static void ConfigureLocalization(this IApplicationBuilder app) app.UseRequestLocalization(options.Value); } - /// - /// Register shared DbContext - /// - /// - /// - /// - /// - public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfigurationRoot configuration) - where TContext : DbContext - { - if (hostingEnvironment.IsStaging()) - { - services.RegisterDbContextsStaging(); - } - else - { - services.RegisterDbContexts(configuration); - } - } - /// /// Register DbContexts /// diff --git a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs index f238aa1a1..9e9971f09 100644 --- a/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs +++ b/src/Skoruba.IdentityServer4.Admin/Middlewares/AuthenticatedTestRequestMiddleware.cs @@ -10,7 +10,6 @@ public class AuthenticatedTestRequestMiddleware { private readonly RequestDelegate _next; public static readonly string TestAuthorizationHeader = "FakeAuthorization"; - public const string TestAdministrationRole = "SkorubaIdentityAdminAdministrator"; public AuthenticatedTestRequestMiddleware(RequestDelegate next) { _next = next; From 5060a3a91ab9d18173b383ce6226897cbe8e32fe Mon Sep 17 00:00:00 2001 From: janskoruba Date: Sat, 14 Dec 2019 12:40:03 +0100 Subject: [PATCH 277/338] Add basic tests --- .../Tests/ApiResourcesControllerTests.cs | 44 +++++++++++++++++++ .../Tests/ClientsControllerTests.cs | 2 +- .../Tests/IdentityResourcesControllerTests.cs | 44 +++++++++++++++++++ .../Tests/RolesControllerTests.cs | 44 +++++++++++++++++++ .../Tests/UsersControllerTests.cs | 44 +++++++++++++++++++ .../Controllers/PersistedGrantsController.cs | 1 - 6 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ApiResourcesControllerTests.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/IdentityResourcesControllerTests.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/RolesControllerTests.cs create mode 100644 src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/UsersControllerTests.cs diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ApiResourcesControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ApiResourcesControllerTests.cs new file mode 100644 index 000000000..1000e50cd --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ApiResourcesControllerTests.cs @@ -0,0 +1,44 @@ +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests +{ + public class ApiResourcesControllerTests : BaseClassFixture + { + public ApiResourcesControllerTests(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task GetApiResourcesAsAdmin() + { + SetupAdminClaimsViaHeaders(); + + var response = await Client.GetAsync("api/apiresources"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + + [Fact] + public async Task GetApiResourcesWithoutPermissions() + { + Client.DefaultRequestHeaders.Clear(); + + var response = await Client.GetAsync("api/apiresources"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs index 4f5899156..8ba4646ef 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/ClientsControllerTests.cs @@ -28,7 +28,7 @@ public async Task GetClientsAsAdmin() } [Fact] - public async Task TryGetClientsWithoutPermissions() + public async Task GetClientsWithoutPermissions() { Client.DefaultRequestHeaders.Clear(); diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/IdentityResourcesControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/IdentityResourcesControllerTests.cs new file mode 100644 index 000000000..8c14ebcaf --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/IdentityResourcesControllerTests.cs @@ -0,0 +1,44 @@ +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests +{ + public class IdentityResourcesControllerTests : BaseClassFixture + { + public IdentityResourcesControllerTests(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task GetIdentityResourcesAsAdmin() + { + SetupAdminClaimsViaHeaders(); + + var response = await Client.GetAsync("api/identityresources"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + + [Fact] + public async Task GetIdentityResourcesWithoutPermissions() + { + Client.DefaultRequestHeaders.Clear(); + + var response = await Client.GetAsync("api/identityresources"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/RolesControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/RolesControllerTests.cs new file mode 100644 index 000000000..91fb99be1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/RolesControllerTests.cs @@ -0,0 +1,44 @@ +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests +{ + public class RolesControllerTests : BaseClassFixture + { + public RolesControllerTests(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task GetRolesAsAdmin() + { + SetupAdminClaimsViaHeaders(); + + var response = await Client.GetAsync("api/roles"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + + [Fact] + public async Task GetRolesWithoutPermissions() + { + Client.DefaultRequestHeaders.Clear(); + + var response = await Client.GetAsync("api/roles"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/UsersControllerTests.cs b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/UsersControllerTests.cs new file mode 100644 index 000000000..1ad43bd4b --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin.Api.IntegrationTests/Tests/UsersControllerTests.cs @@ -0,0 +1,44 @@ +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.Admin.Api.Configuration.Test; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Common; +using Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests.Base; +using Xunit; + +namespace Skoruba.IdentityServer4.Admin.Api.IntegrationTests.Tests +{ + public class UsersControllerTests : BaseClassFixture + { + public UsersControllerTests(WebApplicationFactory factory) : base(factory) + { + } + + [Fact] + public async Task GetRolesAsAdmin() + { + SetupAdminClaimsViaHeaders(); + + var response = await Client.GetAsync("api/users"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + + [Fact] + public async Task GetRolesWithoutPermissions() + { + Client.DefaultRequestHeaders.Clear(); + + var response = await Client.GetAsync("api/users"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs index bb8e1cb2f..b5a19d028 100644 --- a/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs +++ b/src/Skoruba.IdentityServer4.Admin.Api/Controllers/PersistedGrantsController.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using IdentityServer4.AccessTokenValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Skoruba.IdentityServer4.Admin.Api.Configuration.Constants; From 738f6f2ce8a4b21274e3982ca2fdd102d821e1da Mon Sep 17 00:00:00 2001 From: Marko Matic Date: Wed, 18 Dec 2019 09:29:53 +0100 Subject: [PATCH 278/338] exposed IIdentityServerBuilder back to Startup.cs and ConfigureServices --- .../Helpers/StartupHelpers.cs | 8 ++++---- src/Skoruba.IdentityServer4.STS.Identity/Startup.cs | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index 31d9528fd..f50a5c791 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -263,8 +263,6 @@ public static void AddAuthenticationServices(services, configuration); } /// @@ -311,8 +309,8 @@ private static RegisterConfiguration GetRegistrationConfiguration(IConfiguration /// /// /// - private static void AddIdentityServer( - IServiceCollection services, + public static IIdentityServerBuilder AddIdentityServer( + this IServiceCollection services, IConfiguration configuration) where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext @@ -331,6 +329,8 @@ private static void AddIdentityServer diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 60dd0ef93..92c3a6bd3 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -35,8 +35,11 @@ public void ConfigureServices(IServiceCollection services) // Add email senders which is currently setup for SendGrid and SMTP services.AddEmailSenders(Configuration); - // Add services for authentication, including Identity model, IdentityServer4 and external providers - services.AddAuthenticationServices(Configuration); + // Add services for authentication, including Identity model and external providers + services.AddAuthenticationServices(Configuration); + + // Add services for IdentityServer4 + services.AddIdentityServer(Configuration); // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization From 2e93735ed18b14b1f1dc6653cda44fec0180a26d Mon Sep 17 00:00:00 2001 From: janskoruba Date: Thu, 26 Dec 2019 13:16:02 +0100 Subject: [PATCH 279/338] Remove staging methods from production code and creating StartupTest class for integration tests - AdminUI --- .../Configuration/Test/StartupTest.cs | 40 +++++++ .../Helpers/StartupHelpers.cs | 101 +++++------------- src/Skoruba.IdentityServer4.Admin/Startup.cs | 33 ++++-- .../Common/WebApplicationFactoryExtensions.cs | 5 +- .../Tests/Base/BaseClassFixture.cs | 7 +- .../Tests/ConfigurationControllerTests.cs | 3 +- .../Tests/GrantControllerTests.cs | 3 +- .../Tests/HomeControllerTests.cs | 3 +- .../Tests/IdentityControllerTests.cs | 3 +- .../Tests/LogControllerTests.cs | 32 +++++- 10 files changed, 140 insertions(+), 90 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.Admin/Configuration/Test/StartupTest.cs diff --git a/src/Skoruba.IdentityServer4.Admin/Configuration/Test/StartupTest.cs b/src/Skoruba.IdentityServer4.Admin/Configuration/Test/StartupTest.cs new file mode 100644 index 000000000..34029746f --- /dev/null +++ b/src/Skoruba.IdentityServer4.Admin/Configuration/Test/StartupTest.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; +using Skoruba.IdentityServer4.Admin.Helpers; +using Skoruba.IdentityServer4.Admin.Middlewares; + +namespace Skoruba.IdentityServer4.Admin.Configuration.Test +{ + public class StartupTest : Startup + { + public StartupTest(IWebHostEnvironment env, IConfiguration configuration) : base(env, configuration) + { + } + + public override void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContextsStaging(); + } + + public override void RegisterAuthentication(IServiceCollection services) + { + services.AddAuthenticationServicesStaging(); + } + + public override void RegisterAuthorization(IServiceCollection services) + { + var rootConfiguration = CreateRootConfiguration(); + services.AddAuthorizationPolicies(rootConfiguration); + } + + public override void UseAuthentication(IApplicationBuilder app) + { + app.UseAuthentication(); + app.UseMiddleware(); + } + } +} diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index c4975093e..1009bbdb3 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -1,30 +1,24 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Reflection; using System.Threading.Tasks; using IdentityServer4.EntityFramework.Options; -using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Localization; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; -using Serilog; using Skoruba.AuditLogging.EntityFramework.DbContexts; using Skoruba.AuditLogging.EntityFramework.Entities; using Skoruba.AuditLogging.EntityFramework.Extensions; @@ -34,7 +28,6 @@ using Skoruba.IdentityServer4.Admin.BusinessLogic.Services; using Skoruba.IdentityServer4.Admin.BusinessLogic.Services.Interfaces; using Skoruba.IdentityServer4.Admin.ExceptionHandling; -using Skoruba.IdentityServer4.Admin.Middlewares; using Skoruba.IdentityServer4.Admin.Configuration; using Skoruba.IdentityServer4.Admin.Configuration.ApplicationParts; using Skoruba.IdentityServer4.Admin.Configuration.Constants; @@ -44,7 +37,6 @@ using Skoruba.IdentityServer4.Admin.EntityFramework.Repositories.Interfaces; using Skoruba.IdentityServer4.Admin.Helpers.Localization; using System.Linq; -using Microsoft.Extensions.Hosting; using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Configuration; using Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer.Extensions; @@ -101,7 +93,7 @@ public static void RegisterDbContexts { var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); - + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); @@ -206,21 +198,6 @@ public static void UseSecurityHeaders(this IApplicationBuilder app) }); } - /// - /// Use default authentication middleware and middleware for integration testing - /// - /// - /// - public static void ConfigureAuthenticationServices(this IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseAuthentication(); - - if (env.IsStaging()) - { - app.UseMiddleware(); - } - } - /// /// Add middleware for localization /// @@ -231,34 +208,6 @@ public static void ConfigureLocalization(this IApplicationBuilder app) app.UseRequestLocalization(options.Value); } - /// - /// Register DbContexts - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static void AddDbContexts(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, IConfiguration configuration) - where TIdentityDbContext : DbContext - where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext - where TLogDbContext : DbContext, IAdminLogDbContext - where TAuditLoggingDbContext : DbContext, IAuditLoggingDbContext - { - if (hostingEnvironment.IsStaging()) - { - services.RegisterDbContextsStaging(); - } - else - { - services.RegisterDbContexts(configuration); - } - } - /// /// Add authorization policies /// @@ -357,6 +306,30 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) }); } + public static void AddAuthenticationServicesStaging( + this IServiceCollection services) + where TContext : DbContext where TUserIdentity : class where TUserIdentityRole : class + { + services.AddIdentity(options => + { + options.User.RequireUniqueEmail = true; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddAuthentication(options => + { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; + + options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultForbidScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme; + }) + .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme); + } + /// /// Register services for authentication, including Identity. /// For production mode is used OpenId Connect middleware which is connected to IdentityServer4 instance. @@ -366,9 +339,8 @@ public static void AddMvcExceptionFilters(this IServiceCollection services) /// /// /// - /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IWebHostEnvironment hostingEnvironment, AdminConfiguration adminConfiguration) + public static void AddAuthenticationServices(this IServiceCollection services, AdminConfiguration adminConfiguration) where TContext : DbContext where TUserIdentity : class where TUserIdentityRole : class { services.AddIdentity(options => @@ -378,25 +350,7 @@ public static void AddAuthenticationServices() .AddDefaultTokenProviders(); - //For integration tests use only cookie middleware - if (hostingEnvironment.IsStaging()) - { - services.AddAuthentication(options => - { - options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; - - options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultForbidScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme; - }) - .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, - options => { options.Cookie.Name = adminConfiguration.IdentityAdminCookieName; }); - } - else - { - services.AddAuthentication(options => + services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = AuthenticationConsts.OidcAuthenticationScheme; @@ -446,7 +400,6 @@ public static void AddAuthenticationServices OnRedirectToIdentityProvider(context, adminConfiguration) }; }); - } } private static Task OnMessageReceived(MessageReceivedContext context, AdminConfiguration adminConfiguration) diff --git a/src/Skoruba.IdentityServer4.Admin/Startup.cs b/src/Skoruba.IdentityServer4.Admin/Startup.cs index 2df67c69b..4a7e608ae 100644 --- a/src/Skoruba.IdentityServer4.Admin/Startup.cs +++ b/src/Skoruba.IdentityServer4.Admin/Startup.cs @@ -35,10 +35,10 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(rootConfiguration); // Add DbContexts for Asp.Net Core Identity, Logging and IdentityServer - Configuration store and Operational store - services.AddDbContexts(HostingEnvironment, Configuration); + RegisterDbContexts(services); // Add Asp.Net Core Identity Configuration and OpenIdConnect auth as well - services.AddAuthenticationServices(HostingEnvironment, rootConfiguration.AdminConfiguration); + RegisterAuthentication(services); // Add exception filters in MVC services.AddMvcExceptionFilters(); @@ -66,7 +66,7 @@ public void ConfigureServices(IServiceCollection services) RoleClaimsDto>(Configuration); // Add authorization policies for MVC - services.AddAuthorizationPolicies(rootConfiguration); + RegisterAuthorization(services); // Add audit logging services.AddAuditEventLogging(Configuration); @@ -88,8 +88,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseStaticFiles(); - // Use authentication and for integration tests use custom middleware which is used only in Staging environment - app.ConfigureAuthenticationServices(env); + UseAuthentication(app); // Use Localization app.ConfigureLocalization(); @@ -99,7 +98,29 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } - private IRootConfiguration CreateRootConfiguration() + public virtual void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContexts(Configuration); + } + + public virtual void RegisterAuthentication(IServiceCollection services) + { + var rootConfiguration = CreateRootConfiguration(); + services.AddAuthenticationServices(rootConfiguration.AdminConfiguration); + } + + public virtual void RegisterAuthorization(IServiceCollection services) + { + var rootConfiguration = CreateRootConfiguration(); + services.AddAuthorizationPolicies(rootConfiguration); + } + + public virtual void UseAuthentication(IApplicationBuilder app) + { + app.UseAuthentication(); + } + + protected IRootConfiguration CreateRootConfiguration() { var rootConfiguration = new RootConfiguration(); Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs index e7f21379e..a87627533 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -2,12 +2,13 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; +using Skoruba.IdentityServer4.Admin.Configuration.Test; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Common { public static class WebApplicationFactoryExtensions { - public static HttpClient SetupClient(this WebApplicationFactory fixture) + public static HttpClient SetupClient(this WebApplicationFactory fixture) { var options = new WebApplicationFactoryClientOptions { @@ -16,7 +17,7 @@ public static HttpClient SetupClient(this WebApplicationFactory fixture return fixture.WithWebHostBuilder( builder => builder - .UseEnvironment(Microsoft.Extensions.Hosting.Environments.Staging) + .UseStartup() .ConfigureTestServices(services => { }) ).CreateClient(options); } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs index a01e750f7..d1f2725b2 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -2,17 +2,18 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base { - public class BaseClassFixture : IClassFixture> + public class BaseClassFixture : IClassFixture> { - protected readonly WebApplicationFactory Factory; + protected readonly WebApplicationFactory Factory; protected readonly HttpClient Client; - public BaseClassFixture(WebApplicationFactory factory) + public BaseClassFixture(WebApplicationFactory factory) { Factory = factory; Client = factory.SetupClient(); diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs index 64d57c475..f87d971aa 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/ConfigurationControllerTests.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Skoruba.IdentityServer4.Admin.Configuration.Constants; using Skoruba.IdentityServer4.Admin.Configuration.Interfaces; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; @@ -14,7 +15,7 @@ namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { public class ConfigurationControllerTests : BaseClassFixture { - public ConfigurationControllerTests(WebApplicationFactory factory) + public ConfigurationControllerTests(WebApplicationFactory factory) : base(factory) { } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs index df62e0428..6a0bdcde7 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/GrantControllerTests.cs @@ -3,6 +3,7 @@ using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; @@ -11,7 +12,7 @@ namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { public class GrantControllerTests : BaseClassFixture { - public GrantControllerTests(WebApplicationFactory factory) : base(factory) + public GrantControllerTests(WebApplicationFactory factory) : base(factory) { } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs index 4f71bdaf2..e5c190db1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/HomeControllerTests.cs @@ -3,6 +3,7 @@ using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; @@ -10,7 +11,7 @@ namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { public class HomeControllerTests : BaseClassFixture { - public HomeControllerTests(WebApplicationFactory factory) : + public HomeControllerTests(WebApplicationFactory factory) : base(factory) { } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs index 55b764f41..7a450d0c9 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/IdentityControllerTests.cs @@ -4,6 +4,7 @@ using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Common; using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; @@ -12,7 +13,7 @@ namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { public class IdentityControllerTests : BaseClassFixture { - public IdentityControllerTests(WebApplicationFactory factory) : base(factory) + public IdentityControllerTests(WebApplicationFactory factory) : base(factory) { } diff --git a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs index eacc18e04..2f55c1dd1 100644 --- a/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.Admin.IntegrationTests/Tests/LogControllerTests.cs @@ -3,6 +3,7 @@ using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Skoruba.IdentityServer4.Admin.Configuration.Constants; +using Skoruba.IdentityServer4.Admin.Configuration.Test; using Skoruba.IdentityServer4.Admin.IntegrationTests.Tests.Base; using Xunit; @@ -10,7 +11,7 @@ namespace Skoruba.IdentityServer4.Admin.IntegrationTests.Tests { public class LogControllerTests : BaseClassFixture { - public LogControllerTests(WebApplicationFactory factory) : base(factory) + public LogControllerTests(WebApplicationFactory factory) : base(factory) { } @@ -30,6 +31,22 @@ public async Task ReturnRedirectInErrorsLogWithoutAdminRole() response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); } + [Fact] + public async Task ReturnRedirectInAuditLogWithoutAdminRole() + { + //Remove + Client.DefaultRequestHeaders.Clear(); + + // Act + var response = await Client.GetAsync("/log/auditlog"); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Redirect); + + //The redirect to login + response.Headers.Location.ToString().Should().Contain(AuthenticationConsts.AccountLoginPage); + } + [Fact] public async Task ReturnSuccessInErrorsLogWithAdminRole() { @@ -42,5 +59,18 @@ public async Task ReturnSuccessInErrorsLogWithAdminRole() response.EnsureSuccessStatusCode(); response.StatusCode.Should().Be(HttpStatusCode.OK); } + + [Fact] + public async Task ReturnSuccessInAuditLogWithAdminRole() + { + SetupAdminClaimsViaHeaders(); + + // Act + var response = await Client.GetAsync("/log/auditlog"); + + // Assert + response.EnsureSuccessStatusCode(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + } } } From 2a2fa664175cdc78b46f764ecb1f377b628063ba Mon Sep 17 00:00:00 2001 From: janskoruba Date: Thu, 26 Dec 2019 14:11:00 +0100 Subject: [PATCH 280/338] Move Staging methods from production code to StartTest class. --- .../Configuration/Test/StartupTest.cs | 20 ++++++++++ .../Helpers/StartupHelpers.cs | 39 +----------------- .../Startup.cs | 40 ++++++++++++++----- .../Common/WebApplicationFactoryExtensions.cs | 9 ++--- .../Tests/AccountControllerTests.cs | 33 +++++++-------- .../Tests/Base/BaseClassFixture.cs | 9 +++-- .../Tests/DiagnosticsControllerTests.cs | 7 ++-- .../Tests/GrantsControllerTests.cs | 15 +++---- .../Tests/HomeControllerTests.cs | 7 ++-- .../Tests/IdentityServerTests.cs | 5 ++- .../Tests/ManageControllerTests.cs | 25 ++++++------ 11 files changed, 109 insertions(+), 100 deletions(-) create mode 100644 src/Skoruba.IdentityServer4.STS.Identity/Configuration/Test/StartupTest.cs diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Test/StartupTest.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Test/StartupTest.cs new file mode 100644 index 000000000..627cf2fe1 --- /dev/null +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/Test/StartupTest.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; +using Skoruba.IdentityServer4.STS.Identity.Helpers; + +namespace Skoruba.IdentityServer4.STS.Identity.Configuration.Test +{ + public class StartupTest : Startup + { + public StartupTest(IWebHostEnvironment environment, IConfiguration configuration) : base(environment, configuration) + { + } + + public override void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContextsStaging(); + } + } +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs index f50a5c791..197f75dcd 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs @@ -3,7 +3,6 @@ using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; @@ -13,19 +12,15 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using SendGrid; -using Serilog; using Skoruba.IdentityServer4.STS.Identity.Configuration; using Skoruba.IdentityServer4.STS.Identity.Configuration.ApplicationParts; using Skoruba.IdentityServer4.STS.Identity.Configuration.Constants; using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces; using Skoruba.IdentityServer4.STS.Identity.Helpers.Localization; using Skoruba.IdentityServer4.STS.Identity.Services; -using ILogger = Microsoft.Extensions.Logging.ILogger; using System.Linq; -using Microsoft.Extensions.Hosting; using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; using Skoruba.IdentityServer4.Admin.EntityFramework.MySql.Extensions; using Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL.Extensions; @@ -131,32 +126,6 @@ public static void AddEmailSenders(this IServiceCollection services, IConfigurat } } - /// - /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity - /// Configure the connection strings in AppSettings.json - /// - /// - /// - /// - /// - /// - /// - public static void RegisterDbContexts(this IServiceCollection services, IWebHostEnvironment environment, IConfiguration configuration) - where TIdentityDbContext : DbContext - where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext - { - if (environment.IsStaging()) - { - services.RegisterDbContextsInMemory(); - } - else - { - services.RegisterDbContexts(configuration); - } - } - - /// /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity /// Configure the connection strings in AppSettings.json @@ -201,7 +170,7 @@ public static void RegisterDbContexts /// /// - public static void RegisterDbContextsInMemory( + public static void RegisterDbContextsStaging( this IServiceCollection services) where TIdentityDbContext : DbContext where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext @@ -230,13 +199,9 @@ public static void RegisterDbContextsInMemoryDbContext for Identity /// User Identity class /// User Identity Role class - /// - /// /// /// - public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration) where TIdentityDbContext : DbContext - where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration) where TIdentityDbContext : DbContext where TUserIdentity : class where TUserIdentityRole : class { diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs index 92c3a6bd3..7f8905495 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Startup.cs @@ -3,7 +3,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.DbContexts; using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity; using Skoruba.IdentityServer4.STS.Identity.Configuration; @@ -27,27 +26,24 @@ public Startup(IWebHostEnvironment environment, IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { var rootConfiguration = CreateRootConfiguration(); - services.AddSingleton(rootConfiguration); + services.AddSingleton(rootConfiguration); // Register DbContexts for IdentityServer and Identity - services.RegisterDbContexts(Environment, Configuration); + RegisterDbContexts(services); // Add email senders which is currently setup for SendGrid and SMTP services.AddEmailSenders(Configuration); // Add services for authentication, including Identity model and external providers - services.AddAuthenticationServices(Configuration); - - // Add services for IdentityServer4 - services.AddIdentityServer(Configuration); - + RegisterAuthentication(services); + // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization // If you want to change primary keys or use another db model for Asp.Net Core Identity: services.AddMvcWithLocalization(Configuration); // Add authorization policies for MVC - services.AddAuthorizationPolicies(rootConfiguration); + RegisterAuthorization(services); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) @@ -61,7 +57,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseSecurityHeaders(); app.UseStaticFiles(); - app.UseIdentityServer(); + UseAuthentication(app); app.UseMvcLocalizationServices(); app.UseRouting(); @@ -69,7 +65,29 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseEndpoints(endpoint => { endpoint.MapDefaultControllerRoute(); }); } - private IRootConfiguration CreateRootConfiguration() + public virtual void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContexts(Configuration); + } + + public virtual void RegisterAuthentication(IServiceCollection services) + { + services.AddAuthenticationServices(Configuration); + services.AddIdentityServer(Configuration); + } + + public virtual void RegisterAuthorization(IServiceCollection services) + { + var rootConfiguration = CreateRootConfiguration(); + services.AddAuthorizationPolicies(rootConfiguration); + } + + public virtual void UseAuthentication(IApplicationBuilder app) + { + app.UseIdentityServer(); + } + + protected IRootConfiguration CreateRootConfiguration() { var rootConfiguration = new RootConfiguration(); Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs index 38fa03348..072e80c35 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Common/WebApplicationFactoryExtensions.cs @@ -1,15 +1,14 @@ -using System; -using System.IO; -using System.Net.Http; +using System.Net.Http; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common { public static class WebApplicationFactoryExtensions { - public static HttpClient SetupClient(this WebApplicationFactory fixture) + public static HttpClient SetupClient(this WebApplicationFactory fixture) { var options = new WebApplicationFactoryClientOptions { @@ -18,7 +17,7 @@ public static HttpClient SetupClient(this WebApplicationFactory fixture return fixture.WithWebHostBuilder( builder => builder - .UseEnvironment(Microsoft.Extensions.Hosting.Environments.Staging) + .UseStartup() .ConfigureTestServices(services => { }) ).CreateClient(options); } diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs index 3cbdd2843..81642c30b 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/AccountControllerTests.cs @@ -6,6 +6,7 @@ using FluentAssertions; using HtmlAgilityPack; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; @@ -15,7 +16,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class AccountControllerTests : BaseClassFixture { - public AccountControllerTests(WebApplicationFactory factory) : base(factory) + public AccountControllerTests(WebApplicationFactory factory) : base(factory) { } @@ -23,11 +24,11 @@ public AccountControllerTests(WebApplicationFactory factory) : base(fac public async Task UserIsAbleToRegister() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - var registerResponse = await UserMocks.RegisterNewUserAsync(_client, registerFormData); + var registerResponse = await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Assert registerResponse.StatusCode.Should().Be(HttpStatusCode.Redirect); @@ -40,12 +41,12 @@ public async Task UserIsAbleToRegister() public async Task UserIsNotAbleToRegisterWithSameUserName() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - var registerResponseFirst = await UserMocks.RegisterNewUserAsync(_client, registerFormData); + var registerResponseFirst = await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Assert registerResponseFirst.StatusCode.Should().Be(HttpStatusCode.Redirect); @@ -53,7 +54,7 @@ public async Task UserIsNotAbleToRegisterWithSameUserName() //The redirect to login registerResponseFirst.Headers.Location.ToString().Should().Be("/"); - var registerResponseSecond = await UserMocks.RegisterNewUserAsync(_client, registerFormData); + var registerResponseSecond = await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Assert response registerResponseSecond.StatusCode.Should().Be(HttpStatusCode.OK); @@ -88,18 +89,18 @@ public async Task UserIsNotAbleToRegisterWithSameUserName() public async Task UserIsAbleToLogin() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - await UserMocks.RegisterNewUserAsync(_client, registerFormData); + await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Prepare request to login const string accountLoginAction = "/Account/Login"; - var loginResponse = await _client.GetAsync(accountLoginAction); + var loginResponse = await Client.GetAsync(accountLoginAction); var antiForgeryToken = await loginResponse.ExtractAntiForgeryToken(); var loginDataForm = UserMocks.GenerateLoginData(registerFormData["UserName"], registerFormData["Password"], @@ -107,7 +108,7 @@ public async Task UserIsAbleToLogin() // Login var requestMessage = RequestHelper.CreatePostRequestWithCookies(accountLoginAction, loginDataForm, loginResponse); - var responseMessage = await _client.SendAsync(requestMessage); + var responseMessage = await Client.SendAsync(requestMessage); // Assert status code responseMessage.StatusCode.Should().Be(HttpStatusCode.Redirect); @@ -127,18 +128,18 @@ public async Task UserIsAbleToLogin() public async Task UserIsNotAbleToLoginWithIncorrectPassword() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - await UserMocks.RegisterNewUserAsync(_client, registerFormData); + await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Prepare request to login const string accountLoginAction = "/Account/Login"; - var loginResponse = await _client.GetAsync(accountLoginAction); + var loginResponse = await Client.GetAsync(accountLoginAction); var antiForgeryToken = await loginResponse.ExtractAntiForgeryToken(); // User Guid like fake password @@ -146,7 +147,7 @@ public async Task UserIsNotAbleToLoginWithIncorrectPassword() // Login var requestMessage = RequestHelper.CreatePostRequestWithCookies(accountLoginAction, loginDataForm, loginResponse); - var responseMessage = await _client.SendAsync(requestMessage); + var responseMessage = await Client.SendAsync(requestMessage); // Get html content var contentWithErrorMessage = await responseMessage.Content.ReadAsStringAsync(); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs index 5fdf6c564..5d5244db4 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/Base/BaseClassFixture.cs @@ -1,17 +1,18 @@ using System.Net.Http; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Xunit; namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base { - public class BaseClassFixture : IClassFixture> + public class BaseClassFixture : IClassFixture> { - protected readonly HttpClient _client; + protected readonly HttpClient Client; - public BaseClassFixture(WebApplicationFactory factory) + public BaseClassFixture(WebApplicationFactory factory) { - _client = factory.SetupClient(); + Client = factory.SetupClient(); } } } \ No newline at end of file diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs index 049a2c186..23a2fbd08 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/DiagnosticsControllerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; @@ -9,7 +10,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class DiagnosticsControllerTests : BaseClassFixture { - public DiagnosticsControllerTests(WebApplicationFactory factory) : base(factory) + public DiagnosticsControllerTests(WebApplicationFactory factory) : base(factory) { } @@ -17,10 +18,10 @@ public DiagnosticsControllerTests(WebApplicationFactory factory) : base public async Task UnAuthorizeUserCannotAccessDiagnosticsView() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Act - var response = await _client.GetAsync("/Diagnostics/Index"); + var response = await Client.GetAsync("/Diagnostics/Index"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs index f1a1f457c..471ccb854 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/GrantsControllerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; @@ -11,7 +12,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class GrantsControllerTests : BaseClassFixture { - public GrantsControllerTests(WebApplicationFactory factory) : base(factory) + public GrantsControllerTests(WebApplicationFactory factory) : base(factory) { } @@ -19,17 +20,17 @@ public GrantsControllerTests(WebApplicationFactory factory) : base(fact public async Task AuthorizeUserCanAccessGrantsView() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - var registerResponse = await UserMocks.RegisterNewUserAsync(_client, registerFormData); + var registerResponse = await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Get cookie with user identity for next request - _client.PutCookiesOnRequest(registerResponse); + Client.PutCookiesOnRequest(registerResponse); // Act - var response = await _client.GetAsync("/Grants/Index"); + var response = await Client.GetAsync("/Grants/Index"); // Assert response.EnsureSuccessStatusCode(); @@ -40,10 +41,10 @@ public async Task AuthorizeUserCanAccessGrantsView() public async Task UnAuthorizeUserCannotAccessGrantsView() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Act - var response = await _client.GetAsync("/Grants/Index"); + var response = await Client.GetAsync("/Grants/Index"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs index 281eae6b2..39eaff5d2 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/HomeControllerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; @@ -9,17 +10,17 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class HomeControllerTests : BaseClassFixture { - public HomeControllerTests(WebApplicationFactory factory) : base(factory) + public HomeControllerTests(WebApplicationFactory factory) : base(factory) { } [Fact] public async Task EveryoneHasAccessToHomepage() { - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Act - var response = await _client.GetAsync("/home/index"); + var response = await Client.GetAsync("/home/index"); // Assert response.EnsureSuccessStatusCode(); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs index a7ad22463..84eed27d3 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/IdentityServerTests.cs @@ -2,6 +2,7 @@ using FluentAssertions; using IdentityModel.Client; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; using Xunit; @@ -9,14 +10,14 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class IdentityServerTests : BaseClassFixture { - public IdentityServerTests(WebApplicationFactory factory) : base(factory) + public IdentityServerTests(WebApplicationFactory factory) : base(factory) { } [Fact] public async Task CanShowDiscoveryEndpoint() { - var disco = await _client.GetDiscoveryDocumentAsync("http://localhost"); + var disco = await Client.GetDiscoveryDocumentAsync("http://localhost"); disco.Should().NotBeNull(); disco.IsError.Should().Be(false); diff --git a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs index 7bde548cc..cb9061377 100644 --- a/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs +++ b/tests/Skoruba.IdentityServer4.STS.Identity.IntegrationTests/Tests/ManageControllerTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; +using Skoruba.IdentityServer4.STS.Identity.Configuration.Test; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Common; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Mocks; using Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests.Base; @@ -11,7 +12,7 @@ namespace Skoruba.IdentityServer4.STS.Identity.IntegrationTests.Tests { public class ManageControllerTests : BaseClassFixture { - public ManageControllerTests(WebApplicationFactory factory) : base(factory) + public ManageControllerTests(WebApplicationFactory factory) : base(factory) { } @@ -19,19 +20,19 @@ public ManageControllerTests(WebApplicationFactory factory) : base(fact public async Task AuthorizeUserCanAccessManageViews() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - var registerResponse = await UserMocks.RegisterNewUserAsync(_client,registerFormData); + var registerResponse = await UserMocks.RegisterNewUserAsync(Client,registerFormData); // Get cookie with user identity for next request - _client.PutCookiesOnRequest(registerResponse); + Client.PutCookiesOnRequest(registerResponse); foreach (var route in RoutesConstants.GetManageRoutes()) { // Act - var response = await _client.GetAsync($"/Manage/{route}"); + var response = await Client.GetAsync($"/Manage/{route}"); // Assert response.EnsureSuccessStatusCode(); @@ -43,12 +44,12 @@ public async Task AuthorizeUserCanAccessManageViews() public async Task UnAuthorizeUserCannotAccessManageViews() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); foreach (var route in RoutesConstants.GetManageRoutes()) { // Act - var response = await _client.GetAsync($"/Manage/{route}"); + var response = await Client.GetAsync($"/Manage/{route}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.Redirect); @@ -62,18 +63,18 @@ public async Task UnAuthorizeUserCannotAccessManageViews() public async Task UserIsAbleToUpdateProfile() { // Clear headers - _client.DefaultRequestHeaders.Clear(); + Client.DefaultRequestHeaders.Clear(); // Register new user var registerFormData = UserMocks.GenerateRegisterData(); - var registerResponse = await UserMocks.RegisterNewUserAsync(_client, registerFormData); + var registerResponse = await UserMocks.RegisterNewUserAsync(Client, registerFormData); // Get cookie with user identity for next request - _client.PutCookiesOnRequest(registerResponse); + Client.PutCookiesOnRequest(registerResponse); // Prepare request to update profile const string manageAction = "/Manage/Index"; - var manageResponse = await _client.GetAsync(manageAction); + var manageResponse = await Client.GetAsync(manageAction); var antiForgeryToken = await manageResponse.ExtractAntiForgeryToken(); var manageProfileData = UserMocks.GenerateManageProfileData(registerFormData["Email"], antiForgeryToken); @@ -81,7 +82,7 @@ public async Task UserIsAbleToUpdateProfile() // Update profile var requestWithAntiForgeryCookie = RequestHelper.CreatePostRequestWithCookies(manageAction, manageProfileData, manageResponse); var requestWithIdentityCookie = CookiesHelper.CopyCookiesFromResponse(requestWithAntiForgeryCookie, registerResponse); - var responseMessage = await _client.SendAsync(requestWithIdentityCookie); + var responseMessage = await Client.SendAsync(requestWithIdentityCookie); // Assert responseMessage.StatusCode.Should().Be(HttpStatusCode.Redirect); From 69535395d08e55022a1d84164892ec0a25270c36 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Thu, 26 Dec 2019 15:45:43 +0100 Subject: [PATCH 281/338] Add logo and page title into AdminConfiguration in appsettings.json; Remove samples links; --- .../Configuration/AdminConfiguration.cs | 4 ++ .../Resources/Views/Home/Index.da.resx | 14 +---- .../Resources/Views/Home/Index.en.resx | 14 +---- .../Resources/Views/Home/Index.es.resx | 16 +---- .../Resources/Views/Home/Index.fa.resx | 14 +---- .../Resources/Views/Home/Index.fi.resx | 14 +---- .../Resources/Views/Home/Index.fr.resx | 15 +---- .../Resources/Views/Home/Index.ru.resx | 14 +---- .../Resources/Views/Home/Index.sv.resx | 14 +---- .../Resources/Views/Home/Index.zh.resx | 14 +---- .../Resources/Views/Shared/_Layout.da.resx | 11 +--- .../Resources/Views/Shared/_Layout.en.resx | 11 +--- .../Resources/Views/Shared/_Layout.es.resx | 56 +++++++----------- .../Resources/Views/Shared/_Layout.fa.resx | 15 +---- .../Resources/Views/Shared/_Layout.fi.resx | 11 +--- .../Resources/Views/Shared/_Layout.fr.resx | 11 +--- .../Resources/Views/Shared/_Layout.ru.resx | 11 +--- .../Resources/Views/Shared/_Layout.sv.resx | 11 +--- .../Resources/Views/Shared/_Layout.zh.resx | 11 +--- .../Views/Home/Index.cshtml | 45 ++++++-------- .../Views/Shared/_Layout.cshtml | 14 +++-- .../appsettings.json | 3 + .../wwwroot/favicon.ico | Bin 1150 -> 4286 bytes 23 files changed, 74 insertions(+), 269 deletions(-) diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs index eac3070e5..2adfc873e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs +++ b/src/Skoruba.IdentityServer4.STS.Identity/Configuration/AdminConfiguration.cs @@ -2,6 +2,10 @@ { public class AdminConfiguration { + public string PageTitle { get; set; } + public string HomePageLogoUri { get; set; } + public string FaviconUri { get; set; } + public string IdentityAdminBaseUrl { get; set; } public string AdministrationRole { get; set; } } diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx index 50f00a21c..6d74c2779 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.da.resx @@ -129,15 +129,6 @@ Gemte Grants - - prøve eksempler - - - kildekode lager - - - Her er links til - Log ind @@ -148,9 +139,6 @@ Min profil - Welcome to Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Welcome to {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.en.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.en.resx index af0758f32..4cde1b68c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.en.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.en.resx @@ -129,15 +129,6 @@ Persisted Grants - - ready to use samples - - - source code repository - - - Here are links to the - Login @@ -148,9 +139,6 @@ My profile - Welcome to Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Welcome to {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx index 7fe1515f5..f1939b122 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.es.resx @@ -129,15 +129,6 @@ Concesiones persistidas - - ejemplos listos para usar - - - repositorio con el codigo fuente - - - Aquí hay enlaces al - Inicio de sesión @@ -148,9 +139,6 @@ Mi perfil - Bienvenido a Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Bienvenido a {0} - + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fa.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fa.resx index b56d925ee..29693088c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fa.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fa.resx @@ -129,15 +129,6 @@ واگذاری های اصرارشده - - آماده استفاده از نمونه ها - - - مخزن کد منبع - - - در اینجا پیوندهایی آمده است به - ورود @@ -148,9 +139,6 @@ پروفایل من - خوش آمدید به Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + خوش آمدید به {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx index 43f2dc79f..b48e1990e 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fi.resx @@ -129,15 +129,6 @@ Pysyvät oikeudet - - käyttövalmiita näytteitä - - - lähdekoodien arkisto - - - Tässä on linkit - Kirjaudu sisään @@ -148,9 +139,6 @@ Profiilini - Tervetuloa Skoruba IdentityServer4: een - - - Skoruba IdentityServer4 + Tervetuloa {0}: een \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx index 0ed6c61f1..67ee9eb73 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.fr.resx @@ -130,16 +130,6 @@ Consentements Octrois persistants. Explicit mistake for clarity - - échantillons disponibles - (les/des) échantillons disponibles - - - le dépôt de code source - - - Voici des liens vers - Connexion @@ -150,9 +140,6 @@ Mon profil - Bienvenue sur Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Bienvenue sur {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.ru.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.ru.resx index 5f474465c..d1d67555c 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.ru.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.ru.resx @@ -129,15 +129,6 @@ Постоянные права - - готовые к использованию образцы - - - репозиторий исходного кода - - - Здесь ссылки на - Вход @@ -148,9 +139,6 @@ Мой профиль - Добро пожаловать в Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Добро пожаловать в {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.sv.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.sv.resx index 701282614..724b4dc09 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.sv.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.sv.resx @@ -129,15 +129,6 @@ Medgivanden - - exempel - - - källkod - - - Här är länkarna till - Inloggning @@ -148,9 +139,6 @@ Min profil - Välkommen till Skoruba IdentitytServer4 - - - Skoruba IdentityServer4 + Välkommen till {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.zh.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.zh.resx index 5af5e3478..978978edb 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.zh.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Home/Index.zh.resx @@ -129,15 +129,6 @@ 持久授权 - - 准备好使用样品 - - - 源代码库 - - - 这是链接到 - 登录 @@ -148,9 +139,6 @@ 我的个人资料 - 欢迎来到 Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + 欢迎来到 {0} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx index 357086479..ba808c466 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.da.resx @@ -126,11 +126,8 @@ Mine eksterne logins - - Skoruba IdentityServer4 - - © 2019 + © Grants @@ -144,16 +141,10 @@ Menu - - IdentityServer4 - Indstillinger log ud - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.en.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.en.resx index 3b62d9d42..4b5029896 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.en.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.en.resx @@ -126,11 +126,8 @@ My external logins - - Skoruba IdentityServer4 - - © 2019 + © Grants @@ -144,16 +141,10 @@ Menu - - IdentityServer4 - Settings logout - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx index 9cfc0b9fe..508594ad7 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.es.resx @@ -59,47 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -113,14 +112,10 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Autentificación en dos pasos @@ -131,11 +126,8 @@ Mis inicios de sesión externos - - Skoruba IdentityServer4 - - © 2019 + © Concesiones @@ -149,16 +141,10 @@ Menú - - IdentityServer4 - Configuración Cerrar sesión - - Skoruba IdentityServer4 - - + \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fa.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fa.resx index 108aa9106..46730af34 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fa.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fa.resx @@ -126,34 +126,25 @@ ورودی های خارجی من - - Skoruba IdentityServer4 - - © 2019 + © واگذاری ها - + اطلاعات شخصی من - + پروفایل من فهرست - - IdentityServer4 - تنظیمات خروج - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx index 07782079c..999969912 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fi.resx @@ -126,11 +126,8 @@ Omat ulkoiset kirjautumiset - - Skoruba IdentityServer4 - - © 2019 + © Käyttöoikeudet @@ -144,16 +141,10 @@ valikko - - IdentityServer4 - asetukset Kirjaudu ulos - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx index 41c9d943b..40d841ddb 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.fr.resx @@ -126,11 +126,8 @@ Mes identifiants externes - - Skoruba IdentityServer4 - - © 2019 + © Consentements @@ -145,16 +142,10 @@ Menu - - IdentityServer4 - Réglages Déconnexion - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.ru.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.ru.resx index b37a647d2..87cc9886d 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.ru.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.ru.resx @@ -126,11 +126,8 @@ Моя внешняя учетная запись - - Skoruba IdentityServer4 - - © 2019 + © Права @@ -144,16 +141,10 @@ Меню - - IdentityServer4 - Настройки выход - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.sv.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.sv.resx index 00728d189..7525c993a 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.sv.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.sv.resx @@ -126,11 +126,8 @@ Externa inlogg - - Skoruba IdentityServer4 - - © 2019 + © Medgivanden @@ -144,16 +141,10 @@ Many - - IdentityServer4 - Inställningar Logga ut - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.zh.resx b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.zh.resx index 25a30e87a..f1b600922 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.zh.resx +++ b/src/Skoruba.IdentityServer4.STS.Identity/Resources/Views/Shared/_Layout.zh.resx @@ -126,11 +126,8 @@ 我的外部登录 - - Skoruba IdentityServer4 - - © 2019 + © 授权 @@ -144,16 +141,10 @@ 菜单 - - IdentityServer4 - 设置 注销 - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Home/Index.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Home/Index.cshtml index 661893a4f..fcdc52d22 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Home/Index.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Home/Index.cshtml @@ -1,9 +1,11 @@ @using IdentityServer4.Extensions @using Microsoft.AspNetCore.Mvc.Localization +@using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces @inject IViewLocalizer Localizer +@inject IRootConfiguration RootConfiguration
    -

    Logo
    @Localizer["Title"]

    -

    @Localizer["SubTitle"]

    +

    Logo
    @RootConfiguration.AdminConfiguration.PageTitle

    +

    @Localizer["SubTitle", RootConfiguration.AdminConfiguration.PageTitle]

    @@ -21,23 +23,23 @@
    } - + @if (User.IsAuthenticated()) { -
    -
    -

    @Localizer["Grants"]

    -
    -
    -

    - -

    - @Localizer["Grants"] +
    +
    +

    @Localizer["Grants"]

    +
    +
    -
    } - -
    + +

    @Localizer["Discovery"]

    @@ -104,15 +106,4 @@
    -} - - -
    -
    -

    - @Localizer["LinkTitle"] - @Localizer["LinkSource"], - @Localizer["LinkSamples"]. -

    -
    -
    +} \ No newline at end of file diff --git a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml index 3ed839abc..85cb4edef 100644 --- a/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml +++ b/src/Skoruba.IdentityServer4.STS.Identity/Views/Shared/_Layout.cshtml @@ -2,6 +2,8 @@ @using Microsoft.AspNetCore.Identity @using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.EntityFramework.Shared.Entities.Identity +@using Skoruba.IdentityServer4.STS.Identity.Configuration.Interfaces +@inject IRootConfiguration RootConfiguration @inject IViewLocalizer Localizer @{ string name = null; @@ -21,9 +23,9 @@ - @Localizer["PageTitle"] - - + @RootConfiguration.AdminConfiguration.PageTitle + + @@ -40,7 +42,7 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResourcePropertyDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResourcePropertyDelete.cshtml index 86750d8b8..60eb9ba2d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResourcePropertyDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResourcePropertyDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiResourcePropertiesDto @inject IViewLocalizer Localizer @@ -63,4 +63,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResources.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResources.cshtml index dc5ab465a..94a279a4e 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResources.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiResources.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiResourcesDto @inject IViewLocalizer Localizer @@ -55,4 +55,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "ApiResources", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = @ViewBag.Search })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopeDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopeDelete.cshtml index bfd934a76..6c7815908 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopeDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopeDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiScopesDto @inject IViewLocalizer Localizer @@ -58,4 +58,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopes.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopes.cshtml index 64700a226..c173556c5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopes.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiScopes.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiScopesDto @inject IViewLocalizer Localizer @@ -182,4 +182,9 @@ FormMvc.disableEnter($('#api-scope-form')); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecretDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecretDelete.cshtml index 5f5765c2a..780f5874e 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecretDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecretDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiSecretsDto @inject IViewLocalizer Localizer @@ -66,4 +66,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecrets.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecrets.cshtml index 4c3a89fa2..3b3065cf4 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecrets.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ApiSecrets.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ApiSecretsDto @inject IViewLocalizer Localizer @@ -178,4 +178,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client.cshtml index 3ff821a6b..e63fc4361 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -53,4 +53,9 @@ }); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/ActionButtons.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/ActionButtons.cshtml index 39d9f3fe9..0683dbf2b 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/ActionButtons.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/ActionButtons.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -12,4 +12,9 @@ @Localizer["ButtonDelete"] } - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Authentication.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Authentication.cshtml index f89b3d113..25d05e9f8 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Authentication.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Authentication.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -109,4 +109,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Basics.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Basics.cshtml index 26c95bf45..6ab4fd3f8 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Basics.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Basics.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -179,4 +179,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Consent.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Consent.cshtml index ef820fac9..f5dc5cd14 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Consent.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Consent.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -49,4 +49,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/DeviceFlow.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/DeviceFlow.cshtml index 03b598b0d..c97bf088c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/DeviceFlow.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/DeviceFlow.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -25,4 +25,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Label.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Label.cshtml index 9ea53bbae..d156df443 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Label.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Label.cshtml @@ -1,6 +1,11 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer @Localizer[$"{Model}_Label"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Name.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Name.cshtml index c2bfdb82f..00d2735f6 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Name.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Name.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Enums @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -101,4 +101,9 @@ } - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Token.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Token.cshtml index 036ef65a0..f363b5c5b 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Token.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Section/Token.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -182,4 +182,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Settings.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Settings.cshtml index 0e1fa0011..023ba41bb 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Settings.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Client/Settings.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -45,3 +45,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaimDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaimDelete.cshtml index 1d80af69d..824e43b01 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaimDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaimDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientClaimsDto @inject IViewLocalizer Localizer @@ -65,4 +65,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaims.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaims.cshtml index 30c92588c..8b43812be 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaims.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClaims.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientClaimsDto @inject IViewLocalizer Localizer @@ -133,4 +133,9 @@ FormMvc.allowValidateHiddenField($('#client-claims-form')); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClone.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClone.cshtml index 393f081b4..b08537316 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClone.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientClone.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientCloneDto @inject IViewLocalizer Localizer @@ -171,3 +171,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientDelete.cshtml index 87702680e..025921044 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientDto @inject IViewLocalizer Localizer @@ -60,4 +60,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientProperties.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientProperties.cshtml index 2bd4dd075..ed1aee063 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientProperties.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientProperties.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientPropertiesDto @inject IViewLocalizer Localizer @@ -108,4 +108,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientPropertyDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientPropertyDelete.cshtml index 532cd0d7a..2536c774f 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientPropertyDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientPropertyDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientPropertiesDto @inject IViewLocalizer Localizer @@ -63,4 +63,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecretDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecretDelete.cshtml index f8e17a744..e56531887 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecretDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecretDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientSecretsDto @inject IViewLocalizer Localizer @@ -65,4 +65,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecrets.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecrets.cshtml index 9ef2e7731..63940d291 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecrets.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/ClientSecrets.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientSecretsDto @inject IViewLocalizer Localizer @@ -174,4 +174,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Clients.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Clients.cshtml index 25db5513e..652a2a2bf 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Clients.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/Clients.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.ClientsDto @inject IViewLocalizer Localizer @@ -55,4 +55,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "Clients", PageSize = Model.PageSize, TotalCount = Model.TotalCount, Search = ViewBag.Search, EnableSearch = true })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource.cshtml index 7c91ca3ac..4746cfd8e 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.IdentityResourceDto @inject IViewLocalizer Localizer @@ -169,4 +169,9 @@ FormMvc.disableEnter($('#identity-resource-form')); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource/Section/Label.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource/Section/Label.cshtml index c5be5ac23..0741bae6a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource/Section/Label.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResource/Section/Label.cshtml @@ -1,7 +1,12 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer @Localizer[$"{Model}_Label"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceDelete.cshtml index 904d6f8aa..f879d1ef3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.IdentityResourceDto @inject IViewLocalizer Localizer @@ -51,4 +51,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceProperties.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceProperties.cshtml index 74d87b13f..499039a8a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceProperties.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourceProperties.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.IdentityResourcePropertiesDto @inject IViewLocalizer Localizer @@ -108,4 +108,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourcePropertyDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourcePropertyDelete.cshtml index 5237be7d9..eca00b448 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourcePropertyDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResourcePropertyDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.IdentityResourcePropertiesDto @inject IViewLocalizer Localizer @@ -63,4 +63,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResources.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResources.cshtml index 8900188b2..b74a58aed 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResources.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Configuration/IdentityResources.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Dtos.Configuration.IdentityResourcesDto @inject IViewLocalizer Localizer @@ -54,4 +54,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "IdentityResources", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrant.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrant.cshtml index 276b257db..439082679 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrant.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrant.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant @using SkorubaIdentityServer4Admin.Admin.Helpers @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @@ -87,4 +87,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrantDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrantDelete.cshtml index 146f7fc33..25d0905fa 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrantDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrantDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant @model PersistedGrantDto @inject IViewLocalizer Localizer @@ -59,4 +59,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrants.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrants.cshtml index 210f21f73..58f732352 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrants.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Grant/PersistedGrants.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Grant @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model PersistedGrantsDto @@ -50,4 +50,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager() { Action = "PersistedGrants", PageSize = Model.PageSize, TotalCount = Model.TotalCount })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Error.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Error.cshtml index 10d393f60..587a9d078 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Error.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Error.cshtml @@ -1,5 +1,10 @@ -@{ +@{ ViewData["Title"] = "Error"; } -@await Html.PartialAsync("Common/ErrorPage") \ No newline at end of file +@await Html.PartialAsync("Common/ErrorPage") + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Index.cshtml index 7922e020e..2ecc29752 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Home/Index.cshtml @@ -1,13 +1,15 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@using SkorubaIdentityServer4Admin.Admin.Configuration.Interfaces +@inject IRootConfiguration RootConfiguration @inject IViewLocalizer Localizer @{ - ViewBag.Title = Localizer["PageTitle"]; + ViewBag.Title = RootConfiguration.AdminConfiguration.PageTitle; Layout = "_Layout"; }
    -

    @Localizer["PageTitle"]

    +

    @RootConfiguration.AdminConfiguration.PageTitle

    @Localizer["PageSubTitle"]

    @@ -87,4 +89,9 @@ @Localizer["ButtonManage"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role.cshtml index 19c063458..79a7e71c5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IRoleDto @inject IViewLocalizer Localizer @@ -33,7 +33,7 @@ @@ -66,4 +66,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role/Section/Label.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role/Section/Label.cshtml index c5be5ac23..0741bae6a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role/Section/Label.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Role/Section/Label.cshtml @@ -1,7 +1,12 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer @Localizer[$"{Model}_Label"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaims.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaims.cshtml index 70d6d2265..2be0006c3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaims.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaims.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IRoleClaimsDto @inject IViewLocalizer Localizer @@ -130,4 +130,9 @@ FormMvc.allowValidateHiddenField($('#role-claims-form')); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaimsDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaimsDelete.cshtml index 5e3b76666..e027748aa 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaimsDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleClaimsDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IRoleClaimsDto @inject IViewLocalizer Localizer @@ -65,4 +65,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleDelete.cshtml index 64473cebe..5dd754090 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IRoleDto @inject IViewLocalizer Localizer @@ -52,4 +52,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleUsers.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleUsers.cshtml index 51199f08c..e45cfe086 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleUsers.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/RoleUsers.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUsersDto @inject IViewLocalizer Localizer @@ -82,4 +82,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "RoleUsers", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Roles.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Roles.cshtml index 382f04e49..0fb486aa4 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Roles.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Roles.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IRolesDto @inject IViewLocalizer Localizer @@ -35,7 +35,7 @@
    @Localizer["TableButtonEdit"] - @Localizer["TableButtonUsers"] + @Localizer["TableButtonUsers"] @role.Name @@ -53,4 +53,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "Roles", PageSize = Model.PageSize, TotalCount = Model.TotalCount })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/User/Section/Label.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/User/Section/Label.cshtml index c5be5ac23..0741bae6a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/User/Section/Label.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/User/Section/Label.cshtml @@ -1,7 +1,12 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer @Localizer[$"{Model}_Label"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserChangePassword.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserChangePassword.cshtml index 7d45e3349..26c4b9572 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserChangePassword.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserChangePassword.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserChangePasswordDto @inject IViewLocalizer Localizer @@ -77,4 +77,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaims.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaims.cshtml index ad0f33168..0373c1cb5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaims.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaims.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserClaimsDto @inject IViewLocalizer Localizer @@ -129,4 +129,9 @@ FormMvc.allowValidateHiddenField($('#user-claims-form')); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaimsDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaimsDelete.cshtml index 74ffd140c..05c4e7f70 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaimsDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserClaimsDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserClaimsDto @inject IViewLocalizer Localizer @@ -65,4 +65,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserDelete.cshtml index 3a1fbda98..c299b1859 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserDto @inject IViewLocalizer Localizer @@ -49,4 +49,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProfile.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProfile.cshtml index 4fb21f778..7952d08e2 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProfile.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProfile.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserDto @inject IViewLocalizer Localizer @@ -34,6 +34,7 @@ @Localizer["ButtonManageUserClaims"] @Localizer["ButtonManageUserRoles"] @Localizer["ButtonManageUserExternalProviders"] + @Localizer["Audit Log"] @Localizer["ButtonChangePassword"] @Localizer["ButtonDeleteUser"] @@ -178,4 +179,9 @@ $('#logoutend-picker').datetimepicker(); }); -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProviders.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProviders.cshtml index a88664fc7..42e9d0c51 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProviders.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProviders.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserProvidersDto @inject IViewLocalizer Localizer @@ -46,4 +46,9 @@
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProvidersDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProvidersDelete.cshtml index 74e27ad02..45fb8b612 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProvidersDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserProvidersDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserProviderDto @inject IViewLocalizer Localizer @@ -77,4 +77,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRoles.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRoles.cshtml index 0202841cc..4d4757485 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRoles.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRoles.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserRolesDto @inject IViewLocalizer Localizer @@ -92,4 +92,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRolesDelete.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRolesDelete.cshtml index d7cca65f8..31873af0e 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRolesDelete.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/UserRolesDelete.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUserRolesDto @inject IViewLocalizer Localizer @@ -58,4 +58,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Users.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Users.cshtml index 6da93f0f0..93d5e54a6 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Users.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Identity/Users.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common @model Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity.Interfaces.IUsersDto @inject IViewLocalizer Localizer @@ -61,4 +61,9 @@
    @await Html.PartialAsync("Common/Pager", new Pager { Action = "Users", PageSize = Model.PageSize, TotalCount = Model.TotalCount, EnableSearch = true, Search = ViewBag.Search })
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/ErrorPage.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/ErrorPage.cshtml index bf7a11926..5454044f5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/ErrorPage.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/ErrorPage.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using Newtonsoft.Json @using SkorubaIdentityServer4Admin.Admin.Helpers @inject IViewLocalizer Localizer @@ -21,4 +21,9 @@ {

    @notification.Message

    } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Notification.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Notification.cshtml index 73fab687c..c1dd33481 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Notification.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Notification.cshtml @@ -1,4 +1,4 @@ -@using Newtonsoft.Json +@using Newtonsoft.Json @using SkorubaIdentityServer4Admin.Admin.Helpers @if (ViewBag.Notifications != null) { @@ -27,4 +27,9 @@ break; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Pager.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Pager.cshtml index 8e2273756..7c6372cd2 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Pager.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Pager.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @using SkorubaIdentityServer4Admin.Admin.Helpers @model Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common.Pager @inject IViewLocalizer Localizer @@ -83,4 +83,9 @@ } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/PagerDynamic.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/PagerDynamic.cshtml new file mode 100644 index 000000000..01e74f553 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/PagerDynamic.cshtml @@ -0,0 +1,49 @@ +@using Microsoft.AspNetCore.Mvc.Localization +@using SkorubaIdentityServer4Admin.Admin.Helpers +@model Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common.Pager +@inject IViewLocalizer Localizer +@{ + var currentPage = PagerHelpers.GetCurrentPage(Context.Request.Query["page"]); + var totalCount = PagerHelpers.GetTotalPages(Model.PageSize, Model.TotalCount); + var minPage = PagerHelpers.GetMinPageToRender(Model.MaxPages, totalCount, currentPage); + var maxPage = PagerHelpers.GetMaxPageToRender(Model.MaxPages, totalCount, currentPage); +} + +@if (currentPage <= maxPage) +{ + +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Search.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Search.cshtml index 53b2a56db..49606e8a2 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Search.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/Search.cshtml @@ -1,4 +1,4 @@ -@model Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common.Search +@model Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common.Search @using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @@ -14,4 +14,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/SelectLanguage.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/SelectLanguage.cshtml index 622672019..a561713f5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/SelectLanguage.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Common/SelectLanguage.cshtml @@ -1,24 +1,31 @@ -@using Microsoft.AspNetCore.Builder +@using Microsoft.AspNetCore.Builder @using Microsoft.AspNetCore.Localization @using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.Extensions.Options @inject IViewLocalizer Localizer @inject IOptions LocOptions @{ - var requestCulture = Context.Features.Get(); - var cultureItems = LocOptions.Value.SupportedUICultures - .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) - .ToList(); - var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; + var requestCulture = Context.Features.Get(); + var cultureItems = LocOptions.Value.SupportedUICultures + .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) + .ToList(); + var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; } +@if (cultureItems.Count > 1) +{ +
    +
    +
    + + +
    +
    +
    +} + + + + -
    -
    -
    - - -
    -
    -
    \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Components/IdentityServerLink/Default.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Components/IdentityServerLink/Default.cshtml index c32f28eca..4b8486ce3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Components/IdentityServerLink/Default.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Components/IdentityServerLink/Default.cshtml @@ -1,5 +1,10 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer -@Localizer["IdentityServer"] \ No newline at end of file +@Localizer["IdentityServer"] + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Error.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Error.cshtml index 10d393f60..587a9d078 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Error.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/Error.cshtml @@ -1,5 +1,10 @@ -@{ +@{ ViewData["Title"] = "Error"; } -@await Html.PartialAsync("Common/ErrorPage") \ No newline at end of file +@await Html.PartialAsync("Common/ErrorPage") + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/_Layout.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/_Layout.cshtml index 7d65748e2..4fb04446a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/_Layout.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/Shared/_Layout.cshtml @@ -1,13 +1,16 @@ -@using IdentityServer4.Extensions +@using IdentityServer4.Extensions @using Microsoft.AspNetCore.Mvc.Localization +@using SkorubaIdentityServer4Admin.Admin.Configuration.Interfaces @inject IViewLocalizer Localizer +@inject IRootConfiguration RootConfiguration - - @ViewData["Title"] - @Localizer["PageTitle"] + + + @ViewData["Title"] - @RootConfiguration.AdminConfiguration.PageTitle @@ -24,7 +27,7 @@ - @Localizer["TitleLogs"] - + + @if (User.Identity.IsAuthenticated) { @@ -76,8 +87,8 @@
    - @Localizer["FooterTitle"] - @Localizer["FooterCopyright"] + @RootConfiguration.AdminConfiguration.PageTitle + @Localizer["FooterCopyright"] @DateTime.Now.Year
    @await Html.PartialAsync("Common/SelectLanguage") @@ -99,4 +110,9 @@ @RenderSection("scripts", required: false) - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewImports.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewImports.cshtml index 29cfb2ddd..6b6ba80ba 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewImports.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewImports.cshtml @@ -1,2 +1,7 @@ -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@addTagHelper *, SkorubaIdentityServer4Admin.Admin \ No newline at end of file +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, SkorubaIdentityServer4Admin.Admin + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewStart.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewStart.cshtml index a5f10045d..bfa0e1d92 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewStart.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Views/_ViewStart.cshtml @@ -1,3 +1,9 @@ -@{ +@{ Layout = "_Layout"; } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/appsettings.json b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/appsettings.json index 5f46e3b94..e8d7c87f3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/appsettings.json +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/appsettings.json @@ -1,53 +1,43 @@ { - "ConnectionStrings": { - "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" - }, - "AdminConfiguration": { - "IdentityAdminBaseUrl": "http://localhost:9000", - "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", - "IdentityServerBaseUrl": "http://localhost:5000", - "ClientId": "skoruba_identity_admin", - "ClientSecret": "skoruba_admin_client_secret", - "OidcResponseType": "code id_token", - "Scopes": [ - "openid", - "profile", - "email", - "roles" - ], - "IdentityAdminApiSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui", - "IdentityAdminApiSwaggerUIRedirectUrl": "http://localhost:5001/swagger/oauth2-redirect.html", - "IdentityAdminApiScope": "skoruba_identity_admin_api" - }, - "Serilog": { - "MinimumLevel": { - "Default": "Error", - "Override": { - "Skoruba": "Information" - } - }, - "WriteTo": [ - { - "Name": "File", - "Args": { - "path": "Log\\skoruba_admin.txt", - "rollingInterval": "Day" - } - }, - { - "Name": "MSSqlServer", - "Args": { - "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", - "tableName": "Log", - "columnOptionsSection": { - "addStandardColumns": [ "LogEvent" ], - "removeStandardColumns": [ "Properties" ] - } - } - } - ] - } + "ConnectionStrings": { + "ConfigurationDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "PersistedGrantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "IdentityDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "AdminAuditLogDbConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true" + }, + "DatabaseProviderConfiguration": { + "ProviderType": "SqlServer" + }, + "AdminConfiguration": { + "PageTitle": "Skoruba IdentityServer4 Admin", + "FaviconUri": "/favicon.ico", + "IdentityAdminRedirectUri": "http://localhost:9000/signin-oidc", + "IdentityServerBaseUrl": "http://localhost:5000", + "IdentityAdminCookieName": "IdentityServerAdmin", + "IdentityAdminCookieExpiresUtcHours": 12, + "RequireHttpsMetadata": false, + "TokenValidationClaimName": "name", + "TokenValidationClaimRole": "role", + "ClientId": "skoruba_identity_admin", + "ClientSecret": "skoruba_admin_client_secret", + "OidcResponseType": "code id_token", + "Scopes": [ + "openid", + "profile", + "email", + "roles" + ], + "AdministrationRole": "SkorubaIdentityAdminAdministrator" + }, + "AuditLoggingConfiguration": { + "Source": "IdentityServer.Admin.Web", + "SubjectIdentifierClaim": "sub", + "SubjectNameClaim": "name", + "IncludeFormVariables": false + }, + "CultureConfiguration": { + "Cultures": [], + "DefaultCulture": null + } } \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/gulpfile.js b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/gulpfile.js index 43fe75177..56614aa00 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/gulpfile.js +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/gulpfile.js @@ -27,13 +27,19 @@ function processScripts() { './node_modules/moment/min/moment.min.js', './node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.js', './node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fa.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fr.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.ru.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.sv.min.js', + './node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.zh-CN.min.js', './Scripts/App/components/Menu.js', './Scripts/App/components/Picker.es5.js', './Scripts/App/components/Theme.js', './Scripts/App/helpers/FormMvcHelpers.js', './Scripts/App/helpers/jsontree.min.js', './Scripts/App/helpers/DateTimeHelpers.js', - './Scripts/App/pages/ErrorsLog.es5.js', + './Scripts/App/pages/ErrorsLog.js', + './Scripts/App/pages/AuditLog.js', './Scripts/App/pages/Secrets.js', './Scripts/App/components/DatePicker.js' ]) diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identitydata.json b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identitydata.json new file mode 100644 index 000000000..00e562874 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identitydata.json @@ -0,0 +1,25 @@ +{ + "IdentityData": { + "Roles": [ + { + "Name": "SkorubaIdentityAdminAdministrator" + } + ], + "Users": [ + { + "Username": "admin", + "Password": "Pa$$word123", + "Email": "admin@skoruba.com", + "Roles": [ + "SkorubaIdentityAdminAdministrator" + ], + "Claims": [ + { + "Type": "name", + "Value": "admin" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identityserverdata.json b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identityserverdata.json new file mode 100644 index 000000000..cb96df6bb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/identityserverdata.json @@ -0,0 +1,127 @@ +{ + "IdentityServerData": { + "IdentityResources": [ + { + "Name": "roles", + "Enabled": true, + "DisplayName": "Roles", + "UserClaims": [ + "role" + ] + }, + { + "Name": "openid", + "Enabled": true, + "Required": true, + "DisplayName": "Your user identifier", + "UserClaims": [ + "sub" + ] + }, + { + "Name": "profile", + "Enabled": true, + "DisplayName": "User profile", + "Description": "Your user profile information (first name, last name, etc.)", + "Emphasize": true, + "UserClaims": [ + "name", + "family_name", + "given_name", + "middle_name", + "nickname", + "preferred_username", + "profile", + "picture", + "website", + "gender", + "birthdate", + "zoneinfo", + "locale", + "updated_at" + ] + }, + { + "Name": "email", + "Enabled": true, + "DisplayName": "Your email address", + "Emphasize": true, + "UserClaims": [ + "email", + "email_verified" + ] + }, + { + "Name": "address", + "Enabled": true, + "DisplayName": "Your address", + "Emphasize": true, + "UserClaims": [ + "address" + ] + } + ], + "ApiResources": [ + { + "Name": "skoruba_identity_admin_api", + "Scopes": [ + { + "Name": "skoruba_identity_admin_api", + "DisplayName": "skoruba_identity_admin_api", + "Required": true, + "UserClaims": [ + "role", + "name" + ] + } + ] + } + ], + "Clients": [ + { + "ClientId": "skoruba_identity_admin", + "ClientName": "skoruba_identity_admin", + "ClientUri": "http://localhost:9000", + "AllowedGrantTypes": [ + "hybrid" + ], + "ClientSecrets": [ + { + "Value": "skoruba_admin_client_secret" + } + ], + "RedirectUris": [ + "http://localhost:9000/signin-oidc" + ], + "FrontChannelLogoutUri": "http://localhost:9000/signout-oidc", + "PostLogoutRedirectUris": [ + "http://localhost:9000/signout-callback-oidc" + ], + "AllowedCorsOrigins": [ + "http://localhost:9000" + ], + "AllowedScopes": [ + "openid", + "email", + "profile", + "roles" + ] + }, + { + "ClientId": "skoruba_identity_admin_api_swaggerui", + "ClientName": "skoruba_identity_admin_api_swaggerui", + "AllowedGrantTypes": [ + "implicit" + ], + "RedirectUris": [ + "http://localhost:5001/swagger/oauth2-redirect.html" + ], + "AllowedScopes": [ + "skoruba_identity_admin_api" + ], + "AllowAccessTokensViaBrowser": true + + } + ] + } +} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/serilog.json b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/serilog.json new file mode 100644 index 000000000..9cb47c7c7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "MinimumLevel": { + "Default": "Error", + "Override": { + "Skoruba": "Information" + } + }, + "WriteTo": [ + { + "Name": "Console" + }, + { + "Name": "File", + "Args": { + "path": "Log\\skoruba_admin.txt", + "rollingInterval": "Day" + } + }, + { + "Name": "MSSqlServer", + "Args": { + "connectionString": "Server=(localdb)\\mssqllocaldb;Database=IdentityServer4Admin;Trusted_Connection=True;MultipleActiveResultSets=true", + "tableName": "Log", + "columnOptionsSection": { + "addStandardColumns": [ "LogEvent" ], + "removeStandardColumns": [ "Properties" ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/web.config b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/web.config index 3d49211e5..5e0ce7695 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/web.config +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/web.config @@ -7,8 +7,11 @@ - - + + + + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.css b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.css index 836e87141..073e75604 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.css +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.css @@ -486,3 +486,10 @@ label.radio-img > h3, label > h4 { /*Pages*/ .client .action-butons { margin: 20px 0 20px 0; } + +.audit-log-container .modal-dialog { + overflow-y: initial !important; } + +.audit-log-container .modal-body { + max-height: calc(100vh - 200px); + overflow-y: auto; } diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.min.css b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.min.css index c43142868..f27958161 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.min.css +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/css/web.min.css @@ -1 +1 @@ -@media (max-width:767px){.menu{text-align:center}.menu-logo{font-size:1.2em}.menu-item{display:none}.menu-button{display:block}.welcome-block h1{font-size:2em}}@media (min-width:768px){.menu-item{display:block}.menu-button{display:none}}.gravatar-image{max-width:none}.border-top{border-top:1px solid #e5e5e5}.border-bottom{border-bottom:1px solid #e5e5e5}.box-shadow{box-shadow:0 .25rem .75rem rgba(0,0,0,.05)}.welcome-block{max-width:700px}.logo,.logo:hover{color:#000;text-decoration:none}.col-m-5{margin:5px}.col-m-10{margin:10px}.col-m-15{margin:15px}.col-m-20{margin:20px}.col-m-25{margin:25px}.col-m-30{margin:30px}.col-m-35{margin:35px}.col-m-40{margin:40px}.col-m-45{margin:45px}.col-m-50{margin:50px}.col-m-b-5{margin-bottom:5px}.col-m-b-10{margin-bottom:10px}.col-m-b-15{margin-bottom:15px}.col-m-b-20{margin-bottom:20px}.col-m-b-25{margin-bottom:25px}.col-m-b-30{margin-bottom:30px}.col-m-b-35{margin-bottom:35px}.col-m-b-40{margin-bottom:40px}.col-m-b-45{margin-bottom:45px}.col-m-b-50{margin-bottom:50px}.col-m-t-5{margin-top:5px}.col-m-t-10{margin-top:10px}.col-m-t-15{margin-top:15px}.col-m-t-20{margin-top:20px}.col-m-t-25{margin-top:25px}.col-m-t-30{margin-top:30px}.col-m-t-35{margin-top:35px}.col-m-t-40{margin-top:40px}.col-m-t-45{margin-top:45px}.col-m-t-50{margin-top:50px}.col-m-l-5{margin-left:5px}.col-m-l-10{margin-left:10px}.col-m-l-15{margin-left:15px}.col-m-l-20{margin-left:20px}.col-m-l-25{margin-left:25px}.col-m-l-30{margin-left:30px}.col-m-l-35{margin-left:35px}.col-m-l-40{margin-left:40px}.col-m-l-45{margin-left:45px}.col-m-l-50{margin-left:50px}.col-m-r-5{margin-right:5px}.col-m-r-10{margin-right:10px}.col-m-r-15{margin-right:15px}.col-m-r-20{margin-right:20px}.col-m-r-25{margin-right:25px}.col-m-r-30{margin-right:30px}.col-m-r-35{margin-right:35px}.col-m-r-40{margin-right:40px}.col-m-r-45{margin-right:45px}.col-m-r-50{margin-right:50px}.col-p-5{padding:5px}.col-p-10{padding:10px}.col-p-15{padding:15px}.col-p-20{padding:20px}.col-p-25{padding:25px}.col-p-30{padding:30px}.col-p-35{padding:35px}.col-p-40{padding:40px}.col-p-45{padding:45px}.col-p-50{padding:50px}.col-p-b-5{padding-bottom:5px}.col-p-b-10{padding-bottom:10px}.col-p-b-15{padding-bottom:15px}.col-p-b-20{padding-bottom:20px}.col-p-b-25{padding-bottom:25px}.col-p-b-30{padding-bottom:30px}.col-p-b-35{padding-bottom:35px}.col-p-b-40{padding-bottom:40px}.col-p-b-45{padding-bottom:45px}.col-p-b-50{padding-bottom:50px}.col-p-t-5{padding-top:5px}.col-p-t-10{padding-top:10px}.col-p-t-15{padding-top:15px}.col-p-t-20{padding-top:20px}.col-p-t-25{padding-top:25px}.col-p-t-30{padding-top:30px}.col-p-t-35{padding-top:35px}.col-p-t-40{padding-top:40px}.col-p-t-45{padding-top:45px}.col-p-t-50{padding-top:50px}.col-p-l-5{padding-left:5px}.col-p-l-10{padding-left:10px}.col-p-l-15{padding-left:15px}.col-p-l-20{padding-left:20px}.col-p-l-25{padding-left:25px}.col-p-l-30{padding-left:30px}.col-p-l-35{padding-left:35px}.col-p-l-40{padding-left:40px}.col-p-l-45{padding-left:45px}.col-p-l-50{padding-left:50px}.col-p-r-5{padding-right:5px}.col-p-r-10{padding-right:10px}.col-p-r-15{padding-right:15px}.col-p-r-20{padding-right:20px}.col-p-r-25{padding-right:25px}.col-p-r-30{padding-right:30px}.col-p-r-35{padding-right:35px}.col-p-r-40{padding-right:40px}.col-p-r-45{padding-right:45px}.col-p-r-50{padding-right:50px}.col-form-label{text-align:right;font-weight:700}@media (max-width:575px){.col-form-label{text-align:left}}.navbar-brand>img{max-height:31px}.navbar-brand.logo{padding:10px 10px}.navbar-brand-image-mobile{display:none}@media (max-width:767px){.navbar-brand-image{display:none}.navbar-brand-image-mobile{display:block;padding-left:0;padding-right:0}}.validation-summary-errors{color:#ff3834;border:1px solid #ffd3d3;background:0 0;padding-top:9px;-ms-border-radius:4px;border-radius:4px;margin-bottom:15px;margin-top:20px}.switch{display:inline-block;height:28px;position:relative;width:60px;margin-top:5px}.switch input{display:none}.slider{background-color:#ccc;bottom:0;cursor:pointer;left:0;position:absolute;right:0;top:0;transition:.4s}.slider:before{background-color:#fff;bottom:4px;content:"";height:20px;left:7px;position:absolute;transition:.4s;width:20px}input:checked+.slider{background-color:#007bff}input:checked+.slider:before{transform:translateX(26px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.picker hr{margin-bottom:5px}.picker .button__text{display:inline-block;text-align:center;vertical-align:middle;margin:3px;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;border-color:#007bff;color:#007bff}.picker .button__add{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .button__delete,.picker .button__update{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .button__show-all{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .block__buttons__add{margin-top:4px}.picker .search-title{color:gray;font-size:12px}#toast-container>div{opacity:1}label.radio-img>input{visibility:hidden;position:absolute}label.radio-img>input+img{cursor:pointer;border:2px solid transparent}label.radio-img>input:checked+img{background-color:#ffe7ac;-ms-border-radius:15px;border-radius:15px}label.radio-img>input:checked~h3,label.radio-img>input:checked~h4{color:#007bff;text-decoration:underline}label.radio-img>h3,label>h4{cursor:pointer}.client .action-butons{margin:20px 0 20px 0} \ No newline at end of file +@media (max-width:767px){.menu{text-align:center}.menu-logo{font-size:1.2em}.menu-item{display:none}.menu-button{display:block}.welcome-block h1{font-size:2em}}@media (min-width:768px){.menu-item{display:block}.menu-button{display:none}}.gravatar-image{max-width:none}.border-top{border-top:1px solid #e5e5e5}.border-bottom{border-bottom:1px solid #e5e5e5}.box-shadow{box-shadow:0 .25rem .75rem rgba(0,0,0,.05)}.welcome-block{max-width:700px}.logo,.logo:hover{color:#000;text-decoration:none}.col-m-5{margin:5px}.col-m-10{margin:10px}.col-m-15{margin:15px}.col-m-20{margin:20px}.col-m-25{margin:25px}.col-m-30{margin:30px}.col-m-35{margin:35px}.col-m-40{margin:40px}.col-m-45{margin:45px}.col-m-50{margin:50px}.col-m-b-5{margin-bottom:5px}.col-m-b-10{margin-bottom:10px}.col-m-b-15{margin-bottom:15px}.col-m-b-20{margin-bottom:20px}.col-m-b-25{margin-bottom:25px}.col-m-b-30{margin-bottom:30px}.col-m-b-35{margin-bottom:35px}.col-m-b-40{margin-bottom:40px}.col-m-b-45{margin-bottom:45px}.col-m-b-50{margin-bottom:50px}.col-m-t-5{margin-top:5px}.col-m-t-10{margin-top:10px}.col-m-t-15{margin-top:15px}.col-m-t-20{margin-top:20px}.col-m-t-25{margin-top:25px}.col-m-t-30{margin-top:30px}.col-m-t-35{margin-top:35px}.col-m-t-40{margin-top:40px}.col-m-t-45{margin-top:45px}.col-m-t-50{margin-top:50px}.col-m-l-5{margin-left:5px}.col-m-l-10{margin-left:10px}.col-m-l-15{margin-left:15px}.col-m-l-20{margin-left:20px}.col-m-l-25{margin-left:25px}.col-m-l-30{margin-left:30px}.col-m-l-35{margin-left:35px}.col-m-l-40{margin-left:40px}.col-m-l-45{margin-left:45px}.col-m-l-50{margin-left:50px}.col-m-r-5{margin-right:5px}.col-m-r-10{margin-right:10px}.col-m-r-15{margin-right:15px}.col-m-r-20{margin-right:20px}.col-m-r-25{margin-right:25px}.col-m-r-30{margin-right:30px}.col-m-r-35{margin-right:35px}.col-m-r-40{margin-right:40px}.col-m-r-45{margin-right:45px}.col-m-r-50{margin-right:50px}.col-p-5{padding:5px}.col-p-10{padding:10px}.col-p-15{padding:15px}.col-p-20{padding:20px}.col-p-25{padding:25px}.col-p-30{padding:30px}.col-p-35{padding:35px}.col-p-40{padding:40px}.col-p-45{padding:45px}.col-p-50{padding:50px}.col-p-b-5{padding-bottom:5px}.col-p-b-10{padding-bottom:10px}.col-p-b-15{padding-bottom:15px}.col-p-b-20{padding-bottom:20px}.col-p-b-25{padding-bottom:25px}.col-p-b-30{padding-bottom:30px}.col-p-b-35{padding-bottom:35px}.col-p-b-40{padding-bottom:40px}.col-p-b-45{padding-bottom:45px}.col-p-b-50{padding-bottom:50px}.col-p-t-5{padding-top:5px}.col-p-t-10{padding-top:10px}.col-p-t-15{padding-top:15px}.col-p-t-20{padding-top:20px}.col-p-t-25{padding-top:25px}.col-p-t-30{padding-top:30px}.col-p-t-35{padding-top:35px}.col-p-t-40{padding-top:40px}.col-p-t-45{padding-top:45px}.col-p-t-50{padding-top:50px}.col-p-l-5{padding-left:5px}.col-p-l-10{padding-left:10px}.col-p-l-15{padding-left:15px}.col-p-l-20{padding-left:20px}.col-p-l-25{padding-left:25px}.col-p-l-30{padding-left:30px}.col-p-l-35{padding-left:35px}.col-p-l-40{padding-left:40px}.col-p-l-45{padding-left:45px}.col-p-l-50{padding-left:50px}.col-p-r-5{padding-right:5px}.col-p-r-10{padding-right:10px}.col-p-r-15{padding-right:15px}.col-p-r-20{padding-right:20px}.col-p-r-25{padding-right:25px}.col-p-r-30{padding-right:30px}.col-p-r-35{padding-right:35px}.col-p-r-40{padding-right:40px}.col-p-r-45{padding-right:45px}.col-p-r-50{padding-right:50px}.col-form-label{text-align:right;font-weight:700}@media (max-width:575px){.col-form-label{text-align:left}}.navbar-brand>img{max-height:31px}.navbar-brand.logo{padding:10px 10px}.navbar-brand-image-mobile{display:none}@media (max-width:767px){.navbar-brand-image{display:none}.navbar-brand-image-mobile{display:block;padding-left:0;padding-right:0}}.validation-summary-errors{color:#ff3834;border:1px solid #ffd3d3;background:0 0;padding-top:9px;-ms-border-radius:4px;border-radius:4px;margin-bottom:15px;margin-top:20px}.switch{display:inline-block;height:28px;position:relative;width:60px;margin-top:5px}.switch input{display:none}.slider{background-color:#ccc;bottom:0;cursor:pointer;left:0;position:absolute;right:0;top:0;transition:.4s}.slider:before{background-color:#fff;bottom:4px;content:"";height:20px;left:7px;position:absolute;transition:.4s;width:20px}input:checked+.slider{background-color:#007bff}input:checked+.slider:before{transform:translateX(26px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.picker hr{margin-bottom:5px}.picker .button__text{display:inline-block;text-align:center;vertical-align:middle;margin:3px;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;border-color:#007bff;color:#007bff}.picker .button__add{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .button__delete,.picker .button__update{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .button__show-all{margin-top:5px;margin-bottom:5px;margin-right:5px;white-space:normal;text-transform:none}.picker .block__buttons__add{margin-top:4px}.picker .search-title{color:gray;font-size:12px}#toast-container>div{opacity:1}label.radio-img>input{visibility:hidden;position:absolute}label.radio-img>input+img{cursor:pointer;border:2px solid transparent}label.radio-img>input:checked+img{background-color:#ffe7ac;-ms-border-radius:15px;border-radius:15px}label.radio-img>input:checked~h3,label.radio-img>input:checked~h4{color:#007bff;text-decoration:underline}label.radio-img>h3,label>h4{cursor:pointer}.client .action-butons{margin:20px 0 20px 0}.audit-log-container .modal-dialog{overflow-y:initial!important}.audit-log-container .modal-body{max-height:calc(100vh - 200px);overflow-y:auto} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/js/bundle.min.js b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/js/bundle.min.js index 0eccbf27d..ec05d5583 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/js/bundle.min.js +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/wwwroot/dist/js/bundle.min.js @@ -1 +1 @@ -if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,E=le(),S=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Ee(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Se(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Se(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
  • ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(St+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=Et,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(E.settings.themes[e]=t),delete E.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[E.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(E.settings,e);E.vars.preempted=!0,E.vars.dataAttr=d.dataAttr||E.setup.dataAttr,c.renderer=d.renderer?d.renderer:E.setup.renderer,-1===E.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=E.setup.supportsSVG?"svg":E.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(E.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(E.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},E={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(E.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){E.vars.cache.themeKeys=E.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=E.vars.cache.themeKeys[0|Math.random()*E.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?E.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return S.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!S.a.Lb(e,S.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return S.onError?function(){try{return e.apply(this,arguments)}catch(e){throw S.onError&&S.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(S.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw S.onError&&S.onError(e),e},0)},H:function(t,e,n){var i=S.a.zc(n);if(n=u[e],S.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),S.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==S.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),S.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return S.N(e)?e():e},$b:function(e){return S.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],S.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=S.a.c(t);null!==n&&n!==hna||(n="");var i=S.h.firstChild(e);!i||3!=i.nodeType||S.h.nextSibling(i)?S.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,S.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=S.a.c(e),t=S.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
    "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=S.a.W<=8,S.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=S.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=S.a.la(o.lastChild.childNodes)}return n},S.a.Ld=function(e,t){var n=S.a.ta(e,t);return n.length&&n[0].parentElement||S.a.Xb(n)},S.a.dc=function(e,t){if(S.a.Sb(e),null!==(t=S.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=S.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return S.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return S.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&S.eb(n,i,t)})}}),S.b("__tr_ambtns",S.ic.ld),function(){S.B={},S.B.D=function(e){if(this.D=e){var t=S.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},S.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?S.a.dc(this.D,t):this.D[e]=t};var t=S.a.g.Z()+"_";S.B.D.prototype.data=function(e){if(1===arguments.length)return S.a.g.get(this.D,t+e);S.a.g.set(this.D,t+e,arguments[1])};var i=S.a.g.Z();S.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=S.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=S.a.Ld(t,e.ownerDocument),this.text(""),S.a.g.set(e,i,{jb:n,hd:!0})),n}S.a.g.set(e,i,{jb:arguments[0]})},S.B.ia=function(e){this.D=e},S.B.ia.prototype=new S.B.D,S.B.ia.prototype.constructor=S.B.ia,S.B.ia.prototype.text=function(){if(0==arguments.length){var e=S.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}S.a.g.set(this.D,i,{jc:arguments[0]})},S.b("templateSources",S.B),S.b("templateSources.domElement",S.B.D),S.b("templateSources.anonymousTemplate",S.B.ia)}(),function(){function i(e,t,n){var i;for(t=S.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=S.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=S.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),S.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||S.aa.bd(e,[t])}),S.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])E("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(E("
    ").addClass("prev").attr("data-action","previous").append(E("").addClass(this._options.icons.previous))).append(E("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(E("").addClass("next").attr("data-action","next").append(E("").addClass(this._options.icons.next)))),t=E("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[E("
    ").addClass("datepicker-days").append(E("").addClass("table table-sm").append(e).append(E(""))),E("
    ").addClass("datepicker-months").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-years").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),E("
    ").addClass("datepicker-decades").append(E("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},S.prototype._getTimePickerMainTemplate=function(){var e=E(""),t=E(""),n=E("");return this._isEnabled("h")&&(e.append(E("").append(S("").append(S("").append(S("
    ").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(E("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(E("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(E("").addClass("separator")),t.append(E("").addClass("separator").html(":")),n.append(E("").addClass("separator"))),e.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(E("").addClass(this._options.icons.up)))),t.append(E("").append(E("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(E("").append(E("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(E("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(E("").addClass("separator")),t.append(E("").append(E("").addClass("separator"))),E("
    ").addClass("timepicker-picker").append(E("").addClass("table-condensed").append([e,t,n]))},S.prototype._getTimePickerTemplate=function(){var e=E("
    ").addClass("timepicker-hours").append(E("
    ").addClass("table-condensed")),t=E("
    ").addClass("timepicker-minutes").append(E("
    ").addClass("table-condensed")),n=E("
    ").addClass("timepicker-seconds").append(E("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},S.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(E("
    ").append(E("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(E("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(E("").addClass(n))))}return this._options.buttons.showClear&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(E("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(E("").append(E("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(E("").addClass(this._options.icons.close)))),0===e.length?"":E("").addClass("table-condensed").append(E("").append(E("").append(e)))},S.prototype._getTemplate=function(){var e=E("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=E("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=E("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=E("
      ").addClass("list-unstyled"),r=E("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(E("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(E("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},S.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=E(window).height()+E(window).scrollTop()&&t.widget.height()+t._element.outerHeight()E(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===E(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},S.prototype._fillDow=function(){var e=E("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(E(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},S.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=E("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},S.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=E("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=E(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},S.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=E("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=E(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},S.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},S.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(E(e.currentTarget).is(".disabled"))return!1;switch(t=t||E(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=E(e.target).closest("tbody").find("span").index(E(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(E(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(E(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();E(e.target).is(".old")&&l.subtract(1,"M"),E(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(E(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=E(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(E(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(E(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},S.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=E(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),E(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},S.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),E(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",E.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},S.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},S.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},S.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},S.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},S.prototype.widgetPositioning=function(e){if(0===arguments.length)return E.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},S.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=E(e)),null!==e&&"string"!=typeof e&&!(e instanceof E))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},S._jQueryHandleThis=function(e,t,n){var i=E(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&E.extend({},T.Default,t),i||(i=new S(E(e),t),E(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},S._jQueryInterface=function(e,t){return 1===this.length?S._jQueryHandleThis(this[0],e,t):this.each(function(){S._jQueryHandleThis(this,e,t)})},C=S,E(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(E(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(E(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(E(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),E.fn[T.NAME]=C._jQueryInterface,E.fn[T.NAME].Constructor=C,E.fn[T.NAME].noConflict=function(){return E.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=E(t)).length||n.data(T.DATA_KEY)||E.extend({},n.data(),E(this).data()),n}function S(e,t){a(this,S);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(S,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&S.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){S.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=S(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=S(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=S.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==S.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==S.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=S.isFunction(S.uniqueSort)?S.uniqueSort(y):S.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(S.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=S(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=S(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=S(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){S.data(e,"datepicker",this),this.element=S(e),this.inputs=S.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(S(this.inputs),t).on("changeDate",S.proxy(this.dateUpdated,this)),this.pickers=S.map(this.inputs,function(e){return S.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=S.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=S.map(this.dates,function(e){return e.valueOf()});S.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){S.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=S.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=S.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(S.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){S.map(this.pickers,function(e){e.destroy()}),S(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=S.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=S(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=S(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return S.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(S.extend({},c,i,n).language),a=S.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(S.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=S(v).filter(function(e,t){return-1!==S.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(E("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},S.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(E("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},S.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||E(this).addClass("disabled")})},S.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},S.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},S.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},S.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=E("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",S.fn.datepicker.DPGlobal=I,S.fn.datepicker.noConflict=function(){return S.fn.datepicker=i,this},S.fn.datepicker.version="1.9.0",S.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},S(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=S(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),S(function(){r.call(S('[data-provide="datepicker-inline"]'))})});var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()}),$(function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})}),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){(function(){$(".datepicker").datepicker({autoclose:!0,todayHighlight:!0})})()}); \ No newline at end of file +if(function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(x,e){"use strict";function m(e){return null!=e&&e===e.window}var t=[],C=x.document,i=Object.getPrototypeOf,s=t.slice,g=t.concat,l=t.push,r=t.indexOf,n={},a=n.toString,v=n.hasOwnProperty,o=v.toString,u=o.call(Object),y={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){var i,r,a=(n=n||C).createElement("script");if(a.text=e,t)for(i in c)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&a.setAttribute(i,r);n.head.appendChild(a).parentNode.removeChild(a)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[a.call(e)]||"object":typeof e}var d="3.4.1",k=function(e,t){return new k.fn.init(e,t)},h=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function f(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!b(e)&&!m(e)&&("array"===n||0===t||"number"==typeof t&&0>10|55296,1023&i|56320)}function r(){D()}var e,f,_,a,o,p,h,m,w,l,u,D,x,s,C,g,c,v,y,k="sizzle"+1*new Date,b=n.document,T=0,i=0,S=le(),E=le(),M=le(),A=le(),O=function(e,t){return e===t&&(u=!0),0},N={}.hasOwnProperty,t=[],I=t.pop,j=t.push,P=t.push,L=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+R+")"+R+"*"),z=new RegExp(R+"|>"),G=new RegExp(U),K=new RegExp("^"+Y+"$"),Q={ID:new RegExp("^#("+Y+")"),CLASS:new RegExp("^\\.("+Y+")"),TAG:new RegExp("^("+Y+"|[*])"),ATTR:new RegExp("^"+V),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,Z=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ae=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=_e(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=L.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,L.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function se(t,e,n,i){var r,a,o,s,l,u,c,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==x&&D(e),e=e||x,C)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(o=e.getElementById(r)))return n;if(o.id===r)return n.push(o),n}else if(d&&(o=d.getElementById(r))&&y(e,o)&&o.id===r)return n.push(o),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!A[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(c=t,d=e,1===h&&z.test(t)){for((s=e.getAttribute("id"))?s=s.replace(re,ae):e.setAttribute("id",s=k),a=(u=p(t)).length;a--;)u[a]="#"+s+" "+be(u[a]);c=u.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return m(t.replace(q,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>_.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ue(e){return e[k]=!0,e}function ce(e){var t=x.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)_.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&oe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(o){return ue(function(a){return a=+a,ue(function(e,t){for(var n,i=o([],e.length,a),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},D=se.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==x&&9===i.nodeType&&i.documentElement&&(s=(x=i).documentElement,C=!o(x),b!==x&&(n=x.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ce(function(e){return e.appendChild(x.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(x.getElementsByClassName),f.getById=ce(function(e){return s.appendChild(e).id=k,!x.getElementsByName||!x.getElementsByName(k).length}),f.getById?(_.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(_.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},_.find.ID=function(e,t){if(void 0!==t.getElementById&&C){var n,i,r,a=t.getElementById(e);if(a){if((n=a.getAttributeNode("id"))&&n.value===e)return[a];for(r=t.getElementsByName(e),i=0;a=r[i++];)if((n=a.getAttributeNode("id"))&&n.value===e)return[a]}return[]}}),_.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,a=t.getElementsByTagName(e);if("*"!==e)return a;for(;n=a[r++];)1===n.nodeType&&i.push(n);return i},_.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&C)return t.getElementsByClassName(e)},c=[],g=[],(f.qsa=ee.test(x.querySelectorAll))&&(ce(function(e){s.appendChild(e).innerHTML="
    ",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+R+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||g.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=x.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ce(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),c.push("!=",U)}),g=g.length&&new RegExp(g.join("|")),c=c.length&&new RegExp(c.join("|")),t=ee.test(s.compareDocumentPosition),y=t||ee.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return u=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===x||e.ownerDocument===b&&y(b,e)?-1:t===x||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return u=!0,0;var n,i=0,r=e.parentNode,a=t.parentNode,o=[e],s=[t];if(!r||!a)return e===x?-1:t===x?1:r?-1:a?1:l?H(l,e)-H(l,t):0;if(r===a)return he(e,t);for(n=e;n=n.parentNode;)o.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;o[i]===s[i];)i++;return i?he(o[i],s[i]):o[i]===b?-1:s[i]===b?1:0}),x},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==x&&D(e),f.matchesSelector&&C&&!A[t+" "]&&(!c||!c.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&S(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=se.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function A(e,n,i){return b(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?k.grep(e,function(e){return e===n!==i}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:N.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),M.test(i[1])&&k.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=C.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=k.fn,O=k(C);var I=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&E(e,t)?k.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var De=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Te(){return!1}function Se(e,t){return e===function(){try{return C.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,i,r,a){var o,s;if("object"==typeof t){for(s in"string"!=typeof n&&(i=i||n,n=void 0),t)Ee(e,s,n,i,t[s],a);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Te;else if(!r)return e;return 1===a&&(o=r,(r=function(e){return k().off(e),o.apply(this,arguments)}).guid=o.guid||(o.guid=k.guid++)),e.each(function(){k.event.add(this,t,r,i,n)})}function Me(e,r,a){a?(Q.set(e,r,!1),k.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Q.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(k.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=s.call(arguments),Q.set(this,r,i),t=a(this,r),this[r](),i!==(n=Q.get(this,r))||t?Q.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Q.set(this,r,{value:k.event.trigger(k.extend(i[0],k.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,r)&&k.event.add(e,r,ke)}k.event={global:{},add:function(t,e,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.get(t);if(g)for(n.handler&&(n=(a=n).handler,r=a.selector),r&&k.find.matchesSelector(re,r),n.guid||(n.guid=k.guid++),(l=g.events)||(l=g.events={}),(o=g.handle)||(o=g.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(L)||[""]).length;u--;)f=m=(s=Ce.exec(e[u])||[])[1],p=(s[2]||"").split(".").sort(),f&&(d=k.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=k.event.special[f]||{},c=k.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&k.expr.match.needsContext.test(r),namespace:p.join(".")},a),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,o)||t.addEventListener&&t.addEventListener(f,o)),d.add&&(d.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,c):h.push(c),k.event.global[f]=!0)},remove:function(e,t,n,i,r){var a,o,s,l,u,c,d,h,f,p,m,g=Q.hasData(e)&&Q.get(e);if(g&&(l=g.events)){for(u=(t=(t||"").match(L)||[""]).length;u--;)if(f=m=(s=Ce.exec(t[u])||[])[1],p=(s[2]||"").split(".").sort(),f){for(d=k.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=a=h.length;a--;)c=h[a],!r&&m!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(h.splice(a,1),c.selector&&h.delegateCount--,d.remove&&d.remove.call(e,c));o&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||k.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,i,!0);k.isEmptyObject(l)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,a,o,s=k.event.fix(e),l=new Array(arguments.length),u=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(l[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return E(e,"table")&&E(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Le(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,a,o,s,l,u;if(1===t.nodeType){if(Q.hasData(e)&&(a=Q.access(e),o=Q.set(t,a),u=a.events))for(r in delete o.handle,o.events={},u)for(n=0,i=u[r].length;n")},clone:function(e,t,n){var i,r,a,o,s,l,u,c=e.cloneNode(!0),d=ae(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(o=ge(c),i=0,r=(a=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],an=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,a,o=!1!==e.jsonp&&(an.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&an.test(e.data)&&"data");if(o||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,o?e[o]=e[o].replace(an,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return a||k.error(i+" was not called"),a[0]},e.dataTypes[0]="json",r=x[i],x[i]=function(){a=arguments},n.always(function(){void 0===r?k(x).removeProp(i):x[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),a&&b(r)&&r(a[0]),a=r=void 0}),"script"}),y.createHTMLDocument=((nn=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(i)):t=C),a=!n&&[],(r=M.exec(e))?[t.createElement(r[1])]:(r=we([e],t,a),a&&a.length&&k(a).remove(),k.merge([],r.childNodes)));var i,r,a},k.fn.load=function(e,t,n){var i,r,a,o=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(i):e)}).always(n&&function(e,t){o.each(function(){n.apply(this,a||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var i,r,a,o,s,l,u=k.css(e,"position"),c=k(e),d={};"static"===u&&(e.style.position="relative"),s=c.offset(),a=k.css(e,"top"),l=k.css(e,"left"),r=("absolute"===u||"fixed"===u)&&-1<(a+l).indexOf("auto")?(o=(i=c.position()).top,i.left):(o=parseFloat(a)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(d.top=t.top-s.top+o),null!=t.left&&(d.left=t.left-s.left+r),"using"in t?t.using.call(e,d):c.css(d)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===k.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),r.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-k.css(i,"marginTop",!0),left:t.left-r.left-k.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var a="pageYOffset"===r;k.fn[t]=function(e){return W(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(a?i.pageXOffset:n,a?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Xe(y.pixelPosition,function(e,t){if(t)return t=Ze(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(o,s){k.each({padding:"inner"+o,content:s,"":"outer"+o},function(i,a){k.fn[a]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return W(this,function(e,t,n){var i;return m(e)?0===a.indexOf("outer")?e["inner"+o]:e.document.documentElement["client"+o]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+o],i["scroll"+o],e.body["offset"+o],i["offset"+o],i["client"+o])):void 0===n?k.css(e,t,r):k.style(e,t,n,r)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(c(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return c(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=c(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,a,o,s,l=this[0],u=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&u&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=c.data(l.form,"validator").settings).rules,r=c.validator.staticRules(l),e){case"add":c.extend(r,c.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=c.extend(n.messages[l.name],t.messages));break;case"remove":return t?(s={},c.each(t.split(/\s/),function(e,t){s[t]=r[t],delete r[t]}),s):(delete i[l.name],r)}return(a=c.validator.normalizeRules(c.extend({},c.validator.classRules(l),c.validator.attributeRules(l),c.validator.dataRules(l),c.validator.staticRules(l)),l)).required&&(o=a.required,delete a.required,a=c.extend({required:o},a)),a.remote&&(o=a.remote,delete a.remote,a=c.extend(a,{remote:o})),a}}}),c.extend(c.expr.pseudos||c.expr[":"],{blank:function(e){return!c.trim(""+c(e).val())},filled:function(e){var t=c(e).val();return null!==t&&!!c.trim(""+t)},unchecked:function(e){return!c(e).prop("checked")}}),c.validator=function(e,t){this.settings=c.extend(!0,{},c.validator.defaults,e),this.currentForm=t,this.init()},c.validator.format=function(n,e){return 1===arguments.length?function(){var e=c.makeArray(arguments);return e.unshift(n),c.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=c.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 c(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,a,o=this.errorsFor(e),s=this.idOrName(e),l=c(e).attr("aria-describedby");o.length?(o.removeClass(this.settings.validClass).addClass(this.settings.errorClass),o.html(t)):(n=o=c("<"+this.settings.errorElement+">").attr("id",s+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=o.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,c(e)):n.insertAfter(e),o.is("label")?o.attr("for",s):0===o.parents("label[for='"+this.escapeCssMeta(s)+"']").length&&(r=o.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,c(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(a=this,c.each(a.groups,function(e,t){t===i&&c("[name='"+a.escapeCssMeta(e)+"']",a.currentForm).attr("aria-describedby",o.attr("id"))})))),!t&&this.settings.success&&(o.text(""),"string"==typeof this.settings.success?o.addClass(this.settings.success):this.settings.success(o,e)),this.toShow=this.toShow.add(o)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=c(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),c(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return c(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return c("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!c(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!c.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,c(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],c(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(c(this.currentForm).submit(),this.submitButton&&c("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(c(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",c.data(e,"previousValue")||c.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),c(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:c.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=c(e).attr("class");return n&&c.each(n.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(t,c.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,a,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=c(e),a=e.getAttribute("type");for(t in c.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,a,t,n);return i},staticRules:function(e){var t={},n=c.data(e.form,"validator");return n.settings.rules&&(t=c.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return c.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!c(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(c.data(r.form,"validator").resetElements(c(r)),delete i[e])}}else delete i[e]}),c.each(i,function(e,t){i[e]=c.isFunction(t)&&"normalizer"!==e?t(r):t}),c.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),c.each(["rangelength","range"],function(){var e;i[this]&&(c.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),c.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};c.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){c.validator.methods[e]=t,c.validator.messages[e]=void 0!==n?n:c.validator.messages[e],t.length<3&&c.validator.addClassRules(e,c.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,a))}var a,o=c(t).attr("type"),s="Step attribute on input type "+o+" is not supported.",l=new RegExp("\\b"+o+"\\b"),u=!0;if(o&&!l.test(["text","number","range"].join()))throw new Error(s);return a=i(n),(i(e)>a||r(e)%r(n)!=0)&&(u=!1),this.optional(t)||u},equalTo:function(e,t,n){var i=c(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){c(t).valid()}),e===i.val()},remote:function(a,o,e,s){if(this.optional(o))return"dependency-mismatch";s="string"==typeof s&&s||"remote";var l,t,n,u=this.previousValue(o,s);return this.settings.messages[o.name]||(this.settings.messages[o.name]={}),u.originalMessage=u.originalMessage||this.settings.messages[o.name][s],this.settings.messages[o.name][s]=u.message,e="string"==typeof e&&{url:e}||e,n=c.param(c.extend({data:a},e.data)),u.old===n?u.valid:(u.old=n,(l=this).startRequest(o),(t={})[o.name]=a,c.ajax(c.extend(!0,{mode:"abort",port:"validate"+o.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[o.name][s]=u.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(o),l.formSubmitted=i,l.successList.push(o),l.invalid[o.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(o,{method:s,parameters:a}),t[o.name]=u.message=n,l.invalid[o.name]=!0,l.showErrors(t)),u.valid=r,l.stopRequest(o,r)}},e)),"pending")}}});var i,r={};return c.ajaxPrefilter?c.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=c.ajax,c.ajax=function(e){var t=("mode"in e?e:c.ajaxSettings).mode,n=("port"in e?e:c.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),c}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,o=l.validator,s="unobtrusiveValidation";function u(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function c(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=a[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(s),r=l.proxy(f,i),a=o.unobtrusive.options||{};return n||(n={options:{errorClass:a.errorClass||"input-validation-error",errorElement:a.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+c(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+s,r).on("reset."+s,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(s,n)),n}return o.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,a,o=l(i),s=o.parents("form")[0];s&&((t=p(s)).options.rules[i.name]=r={},t.options.messages[i.name]=a={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=o.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=o.attr(e+this)}),this.adapt({element:i,form:s,message:t,params:n,rules:r,messages:a}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){o.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=o.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){u(e,n||t,!0)})},e.addMinMax=function(e,i,r,a,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?u(e,a,[t,n]):t?u(e,i,t):n&&u(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){u(e,i||t,e.params[n])})},o.addMethod("__dummy__",function(e,t,n){return!0}),o.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),o.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),o.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);u(e,"equalTo",l(e.form).find(":input").filter("[name='"+c(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||u(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},a=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,a);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+c(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),u(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&u(e,"minlength",e.params.min),e.params.nonalphamin&&u(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&u(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){u(e,"extension",e.params.extensions)}),l(function(){o.unobtrusive.parse(document)}),o.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(a[t],r[e]-("right"===e?a.width:a.height))),w({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";a=D({},a,o[t](e))}),e.offsets.popper=a,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=x(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(i),o=a?"right":"bottom",s=a?"left":"top",l=a?"width":"height";return t[o]r(n[o])&&(e.offsets.popper[s]=r(n[o])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!Y(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=x(e.offsets.popper),a=e.offsets.reference,o=-1!==["left","right"].indexOf(i),s=o?"height":"width",l=o?"top":"left",u=o?"left":"top",c=o?"bottom":"right",d=M(n)[s];a[c]-dr[c]&&(e.offsets.popper[l]+=a[l]+d-r[c]);var h=a[l]+a[s]/2-d/2-x(e.offsets.popper)[l];return h=Math.max(Math.min(r[s]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[u]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(L(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=A(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case W:b=[g,v];break;case q:b=U(g);break;case B:b=U(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=A(g);var n=x(f.offsets.popper),i=f.offsets.reference,r=Math.floor,a="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),c="left"===g&&o||"right"===g&&s||"top"===g&&l||"bottom"===g&&u,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&o||d&&"end"===y&&s||!d&&"start"===y&&l||!d&&"end"===y&&u);(a||c||h)&&(f.flipped=!0,(a||c)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=x(e.offsets.popper),r=x(e.offsets.reference),a=-1!==["left","right"].indexOf(n),o=-1===["top","left"].indexOf(n);return i[a?"left":"top"]=r[t]-(o?i[a?"width":"height"]:0),e.placement=A(t),e.offsets.popper=x(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!Y(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:_t},jt="show",Pt="out",Lt={HIDE:"hide"+Tt,HIDDEN:"hidden"+Tt,SHOW:"show"+Tt,SHOWN:"shown"+Tt,INSERTED:"inserted"+Tt,CLICK:"click"+Tt,FOCUSIN:"focusin"+Tt,FOCUSOUT:"focusout"+Tt,MOUSEENTER:"mouseenter"+Tt,MOUSELEAVE:"mouseleave"+Tt},Ht="fade",Ft="show",Rt=".tooltip-inner",Yt=".arrow",Vt="hover",Ut="focus",Wt="click",qt="manual",Bt=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Ft))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=m.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&p(r).addClass(Ht);var o="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:s,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Yt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var u=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var c=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,u).emulateTransitionEnd(c)}else u()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Ft),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Wt]=!1,this._activeTrigger[Ut]=!1,this._activeTrigger[Vt]=!1,p(this.tip).hasClass(Ht)){var a=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(a)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Et+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(Rt)),this.getTitle()),p(e).removeClass(Ht+" "+Ft)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=xt(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return Nt[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==qt){var t=e===Vt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Vt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Ut:Vt]=!0),p(t.getTipElement()).hasClass(Ft)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Ut:Vt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==At.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Ct,e,this.constructor.DefaultType),e.sanitize&&(e.template=xt(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Mt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(kt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(kt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},o(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return It}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return kt}},{key:"Event",get:function(){return Lt}},{key:"EVENT_KEY",get:function(){return Tt}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Ct]=Bt._jQueryInterface,p.fn[Ct].Constructor=Bt,p.fn[Ct].noConflict=function(){return p.fn[Ct]=St,Bt._jQueryInterface};var $t="popover",zt="bs.popover",Gt="."+zt,Kt=p.fn[$t],Qt="bs-popover",Jt=new RegExp("(^|\\s)"+Qt+"\\S+","g"),Zt=l({},Bt.Default,{placement:"right",trigger:"click",content:"",template:''}),Xt=l({},Bt.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",an={HIDE:"hide"+Gt,HIDDEN:"hidden"+Gt,SHOW:"show"+Gt,SHOWN:"shown"+Gt,INSERTED:"inserted"+Gt,CLICK:"click"+Gt,FOCUSIN:"focusin"+Gt,FOCUSOUT:"focusout"+Gt,MOUSEENTER:"mouseenter"+Gt,MOUSELEAVE:"mouseleave"+Gt},on=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Qt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Jt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,a,o,s,l=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,a=(3&t)<<4|(n=e.charCodeAt(l++))>>4,o=(15&n)<<2|(i=e.charCodeAt(l++))>>6,s=63&i,l===e.length+2?s=o=64:l===e.length+1&&(s=64),u.push(c.charAt(r),c.charAt(a),c.charAt(o),c.charAt(s));return u.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(s,e,O){(function(u){var e=O(2),h=O(3),k=O(6),g=O(7),v=O(8),y=O(9),T=O(10),t=O(11),c=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,_=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(S.settings.themes[e]=t),delete S.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[S.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&D(e))},run:function(e){e=e||{};var c={},d=m(S.settings,e);S.vars.preempted=!0,S.vars.dataAttr=d.dataAttr||S.setup.dataAttr,c.renderer=d.renderer?d.renderer:S.setup.renderer,-1===S.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=S.setup.supportsSVG?"svg":S.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=!!d.noFontFallback,c.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;c.stylesheets.push(i)}}),n.forEach(function(e){if(u.getComputedStyle){var t=u.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",a=n.indexOf(r);if(0===a)i=n;else if(1===a&&"?"===n[0])i=n.slice(1);else{var o=n.substr(a).match(/([^\"]*)"?\)/);if(null!==o)i=o[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var s=l(i,d);s&&p({mode:"background",el:e,flags:s,engineSettings:c})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(S.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,c,t.data,e):i&&f(d,c,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(S.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,a,o,s=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),u=null!=t.rendered&&"true"==t.rendered;s?0===t.src.indexOf(d.domain)?f(d,c,t.src,e):l&&(u?f(d,c,t.dataSrc,e):(n=t.src,i=d,r=c,a=t.dataSrc,o=e,g.imageExists(n,function(e){e||f(i,r,a,o)}))):l&&f(d,c,t.dataSrc,e)}),this}},S={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(S.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var a=r[0].split("/");n.holderURL=e;var o=a[1],s=o.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=-1!==o.indexOf("p"),n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var u=parseFloat(n.dimensions.width.replace("%","")),c=parseFloat(n.dimensions.height.replace("%",""));c=Math.floor(c/u*100),u=100,n.dimensions.width=u+"%",n.dimensions.height=c+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){S.vars.cache.themeKeys=S.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=S.vars.cache.themeKeys[0|Math.random()*S.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,a=i.dimensions,o=i.theme,s=a.width+"x"+a.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(o.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=o.text.split("\\n"),u=0;u=r||!0==C)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,_+=f.properties.leading,w+=1,(g=new o.Group("line"+w)).y=_),!0!=C&&(m.moveTo(b,0),b+=p.spaceWidth+x.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new o.Text(e.text),(g=new o.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}(o);function l(){var e=null;switch(a.renderer){case"canvas":e=d(s,t);break;case"svg":e=c(s,t);break;default:throw"Holder: invalid renderer: "+a.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",a.noBackgroundSize||(i.style.backgroundSize=o.width+"px "+o.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),a.reRender&&u.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function D(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?S.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function o(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}o.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},o.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,a=r*(1-Math.abs(parseInt(i)%2-1)),o=n-r/2,s=0,l=0,u=0;return 0<=i&&i<1?(s=r,l=a):1<=i&&i<2?(s=a,l=r):2<=i&&i<3?(l=r,u=a):3<=i&&i<4?(l=a,u=r):4<=i&&i<5?(s=a,u=r):5<=i&&i<6&&(s=r,u=a),s+=o,l+=o,u+=o,[s=parseInt(255*s),l=parseInt(255*l),u=parseInt(255*u)]},o.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,a=-.09991*t-.33609*n+.436*i,o=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:a,v:o},this},o.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),a=o.rgb2hex(n,i,r);return new o(a)},o.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},o.prototype.lighterThan=function(e){return e instanceof o||(e=new o(e)),this.yuv.y>e.yuv.y},o.prototype.blendAlpha=function(e){e instanceof o||(e=new o(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new o(o.rgb2hex(n,i,r))},e.exports=o},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),_=n(7),w=i.svg_ns,D=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,o=r.children.holderTextGroup,a="#"+i+" text { "+function(e){return _.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(o.properties)+" } ";o.y+=.8*o.textPositionData.boundingBox.height;var s=[];Object.keys(o.children).forEach(function(e){var a=o.children[e];Object.keys(a.children).forEach(function(e){var t=a.children[e],n=o.x+a.x+t.x,i=o.y+a.y+t.y,r=D({tag:"text",content:t.properties.text,x:n,y:i});s.push(r)})});var l=D({tag:"g",content:s}),u=null;if(r.children.holderBg.properties.outline){var c=r.children.holderBg.properties.outline;u=D({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,c.width),"stroke-width":c.width,stroke:c.fill,fill:"none"})}var d=function(e,t){return D({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),c&&h.push(u),h.push(l);var f=D({tag:"g",id:i,content:h}),p=D({tag:"style",content:a,type:"text/css"}),m=D({tag:"defs",content:p}),g=D({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:w,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,a,o,s,l,u,c,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],u=l.match(/^[\w-]+/),c={tag:u?u[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(c.attr.id=d[1],i[d[1]]=c),h&&(i[h[1]]=c),f&&(c.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),c);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])o=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(a in t[g])t[g].hasOwnProperty(a)&&null!==t[g][a]&&!1!==t[g][a]&&("style"===a&&"object"==typeof t[g][a]?t[0].attr[a]=JSON.stringify(t[g][a],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[a]=t[g][a])}}if(!1!==t[0]){for(s in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(s)&&(r+=" "+s+'="'+((m=t[0].attr[s])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],o&&o(t[0]),i}},function(e,t){"use strict";var s=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=s.exec(n);if(!i)return n;var r="",a=0,o=0;for(a=i.index;ae.length)&&e.substring(0,t.length)===t},ud:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Rb:function(e){return E.a.ud(e,e.ownerDocument.documentElement)},jd:function(e){return!!E.a.Lb(e,E.a.Rb)},P:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},zc:function(e){return E.onError?function(){try{return e.apply(this,arguments)}catch(e){throw E.onError&&E.onError(e),e}}:e},setTimeout:function(e,t){return setTimeout(E.a.zc(e),t)},Fc:function(e){setTimeout(function(){throw E.onError&&E.onError(e),e},0)},H:function(t,e,n){var i=E.a.zc(n);if(n=u[e],E.options.useOnlyNativeEvents||n||!lna)if(n||"function"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error("Browser doesn't support addEventListener or attachEvent");function r(e){i.call(t,e)}var a="on"+e;t.attachEvent(a,r),E.a.I.za(t,function(){t.detachEvent(a,r)})}else t.addEventListener(e,i,!1);else l=l||("function"==typeof lna(t).on?"on":"bind"),lna(t)[l](e,i)},Fb:function(e,t){if(!e||!e.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var n;if(n=!("input"!==E.a.P(e)||!e.type||"click"!=t.toLowerCase()||"checkbox"!=(n=e.type)&&"radio"!=n),E.options.useOnlyNativeEvents||!lna||n)if("function"==typeof jna.createEvent){if("function"!=typeof e.dispatchEvent)throw Error("The supplied element doesn't support dispatchEvent");(n=jna.createEvent(s[t]||"HTMLEvents")).initEvent(t,!0,!0,ina,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error("Browser doesn't support triggering events");e.fireEvent("on"+t)}else lna(e).trigger(t)},c:function(e){return E.N(e)?e():e},$b:function(e){return E.N(e)?e.w():e},Eb:function(t,e,n){var i;e&&("object"==typeof t.classList?(i=t.classList[n?"add":"remove"],E.a.C(e.match(h),function(e){i.call(t.classList,e)})):"string"==typeof t.className.baseVal?r(t.className,"baseVal",e,n):r(t,"className",e,n))},Ab:function(e,t){var n=E.a.c(t);null!==n&&n!==hna||(n="");var i=E.h.firstChild(e);!i||3!=i.nodeType||E.h.nextSibling(i)?E.h.ua(e,[e.ownerDocument.createTextNode(n)]):i.data=n,E.a.zd(e)},Xc:function(e,t){if(e.name=t,c<=7)try{var n=e.name.replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt(0)+";"});e.mergeAttributes(jna.createElement(""),!1)}catch(e){}},zd:function(e){9<=c&&(e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom)},vd:function(e){if(c){var t=e.style.width;e.style.width=0,e.style.width=t}},Od:function(e,t){e=E.a.c(e),t=E.a.c(t);for(var n=[],i=e;i<=t;i++)n.push(i);return n},la:function(e){for(var t=[],n=0,i=e.length;n","
  • "],tbody:t,tfoot:t,tr:[2,"","
    "],td:c=[3,"","
    "],th:c,option:d=[1,""],optgroup:d},f=E.a.W<=8,E.a.ta=function(e,t){var n;if(lna){if(lna.parseHTML)n=lna.parseHTML(e,t)||[];else if((n=lna.clean([e],t))&&n[0]){for(var i=n[0];i.parentNode&&11!==i.parentNode.nodeType;)i=i.parentNode;i.parentNode&&i.parentNode.removeChild(i)}}else{(n=t)||(n=jna),i=n.parentWindow||n.defaultView||ina;var r,a=E.a.Cb(e).toLowerCase(),o=n.createElement("div");for(a=(r=(a=a.match(/^(?:\x3c!--.*?--\x3e\s*?)*?<([a-z]+)[\s>]/))&&h[a[1]]||l)[0],r="ignored
    "+r[1]+e+r[2]+"
    ","function"==typeof i.innerShiv?o.appendChild(i.innerShiv(r)):(f&&n.body.appendChild(o),o.innerHTML=r,f&&o.parentNode.removeChild(o));a--;)o=o.lastChild;n=E.a.la(o.lastChild.childNodes)}return n},E.a.Ld=function(e,t){var n=E.a.ta(e,t);return n.length&&n[0].parentElement||E.a.Xb(n)},E.a.dc=function(e,t){if(E.a.Sb(e),null!==(t=E.a.c(t))&&t!==hna)if("string"!=typeof t&&(t=t.toString()),lna)lna(e).html(t);else for(var n=E.a.ta(t,e.ownerDocument),i=0;i]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,he=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g,{wd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return E.ic.Kd(e,t)},n)},Kd:function(e,a){return e.replace(de,function(e,t,n,i,r){return ge(r,t,n,a)}).replace(he,function(e,t){return ge(t,"\x3c!-- ko --\x3e","#comment",a)})},ld:function(i,r){return E.aa.Wb(function(e,t){var n=e.nextSibling;n&&n.nodeName.toLowerCase()===r&&E.eb(n,i,t)})}}),E.b("__tr_ambtns",E.ic.ld),function(){E.B={},E.B.D=function(e){if(this.D=e){var t=E.a.P(e);this.Db="script"===t?1:"textarea"===t?2:"template"==t&&e.content&&11===e.content.nodeType?3:4}},E.B.D.prototype.text=function(){var e=1===this.Db?"text":2===this.Db?"value":"innerHTML";if(0==arguments.length)return this.D[e];var t=arguments[0];"innerHTML"==e?E.a.dc(this.D,t):this.D[e]=t};var t=E.a.g.Z()+"_";E.B.D.prototype.data=function(e){if(1===arguments.length)return E.a.g.get(this.D,t+e);E.a.g.set(this.D,t+e,arguments[1])};var i=E.a.g.Z();E.B.D.prototype.nodes=function(){var e=this.D;if(0==arguments.length){var t=E.a.g.get(e,i)||{},n=t.jb||(3===this.Db?e.content:4===this.Db?e:hna);return n&&!t.hd||(t=this.text())&&(n=E.a.Ld(t,e.ownerDocument),this.text(""),E.a.g.set(e,i,{jb:n,hd:!0})),n}E.a.g.set(e,i,{jb:arguments[0]})},E.B.ia=function(e){this.D=e},E.B.ia.prototype=new E.B.D,E.B.ia.prototype.constructor=E.B.ia,E.B.ia.prototype.text=function(){if(0==arguments.length){var e=E.a.g.get(this.D,i)||{};return e.jc===hna&&e.jb&&(e.jc=e.jb.innerHTML),e.jc}E.a.g.set(this.D,i,{jc:arguments[0]})},E.b("templateSources",E.B),E.b("templateSources.domElement",E.B.D),E.b("templateSources.anonymousTemplate",E.B.ia)}(),function(){function i(e,t,n){var i;for(t=E.h.nextSibling(t);e&&(i=e)!==t;)n(i,e=E.h.nextSibling(i))}function h(e,t){if(e.length){var r=e[0],a=e[e.length-1],n=r.parentNode,o=E.ga.instance,s=o.preprocessNode;if(s){if(i(r,a,function(e,t){var n=e.previousSibling,i=s.call(o,e);i&&(e===r&&(r=i[0]||t),e===a&&(a=i[i.length-1]||n))}),e.length=0,!r)return;r===a?e.push(r):(e.push(r,a),E.a.Ua(e,n))}i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.uc(t,e)}),i(r,a,function(e){1!==e.nodeType&&8!==e.nodeType||E.aa.bd(e,[t])}),E.a.Ua(e,n)}}function l(e){return e.nodeType?e:0"+t+"<\/script>")},0").attr("id",e.containerId).addClass(e.positionClass)).appendTo(g(e.target)),w}(e)),w}function i(e,t,n){var i=!(!n||!n.force)&&n.force;return!(!e||!i&&0!==g(":focus",e).length||(e[t.hideMethod]({duration:t.hideDuration,easing:t.hideEasing,complete:function(){_(e)}}),0))}function y(e){t&&t(e)}function r(t){var r=b(),e=t.iconClass||r.iconClass;if(void 0!==t.optionsOverride&&(r=g.extend(r,t.optionsOverride),e=t.optionsOverride.iconClass||e),!function(e,t){if(e.preventDuplicates){if(t.message===D)return!0;D=t.message}return!1}(r,t)){x++,w=v(r,!0);var a=null,o=g("
    "),n=g("
    "),i=g("
    "),s=g("
    "),l=g(r.closeHtml),u={intervalId:null,hideEta:null,maxHideTime:null},c={toastId:x,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&o.addClass(r.toastClass).addClass(e),function(){if(t.title){var e=t.title;r.escapeHtml&&(e=d(t.title)),n.append(e).addClass(r.titleClass),o.append(n)}}(),function(){if(t.message){var e=t.message;r.escapeHtml&&(e=d(t.message)),i.append(e).addClass(r.messageClass),o.append(i)}}(),r.closeButton&&(l.addClass(r.closeClass).attr("role","button"),o.prepend(l)),r.progressBar&&(s.addClass(r.progressClass),o.prepend(s)),r.rtl&&o.addClass("rtl"),r.newestOnTop?w.prepend(o):w.append(o),function(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}o.attr("aria-live",e)}(),o.hide(),o[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),0/g,">")}function h(e){var t=e&&!1!==r.closeMethod?r.closeMethod:r.hideMethod,n=e&&!1!==r.closeDuration?r.closeDuration:r.hideDuration,i=e&&!1!==r.closeEasing?r.closeEasing:r.hideEasing;if(!g(":focus",o).length||e)return clearTimeout(u.intervalId),o[t]({duration:n,easing:i,complete:function(){_(o),clearTimeout(a),r.onHidden&&"hidden"!==c.state&&r.onHidden(),c.state="hidden",c.endTime=new Date,y(c)}})}function f(){(0×',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},e.options)}function _(e){w=w||v(),e.is(":visible")||(e.remove(),e=null,0===w.children().length&&(w.remove(),D=void 0))}var w,t,D,x,a,o,s,l,e}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,r;function y(){return e.apply(null,arguments)}function s(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function l(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function u(e){return void 0===e}function c(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function h(e,t){var n,i=[];for(n=0;n>>0,i=0;iDe(e)?(a=e+1,s-De(e)):(a=e,s),{year:a,dayOfYear:o}}function Ve(e,t,n){var i,r,a=Re(e.year(),t,n),o=Math.floor((e.dayOfYear()-a-1)/7)+1;return o<1?i=o+Ue(r=e.year()-1,t,n):o>Ue(e.year(),t,n)?(i=o-Ue(e.year(),t,n),r=e.year()+1):(r=e.year(),i=o),{week:i,year:r}}function Ue(e,t,n){var i=Re(e,t,n),r=Re(e+1,t,n);return(De(e)-i+r)/7}function We(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),L("week",5),L("isoWeek",5),le("w",Q),le("ww",Q,$),le("W",Q),le("WW",Q,$),he(["w","ww","W","WW"],function(e,t,n,i){t[i.substr(0,1)]=C(e)}),U("d",0,"do","day"),U("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),U("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),U("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),le("d",Q),le("e",Q),le("E",Q),le("dd",function(e,t){return t.weekdaysMinRegex(e)}),le("ddd",function(e,t){return t.weekdaysShortRegex(e)}),le("dddd",function(e,t){return t.weekdaysRegex(e)}),he(["dd","ddd","dddd"],function(e,t,n,i){var r=n._locale.weekdaysParse(e,i,n._strict);null!=r?t.d=r:_(n).invalidWeekday=e}),he(["d","e","E"],function(e,t,n,i){t[i]=C(e)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ze=oe,Ge=oe,Ke=oe;function Qe(){function e(e,t){return t.length-e.length}var t,n,i,r,a,o=[],s=[],l=[],u=[];for(t=0;t<7;t++)n=p([2e3,1]).day(t),i=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),a=this.weekdays(n,""),o.push(i),s.push(r),l.push(a),u.push(i),u.push(r),u.push(a);for(o.sort(e),s.sort(e),l.sort(e),u.sort(e),t=0;t<7;t++)s[t]=ue(s[t]),l[t]=ue(l[t]),u[t]=ue(u[t]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Je(){return this.hours()%12||12}function Ze(e,t){U(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Xe(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Je),U("k",["kk",2],0,function(){return this.hours()||24}),U("hmm",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Je.apply(this)+H(this.minutes(),2)+H(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+H(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+H(this.minutes(),2)+H(this.seconds(),2)}),Ze("a",!0),Ze("A",!1),N("hour","h"),L("hour",13),le("a",Xe),le("A",Xe),le("H",Q),le("h",Q),le("k",Q),le("HH",Q,$),le("hh",Q,$),le("kk",Q,$),le("hmm",J),le("hmmss",Z),le("Hmm",J),le("Hmmss",Z),de(["H","HH"],ge),de(["k","kk"],function(e,t,n){var i=C(e);t[ge]=24===i?0:i}),de(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),de(["h","hh"],function(e,t,n){t[ge]=C(e),_(n).bigHour=!0}),de("hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i)),_(n).bigHour=!0}),de("hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r)),_(n).bigHour=!0}),de("Hmm",function(e,t,n){var i=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i))}),de("Hmmss",function(e,t,n){var i=e.length-4,r=e.length-2;t[ge]=C(e.substr(0,i)),t[ve]=C(e.substr(i,2)),t[ye]=C(e.substr(r))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Ne,week:{dow:0,doy:6},weekdays:qe,weekdaysMin:$e,weekdaysShort:Be,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),st(t)}catch(e){}return it[e]}function st(e,t){var n;return e&&((n=u(t)?ut(e):lt(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,i=nt;if(t.abbr=e,null!=it[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])i=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;i=n._config}return it[e]=new A(M(i,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),st(e),it[e]}function ut(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!s(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,i,r,a=0;a=t&&o(r,n,!0)>=t-1)break;t--}a++}return et}(e)}function ct(e){var t,n=e._a;return n&&-2===_(e).overflow&&(t=n[pe]<0||11Me(n[fe],n[pe])?me:n[ge]<0||24Ue(n,a,o)?_(e)._overflowWeeks=!0:null!=l?_(e)._overflowWeekday=!0:(s=Ye(n,i,r,a,o),e._a[fe]=s.year,e._dayOfYear=s.dayOfYear)}(e),null!=e._dayOfYear&&(a=dt(e._a[fe],i[fe]),(e._dayOfYear>De(a)||0===e._dayOfYear)&&(_(e)._overflowDayOfYear=!0),n=Fe(a,0,e._dayOfYear),e._a[pe]=n.getUTCMonth(),e._a[me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=o[t]=i[t];for(;t<7;t++)e._a[t]=o[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[ye]&&0===e._a[be]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Fe:function(e,t,n,i,r,a,o){var s;return e<100&&0<=e?(s=new Date(e+400,t,n,i,r,a,o),isFinite(s.getFullYear())&&s.setFullYear(e)):s=new Date(e,t,n,i,r,a,o),s}).apply(null,o),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(_(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],yt=/^\/?Date\((\-?\d+)/i;function bt(e){var t,n,i,r,a,o,s=e._i,l=ft.exec(s)||pt.exec(s);if(l){for(_(e).iso=!0,t=0,n=gt.length;tn.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},dn.isLocal=function(){return!!this.isValid()&&!this._isUTC},dn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},dn.isUtc=Rt,dn.isUTC=Rt,dn.zoneAbbr=function(){return this._isUTC?"UTC":""},dn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},dn.dates=n("dates accessor is deprecated. Use date instead.",an),dn.months=n("months accessor is deprecated. Use month instead",je),dn.years=n("years accessor is deprecated. Use year instead",ke),dn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),dn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!u(this._isDSTShifted))return this._isDSTShifted;var e={};if(v(e,this),(e=Ct(e))._a){var t=e._isUTC?p(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0 div").hide().filter(".datepicker-"+h[this.currentViewMode].CLASS_NAME).show())},y.prototype._isInDisabledDates=function(e){return!0===this._options.disabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInEnabledDates=function(e){return!0===this._options.enabledDates[e.format("YYYY-MM-DD")]},y.prototype._isInDisabledHours=function(e){return!0===this._options.disabledHours[e.format("H")]},y.prototype._isInEnabledHours=function(e){return!0===this._options.enabledHours[e.format("H")]},y.prototype._isValid=function(e,t){if(!e.isValid())return!1;if(this._options.disabledDates&&"d"===t&&this._isInDisabledDates(e))return!1;if(this._options.enabledDates&&"d"===t&&!this._isInEnabledDates(e))return!1;if(this._options.minDate&&e.isBefore(this._options.minDate,t))return!1;if(this._options.maxDate&&e.isAfter(this._options.maxDate,t))return!1;if(this._options.daysOfWeekDisabled&&"d"===t&&-1!==this._options.daysOfWeekDisabled.indexOf(e.day()))return!1;if(this._options.disabledHours&&("h"===t||"m"===t||"s"===t)&&this._isInDisabledHours(e))return!1;if(this._options.enabledHours&&("h"===t||"m"===t||"s"===t)&&!this._isInEnabledHours(e))return!1;if(this._options.disabledTimeIntervals&&("h"===t||"m"===t||"s"===t)){var n=!1;if(o.each(this._options.disabledTimeIntervals,function(){if(e.isBetween(this[0],this[1]))return!(n=!0)}),n)return!1}return!0},y.prototype._parseInputDate=function(e){return void 0===this._options.parseInputDate?n.isMoment(e)||(e=this.getMoment(e)):e=this._options.parseInputDate(e),e},y.prototype._keydown=function(e){var t=null,n=void 0,i=void 0,r=void 0,a=void 0,o=[],s={},l=e.which;for(n in m[l]="p",m)m.hasOwnProperty(n)&&"p"===m[n]&&(o.push(n),parseInt(n,10)!==l&&(s[n]=!0));for(n in this._options.keyBinds)if(this._options.keyBinds.hasOwnProperty(n)&&"function"==typeof this._options.keyBinds[n]&&(r=n.split(" ")).length===o.length&&f[l]===r[r.length-1]){for(a=!0,i=r.length-2;0<=i;i--)if(!(f[r[i]]in s)){a=!1;break}if(a){t=this._options.keyBinds[n];break}}t&&t.call(this)&&(e.stopPropagation(),e.preventDefault())},y.prototype._keyup=function(e){m[e.which]="r",g[e.which]&&(g[e.which]=!1,e.stopPropagation(),e.preventDefault())},y.prototype._indexGivenDates=function(e){var t={},n=this;return o.each(e,function(){var e=n._parseInputDate(this);e.isValid()&&(t[e.format("YYYY-MM-DD")]=!0)}),!!Object.keys(t).length&&t},y.prototype._indexGivenHours=function(e){var t={};return o.each(e,function(){t[this]=!0}),!!Object.keys(t).length&&t},y.prototype._initFormatting=function(){var e=this._options.format||"L LT",t=this;this.actualFormat=e.replace(/(\[[^\[]*])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(e){return t._dates[0].localeData().longDateFormat(e)||e}),this.parseFormats=this._options.extraFormats?this._options.extraFormats.slice():[],this.parseFormats.indexOf(e)<0&&this.parseFormats.indexOf(this.actualFormat)<0&&this.parseFormats.push(this.actualFormat),this.use24Hours=this.actualFormat.toLowerCase().indexOf("a")<1&&this.actualFormat.replace(/\[.*?]/g,"").indexOf("h")<1,this._isEnabled("y")&&(this.MinViewModeNumber=2),this._isEnabled("M")&&(this.MinViewModeNumber=1),this._isEnabled("d")&&(this.MinViewModeNumber=0),this.currentViewMode=Math.max(this.MinViewModeNumber,this.currentViewMode),this.unset||this._setValue(this._dates[0],0)},y.prototype._getLastPickedDate=function(){return this._dates[this._getLastPickedDateIndex()]},y.prototype._getLastPickedDateIndex=function(){return this._dates.length-1},y.prototype.getMoment=function(e){var t=void 0;return t=null==e?n():this._hasTimeZone()?n.tz(e,this.parseFormats,this._options.locale,this._options.useStrict,this._options.timeZone):n(e,this.parseFormats,this._options.locale,this._options.useStrict),this._hasTimeZone()&&t.tz(this._options.timeZone),t},y.prototype.toggle=function(){return this.widget?this.hide():this.show()},y.prototype.ignoreReadonly=function(e){if(0===arguments.length)return this._options.ignoreReadonly;if("boolean"!=typeof e)throw new TypeError("ignoreReadonly () expects a boolean parameter");this._options.ignoreReadonly=e},y.prototype.options=function(e){if(0===arguments.length)return o.extend(!0,{},this._options);if(!(e instanceof Object))throw new TypeError("options() this.options parameter should be an object");o.extend(!0,this._options,e);var n=this;o.each(this._options,function(e,t){void 0!==n[e]&&n[e](t)})},y.prototype.date=function(e,t){if(t=t||0,0===arguments.length)return this.unset?null:this._options.allowMultidate?this._dates.join(this._options.multidateSeparator):this._dates[t].clone();if(!(null===e||"string"==typeof e||n.isMoment(e)||e instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");this._setValue(null===e?null:this._parseInputDate(e),t)},y.prototype.format=function(e){if(0===arguments.length)return this._options.format;if("string"!=typeof e&&("boolean"!=typeof e||!1!==e))throw new TypeError("format() expects a string or boolean:false parameter "+e);this._options.format=e,this.actualFormat&&this._initFormatting()},y.prototype.timeZone=function(e){if(0===arguments.length)return this._options.timeZone;if("string"!=typeof e)throw new TypeError("newZone() expects a string parameter");this._options.timeZone=e},y.prototype.dayViewHeaderFormat=function(e){if(0===arguments.length)return this._options.dayViewHeaderFormat;if("string"!=typeof e)throw new TypeError("dayViewHeaderFormat() expects a string parameter");this._options.dayViewHeaderFormat=e},y.prototype.extraFormats=function(e){if(0===arguments.length)return this._options.extraFormats;if(!1!==e&&!(e instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");this._options.extraFormats=e,this.parseFormats&&this._initFormatting()},y.prototype.disabledDates=function(e){if(0===arguments.length)return this._options.disabledDates?o.extend({},this._options.disabledDates):this._options.disabledDates;if(!e)return this._options.disabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("disabledDates() expects an array parameter");this._options.disabledDates=this._indexGivenDates(e),this._options.enabledDates=!1,this._update()},y.prototype.enabledDates=function(e){if(0===arguments.length)return this._options.enabledDates?o.extend({},this._options.enabledDates):this._options.enabledDates;if(!e)return this._options.enabledDates=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("enabledDates() expects an array parameter");this._options.enabledDates=this._indexGivenDates(e),this._options.disabledDates=!1,this._update()},y.prototype.daysOfWeekDisabled=function(e){if(0===arguments.length)return this._options.daysOfWeekDisabled.splice(0);if("boolean"==typeof e&&!e)return this._options.daysOfWeekDisabled=!1,this._update(),!0;if(!(e instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(this._options.daysOfWeekDisabled=e.reduce(function(e,t){return 6<(t=parseInt(t,10))||t<0||isNaN(t)||-1===e.indexOf(t)&&e.push(t),e},[]).sort(),this._options.useCurrent&&!this._options.keepInvalid)for(var t=0;t").append(S("
    ").addClass("prev").attr("data-action","previous").append(S("").addClass(this._options.icons.previous))).append(S("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",this._options.calendarWeeks?"6":"5")).append(S("").addClass("next").attr("data-action","next").append(S("").addClass(this._options.icons.next)))),t=S("
    ").attr("colspan",this._options.calendarWeeks?"8":"7")));return[S("
    ").addClass("datepicker-days").append(S("").addClass("table table-sm").append(e).append(S(""))),S("
    ").addClass("datepicker-months").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-years").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone())),S("
    ").addClass("datepicker-decades").append(S("
    ").addClass("table-condensed").append(e.clone()).append(t.clone()))]},E.prototype._getTimePickerMainTemplate=function(){var e=S(""),t=S(""),n=S("");return this._isEnabled("h")&&(e.append(S("
    ").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:this._options.tooltips.pickHour}).attr("data-action","showHours"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(S("").addClass(this._options.icons.down))))),this._isEnabled("m")&&(this._isEnabled("h")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:this._options.tooltips.pickMinute}).attr("data-action","showMinutes"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(S("").addClass(this._options.icons.down))))),this._isEnabled("s")&&(this._isEnabled("m")&&(e.append(S("").addClass("separator")),t.append(S("").addClass("separator").html(":")),n.append(S("").addClass("separator"))),e.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(S("").addClass(this._options.icons.up)))),t.append(S("").append(S("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:this._options.tooltips.pickSecond}).attr("data-action","showSeconds"))),n.append(S("").append(S("").attr({href:"#",tabindex:"-1",title:this._options.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(S("").addClass(this._options.icons.down))))),this.use24Hours||(e.append(S("").addClass("separator")),t.append(S("").append(S("").addClass("separator"))),S("
    ").addClass("timepicker-picker").append(S("").addClass("table-condensed").append([e,t,n]))},E.prototype._getTimePickerTemplate=function(){var e=S("
    ").addClass("timepicker-hours").append(S("
    ").addClass("table-condensed")),t=S("
    ").addClass("timepicker-minutes").append(S("
    ").addClass("table-condensed")),n=S("
    ").addClass("timepicker-seconds").append(S("
    ").addClass("table-condensed")),i=[this._getTimePickerMainTemplate()];return this._isEnabled("h")&&i.push(e),this._isEnabled("m")&&i.push(t),this._isEnabled("s")&&i.push(n),i},E.prototype._getToolbar=function(){var e=[];if(this._options.buttons.showToday&&e.push(S("
    ").append(S("").attr({href:"#",tabindex:"-1","data-action":"today",title:this._options.tooltips.today}).append(S("").addClass(this._options.icons.today)))),!this._options.sideBySide&&this._hasDate()&&this._hasTime()){var t=void 0,n=void 0;n="times"===this._options.viewMode?(t=this._options.tooltips.selectDate,this._options.icons.date):(t=this._options.tooltips.selectTime,this._options.icons.time),e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"togglePicker",title:t}).append(S("").addClass(n))))}return this._options.buttons.showClear&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"clear",title:this._options.tooltips.clear}).append(S("").addClass(this._options.icons.clear)))),this._options.buttons.showClose&&e.push(S("").append(S("").attr({href:"#",tabindex:"-1","data-action":"close",title:this._options.tooltips.close}).append(S("").addClass(this._options.icons.close)))),0===e.length?"":S("").addClass("table-condensed").append(S("").append(S("").append(e)))},E.prototype._getTemplate=function(){var e=S("
    ").addClass("bootstrap-datetimepicker-widget dropdown-menu"),t=S("
    ").addClass("datepicker").append(this._getDatePickerTemplate()),n=S("
    ").addClass("timepicker").append(this._getTimePickerTemplate()),i=S("
      ").addClass("list-unstyled"),r=S("
    • ").addClass("picker-switch"+(this._options.collapse?" accordion-toggle":"")).append(this._getToolbar());return this._options.inline&&e.removeClass("dropdown-menu"),this.use24Hours&&e.addClass("usetwentyfour"),this._isEnabled("s")&&!this.use24Hours&&e.addClass("wider"),this._options.sideBySide&&this._hasDate()&&this._hasTime()?(e.addClass("timepicker-sbs"),"top"===this._options.toolbarPlacement&&e.append(r),e.append(S("
      ").addClass("row").append(t.addClass("col-md-6")).append(n.addClass("col-md-6"))),"bottom"!==this._options.toolbarPlacement&&"default"!==this._options.toolbarPlacement||e.append(r),e):("top"===this._options.toolbarPlacement&&i.append(r),this._hasDate()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasTime()?"collapse":"").addClass(this._options.collapse&&this._hasTime()&&"times"===this._options.viewMode?"":"show").append(t)),"default"===this._options.toolbarPlacement&&i.append(r),this._hasTime()&&i.append(S("
    • ").addClass(this._options.collapse&&this._hasDate()?"collapse":"").addClass(this._options.collapse&&this._hasDate()&&"times"===this._options.viewMode?"show":"").append(n)),"bottom"===this._options.toolbarPlacement&&i.append(r),e.append(i))},E.prototype._place=function(e){var t=e&&e.data&&e.data.picker||this,n=t._options.widgetPositioning.vertical,i=t._options.widgetPositioning.horizontal,r=void 0,a=(t.component&&t.component.length?t.component:t._element).position(),o=(t.component&&t.component.length?t.component:t._element).offset();if(t._options.widgetParent)r=t._options.widgetParent.append(t.widget);else if(t._element.is("input"))r=t._element.after(t.widget).parent();else{if(t._options.inline)return void(r=t._element.append(t.widget));r=t._element,t._element.children().first().after(t.widget)}if("auto"===n&&(n=o.top+1.5*t.widget.height()>=S(window).height()+S(window).scrollTop()&&t.widget.height()+t._element.outerHeight()S(window).width()?"right":"left"),"top"===n?t.widget.addClass("top").removeClass("bottom"):t.widget.addClass("bottom").removeClass("top"),"right"===i?t.widget.addClass("float-right"):t.widget.removeClass("float-right"),"relative"!==r.css("position")&&(r=r.parents().filter(function(){return"relative"===S(this).css("position")}).first()),0===r.length)throw new Error("datetimepicker component should be placed within a relative positioned container");t.widget.css({top:"top"===n?"auto":a.top+t._element.outerHeight()+"px",bottom:"top"===n?r.outerHeight()-(r===t._element?0:a.top)+"px":"auto",left:"left"===i?(r===t._element?0:a.left)+"px":"auto",right:"left"===i?"auto":r.outerWidth()-t._element.outerWidth()-(r===t._element?0:a.left)+"px"})},E.prototype._fillDow=function(){var e=S("
    "),t=this._viewDate.clone().startOf("w").startOf("d");for(!0===this._options.calendarWeeks&&e.append(S(""),this._options.calendarWeeks&&r.append('"),n.push(r)),a="",i.isBefore(this._viewDate,"M")&&(a+=" old"),i.isAfter(this._viewDate,"M")&&(a+=" new"),this._options.allowMultidate){var s=this._datesFormatted.indexOf(i.format("YYYY-MM-DD"));-1!==s&&i.isSame(this._datesFormatted[s],"d")&&!this.unset&&(a+=" active")}else i.isSame(this._getLastPickedDate(),"d")&&!this.unset&&(a+=" active");this._isValid(i,"d")||(a+=" disabled"),i.isSame(this.getMoment(),"d")&&(a+=" today"),0!==i.day()&&6!==i.day()||(a+=" weekend"),r.append('"),i.add(1,"d")}e.find("tbody").empty().append(n),this._updateMonths(),this._updateYears(),this._updateDecades()}},E.prototype._fillHours=function(){var e=this.widget.find(".timepicker-hours table"),t=this._viewDate.clone().startOf("d"),n=[],i=S("");for(11"),n.push(i)),i.append('"),t.add(1,"h");e.empty().append(n)},E.prototype._fillMinutes=function(){for(var e=this.widget.find(".timepicker-minutes table"),t=this._viewDate.clone().startOf("h"),n=[],i=1===this._options.stepping?5:this._options.stepping,r=S("");this._viewDate.isSame(t,"h");)t.minute()%(4*i)==0&&(r=S(""),n.push(r)),r.append('"),t.add(i,"m");e.empty().append(n)},E.prototype._fillSeconds=function(){for(var e=this.widget.find(".timepicker-seconds table"),t=this._viewDate.clone().startOf("m"),n=[],i=S("");this._viewDate.isSame(t,"m");)t.second()%20==0&&(i=S(""),n.push(i)),i.append('"),t.add(5,"s");e.empty().append(n)},E.prototype._fillTime=function(){var e=void 0,t=void 0,n=this.widget.find(".timepicker span[data-time-component]");this.use24Hours||(e=this.widget.find(".timepicker [data-action=togglePeriod]"),t=this._getLastPickedDate().clone().add(12<=this._getLastPickedDate().hours()?-12:12,"h"),e.text(this._getLastPickedDate().format("A")),this._isValid(t,"h")?e.removeClass("disabled"):e.addClass("disabled")),n.filter("[data-time-component=hours]").text(this._getLastPickedDate().format(this.use24Hours?"HH":"hh")),n.filter("[data-time-component=minutes]").text(this._getLastPickedDate().format("mm")),n.filter("[data-time-component=seconds]").text(this._getLastPickedDate().format("ss")),this._fillHours(),this._fillMinutes(),this._fillSeconds()},E.prototype._doAction=function(e,t){var n=this._getLastPickedDate();if(S(e.currentTarget).is(".disabled"))return!1;switch(t=t||S(e.currentTarget).data("action")){case"next":var i=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.add(T.DatePickerModes[this.currentViewMode].NAV_STEP,i),this._fillDate(),this._viewUpdate(i);break;case"previous":var r=T.DatePickerModes[this.currentViewMode].NAV_FUNCTION;this._viewDate.subtract(T.DatePickerModes[this.currentViewMode].NAV_STEP,r),this._fillDate(),this._viewUpdate(r);break;case"pickerSwitch":this._showMode(1);break;case"selectMonth":var a=S(e.target).closest("tbody").find("span").index(S(e.target));this._viewDate.month(a),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()).month(this._viewDate.month()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("M");break;case"selectYear":var o=parseInt(S(e.target).text(),10)||0;this._viewDate.year(o),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDecade":var s=parseInt(S(e.target).data("selection"),10)||0;this._viewDate.year(s),this.currentViewMode===this.MinViewModeNumber?(this._setValue(n.clone().year(this._viewDate.year()),this._getLastPickedDateIndex()),this._options.inline||this.hide()):(this._showMode(-1),this._fillDate()),this._viewUpdate("YYYY");break;case"selectDay":var l=this._viewDate.clone();S(e.target).is(".old")&&l.subtract(1,"M"),S(e.target).is(".new")&&l.add(1,"M");var u=l.date(parseInt(S(e.target).text(),10)),c=0;this._options.allowMultidate?-1!==(c=this._datesFormatted.indexOf(u.format("YYYY-MM-DD")))?this._setValue(null,c):this._setValue(u,this._getLastPickedDateIndex()+1):this._setValue(u,this._getLastPickedDateIndex()),this._hasTime()||this._options.keepOpen||this._options.inline||this._options.allowMultidate||this.hide();break;case"incrementHours":var d=n.clone().add(1,"h");this._isValid(d,"h")&&this._setValue(d,this._getLastPickedDateIndex());break;case"incrementMinutes":var h=n.clone().add(this._options.stepping,"m");this._isValid(h,"m")&&this._setValue(h,this._getLastPickedDateIndex());break;case"incrementSeconds":var f=n.clone().add(1,"s");this._isValid(f,"s")&&this._setValue(f,this._getLastPickedDateIndex());break;case"decrementHours":var p=n.clone().subtract(1,"h");this._isValid(p,"h")&&this._setValue(p,this._getLastPickedDateIndex());break;case"decrementMinutes":var m=n.clone().subtract(this._options.stepping,"m");this._isValid(m,"m")&&this._setValue(m,this._getLastPickedDateIndex());break;case"decrementSeconds":var g=n.clone().subtract(1,"s");this._isValid(g,"s")&&this._setValue(g,this._getLastPickedDateIndex());break;case"togglePeriod":this._setValue(n.clone().add(12<=n.hours()?-12:12,"h"),this._getLastPickedDateIndex());break;case"togglePicker":var v=S(e.target),y=v.closest("a"),b=v.closest("ul"),_=b.find(".show"),w=b.find(".collapse:not(.show)"),D=v.is("span")?v:v.find("span"),x=void 0;if(_&&_.length){if((x=_.data("collapse"))&&x.transitioning)return!0;_.collapse?(_.collapse("hide"),w.collapse("show")):(_.removeClass("show"),w.addClass("show")),D.toggleClass(this._options.icons.time+" "+this._options.icons.date),D.hasClass(this._options.icons.date)?y.attr("title",this._options.tooltips.selectDate):y.attr("title",this._options.tooltips.selectTime)}break;case"showPicker":this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(),this.widget.find(".timepicker .timepicker-picker").show();break;case"showHours":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-hours").show();break;case"showMinutes":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-minutes").show();break;case"showSeconds":this.widget.find(".timepicker .timepicker-picker").hide(),this.widget.find(".timepicker .timepicker-seconds").show();break;case"selectHour":var C=parseInt(S(e.target).text(),10);this.use24Hours||(12<=n.hours()?12!==C&&(C+=12):12===C&&(C=0)),this._setValue(n.clone().hours(C),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("m")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectMinute":this._setValue(n.clone().minutes(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._isEnabled("s")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"selectSecond":this._setValue(n.clone().seconds(parseInt(S(e.target).text(),10)),this._getLastPickedDateIndex()),this._isEnabled("a")||this._options.keepOpen||this._options.inline?this._doAction(e,"showPicker"):this.hide();break;case"clear":this.clear();break;case"close":this.hide();break;case"today":var k=this.getMoment();this._isValid(k,"d")&&this._setValue(k,this._getLastPickedDateIndex())}return!1},E.prototype.hide=function(){var t=!1;this.widget&&(this.widget.find(".collapse").each(function(){var e=S(this).data("collapse");return!e||!e.transitioning||!(t=!0)}),t||(this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this.widget.hide(),S(window).off("resize",this._place()),this.widget.off("click","[data-action]"),this.widget.off("mousedown",!1),this.widget.remove(),this.widget=!1,this._notifyEvent({type:T.Event.HIDE,date:this._getLastPickedDate().clone()}),void 0!==this.input&&this.input.blur(),this._viewDate=this._getLastPickedDate().clone()))},E.prototype.show=function(){var e=void 0,t={year:function(e){return e.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(e){return e.date(1).hours(0).seconds(0).minutes(0)},day:function(e){return e.hours(0).seconds(0).minutes(0)},hour:function(e){return e.seconds(0).minutes(0)},minute:function(e){return e.seconds(0)}};if(void 0!==this.input){if(this.input.prop("disabled")||!this._options.ignoreReadonly&&this.input.prop("readonly")||this.widget)return;void 0!==this.input.val()&&0!==this.input.val().trim().length?this._setValue(this._parseInputDate(this.input.val().trim()),0):this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0))}else this.unset&&this._options.useCurrent&&(e=this.getMoment(),"string"==typeof this._options.useCurrent&&(e=t[this._options.useCurrent](e)),this._setValue(e,0));this.widget=this._getTemplate(),this._fillDow(),this._fillMonths(),this.widget.find(".timepicker-hours").hide(),this.widget.find(".timepicker-minutes").hide(),this.widget.find(".timepicker-seconds").hide(),this._update(),this._showMode(),S(window).on("resize",{picker:this},this._place),this.widget.on("click","[data-action]",S.proxy(this._doAction,this)),this.widget.on("mousedown",!1),this.component&&this.component.hasClass("btn")&&this.component.toggleClass("active"),this._place(),this.widget.show(),void 0!==this.input&&this._options.focusOnShow&&!this.input.is(":focus")&&this.input.focus(),this._notifyEvent({type:T.Event.SHOW})},E.prototype.destroy=function(){this.hide(),this._element.removeData(T.DATA_KEY),this._element.removeData("date")},E.prototype.disable=function(){this.hide(),this.component&&this.component.hasClass("btn")&&this.component.addClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!0)},E.prototype.enable=function(){this.component&&this.component.hasClass("btn")&&this.component.removeClass("disabled"),void 0!==this.input&&this.input.prop("disabled",!1)},E.prototype.toolbarPlacement=function(e){if(0===arguments.length)return this._options.toolbarPlacement;if("string"!=typeof e)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===x.indexOf(e))throw new TypeError("toolbarPlacement() parameter must be one of ("+x.join(", ")+") value");this._options.toolbarPlacement=e,this.widget&&(this.hide(),this.show())},E.prototype.widgetPositioning=function(e){if(0===arguments.length)return S.extend({},this._options.widgetPositioning);if("[object Object]"!=={}.toString.call(e))throw new TypeError("widgetPositioning() expects an object variable");if(e.horizontal){if("string"!=typeof e.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(e.horizontal=e.horizontal.toLowerCase(),-1===D.indexOf(e.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+D.join(", ")+")");this._options.widgetPositioning.horizontal=e.horizontal}if(e.vertical){if("string"!=typeof e.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(e.vertical=e.vertical.toLowerCase(),-1===w.indexOf(e.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+w.join(", ")+")");this._options.widgetPositioning.vertical=e.vertical}this._update()},E.prototype.widgetParent=function(e){if(0===arguments.length)return this._options.widgetParent;if("string"==typeof e&&(e=S(e)),null!==e&&"string"!=typeof e&&!(e instanceof S))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");this._options.widgetParent=e,this.widget&&(this.hide(),this.show())},E._jQueryHandleThis=function(e,t,n){var i=S(e).data(T.DATA_KEY);if("object"===(void 0===t?"undefined":r(t))&&S.extend({},T.Default,t),i||(i=new E(S(e),t),S(e).data(T.DATA_KEY,i)),"string"==typeof t){if(void 0===i[t])throw new Error('No method named "'+t+'"');return void 0===n?i[t]():i[t](n)}},E._jQueryInterface=function(e,t){return 1===this.length?E._jQueryHandleThis(this[0],e,t):this.each(function(){E._jQueryHandleThis(this,e,t)})},C=E,S(document).on(T.Event.CLICK_DATA_API,T.Selector.DATA_TOGGLE,function(){var e=k(S(this));0!==e.length&&C._jQueryInterface.call(e,"toggle")}).on(T.Event.CHANGE,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_change",e)}).on(T.Event.BLUR,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&(n._options.debug||window.debug||C._jQueryInterface.call(t,"hide",e))}).on(T.Event.KEYDOWN,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keydown",e)}).on(T.Event.KEYUP,"."+T.ClassName.INPUT,function(e){var t=k(S(this));0!==t.length&&C._jQueryInterface.call(t,"_keyup",e)}).on(T.Event.FOCUS,"."+T.ClassName.INPUT,function(e){var t=k(S(this)),n=t.data(T.DATA_KEY);0!==t.length&&n._options.allowInputToggle&&C._jQueryInterface.call(t,"show",e)}),S.fn[T.NAME]=C._jQueryInterface,S.fn[T.NAME].Constructor=C,S.fn[T.NAME].noConflict=function(){return S.fn[T.NAME]=_,C._jQueryInterface};function k(e){var t=e.data("target"),n=void 0;return t||(t=e.attr("href")||"",t=/^#[a-z]/i.test(t)?t:null),0===(n=S(t)).length||n.data(T.DATA_KEY)||S.extend({},n.data(),S(this).data()),n}function E(e,t){a(this,E);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,b.call(this,e,t));return n._init(),n}}(),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(E,M){function A(){return new Date(Date.UTC.apply(Date,arguments))}function O(){var e=new Date;return A(e.getFullYear(),e.getMonth(),e.getDate())}function a(e,t){return e.getUTCFullYear()===t.getUTCFullYear()&&e.getUTCMonth()===t.getUTCMonth()&&e.getUTCDate()===t.getUTCDate()}function e(e,t){return function(){return t!==M&&E.fn.datepicker.deprecated(t),this[e].apply(this,arguments)}}function w(e,t){E.data(e,"datepicker",this),this._events=[],this._secondaryEvents=[],this._process_options(t),this.dates=new n,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=E(e),this.isInput=this.element.is("input"),this.inputField=this.isInput?this.element:this.element.find("input"),this.component=!!this.element.hasClass("date")&&this.element.find(".add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn"),this.component&&0===this.component.length&&(this.component=!1),this.isInline=!this.component&&this.element.is("div"),this.picker=E(I.template),this._check_template(this.o.templates.leftArrow)&&this.picker.find(".prev").html(this.o.templates.leftArrow),this._check_template(this.o.templates.rightArrow)&&this.picker.find(".next").html(this.o.templates.rightArrow),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.o.calendarWeeks&&this.picker.find(".datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear").attr("colspan",function(e,t){return Number(t)+1}),this._process_options({startDate:this._o.startDate,endDate:this._o.endDate,daysOfWeekDisabled:this.o.daysOfWeekDisabled,daysOfWeekHighlighted:this.o.daysOfWeekHighlighted,datesDisabled:this.o.datesDisabled}),this._allow_update=!1,this.setViewMode(this.o.startView),this._allow_update=!0,this.fillDow(),this.fillMonths(),this.update(),this.isInline&&this.show()}var t,n=(t={get:function(e){return this.slice(e)[0]},contains:function(e){for(var t=e&&e.valueOf(),n=0,i=this.length;n]/g)||[]).length<=0||0this.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate),t?(this.setValue(),this.element.change()):this.dates.length&&String(e)!==String(this.dates)&&t&&(this._trigger("changeDate"),this.element.change()),!this.dates.length&&e.length&&(this._trigger("clearDate"),this.element.change()),this.fill(),this},fillDow:function(){if(this.o.showWeekDays){var e=this.o.weekStart,t="";for(this.o.calendarWeeks&&(t+='');e";t+="",this.picker.find(".datepicker-days thead").append(t)}},fillMonths:function(){for(var e=this._utc_to_local(this.viewDate),t="",n=0;n<12;n++)t+=''+N[this.o.language].monthsShort[n]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=E.map(e,function(e){return e.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var t=[],n=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),r=O();return e.getUTCFullYear()n||e.getUTCFullYear()===n&&e.getUTCMonth()>i)&&t.push("new"),this.focusDate&&e.valueOf()===this.focusDate.valueOf()&&t.push("focused"),this.o.todayHighlight&&a(e,r)&&t.push("today"),-1!==this.dates.contains(e)&&t.push("active"),this.dateWithinRange(e)||t.push("disabled"),this.dateIsDisabled(e)&&t.push("disabled","disabled-date"),-1!==E.inArray(e.getUTCDay(),this.o.daysOfWeekHighlighted)&&t.push("highlighted"),this.range&&(e>this.range[0]&&e"+v+"";h.find(".datepicker-switch").text(f+"-"+p),h.find("td").html(c)},fill:function(){var e,t,n=new Date(this.viewDate),r=n.getUTCFullYear(),i=n.getUTCMonth(),a=this.o.startDate!==-1/0?this.o.startDate.getUTCFullYear():-1/0,o=this.o.startDate!==-1/0?this.o.startDate.getUTCMonth():-1/0,s=this.o.endDate!==1/0?this.o.endDate.getUTCFullYear():1/0,l=this.o.endDate!==1/0?this.o.endDate.getUTCMonth():1/0,u=N[this.o.language].today||N.en.today||"",c=N[this.o.language].clear||N.en.clear||"",d=N[this.o.language].titleFormat||N.en.titleFormat,h=O(),f=(!0===this.o.todayBtn||"linked"===this.o.todayBtn)&&h>=this.o.startDate&&h<=this.o.endDate&&!this.weekOfDateIsDisabled(h);if(!isNaN(r)&&!isNaN(i)){this.picker.find(".datepicker-days .datepicker-switch").text(I.formatDate(n,d,this.o.language)),this.picker.find("tfoot .today").text(u).css("display",f?"table-cell":"none"),this.picker.find("tfoot .clear").text(c).css("display",!0===this.o.clearBtn?"table-cell":"none"),this.picker.find("thead .datepicker-title").text(this.o.title).css("display","string"==typeof this.o.title&&""!==this.o.title?"table-cell":"none"),this.updateNavArrows(),this.fillMonths();var p=A(r,i,0),m=p.getUTCDate();p.setUTCDate(m-(p.getUTCDay()-this.o.weekStart+7)%7);var g=new Date(p);p.getUTCFullYear()<100&&g.setUTCFullYear(p.getUTCFullYear()),g.setUTCDate(g.getUTCDate()+42),g=g.valueOf();for(var v,y,b=[];p.valueOf()"),this.o.calendarWeeks)){var _=new Date(+p+(this.o.weekStart-v-7)%7*864e5),w=new Date(Number(_)+(11-_.getUTCDay())%7*864e5),D=new Date(Number(D=A(w.getUTCFullYear(),0,1))+(11-D.getUTCDay())%7*864e5),x=(w-D)/864e5/7+1;b.push('")}(y=this.getClassNames(p)).push("day");var C=p.getUTCDate();this.o.beforeShowDay!==E.noop&&((t=this.o.beforeShowDay(this._utc_to_local(p)))===M?t={}:"boolean"==typeof t?t={enabled:t}:"string"==typeof t&&(t={classes:t}),!1===t.enabled&&y.push("disabled"),t.classes&&(y=y.concat(t.classes.split(/\s+/))),t.tooltip&&(e=t.tooltip),t.content&&(C=t.content)),y=E.isFunction(E.uniqueSort)?E.uniqueSort(y):E.unique(y),b.push('"),e=null,v===this.o.weekEnd&&b.push(""),p.setUTCDate(p.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").html(b.join(""));var k=N[this.o.language].monthsTitle||N.en.monthsTitle||"Months",T=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?k:r).end().find("tbody span").removeClass("active");if(E.each(this.dates,function(e,t){t.getUTCFullYear()===r&&T.eq(t.getUTCMonth()).addClass("active")}),(rs;break;case 0:e=i<=a&&r<=o,t=s<=i&&l<=r}this.picker.find(".prev").toggleClass("disabled",e),this.picker.find(".next").toggleClass("disabled",t)}},click:function(e){var t,n,i;e.preventDefault(),e.stopPropagation(),(t=E(e.target)).hasClass("datepicker-switch")&&this.viewMode!==this.o.maxViewMode&&this.setViewMode(this.viewMode+1),t.hasClass("today")&&!t.hasClass("day")&&(this.setViewMode(0),this._setDate(O(),"linked"===this.o.todayBtn?null:"view")),t.hasClass("clear")&&this.clearDates(),t.hasClass("disabled")||(t.hasClass("month")||t.hasClass("year")||t.hasClass("decade")||t.hasClass("century"))&&(this.viewDate.setUTCDate(1),1===this.viewMode?(i=t.parent().find("span").index(t),n=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(i)):(i=0,n=Number(t.text()),this.viewDate.setUTCFullYear(n)),this._trigger(I.viewModes[this.viewMode-1].e,this.viewDate),this.viewMode===this.o.minViewMode?this._setDate(A(n,i,1)):(this.setViewMode(this.viewMode-1),this.fill())),this.picker.is(":visible")&&this._focused_from&&this._focused_from.focus(),delete this._focused_from},dayCellClick:function(e){var t=E(e.currentTarget).data("date"),n=new Date(t);this.o.updateViewDate&&(n.getUTCFullYear()!==this.viewDate.getUTCFullYear()&&this._trigger("changeYear",this.viewDate),n.getUTCMonth()!==this.viewDate.getUTCMonth()&&this._trigger("changeMonth",this.viewDate)),this._setDate(n)},navArrowsClick:function(e){var t=E(e.currentTarget).hasClass("prev")?-1:1;0!==this.viewMode&&(t*=12*I.viewModes[this.viewMode].navStep),this.viewDate=this.moveMonth(this.viewDate,t),this._trigger(I.viewModes[this.viewMode].e,this.viewDate),this.fill()},_toggle_multidate:function(e){var t=this.dates.contains(e);if(e||this.dates.clear(),-1!==t?(!0===this.o.multidate||1this.o.multidate;)this.dates.remove(0)},_setDate:function(e,t){t&&"date"!==t||this._toggle_multidate(e&&new Date(e)),(!t&&this.o.updateViewDate||"view"===t)&&(this.viewDate=e&&new Date(e)),this.fill(),this.setValue(),t&&"view"===t||this._trigger("changeDate"),this.inputField.trigger("change"),!this.o.autoclose||t&&"date"!==t||this.hide()},moveDay:function(e,t){var n=new Date(e);return n.setUTCDate(e.getUTCDate()+t),n},moveWeek:function(e,t){return this.moveDay(e,7*t)},moveMonth:function(e,t){if(!function(e){return e&&!isNaN(e.getTime())}(e))return this.o.defaultViewDate;if(!t)return e;var n,i,r=new Date(e.valueOf()),a=r.getUTCDate(),o=r.getUTCMonth(),s=Math.abs(t);if(t=0=this.o.startDate&&e<=this.o.endDate},keydown:function(e){if(this.picker.is(":visible")){var t,n,i=!1,r=this.focusDate||this.viewDate;switch(e.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),e.preventDefault(),e.stopPropagation();break;case 37:case 38:case 39:case 40:if(!this.o.keyboardNavigation||7===this.o.daysOfWeekDisabled.length)break;t=37===e.keyCode||38===e.keyCode?-1:1,0===this.viewMode?e.ctrlKey?(n=this.moveAvailableDate(r,t,"moveYear"))&&this._trigger("changeYear",this.viewDate):e.shiftKey?(n=this.moveAvailableDate(r,t,"moveMonth"))&&this._trigger("changeMonth",this.viewDate):37===e.keyCode||39===e.keyCode?n=this.moveAvailableDate(r,t,"moveDay"):this.weekOfDateIsDisabled(r)||(n=this.moveAvailableDate(r,t,"moveWeek")):1===this.viewMode?(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveMonth")):2===this.viewMode&&(38!==e.keyCode&&40!==e.keyCode||(t*=4),n=this.moveAvailableDate(r,t,"moveYear")),n&&(this.focusDate=this.viewDate=n,this.setValue(),this.fill(),e.preventDefault());break;case 13:if(!this.o.forceParse)break;r=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(r),i=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(e.preventDefault(),e.stopPropagation(),this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}i&&(this.dates.length?this._trigger("changeDate"):this._trigger("clearDate"),this.inputField.trigger("change"))}else 40!==e.keyCode&&27!==e.keyCode||(this.show(),e.stopPropagation())},setViewMode:function(e){this.viewMode=e,this.picker.children("div").hide().filter(".datepicker-"+I.viewModes[this.viewMode].clsName).show(),this.updateNavArrows(),this._trigger("changeViewMode",new Date(this.viewDate))}};function u(e,t){E.data(e,"datepicker",this),this.element=E(e),this.inputs=E.map(t.inputs,function(e){return e.jquery?e[0]:e}),delete t.inputs,this.keepEmptyValues=t.keepEmptyValues,delete t.keepEmptyValues,r.call(E(this.inputs),t).on("changeDate",E.proxy(this.dateUpdated,this)),this.pickers=E.map(this.inputs,function(e){return E.data(e,"datepicker")}),this.updateDates()}u.prototype={updateDates:function(){this.dates=E.map(this.pickers,function(e){return e.getUTCDate()}),this.updateRanges()},updateRanges:function(){var n=E.map(this.dates,function(e){return e.valueOf()});E.each(this.pickers,function(e,t){t.setRange(n)})},clearDates:function(){E.each(this.pickers,function(e,t){t.clearDates()})},dateUpdated:function(e){if(!this.updating){this.updating=!0;var n=E.data(e.target,"datepicker");if(n!==M){var i=n.getUTCDate(),r=this.keepEmptyValues,t=E.inArray(e.target,this.inputs),a=t-1,o=t+1,s=this.inputs.length;if(-1!==t){if(E.each(this.pickers,function(e,t){t.getUTCDate()||t!==n&&r||t.setUTCDate(i)}),ithis.dates[o])for(;othis.dates[o];)this.pickers[o++].setUTCDate(i);this.updateDates(),delete this.updating}}}},destroy:function(){E.map(this.pickers,function(e){e.destroy()}),E(this.inputs).off("changeDate",this.dateUpdated),delete this.element.data().datepicker},remove:e("destroy","Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead")};var i=E.fn.datepicker,r=function(o){var s,l=Array.apply(null,arguments);if(l.shift(),this.each(function(){var e=E(this),t=e.data("datepicker"),n="object"==typeof o&&o;if(!t){var i=function(e,t){function n(e,t){return t.toLowerCase()}var i=E(e).data(),r={},a=new RegExp("^"+t.toLowerCase()+"([A-Z])");for(var o in t=new RegExp("^"+t.toLowerCase()),i)t.test(o)&&(r[o.replace(a,n)]=i[o]);return r}(this,"date"),r=function(e){var n={};if(N[e]||(e=e.split("-")[0],N[e])){var i=N[e];return E.each(d,function(e,t){t in i&&(n[t]=i[t])}),n}}(E.extend({},c,i,n).language),a=E.extend({},c,r,i,n);t=e.hasClass("input-daterange")||a.inputs?(E.extend(a,{inputs:a.inputs||e.find("input").toArray()}),new u(this,a)):new w(this,a),e.data("datepicker",t)}"string"==typeof o&&"function"==typeof t[o]&&(s=t[o].apply(t,l))}),s===M||s instanceof w||s instanceof u)return this;if(1(new Date).getFullYear()+t&&(e-=100),e}(t,i):t)},m:function(e,t){if(isNaN(e))return e;for(t-=1;t<0;)t+=12;for(t%=12,e.setUTCMonth(t);e.getUTCMonth()!==t;)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}};g.yy=g.yyyy,g.M=g.MM=g.mm=g.m,g.dd=g.d,e=O();var v=t.parts.slice();if(a.length!==v.length&&(v=E(v).filter(function(e,t){return-1!==E.inArray(t,m)}).toArray()),a.length===v.length){var y,b,_;for(l=0,y=v.length;l",contTemplate:'',footTemplate:''};I.template='
    ").addClass("cw").text("#"));t.isBefore(this._viewDate.clone().endOf("w"));)e.append(S("").addClass("dow").text(t.format("dd"))),t.add(1,"d");this.widget.find(".datepicker-days thead").append(e)},E.prototype._fillMonths=function(){for(var e=[],t=this._viewDate.clone().startOf("y").startOf("d");t.isSame(this._viewDate,"y");)e.push(S("").attr("data-action","selectMonth").addClass("month").text(t.format("MMM"))),t.add(1,"M");this.widget.find(".datepicker-months td").empty().append(e)},E.prototype._updateMonths=function(){var e=this.widget.find(".datepicker-months"),t=e.find("th"),n=e.find("tbody").find("span"),i=this;t.eq(0).find("span").attr("title",this._options.tooltips.prevYear),t.eq(1).attr("title",this._options.tooltips.selectYear),t.eq(2).find("span").attr("title",this._options.tooltips.nextYear),e.find(".disabled").removeClass("disabled"),this._isValid(this._viewDate.clone().subtract(1,"y"),"y")||t.eq(0).addClass("disabled"),t.eq(1).text(this._viewDate.year()),this._isValid(this._viewDate.clone().add(1,"y"),"y")||t.eq(2).addClass("disabled"),n.removeClass("active"),this._getLastPickedDate().isSame(this._viewDate,"y")&&!this.unset&&n.eq(this._getLastPickedDate().month()).addClass("active"),n.each(function(e){i._isValid(i._viewDate.clone().month(e),"M")||S(this).addClass("disabled")})},E.prototype._getStartEndYear=function(e,t){var n=e/10,i=Math.floor(t/e)*e;return[i,i+9*n,Math.floor(t/n)*n]},E.prototype._updateYears=function(){var e=this.widget.find(".datepicker-years"),t=e.find("th"),n=this._getStartEndYear(10,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevDecade),t.eq(1).attr("title",this._options.tooltips.selectDecade),t.eq(2).find("span").attr("title",this._options.tooltips.nextDecade),e.find(".disabled").removeClass("disabled"),this._options.minDate&&this._options.minDate.isAfter(i,"y")&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),a+=''+(i.year()-1)+"";!i.isAfter(r,"y");)a+=''+i.year()+"",i.add(1,"y");a+=''+i.year()+"",e.find("td").html(a)},E.prototype._updateDecades=function(){var e=this.widget.find(".datepicker-decades"),t=e.find("th"),n=this._getStartEndYear(100,this._viewDate.year()),i=this._viewDate.clone().year(n[0]),r=this._viewDate.clone().year(n[1]),a=!1,o=!1,s=void 0,l="";for(t.eq(0).find("span").attr("title",this._options.tooltips.prevCentury),t.eq(2).find("span").attr("title",this._options.tooltips.nextCentury),e.find(".disabled").removeClass("disabled"),(0===i.year()||this._options.minDate&&this._options.minDate.isAfter(i,"y"))&&t.eq(0).addClass("disabled"),t.eq(1).text(i.year()+"-"+r.year()),this._options.maxDate&&this._options.maxDate.isBefore(r,"y")&&t.eq(2).addClass("disabled"),i.year()-10<0?l+=" ":l+=''+(i.year()-10)+"";!i.isAfter(r,"y");)s=i.year()+11,a=this._options.minDate&&this._options.minDate.isAfter(i,"y")&&this._options.minDate.year()<=s,o=this._options.maxDate&&this._options.maxDate.isAfter(i,"y")&&this._options.maxDate.year()<=s,l+=''+i.year()+"",i.add(10,"y");l+=''+i.year()+"",e.find("td").html(l)},E.prototype._fillDate=function(){var e=this.widget.find(".datepicker-days"),t=e.find("th"),n=[],i=void 0,r=void 0,a=void 0,o=void 0;if(this._hasDate()){for(t.eq(0).find("span").attr("title",this._options.tooltips.prevMonth),t.eq(1).attr("title",this._options.tooltips.selectMonth),t.eq(2).find("span").attr("title",this._options.tooltips.nextMonth),e.find(".disabled").removeClass("disabled"),t.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)),this._isValid(this._viewDate.clone().subtract(1,"M"),"M")||t.eq(0).addClass("disabled"),this._isValid(this._viewDate.clone().add(1,"M"),"M")||t.eq(2).addClass("disabled"),i=this._viewDate.clone().startOf("M").startOf("w").startOf("d"),o=0;o<42;o++){if(0===i.weekday()&&(r=S("
    '+i.week()+"'+i.date()+"
    '+t.format(this.use24Hours?"HH":"hh")+"
    '+t.format("mm")+"
    '+t.format("ss")+"
     
    '+x+"'+C+"
    '+c.templates.leftArrow+''+c.templates.rightArrow+"
    '+I.headTemplate+""+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+'
    '+I.headTemplate+I.contTemplate+I.footTemplate+"
    ",E.fn.datepicker.DPGlobal=I,E.fn.datepicker.noConflict=function(){return E.fn.datepicker=i,this},E.fn.datepicker.version="1.9.0",E.fn.datepicker.deprecated=function(e){var t=window.console;t&&t.warn&&t.warn("DEPRECATED: "+e)},E(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var t=E(this);t.data("datepicker")||(e.preventDefault(),r.call(t,"show"))}),E(function(){r.call(E('[data-provide="datepicker-inline"]'))})}),jQuery.fn.datepicker.dates.fa={days:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"],daysShort:["یک","دو","سه","چهار","پنج","جمعه","شنبه","یک"],daysMin:["ی","د","س","چ","پ","ج","ش","ی"],months:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthsShort:["ژان","فور","مار","آور","مه","ژون","ژوی","اوت","سپت","اکت","نوا","دسا"],today:"امروز",clear:"پاک کن",weekStart:1,format:"yyyy/mm/dd"},jQuery.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"},jQuery.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"},jQuery.fn.datepicker.dates.sv={days:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],daysShort:["sön","mån","tis","ons","tor","fre","lör"],daysMin:["sö","må","ti","on","to","fr","lö"],months:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"},jQuery.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"选择月份",clear:"清除",format:"yyyy-mm-dd",titleFormat:"yyyy年mm月",weekStart:1};var Menu={init:function(){$(function(){Menu.itemClick()})},itemClick:function(){$(".menu-button").click(function(e){e.preventDefault(),$(".menu-item").is(":visible")?$(".menu-item").css("display",""):$(".menu-item").show()})}};Menu.init(),ko.bindingHandlers.modal={init:function(e,t){$(e).modal({show:!1});var n=t();ko.isObservable(n)&&$(e).on("hidden.bs.modal",function(){n(!1)})},update:function(e,t){var n=t();ko.utils.unwrapObservable(n)?$(e).modal("show"):$(e).modal("hide")}},ko.components.register("picker",{viewModel:function(n){var i=this;this.textTerm=ko.observable("").extend({rateLimit:500}),this.minSearchText=ko.observable(n.minSearchText||2),this.multipleSelect=ko.observable(n.multipleSelect||!1),this.searchInputPlaceholder=ko.observable(n.searchInputPlaceholder||"Enter "+this.minSearchText()+" or more characters"),this.selectedItemsTitle=ko.observable(n.selectedItemsTitle||"Selected: "),this.searchResultTitle=ko.observable(n.searchResultTitle||"Search result: "),this.suggestedItemsTitle=ko.observable(n.suggestedItemsTitle||"Suggested items: "),this.noItemSelectedTitle=ko.observable(n.noItemSelectedTitle||"No item/s selected"),this.showAllItemsTitle=ko.observable(n.showAllItemsTitle||"more"),this.allowSuggestedItems=ko.observable(n.allowSuggestedItems&&n.url||!1),this.topSuggestedItems=ko.observable(n.topSuggestedItems||5),this.allowItemAlreadySelectedNotification=ko.observable(n.allowItemAlreadySelectedNotification||!0),this.itemAlreadySelectedTitle=ko.observable(n.itemAlreadySelectedTitle||"item already selected"),this.searchResult=ko.observableArray([]),this.selectedResult=ko.observableArray(n.selectedItems||[]),this.suggestedResult=ko.observableArray([]),this.loading=ko.observable(!1),this.isVisibleEditDialog=ko.observable(!1),this.editedItem=ko.observable(""),this.editedItemOriginal=ko.observable("");var e=ko.toJSON(this.selectedResult);!0===this.multipleSelect()?0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(e):0===this.selectedResult().length?$("#"+n.hiddenId).val(""):$("#"+n.hiddenId).val(this.selectedResult()[0]),this.textTerm.subscribe(function(t){""===t.trim()&&i.searchResult([]),""!==t.trim()&&t.trim().length>=i.minSearchText()&&(n.url?(i.loading(!0),$.get(n.url+"="+t,function(e){-1===e.indexOf(t)&&e.push(t),i.searchResult(e),i.loading(!1)})):i.searchResult([t]))}),this.notify=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.info(e+" "+this.itemAlreadySelectedTitle())},this.notifyError=function(e){toastr.options.closeButton=!0,toastr.options.preventDuplicates=!0,toastr.error(e)},this.add=function(e){e=e.replace(/'/g,"").replace(/"/g,""),-1

    Loading..

    \x3c!-- ko foreach: suggestedResult --\x3e\x3c!-- /ko --\x3e
    '}),ko.applyBindings(),Holder.addTheme("thumb",{bg:"#55595c",fg:"#eceeef",text:"Thumbnail"});var FormMvc={allowValidateHiddenField:function(e){e.data("validator").settings.ignore=""},disableEnter:function(e){e.on("keyup keypress",function(e){if(13===(e.keyCode||e.which))return e.preventDefault(),!1})}};$(function(){$(".single-select").removeAttr("multiple"),$('[data-toggle="tooltip"]').tooltip()});var JSONTree=function(){var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e=0,n=0;this.create=function(e,t){return n+=1,p(s(e,0,!1),{class:"jstValue"})};function a(e){return e.replace(/[&<>'"]/g,function(e){return t[e]})}function o(){return n+"_"+e++}var s=function(e,t,n){if(null===e)return d(n?t:0);switch(typeof e){case"boolean":return c(e,n?t:0);case"number":return u(e,n?t:0);case"string":return l(e,n?t:0);default:return e instanceof Array?r(e,t,n):i(e,t,n)}},i=function(t,n,e){var i=o(),r=Object.keys(t).map(function(e){return h(e,t[e],n+1,!0)}).join(f()),a=[g("{",e?n:0,i),p(r,{id:i}),v("}",n)].join("\n");return p(a,{})},r=function(e,t,n){var i=o(),r=e.map(function(e){return s(e,t+1,!0)}).join(f());return[g("[",n?t:0,i),p(r,{id:i}),v("]",t)].join("\n")},l=function(e,t){var n=a(JSON.stringify(e));return p(y(n,t),{class:"jstStr"})},u=function(e,t){return p(y(e,t),{class:"jstNum"})},c=function(e,t){return p(y(e,t),{class:"jstBool"})},d=function(e){return p(y("null",e),{class:"jstNull"})},h=function(e,t,n){var i=y(a(JSON.stringify(e))+": ",n),r=p(s(t,n,!1),{});return p(i+r,{class:"jstProperty"})},f=function(){return p(",\n",{class:"jstComma"})},p=function(e,t){return m("span",t,e)},m=function(e,t,n){return"<"+e+Object.keys(t).map(function(e){return" "+e+'="'+t[e]+'"'}).join("")+">"+n+""},g=function(e,t,n){return p(y(e,t),{class:"jstBracket"})+p("",{class:"jstFold",onclick:"JSONTree.toggle('"+n+"')"})};this.toggle=function(e){var t=document.getElementById(e),n=t.parentNode,i=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",n.className="jstFolded",i.className="jstExpand"):(t.className="",n.className="",i.className="jstFold")};var v=function(e,t){return p(y(e,t),{})},y=function(e,t){return Array(2*t+1).join(" ")+e};return this}();$(function(){$(".local-datetime").each(function(){var e=$(this),t=parseInt(e.attr("data-utc"),10)||0;if(t){var n=moment.utc(t).local().format("DD MMM YYYY HH:mm");e.text(n)}}),$('[data-toggle="tooltip"]').tooltip()});var errorLog={eventHandlers:function(){$(".error-log-delete-button").click(function(){return $(".error-log-form").validate(),$(".error-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1}),$(".row-error-detail>td").each(function(){var t,n=$(this).data("error-json");try{t=JSONTree.create(JSON.parse(n))}catch(e){t=JSONTree.create(n)}$(this).html(t)}),$(".btn-error-detail").click(function(e){e.preventDefault();var t=$(this).data("error-id");return $(".row-error-detail[data-error-id="+t+"]").is(":visible")?$(".row-error-detail[data-error-id="+t+"]").addClass("d-none"):$(".row-error-detail[data-error-id="+t+"]").removeClass("d-none"),!1})},init:function(){$(function(){errorLog.eventHandlers()})}};errorLog.init();var auditLog={createJsonTree:function(t){var n;try{n=JSONTree.create(JSON.parse(t))}catch(e){n=JSONTree.create(t)}return n},initJsonTrees:function(){$(".json-tree").each(function(){var e=$(this).data("json-tree"),t=auditLog.createJsonTree(e);$(this).html(t)})},eventHandlers:function(){$(".audit-subject-button").click(function(){var e=$(this).data("subject-identifier"),t=$(this).data("subject-name"),n=$(this).data("subject-type"),i=$(this).data("subject-additional-data");$(".modal-title").html(t+" - "+e+" - ("+n+")"),$(".audit-modal-value").html(auditLog.createJsonTree(i)),$(".audit-modal").modal("show")}),$(".audit-action-button").click(function(){var e=$(this).data("action"),t=$(this).data("action-title");$(".modal-title").html(t),$(".audit-modal-value").html(auditLog.createJsonTree(e)),$(".audit-modal").modal("show")}),$(".audit-log-delete-button").click(function(){return $(".audit-log-form").validate(),$(".audit-log-form").validate().form()?$("#deleteLogsModal").modal("show"):$(this).submit(),!1})},init:function(){$(function(){auditLog.eventHandlers(),auditLog.initJsonTrees()})}};auditLog.init(),$(function(){var e={guid:function(){return"ss-s-s-s-sss".replace(/s/g,e.s4)},s4:function(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)},eventHandlers:function(){$("#generate-guid-button").click(function(){$("#secret-input").val(e.guid())}),$(".secret-value-button").click(function(){var e=$(this).data("secret-value");$(".modal-secret-value").html(e),$(".secret-modal").modal("show")})},init:function(){e.eventHandlers()}};e.init()}),$(function(){var t={getCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),i=0;iv=T1^5j|)( zEfd8oFL-&df+94?iRi`4L=T!M(x8GF=^RjSs&RJzf1CxI)66jEy!bLlezVqDd#&}Y zz4o{Es3BzdQ&SWC8TM9&P!&QL4VuDZu>HRe*NQ($l7t>TdvLRIpyfaaW$MMafmnzy z(S%bti;MUUQ;2*x(f<8V*< zVmc1tXDq@j+=EhLRnp)2y)WmRi|6nRp1?fp#W9?Rd;dLNgmEU}DAwT}_^hhX-8BrS zulF?vtFa9mum*2pJ-)&oe2vRU;5|Qx-l$LcnEKP`ZhZR<#xOj9M=$}i@gClX>sW%f zaT3P=6%%3naWE&$#a&o|uHyIMy7zrQjOV`3DAZlUlh}bX_yyi;6U_a;a1E}_957CQ z+<}oefZZ@hI$MMNYw;9Z>n3=gZxwt_`6JA2?=|fz-#>z9qj-MT?l_;(N(?}8pY(Uv z@4nxS`%n+pz7^)ec3ek{{~L9m!3d=1iS<`$KL`6?!YT|w6@12b!aX-{?uGkhY)kXc zeRhBU!QW_ubG70SX5v=Fc^)@KZSW}o__%M^IIH-bNqog zkFnj4YNX?(>vwVO8?+;ii)9OK=9>HL9AhyKJ}cMkepvUtvJ~5K299?hJo}yPcWxaRtuT1n(_9KGuiQ-hlHcjv2on;o20$F_yQ( z`}WK&zXS>2=@J`w(-pIIiCh7W&2cN-bYtd?U=;LGY}*KCOpmq@%dDnTNF~HDKv_YC_UDJNb>V|*Wa zK8$x9zALI>?wGT_Lv|L*mnl6bo(Z3kIn&XcrL_5;8xC{$4fsylk7+O;{CzVRu5&70 z!F2eHN{Q2*zMh#CIE@x~u0O*ze1Uyff??>+eC70UKg`R`IDxZh#9E9+Uv#+dH|y`+ zJ#l;f%~!|)ilR?jSevwkI^^2JEfwt{R3ylUOg0~~KeUC4#t?E1A=L5T39CYLXbsJo ge5Sd!CY$8xn-94pUsIj5Qg5Z6gz6+|!2du00v~-&mjD0& literal 0 HcmV?d00001 diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AccountOptions.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AccountOptions.cs index 0e50b1d82..3cca204e7 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AccountOptions.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AccountOptions.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System; @@ -25,3 +25,9 @@ public class AccountOptions public static string InvalidCredentialsErrorMessage = "Invalid username or password"; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AdminConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AdminConfiguration.cs index 26c74ca10..0b218cdbf 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AdminConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/AdminConfiguration.cs @@ -1,9 +1,16 @@ -using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces; - namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { - public class AdminConfiguration : IAdminConfiguration + public class AdminConfiguration { - public string IdentityAdminBaseUrl { get; set; } = "http://localhost:9000"; + public string PageTitle { get; set; } + public string HomePageLogoUri { get; set; } + public string FaviconUri { get; set; } + public string IdentityAdminBaseUrl { get; set; } + public string AdministrationRole { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericControllerRouteConvention.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericControllerRouteConvention.cs index d6a79d706..420750f28 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericControllerRouteConvention.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericControllerRouteConvention.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.AspNetCore.Mvc.ApplicationModels; namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.ApplicationParts { @@ -18,4 +18,9 @@ public void Apply(ControllerModel controller) } } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericTypeControllerFeatureProvider.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericTypeControllerFeatureProvider.cs index d3244a07b..6772e941d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericTypeControllerFeatureProvider.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ApplicationParts/GenericTypeControllerFeatureProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -36,4 +36,9 @@ public void PopulateFeature(IEnumerable parts, ControllerFeatur } } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CertificateConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CertificateConfiguration.cs index 02157d0b1..1f37f8f98 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CertificateConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CertificateConfiguration.cs @@ -1,9 +1,12 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class CertificateConfiguration { public bool UseTemporarySigningKeyForDevelopment { get; set; } + public string CertificateStoreLocation { get; set; } + public bool CertificateValidOnly { get; set; } + public bool UseSigningCertificateThumbprint { get; set; } public string SigningCertificateThumbprint { get; set; } @@ -25,3 +28,9 @@ public class CertificateConfiguration public string ValidationCertificatePfxFilePassword { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ConsentOptions.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ConsentOptions.cs index eb6006648..6d17f2331 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ConsentOptions.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ConsentOptions.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { @@ -16,3 +16,9 @@ public class ConsentOptions public static readonly string InvalidSelectionErrorMessage = "Invalid selection"; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AddressClaimConstants.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AddressClaimConstants.cs index b3ffdec49..c88c0c682 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AddressClaimConstants.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AddressClaimConstants.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants { public static class AddressClaimConstants { @@ -9,3 +9,9 @@ public static class AddressClaimConstants public static readonly string Country = "country"; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AuthorizationConsts.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AuthorizationConsts.cs index e233b4773..3a0cd7c3f 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AuthorizationConsts.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/AuthorizationConsts.cs @@ -1,8 +1,12 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants { public class AuthorizationConsts { public const string AdministrationPolicy = "RequireAdministratorRole"; - public const string AdministrationRole = "SkorubaIdentityAdminAdministrator"; } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/ConfigurationConsts.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/ConfigurationConsts.cs index ba756d8f8..f21c91908 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/ConfigurationConsts.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Constants/ConfigurationConsts.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants { public class ConfigurationConsts { @@ -14,6 +14,11 @@ public class ConfigurationConsts public const string AdminConfigurationKey = "AdminConfiguration"; - public const string RegisterConfiguration = "RegisterConfiguration"; + public const string RegisterConfigurationKey = "RegisterConfiguration"; } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CultureConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CultureConfiguration.cs new file mode 100644 index 000000000..53751283a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/CultureConfiguration.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +{ + public class CultureConfiguration + { + public static readonly string[] AvailableCultures = { "en", "fa", "fr", "ru", "sv", "zh", "da", "fi" }; + public static readonly string DefaultRequestCulture = "en"; + + public List Cultures { get; set; } + public string DefaultCulture { get; set; } = DefaultRequestCulture; + } +} + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ExternalProvidersConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ExternalProvidersConfiguration.cs index 9943e6863..6bb8eac88 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ExternalProvidersConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/ExternalProvidersConfiguration.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class ExternalProvidersConfiguration { @@ -7,3 +7,9 @@ public class ExternalProvidersConfiguration public string GitHubClientSecret { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs deleted file mode 100644 index a277b849c..000000000 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IAdminConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces -{ - public interface IAdminConfiguration - { - string IdentityAdminBaseUrl { get; } - } -} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs deleted file mode 100644 index ad361cc3c..000000000 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRegisterConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces -{ - public interface IRegisterConfiguration - { - bool Enabled { get; } - } -} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs deleted file mode 100644 index faeccb679..000000000 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Intefaces/IRootConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces -{ - public interface IRootConfiguration - { - IAdminConfiguration AdminConfiguration { get; } - - IRegisterConfiguration RegisterConfiguration { get; } - } -} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs new file mode 100644 index 000000000..cfc9ac5c7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Interfaces/IRootConfiguration.cs @@ -0,0 +1,14 @@ +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces +{ + public interface IRootConfiguration + { + AdminConfiguration AdminConfiguration { get; } + + RegisterConfiguration RegisterConfiguration { get; } + } +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginConfiguration.cs index 0e10ab945..a73f07deb 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginConfiguration.cs @@ -1,7 +1,13 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class LoginConfiguration { public LoginResolutionPolicy ResolutionPolicy { get; set; } = LoginResolutionPolicy.Username; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginResolutionPolicy.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginResolutionPolicy.cs index 42dffd994..6dcc9f4a3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginResolutionPolicy.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/LoginResolutionPolicy.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { // From where should the login be sourced // by default it's sourced from Username @@ -8,3 +8,9 @@ public enum LoginResolutionPolicy Email = 1 } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RegisterConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RegisterConfiguration.cs index 80937989e..fd3be8c26 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RegisterConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RegisterConfiguration.cs @@ -1,9 +1,13 @@ -using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces; - namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { - public class RegisterConfiguration : IRegisterConfiguration + public class RegisterConfiguration { public bool Enabled { get; set; } = true; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RootConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RootConfiguration.cs index 2a20691f0..51d2c4493 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RootConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/RootConfiguration.cs @@ -1,17 +1,15 @@ -using Microsoft.Extensions.Options; -using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces; namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class RootConfiguration : IRootConfiguration { - public IAdminConfiguration AdminConfiguration { get; set; } - public IRegisterConfiguration RegisterConfiguration { get; } - - public RootConfiguration(IOptions adminConfiguration, IOptions registerConfiguration) - { - RegisterConfiguration = registerConfiguration.Value; - AdminConfiguration = adminConfiguration.Value; - } + public AdminConfiguration AdminConfiguration { get; } = new AdminConfiguration(); + public RegisterConfiguration RegisterConfiguration { get; } = new RegisterConfiguration(); } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SendgridConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SendgridConfiguration.cs index 0d5962a57..1be784600 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SendgridConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SendgridConfiguration.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class SendgridConfiguration { @@ -7,3 +7,9 @@ public class SendgridConfiguration public string ApiKey { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SmtpConfiguration.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SmtpConfiguration.cs index 6ab74c286..0f17d4aee 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SmtpConfiguration.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/SmtpConfiguration.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration { public class SmtpConfiguration { @@ -9,3 +9,9 @@ public class SmtpConfiguration public bool UseSSL { get; set; } = true; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Test/StartupTest.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Test/StartupTest.cs new file mode 100644 index 000000000..6589fcf80 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Configuration/Test/StartupTest.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.DbContexts; +using SkorubaIdentityServer4Admin.STS.Identity.Helpers; + +namespace SkorubaIdentityServer4Admin.STS.Identity.Configuration.Test +{ + public class StartupTest : Startup + { + public StartupTest(IWebHostEnvironment environment, IConfiguration configuration) : base(environment, configuration) + { + } + + public override void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContextsStaging(); + } + } +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/AccountController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/AccountController.cs index 58617de2f..a349be40b 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/AccountController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/AccountController.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Samples -// Modified by Jan Škoruba +// Modified by Jan koruba using System; using System.Linq; @@ -359,6 +359,14 @@ public async Task ExternalLoginCallback(string returnUrl = null, { return RedirectToLocal(returnUrl); } + if (result.RequiresTwoFactor) + { + return RedirectToAction(nameof(LoginWith2fa), new { ReturnUrl = returnUrl }); + } + if (result.IsLockedOut) + { + return View("Lockout"); + } // If the user does not have an account, then ask the user to create an account. ViewData["ReturnUrl"] = returnUrl; @@ -540,7 +548,15 @@ public IActionResult Register(string returnUrl = null) ViewData["ReturnUrl"] = returnUrl; - return View(); + switch (_loginConfiguration.ResolutionPolicy) + { + case LoginResolutionPolicy.Username: + return View(); + case LoginResolutionPolicy.Email: + return View("RegisterWithoutUsername"); + default: + return View("RegisterFailure"); + } } [HttpPost] @@ -578,6 +594,23 @@ public async Task Register(RegisterViewModel model, string return return View(model); } + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task RegisterWithoutUsername(RegisterWithoutUsernameViewModel model, string returnUrl = null) + { + var registerModel = new RegisterViewModel + { + UserName = model.Email, + Email = model.Email, + Password = model.Password, + ConfirmPassword = model.ConfirmPassword + }; + + return await Register(registerModel, returnUrl); + } + + /*****************************************/ /* helper APIs for the AccountController */ /*****************************************/ @@ -723,4 +756,9 @@ private async Task BuildLoggedOutViewModelAsync(string logou return vm; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ConsentController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ConsentController.cs index 3d1db9db1..7a42323d9 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ConsentController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ConsentController.cs @@ -269,4 +269,9 @@ private ScopeViewModel GetOfflineAccessScope(bool check) }; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DeviceController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DeviceController.cs index 18a2711e7..4b915ff4a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DeviceController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DeviceController.cs @@ -239,4 +239,9 @@ private ScopeViewModel GetOfflineAccessScope(bool check) }; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DiagnosticsController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DiagnosticsController.cs index bc63cc4e8..88e46b532 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DiagnosticsController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/DiagnosticsController.cs @@ -20,8 +20,8 @@ public class DiagnosticsController : Controller { public async Task Index() { - var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection.LocalIpAddress.ToString() }; - if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString())) + var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection?.LocalIpAddress?.ToString() }; + if (!localAddresses.Contains(HttpContext.Connection?.RemoteIpAddress?.ToString())) { return NotFound(); } @@ -30,4 +30,9 @@ public async Task Index() return View(model); } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/GrantsController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/GrantsController.cs index 46b7b9eec..e03cc000a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/GrantsController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/GrantsController.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System.Collections.Generic; using System.Linq; @@ -90,4 +90,9 @@ private async Task BuildViewModelAsync() }; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/HomeController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/HomeController.cs index 3227e6e98..34c906fc5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/HomeController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/HomeController.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System; using System.Threading.Tasks; @@ -58,4 +58,9 @@ public async Task Error(string errorId) return View("Error", vm); } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ManageController.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ManageController.cs index f20330795..91acbcd65 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ManageController.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Controllers/ManageController.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Text; using System.Text.Encodings.Web; @@ -715,4 +715,9 @@ private void AddError(string description, string title = "") ModelState.AddModelError(title, description); } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Dockerfile b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Dockerfile new file mode 100644 index 000000000..23e58b263 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Dockerfile @@ -0,0 +1,24 @@ +FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build +WORKDIR /src +COPY ["src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj", "src/SkorubaIdentityServer4Admin.STS.Identity/"] +COPY ["src/SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared/SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.csproj", "src/SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared/"] +COPY ["src/SkorubaIdentityServer4Admin.Admin.EntityFramework.SqlServer/SkorubaIdentityServer4Admin.Admin.EntityFramework.SqlServer.csproj", "src/SkorubaIdentityServer4Admin.Admin.EntityFramework.SqlServer/"] +COPY ["src/SkorubaIdentityServer4Admin.Admin.EntityFramework.PostgreSQL/SkorubaIdentityServer4Admin.Admin.EntityFramework.PostgreSQL.csproj", "src/SkorubaIdentityServer4Admin.Admin.EntityFramework.PostgreSQL/"] +COPY ["src/SkorubaIdentityServer4Admin.Admin.EntityFramework.MySql/SkorubaIdentityServer4Admin.Admin.EntityFramework.MySql.csproj", "src/SkorubaIdentityServer4Admin.Admin.EntityFramework.MySql/"] +RUN dotnet restore "src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj" +COPY . . +WORKDIR "/src/src/SkorubaIdentityServer4Admin.STS.Identity" +RUN dotnet build "SkorubaIdentityServer4Admin.STS.Identity.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "SkorubaIdentityServer4Admin.STS.Identity.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true +ENTRYPOINT ["dotnet", "SkorubaIdentityServer4Admin.STS.Identity.dll"] \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Extensions.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Extensions.cs index 04987bf88..b0baa7267 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Extensions.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Extensions.cs @@ -29,3 +29,9 @@ public static async Task IsPkceClientAsync(this IClientStore store, string } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs index 9593026f1..c1a9a6f28 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/IdentityServerBuilderExtensions.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using System; using System.IO; using System.Security.Cryptography; @@ -23,9 +23,8 @@ public static class IdentityServerBuilderExtensions /// /// /// - /// /// - public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentityServerBuilder builder, IConfiguration configuration, ILogger logger) + public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentityServerBuilder builder, IConfiguration configuration) { var certificateConfiguration = configuration.GetSection(nameof(CertificateConfiguration)).Get(); @@ -36,10 +35,28 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe throw new Exception(SigningCertificateThumbprintNotFound); } - var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); + StoreLocation storeLocation = StoreLocation.LocalMachine; + bool validOnly = certificateConfiguration.CertificateValidOnly; + + // Parse the Certificate StoreLocation + string certStoreLocationLower = certificateConfiguration.CertificateStoreLocation.ToLower(); + if (certStoreLocationLower == StoreLocation.CurrentUser.ToString().ToLower() || + certificateConfiguration.CertificateStoreLocation == ((int)StoreLocation.CurrentUser).ToString()) + { + storeLocation = StoreLocation.CurrentUser; + } + else if (certStoreLocationLower == StoreLocation.LocalMachine.ToString().ToLower() || + certStoreLocationLower == ((int)StoreLocation.LocalMachine).ToString()) + { + storeLocation = StoreLocation.LocalMachine; + } + else { storeLocation = StoreLocation.LocalMachine; validOnly = true; } + + // Open Certificate + var certStore = new X509Store(StoreName.My, storeLocation); certStore.Open(OpenFlags.ReadOnly); - var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, true); + var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, validOnly); if (certCollection.Count == 0) { throw new Exception(CertificateNotFound); @@ -63,9 +80,9 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe { builder.AddSigningCredential(new X509Certificate2(certificateConfiguration.SigningCertificatePfxFilePath, certificateConfiguration.SigningCertificatePfxFilePassword)); } - catch (CryptographicException e) + catch (Exception e) { - logger.LogError($"There was an error adding the key file - during the creation of the signing key {e.Message}"); + throw new Exception("There was an error adding the key file - during the creation of the signing key", e); } } else @@ -77,6 +94,10 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe { builder.AddDeveloperSigningCredential(); } + else + { + throw new Exception("Signing credential is not specified"); + } return builder; } @@ -87,9 +108,8 @@ public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentitySe /// /// /// - /// /// - public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServerBuilder builder, IConfiguration configuration, ILogger logger) + public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServerBuilder builder, IConfiguration configuration) { var certificateConfiguration = configuration.GetSection(nameof(CertificateConfiguration)).Get(); @@ -128,9 +148,9 @@ public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServer builder.AddValidationKey(new X509Certificate2(certificateConfiguration.ValidationCertificatePfxFilePath, certificateConfiguration.ValidationCertificatePfxFilePassword)); } - catch (CryptographicException e) + catch (Exception e) { - logger.LogError($"There was an error adding the key file - during the creation of the validation key {e.Message}"); + throw new Exception("There was an error adding the key file - during the creation of the validation key", e); } } else @@ -143,3 +163,9 @@ public static IIdentityServerBuilder AddCustomValidationKey(this IIdentityServer } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs index 4b520573c..b2d9bc272 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/GenericServiceLocalizer.cs @@ -1,12 +1,11 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // https://github.com/aspnet/Extensions/blob/master/src/Localization/Abstractions/src/StringLocalizerOfT.cs -// Modified by Jan Škoruba +// Modified by Jan koruba using System; using System.Collections.Generic; -using System.Globalization; using System.Reflection; using Microsoft.Extensions.Localization; @@ -32,13 +31,6 @@ public GenericControllerLocalizer(IStringLocalizerFactory factory) _localizer = factory.Create(baseName, assemblyName); } - /// - public virtual IStringLocalizer WithCulture(CultureInfo culture) - { - return _localizer.WithCulture(culture); - } - - /// public virtual LocalizedString this[string name] { get @@ -49,7 +41,6 @@ public virtual LocalizedString this[string name] } } - /// public virtual LocalizedString this[string name, params object[] arguments] { get @@ -60,10 +51,14 @@ public virtual LocalizedString this[string name] } } - /// public IEnumerable GetAllStrings(bool includeParentCultures) { return _localizer.GetAllStrings(includeParentCultures); } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs index a9d8abc5b..ba27e335f 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/IGenericControllerLocalizer.cs @@ -1,9 +1,19 @@ -using Microsoft.Extensions.Localization; +using System.Collections.Generic; +using Microsoft.Extensions.Localization; namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers.Localization { - public interface IGenericControllerLocalizer : IStringLocalizer + public interface IGenericControllerLocalizer { - + LocalizedString this[string name] { get; } + + LocalizedString this[string name, params object[] arguments] { get; } + + IEnumerable GetAllStrings(bool includeParentCultures); } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/LoginPolicyResolutionLocalizer.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/LoginPolicyResolutionLocalizer.cs index fb1fd0349..ddacb1400 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/LoginPolicyResolutionLocalizer.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Localization/LoginPolicyResolutionLocalizer.cs @@ -1,4 +1,4 @@ -using SkorubaIdentityServer4Admin.STS.Identity.Configuration; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration; namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers.Localization { @@ -18,3 +18,9 @@ public static string GetUserNameLocalizationKey(LoginResolutionPolicy policy) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Md5HashHelper.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Md5HashHelper.cs index 3e15e9d26..f96d3ed16 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Md5HashHelper.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/Md5HashHelper.cs @@ -1,4 +1,4 @@ -using System.Security.Cryptography; +using System.Security.Cryptography; using System.Text; namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers @@ -32,3 +32,9 @@ public static string GetHash(string input) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenIDProfile.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenIDProfile.cs index a89cc7ec0..fc47564af 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenIDProfile.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenIDProfile.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers +namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers { public class OpenIdProfile { @@ -12,3 +12,9 @@ public class OpenIdProfile public string Country { get; internal set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenidClaimHelpers.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenidClaimHelpers.cs index e7fd826df..43e7de6ab 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenidClaimHelpers.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/OpenidClaimHelpers.cs @@ -1,4 +1,4 @@ -using IdentityModel; +using IdentityModel; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants; @@ -226,3 +226,9 @@ public static IList> ExtractClaimsToReplace(IList oldC } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/SecurityHeadersAttribute.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/SecurityHeadersAttribute.cs index 2eebdec72..13b20bb6b 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/SecurityHeadersAttribute.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/SecurityHeadersAttribute.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -56,3 +56,9 @@ public override void OnResultExecuting(ResultExecutingContext context) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/StartupHelpers.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/StartupHelpers.cs index 5e5211b09..b47349724 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/StartupHelpers.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/StartupHelpers.cs @@ -1,31 +1,32 @@ -using System; +using System; using System.Globalization; -using System.Reflection; -using IdentityServer4.EntityFramework.Interfaces; +using IdentityServer4.EntityFramework.Storage; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Localization; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using SendGrid; -using Serilog; using SkorubaIdentityServer4Admin.STS.Identity.Configuration; using SkorubaIdentityServer4Admin.STS.Identity.Configuration.ApplicationParts; using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants; -using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces; using SkorubaIdentityServer4Admin.STS.Identity.Helpers.Localization; using SkorubaIdentityServer4Admin.STS.Identity.Services; -using ILogger = Microsoft.Extensions.Logging.ILogger; +using System.Linq; +using Skoruba.IdentityServer4.Admin.EntityFramework.Interfaces; +using SkorubaIdentityServer4Admin.Admin.EntityFramework.MySql.Extensions; +using SkorubaIdentityServer4Admin.Admin.EntityFramework.PostgreSQL.Extensions; +using SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.Configuration; +using SkorubaIdentityServer4Admin.Admin.EntityFramework.SqlServer.Extensions; +using Skoruba.IdentityServer4.Admin.EntityFramework.Helpers; namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers { @@ -35,7 +36,7 @@ public static class StartupHelpers /// Register services for MVC and localization including available languages /// /// - public static void AddMvcWithLocalization(this IServiceCollection services) + public static IMvcBuilder AddMvcWithLocalization(this IServiceCollection services, IConfiguration configuration) where TUser : IdentityUser where TKey : IEquatable { @@ -43,11 +44,10 @@ public static void AddMvcWithLocalization(this IServiceCollection s services.TryAddTransient(typeof(IGenericControllerLocalizer<>), typeof(GenericControllerLocalizer<>)); - services.AddMvc(o => + var mvcBuilder = services.AddControllersWithViews(o => { o.Conventions.Add(new GenericControllerRouteConvention()); }) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = ConfigurationConsts.ResourcesPath; }) @@ -57,22 +57,32 @@ public static void AddMvcWithLocalization(this IServiceCollection s m.FeatureProviders.Add(new GenericTypeControllerFeatureProvider()); }); + var cultureConfiguration = configuration.GetSection(nameof(CultureConfiguration)).Get(); services.Configure( opts => { - var supportedCultures = new[] - { - new CultureInfo("en"), - new CultureInfo("fa"), - new CultureInfo("ru"), - new CultureInfo("sv"), - new CultureInfo("zh") - }; - - opts.DefaultRequestCulture = new RequestCulture("en"); + // If cultures are specified in the configuration, use them (making sure they are among the available cultures), + // otherwise use all the available cultures + var supportedCultureCodes = (cultureConfiguration?.Cultures?.Count > 0 ? + cultureConfiguration.Cultures.Intersect(CultureConfiguration.AvailableCultures) : + CultureConfiguration.AvailableCultures).ToArray(); + + if (!supportedCultureCodes.Any()) supportedCultureCodes = CultureConfiguration.AvailableCultures; + var supportedCultures = supportedCultureCodes.Select(c => new CultureInfo(c)).ToList(); + + // If the default culture is specified use it, otherwise use CultureConfiguration.DefaultRequestCulture ("en") + var defaultCultureCode = string.IsNullOrEmpty(cultureConfiguration?.DefaultCulture) ? + CultureConfiguration.DefaultRequestCulture : cultureConfiguration?.DefaultCulture; + + // If the default culture is not among the supported cultures, use the first supported culture as default + if (!supportedCultureCodes.Contains(defaultCultureCode)) defaultCultureCode = supportedCultureCodes.FirstOrDefault(); + + opts.DefaultRequestCulture = new RequestCulture(defaultCultureCode); opts.SupportedCultures = supportedCultures; opts.SupportedUICultures = supportedCultures; }); + + return mvcBuilder; } ///
    @@ -117,22 +127,82 @@ public static void AddEmailSenders(this IServiceCollection services, IConfigurat } } + /// + /// Register DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + /// + public static void RegisterDbContexts(this IServiceCollection services, IConfiguration configuration) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + + var identityConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + var configurationConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + services.RegisterSqlServerDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + case DatabaseProviderType.PostgreSQL: + services.RegisterNpgSqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + case DatabaseProviderType.MySql: + services.RegisterMySqlDbContexts(identityConnectionString, configurationConnectionString, persistedGrantsConnectionString); + break; + default: + throw new ArgumentOutOfRangeException(nameof(databaseProvider.ProviderType), $@"The value needs to be one of {string.Join(", ", Enum.GetNames(typeof(DatabaseProviderType)))}."); + } + } + + /// + /// Register InMemory DbContexts for IdentityServer ConfigurationStore and PersistedGrants and Identity + /// Configure the connection strings in AppSettings.json + /// + /// + /// + /// + /// + public static void RegisterDbContextsStaging( + this IServiceCollection services) + where TIdentityDbContext : DbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + { + var identityDatabaseName = Guid.NewGuid().ToString(); + services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(identityDatabaseName)); + + var configurationDatabaseName = Guid.NewGuid().ToString(); + var operationalDatabaseName = Guid.NewGuid().ToString(); + + services.AddConfigurationDbContext(options => + { + options.ConfigureDbContext = b => b.UseInMemoryDatabase(configurationDatabaseName); + }); + + services.AddOperationalDbContext(options => + { + options.ConfigureDbContext = b => b.UseInMemoryDatabase(operationalDatabaseName); + }); + } + /// /// Add services for authentication, including Identity model, IdentityServer4 and external providers /// /// DbContext for Identity /// User Identity class /// User Identity Role class - /// - /// /// - /// /// - /// - public static void AddAuthenticationServices(this IServiceCollection services, IHostingEnvironment hostingEnvironment, IConfiguration configuration, ILogger logger) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - where TIdentityDbContext : DbContext + public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration) where TIdentityDbContext : DbContext where TUserIdentity : class where TUserIdentityRole : class { @@ -159,8 +229,6 @@ public static void AddAuthenticationServices(services, configuration, logger, hostingEnvironment); } /// @@ -199,24 +267,6 @@ private static RegisterConfiguration GetRegistrationConfiguration(IConfiguration return registerConfiguration; } - /// - /// Configuration root configuration - /// - /// - /// - /// - public static IServiceCollection ConfigureRootConfiguration(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - - services.Configure(configuration.GetSection(ConfigurationConsts.AdminConfigurationKey)); - services.Configure(configuration.GetSection(ConfigurationConsts.RegisterConfiguration)); - - services.TryAddSingleton(); - - return services; - } - /// /// Add configuration for IdentityServer4 /// @@ -225,14 +275,12 @@ public static IServiceCollection ConfigureRootConfiguration(this IServiceCollect /// /// /// - /// - /// - private static void AddIdentityServer( - IServiceCollection services, - IConfiguration configuration, ILogger logger, IHostingEnvironment hostingEnvironment) + public static IIdentityServerBuilder AddIdentityServer( + this IServiceCollection services, + IConfiguration configuration) + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext where TUserIdentity : class - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext { var builder = services.AddIdentityServer(options => { @@ -241,11 +289,14 @@ private static void AddIdentityServer() - .AddIdentityServerStoresWithDbContexts(configuration, hostingEnvironment); + .AddConfigurationStore() + .AddOperationalStore() + .AddAspNetIdentity(); + + builder.AddCustomSigningCredential(configuration); + builder.AddCustomValidationKey(configuration); - builder.AddCustomSigningCredential(configuration, logger); - builder.AddCustomValidationKey(configuration, logger); + return builder; } /// @@ -269,130 +320,6 @@ private static void AddExternalProviders(AuthenticationBuilder authenticationBui } } - /// - /// Add DbContext for Identity - /// - /// - /// - /// - /// - public static void AddIdentityDbContext(this IServiceCollection services, - IConfiguration configuration, IHostingEnvironment hostingEnvironment) - where TContext : DbContext - { - if (hostingEnvironment.IsStaging()) - { - RegisterIdentityDbContextStaging(services); - } - else - { - RegisterIdentityDbContext(services, configuration); - } - } - - private static void RegisterIdentityDbContextStaging(IServiceCollection services) where TContext : DbContext - { - var identityDatabaseName = Guid.NewGuid().ToString(); - - services.AddDbContext(optionsBuilder => optionsBuilder.UseInMemoryDatabase(identityDatabaseName)); - } - - private static void RegisterIdentityDbContext(IServiceCollection services, IConfiguration configuration) - where TContext : DbContext - { - var connectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); - services.AddDbContext(options => options.UseSqlServer(connectionString)); - } - - /// - /// Add shared DbContext for Identity and IdentityServer4 stores - /// - /// - /// - /// - public static void AddDbContexts(this IServiceCollection services, IConfiguration configuration) - where TContext : DbContext - { - var connectionString = configuration.GetConnectionString(ConfigurationConsts.AdminConnectionStringKey); - services.AddDbContext(options => options.UseSqlServer(connectionString)); - } - - /// - /// Register DbContexts and configure stores for IdentityServer4 - /// - /// - /// - /// - /// - /// - public static IIdentityServerBuilder AddIdentityServerStoresWithDbContexts(this IIdentityServerBuilder builder, IConfiguration configuration, - IHostingEnvironment hostingEnvironment) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - if (hostingEnvironment.IsStaging()) - { - return RegisterIdentityServerStoresWithDbContextsStaging(builder, configuration); - } - else - { - return RegisterIdentityServerStoresWithDbContexts(builder, configuration); - } - } - - private static IIdentityServerBuilder - RegisterIdentityServerStoresWithDbContextsStaging( - IIdentityServerBuilder builder, IConfiguration configuration) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - var configurationDatabaseName = Guid.NewGuid().ToString(); - var operationalDatabaseName = Guid.NewGuid().ToString(); - - builder.AddConfigurationStore(options => - { - options.ConfigureDbContext = b => b.UseInMemoryDatabase(configurationDatabaseName); - }); - - builder.AddOperationalStore(options => - { - options.ConfigureDbContext = b => b.UseInMemoryDatabase(operationalDatabaseName); - }); - - return builder; - } - - private static IIdentityServerBuilder - RegisterIdentityServerStoresWithDbContexts( - IIdentityServerBuilder builder, IConfiguration configuration) - where TPersistedGrantDbContext : DbContext, IPersistedGrantDbContext - where TConfigurationDbContext : DbContext, IConfigurationDbContext - { - var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; - - // Config DB from existing connection - builder.AddConfigurationStore(options => - { - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - // Operational DB from existing connection - builder.AddOperationalStore(options => - { - options.EnableTokenCleanup = true; - options.ConfigureDbContext = b => - b.UseSqlServer( - configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey), - sql => sql.MigrationsAssembly(migrationsAssembly)); - }); - - return builder; - } - /// /// Register middleware for localization /// @@ -403,30 +330,81 @@ public static void UseMvcLocalizationServices(this IApplicationBuilder app) app.UseRequestLocalization(options.Value); } - /// - /// Add configuration for logging - /// - /// - /// - /// - public static void AddLogging(this IApplicationBuilder app, ILoggerFactory loggerFactory, IConfiguration configuration) - { - Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(configuration) - .CreateLogger(); - } - /// /// Add authorization policies /// /// - public static void AddAuthorizationPolicies(this IServiceCollection services) + /// + public static void AddAuthorizationPolicies(this IServiceCollection services, + IRootConfiguration rootConfiguration) { services.AddAuthorization(options => { options.AddPolicy(AuthorizationConsts.AdministrationPolicy, - policy => policy.RequireRole(AuthorizationConsts.AdministrationRole)); + policy => policy.RequireRole(rootConfiguration.AdminConfiguration.AdministrationRole)); }); } + + public static void AddIdSHealthChecks(this IServiceCollection services, IConfiguration configuration) + where TConfigurationDbContext : DbContext, IAdminConfigurationDbContext + where TPersistedGrantDbContext : DbContext, IAdminPersistedGrantDbContext + where TIdentityDbContext : DbContext + { + var configurationDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.ConfigurationDbConnectionStringKey); + var persistedGrantsDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.PersistedGrantDbConnectionStringKey); + var identityDbConnectionString = configuration.GetConnectionString(ConfigurationConsts.IdentityDbConnectionStringKey); + + var healthChecksBuilder = services.AddHealthChecks() + .AddDbContextCheck("ConfigurationDbContext") + .AddDbContextCheck("PersistedGrantsDbContext") + .AddDbContextCheck("IdentityDbContext"); + + var serviceProvider = services.BuildServiceProvider(); + var scopeFactory = serviceProvider.GetRequiredService(); + using (var scope = scopeFactory.CreateScope()) + { + var configurationTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var persistedGrantTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + var identityTableName = DbContextHelpers.GetEntityTable(scope.ServiceProvider); + + var databaseProvider = configuration.GetSection(nameof(DatabaseProviderConfiguration)).Get(); + switch (databaseProvider.ProviderType) + { + case DatabaseProviderType.SqlServer: + healthChecksBuilder + .AddSqlServer(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{configurationTableName}]") + .AddSqlServer(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{persistedGrantTableName}]") + .AddSqlServer(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT TOP 1 * FROM dbo.[{identityTableName}]"); + + break; + case DatabaseProviderType.PostgreSQL: + healthChecksBuilder + .AddNpgSql(configurationDbConnectionString, name: "ConfigurationDb", + healthQuery: $"SELECT * FROM {configurationTableName} LIMIT 1") + .AddNpgSql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb", + healthQuery: $"SELECT * FROM {persistedGrantTableName} LIMIT 1") + .AddNpgSql(identityDbConnectionString, name: "IdentityDb", + healthQuery: $"SELECT * FROM {identityTableName} LIMIT 1"); + break; + case DatabaseProviderType.MySql: + healthChecksBuilder + .AddMySql(configurationDbConnectionString, name: "ConfigurationDb") + .AddMySql(persistedGrantsDbConnectionString, name: "PersistentGrantsDb") + .AddMySql(identityDbConnectionString, name: "IdentityDb"); + break; + default: + throw new NotImplementedException($"Health checks not defined for database provider {databaseProvider.ProviderType}"); + } + } + } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/GravatarTagHelper.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/GravatarTagHelper.cs index d141771e0..3ca913600 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/GravatarTagHelper.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/GravatarTagHelper.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; namespace SkorubaIdentityServer4Admin.STS.Identity.Helpers.TagHelpers { @@ -47,3 +47,9 @@ private static string GetAvatarUrl(string hash, int size) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/SwitchTagHelper.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/SwitchTagHelper.cs index 7654a5332..b65499114 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/SwitchTagHelper.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/TagHelpers/SwitchTagHelper.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -22,3 +22,9 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/UserResolver.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/UserResolver.cs index 1a488d07d..ac25db891 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/UserResolver.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Helpers/UserResolver.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity; using SkorubaIdentityServer4Admin.STS.Identity.Configuration; using System.Threading.Tasks; @@ -29,3 +29,9 @@ public async Task GetUserAsync(string login) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Program.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Program.cs index cd1b982b9..738b09072 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Program.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Program.cs @@ -1,5 +1,8 @@ -using Microsoft.AspNetCore; +using System; +using System.IO; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; using Serilog; namespace SkorubaIdentityServer4Admin.STS.Identity @@ -8,13 +11,59 @@ public class Program { public static void Main(string[] args) { - CreateWebHostBuilder(args) - .UseSerilog() - .Build().Run(); + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(Configuration) + .CreateLogger(); + try + { + CreateHostBuilder(args).Build().Run(); + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly"); + } + finally + { + Log.CloseAndFlush(); + } } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); + public static IConfiguration Configuration { get; } = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile("serilog.json", optional: true, reloadOnChange: true) + .AddEnvironmentVariables() + .Build(); + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostContext, configApp) => + { + configApp.AddJsonFile("serilog.json", optional: true, reloadOnChange: true); + + if (hostContext.HostingEnvironment.IsDevelopment()) + { + configApp.AddUserSecrets(); + } + + configApp.AddEnvironmentVariables(); + configApp.AddCommandLine(args); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureKestrel(options => options.AddServerHeader = false); + webBuilder.UseStartup(); + }) + .UseSerilog((hostContext, loggerConfig) => + { + loggerConfig + .ReadFrom.Configuration(hostContext.Configuration) + .Enrich.WithProperty("ApplicationName", hostContext.HostingEnvironment.ApplicationName); + }); } } + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Properties/launchSettings.json b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Properties/launchSettings.json index d6f4293b0..e730e8c62 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Properties/launchSettings.json +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Properties/launchSettings.json @@ -1,27 +1,34 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:5000", - "sslPort": 0 - } + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5000", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "SkorubaIdentityServer4Admin.AspNetIdentity": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "SkorubaIdentityServer4Admin.AspNetIdentity": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:5001;http://localhost:5000" - } + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "environmentVariables": {}, + "httpPort": 10000 } + } } \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.da.resx new file mode 100644 index 000000000..e1619132c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.da.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft venligst din email konto ved at <a href='{0}'>klikke her</a>. + + + Bekræft din email konto + + + Brugeren eksisterer ikke eller er ikke bekræftet + + + Fejl fra extern udbyder: {0} + + + Ugyldig autentifikator kode. + + + Ugyldig gendannelses kode. + + + Nulstil din adgangskode ved at <a href='{0}'>klikke her</a>. + + + Nulstil Adgangskode + + + Kan ikke indlæse Two-Factor Authentication for denne bruger. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.es.resx new file mode 100644 index 000000000..4761c4faf --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.es.resx @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Por favor, confirma tu cuenta haciento <a href='{0}'>clic aquí</a>. + + + Confirma tu e-mail + + + El usuario no existe o no ha confirmado su cuenta + + + Error de proveedor externo: {0} + + + Código de autenticador invalido. + + + El código de recuperación ingresado es invalido. + + + Por favor, cambia tu contraseña haciendo <a href='{0}'>clic aquí</a>. + + + Restablecer contraseña + + + Fue imposible cargar el usuario de autenticación en dos pasos. + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fi.resx new file mode 100644 index 000000000..c0cc2e150 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fi.resx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista tilisi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + vahvista sähköpostiosoitteesi + + + Käyttäjää ei ole tai sitä ei ole vahvistettu + + + Ulkoisen palveluntarjoajan virhe: {0} + + + Virheellinen todennuskoodi. + + + Annettu virheellinen palautuskoodi. + + + Palauta salasanasi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + Nollaa salasana + + + Kahden tekijän todennuksen käyttäjää ei voi ladata. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fr.resx new file mode 100644 index 000000000..0d07e6d5c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/AccountController.fr.resx @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Veuillez confirmer votre compte par <a href='{0}'>en cliquant ici</a>. + + + Confirmez votre e-mail + + + L'utilisateur n'existe pas ou n'est pas valide + + + Erreur de la part d'un fournisseur externe : {0} + + + Code d'authentification invalide. + + + Code de récupération invalide. + Code de récupération saisi non valide. + + + Veuillez réinitialiser votre mot de passe <a href='{0}'>en cliquant ici</a>. + + + Réinitialiser le mot de passe + Réinitialiser Mot de passe + + + Impossible de charger l'utilisateur d'authentification à deux facteurs. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.da.resx new file mode 100644 index 000000000..27fe9c34c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.da.resx @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bruger med ID '{0}' har bedt om at få deres personlige data. + + + Din Authenticator App er blevet bekræftet. + + + Bekræft venligst din email konto ved at <a href='{0}'>klikke her</a>. + + + Bekræft din email konto + + + Bruger med ID '{0}' har slettet sin bruger. + + + Kan ikke generere gendannelseskoder til bruger med ID {0}, fordi de ikke har 2FA aktiveret. + + + Fejl Kode + + + Der opstod en uventet fejl ved sletning af bruger med ID {0}. + + + Der opstod en uventet fejl, da der blev deaktiveret 2FA for bruger med ID {0}. + + + Kan ikke generere gendannelseskoder for brugeren, da brugeren ikke har 2FA aktiveret. + + + Der opstod en uventet fejl ved indlæsning af eksterne login informationer for bruger med ID {0}. + + + Der opstod en uventet fejl ved fjernelse af eksternt login til bruger med ID {0}. + + + Der opstod en uventet fejl ved indstilling af e-mail til bruger med ID {0}. + + + Der opstod en uventet fejl ved indstilling af telefonnummer for bruger med ID {0}. + + + Det eksterne login blev tilføjet. + + + Det eksterne login blev fjernet. + + + Bekræftelseskoden er ugyldig. + + + Dit password er blevet ændret. + + + Bruger {0} ændrede deres adgangskode succesfuldt. + + + Password er ikke korrekt. + + + Dit password er gemt. + + + Din profil er blevet opdateret + + + Bruger med ID {0} har deaktiveret 2FA. + + + Den aktuelle browser er glemt. Når du logger ind igen fra denne browser, bliver du bedt om din 2FA-kode. + + + Bruger med id {0} har nulstillet deres Authenticator App nøgle. + + + Bruger med ID {0} har aktiveret 2FA med en Authenticator App. + + + Bruger med ID {0} har genereret nye 2FA gendannelseskoder. + + + Kan ikke indlæse bruger med ID {0}. + + + Bekræftelses e-mail er sendt. Tjek venligst din email. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.es.resx new file mode 100644 index 000000000..685d9ba7b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.es.resx @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El usuario con ID '{0}' pregunto por su información personal. + + + Tu aplicación autenticadora fue verificada. + + + Por favor, confirma tu cuenta haciendo <a href='{0}'>clic aquí</a> + . + + + Confirma tu e-mail + + + El usuario con ID '{0}' se eliminó a si mismo. + + + No se pueden generar los codigos de recuperación para el usuario con ID {0} porque no tienen la autenticación en dos pasos habilitada. + + + Código + + + Ocurrio un error inesperado al tratar de eliminar el usuario con ID {0}. + + + Ocurrio un error inesperado al tratar de deshabilitar autenticación en dos pasos para el usuario con ID {0}. + + + No se pudieron generar los codigos de recuperación para el usuario ya que no tiene la autenticación en dos pasos habilitada. + + + Ocurrio un error inesperado al cargar la información externa de inicio de sesión para el usuario con ID {0}. + + + Ocurrio un error inesperado al remover el inicio de sesión externo para el usuario con ID {0}. + + + Ocurrio un error inesperado al configurar el e-mail para el usuario con ID {0}. + + + Ocurrio un error inesperado al configurar el número de telefono para el usuario con ID {0}. + + + El inicio de sesión externo fue agregado. + + + El inicio de sesión externo fue quitado. + + + El código de verificación es inválido. + + + Tu contraseña ha sido cambiada. + + + El usuario {0} cambió su contraseña con éxito. + + + La contraseña no es correcta. + + + Tu contraseña ha sido establecida. + + + Tu perfil ha sido actualizado. + + + El usuario con ID {0} ha desabilitado la autenticación en dos pasos. + + + El navegador actual ha sido olvidado. Cuando te autentifiques denuevo desde este navegador se te preguntara con tu código de autenticación en dos pasos. + + + El usuario con ID {0} ha restablecido su llave de app de autenticación. + + + El usuario con ID {0} ha habilitado la autenticación en dos pasos con una app autenticadora. + + + El usuario con ID {0} ha generado nuevos códigos de recuperación de autenticación en dos pasos. + + + No es posible cargar el usuario con ID {0}. + + + E-mail de verificación enviado. Por favor, revisa tu bandeja de entrada. + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fi.resx new file mode 100644 index 000000000..518caf788 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fi.resx @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Käyttäjä, jonka tunnus '{0}', pyysi henkilökohtaisia tietojaan. + + + Autentikaattorisovelluksesi on vahvistettu. + + + Vahvista tilisi napsauttamalla <a href='{0}'> napsauttamalla tätä </a>. + + + vahvista sähköpostiosoitteesi + + + Käyttäjä, jonka tunnus '{0}', poisti itsensä. + + + Palautuskoodeja ei voi luoda käyttäjälle, jonka tunnus on {0}, koska heillä ei ole 2FA: ta käytössä. + + + Koodi + + + Käyttäjän, jolla on tunnus {0}, poistamisessa tapahtui odottamaton virhe. + + + Odottamaton virhe tapahtui poistamalla 2FA käytöstä käyttäjälle, jolla on tunnus {0}. + + + Palautuskoodeja ei voi luoda käyttäjälle, koska heillä ei ole 2FA: ta käytössä. + + + Odottamaton virhe ladattaessa ulkoista kirjautumistietoa käyttäjälle, jolla on tunnus {0}. + + + Odottamaton virhe ulkoisen kirjautumisen poistamisessa käyttäjälle, jolla on tunnus {0}. + + + Asettamalla odottamaton virhe sähköpostin asettamisessa käyttäjälle, jolla on tunnus {0}. + + + Asettamalla odottamaton virhe puhelinnumeron asettamisessa käyttäjälle, jolla on tunnus {0}. + + + Ulkoinen kirjautuminen lisättiin. + + + Ulkoinen sisäänkirjautuminen poistettiin. + + + Vahvistuskoodi on virheellinen. + + + Salasanasi on vaihdettu. + + + Käyttäjä {0} vaihtoi salasanansa onnistuneesti. + + + Salasana ei ole oikea. + + + Salasanasi on asetettu. + + + Profiilisi on päivitetty + + + Käyttäjätunnuksella {0} on poistettu 2fa käytöstä. + + + Nykyinen selain on unohdettu. Kun kirjaudut sisään uudelleen tästä selaimesta, sinulta kysytään 2fa-koodiasi. + + + Käyttäjä, jonka tunnus on {0}, on nollannut todennussovelluksen avaimen. + + + Käyttäjä, jonka tunnus on {0}, on ottanut käyttöön 2FA: n todennussovelluksella. + + + Käyttäjä, jonka tunnus on {0}, on luonut uusia 2FA-palautuskoodeja. + + + Käyttäjää, jolla on tunnus {0}, ei voi ladata. + + + Varmennusviesti lähetetty. Ole hyvä ja tarkista sähköpostisi. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fr.resx new file mode 100644 index 000000000..ed67250a8 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Controllers/ManageController.fr.resx @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + L'utilisateur avec l'ID '{0}' a demandé ses données personnelles. + + + Votre application d'authentification a été vérifiée. + + + Veuillez confirmer votre compte <a href='{0}'>en cliquant ici</a>. + + + Confirmez votre e-mail + + + L'utilisateur avec l'ID '{0}' s'est supprimé. + + + Impossible de générer des codes de récupération pour l'utilisateur avec l'ID {0} car A2F n'est pas activé. + + + Code + + + Une erreur inattendue s'est produite lors de la suppression de l'utilisateur avec l'ID {0}. + + + Une erreur inattendue s'est produite en désactivant A2F pour l'utilisateur avec l'ID {0}. + + + Impossible de générer des codes de récupération pour l'utilisateur car A2F n'est pas activé. + + + Une erreur inattendue s'est produite lors du chargement des informations de connexion externe de l'utilisateur avec l'ID {0}. + + + Une erreur inattendue s'est produite en supprimant la connexion externe pour l'utilisateur avec l'ID {0}. + + + Une erreur inattendue s'est produite lors du paramétrage de l'e-mail pour l'utilisateur avec l'ID {0}. + + + Une erreur inattendue s'est produite lors du réglage du numéro de téléphone de l'utilisateur avec l'ID {0}. + + + Le login externe a été ajouté. + + + Le login externe a été supprimé. + + + Le code de vérification n'est pas valide. + + + Votre mot de passe a été modifié. + + + L'utilisateur {0} a modifié son mot de passe avec succès. + + + Mot de passe incorrect. + + + Votre mot de passe a été défini. + + + Votre profil a été mis à jour + + + L'utilisateur avec l'ID {0} a désactivé A2F. + + + Le navigateur actuel a été oublié. Lorsque vous vous reconnectez à partir de ce navigateur, vous serez invité à entrer votre code A2F. + + + L'utilisateur avec l'ID {0} a réinitialisé sa clé d'application d'authentification. + + + L'utilisateur avec ID {0} a activé A2F avec une application d'authentification. + L'utilisateur avec l'ID {0} a activé A2F avec une application d'authentification. + + + L'utilisateur avec ID {0} a généré de nouveaux codes de récupération A2F. + L'utilisateur avec l'ID {0} a généré de nouveaux codes de récupération A2F. + + + Impossible de charger l'utilisateur avec ID {0}. + Impossible de charger l'utilisateur avec l'ID {0}. + + + Envoi d'un e-mail de vérification. Veuillez vérifier vos courriels. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx new file mode 100644 index 000000000..e6205937c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tak for bekræftelsen af ​​din e-mail. + + + Bekræft Email + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx new file mode 100644 index 000000000..ff2587e80 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gracias por confirmar tu e-mail. + + + Confirmar e-mail + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx new file mode 100644 index 000000000..dbe9d059d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kiitos sähköpostiviestisi vahvistamisesta. + + + Vahvista sähköposti + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fr.resx new file mode 100644 index 000000000..c979fbfe0 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ConfirmEmail.fr.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Merci d'avoir confirmé votre e-mail. + + + Confirmation e-mail + Confirmer l'e-mail + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx new file mode 100644 index 000000000..6a6278ffa --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.da.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Email + + + Du har godkendt med {0}. + Indtast en email adresse for dette websted nedenfor og klik på knappen Registrer for at afslutte + log ind. + + + Registrer + + + Tilknyt din {0} konto. + + + Registrer + + + Brugernavn + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx new file mode 100644 index 000000000..9255de959 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.es.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Email + + + Te has autentificado de manera exitosa con {0}. + Por favor, ingresa una dirección de correo electrónico para este sitio debajo y has clic en el boton Register para terminar de + iniciar sesión. + + + Regístrate + + + Asocia tu {0} cuenta. + + + Regístrate + + + Nombre de usuario + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx new file mode 100644 index 000000000..bb20d998a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fi.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sähköposti + + + Olet todennut {0} onnistuneesti. +        Kirjoita tämän sivuston sähköpostiosoite alle ja napsauta Rekisteröi-painiketta viimeistelläksesi +        Kirjaudu sisään. + + + Rekisteröidy + + + Yhdistä {0} -tilisi. + + + Rekisteröidy + + + Käyttäjänimi + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fr.resx new file mode 100644 index 000000000..24db20ffb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginConfirmation.fr.resx @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + E-mail + + + Vous avez réussi à vous authentifier avec {0}. + Veuillez entrer une adresse e-mail pour ce site ci-dessous et cliquez sur le bouton S'inscrire pour terminer + de vous connecter. + + + S'inscrire + + + Associez votre compte {0}. + + + S'inscrire + + + Nom d'utilisateur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx new file mode 100644 index 000000000..283335e5c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mislykket login med service. + + + Login fejl + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx new file mode 100644 index 000000000..e1cb7a3ce --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + La autentificación con el servicio no fue exitosa. + + + Fallo de inicio de sesión + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx new file mode 100644 index 000000000..742fb61e1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Epäonnistunut kirjautuminen palveluun. + + + Kirjautuminen epäonnistui + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fr.resx new file mode 100644 index 000000000..2ca02d51b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ExternalLoginFailure.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Connexion échouée avec le service. + + + Échec de connexion + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx new file mode 100644 index 000000000..75ff569ed --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Indsend + + + Indtast din e-mail. + + + Glemt dit password? + + + Email + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx new file mode 100644 index 000000000..0e6846c00 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Enviar + + + Ingresa tu e-mail. + + + ¿Olvidaste tu contraseña? + + + E-mail + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx new file mode 100644 index 000000000..621f15286 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lähetä + + + Syötä sähköpostiosoitteesi. + + + Unohditko salasanasi? + + + Sähköposti + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fr.resx new file mode 100644 index 000000000..38eaf31bb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPassword.fr.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Valider + + + Entrez votre e-mail. + + + Mot de passe oublié ? + + + E-mail + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx new file mode 100644 index 000000000..a5b02c3a1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kontroller din e-mail for at nulstille din adgangskode. + + + Glemt password bekræftelse + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx new file mode 100644 index 000000000..11babf008 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Por favor, revisa tu e-mail para restablecer tu contraseña. + + + Confirmación de contraseña olvidada + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx new file mode 100644 index 000000000..fd4ad8b6c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tarkista salasanasi tarkistamalla sähköpostiosoitteesi. + + + Unohtunut salasanan vahvistus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fr.resx new file mode 100644 index 000000000..912eb27ce --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ForgotPasswordConfirmation.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Veuillez vérifier votre e-mail pour réinitialiser votre mot de passe. + + + Confirmation du mot de passe oublié + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.da.resx new file mode 100644 index 000000000..42c257513 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne konto er blevet låst. Prøv igen senere. + + + Låst ude + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.es.resx new file mode 100644 index 000000000..55d62692f --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Esta cuenta ha sido bloqueado. Por favor, intentelo nuevamente más tarde. + + + Bloqueado + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fi.resx new file mode 100644 index 000000000..bad3dc307 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tämä tili on lukittu, yritä myöhemmin uudelleen. + + + Lukittu + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fr.resx new file mode 100644 index 000000000..9eee3853a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Lockout.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ce compte a été verrouillé, veuillez réessayer plus tard. + + + Verrouillé + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.da.resx new file mode 100644 index 000000000..9e8933f9d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Klik + + + her + + + for at vende tilbage til + + + Du er nu logget ud + + + Log ud + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.es.resx new file mode 100644 index 000000000..b3dbf454d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Clic + + + aquí + + + para volver a la + + + Tu sesión ha sido cerrada + + + Sesión cerrada + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx new file mode 100644 index 000000000..e034ef8fb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Klikkaus + + + tässä + + + palata + + + Olet nyt kirjautunut ulos + + + Kirjaudu ulos + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fr.resx new file mode 100644 index 000000000..cfca9033b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoggedOut.fr.resx @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cliquez + + + ici + + + pour revenir à + "to return to the" ?? + + + Vous êtes maintenant déconnecté + + + Déconnexion + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.da.resx new file mode 100644 index 000000000..359faf6b1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.da.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilbage + + + Email + + + Externt Log ind + + + Glemt password + + + Ugyldigt log ind + + + Lokalt Log ind + + + Log ind + + + Der er ingen log ind skemaer, der er konfigureret til denne Client. + + + Password + + + Registrer + + + Husk mit log ind + + + Log ind + + + Brugernavn + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.es.resx new file mode 100644 index 000000000..25efaa08e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.es.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cancelar + + + E-mail + + + Inicio de sesión externo + + + Olvidé mi contraseña + + + Petición de inicio de sesión inválido + + + Inicio de sesión local + + + Inicio de sesión + + + No hay esquemas de inicio de sesión configurados para este cliente. + + + Contraseña + + + Registrarse + + + Recordar inicio de sesión + + + Iniciar sesión + + + Nombre de usuario + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fi.resx new file mode 100644 index 000000000..3ea20a2f7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fi.resx @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Peruuttaa + + + Sähköposti + + + Ulkoinen kirjautuminen + + + Unohtuiko salasana + + + Virheellinen sisäänkirjauspyyntö + + + Paikallinen kirjautuminen + + + Kirjaudu sisään + + + Tätä asiakasohjelmaa varten ei ole määritetty kirjautumismalleja. + + + Salasana + + + Rekisteröidy + + + Muista kirjautumiseni + + + Kirjaudu sisään + + + Käyttäjätunnus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fr.resx new file mode 100644 index 000000000..7a5e7df8e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Login.fr.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Annuler + + + E-mail + + + Connexion externe + + + Mot de passe oublié + + + Demande de connexion invalide + + + Connexion locale + + + Connexion + + + Il n'y a pas de schéma de connexion configuré pour ce client. + There are no login schemes configured for this client. + + + Mot de passe + + + S'inscrire + + + Se souvenir de moi + Se rappeler de mon identifiant + + + Connexion + + + Identifiant + Nom d'utilisateur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx new file mode 100644 index 000000000..3a034769d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authenticator kode + + + Dit login er beskyttet med en Authenticator App. Indtast din Authenticator Kode forneden. + + + Log ind + + + Log ind med en gendannelseskode + + + Har du ikke adgang til din Authenticator Device? Du kan + + + Husk denne maskine + + + Two-Factor Authentication + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx new file mode 100644 index 000000000..429311a73 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código autenticador + + + Tu inicio de sesión esta protegido con una app autenticadora. Ingresa tu código autenticador debajo. + + + Iniciar sesión + + + Inicia sesión con un código de recuperación + + + ¿No tienes acceso a tu dispositivo autenticador? Puedes + + + Recordar esta máquina + + + Autentificación en dos pasos + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx new file mode 100644 index 000000000..82a0a38a4 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authenticator-koodi + + + Kirjautumistunnuksesi on suojattu todennussovelluksella. Kirjoita todennuskoodi alla. + + + Kirjaudu sisään + + + kirjaudu sisään palautuskoodilla + + + Eikö sinulla ole pääsyä todennuslaitteeseesi? Sinä pystyt + + + Muista tämä kone + + + Kaksivaiheinen todennus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fr.resx new file mode 100644 index 000000000..7da4d3308 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWith2fa.fr.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Code d'authentification + + + Votre connexion est protégée par une application d'authentification. Entrez votre code d'authentification ci-dessous. + + + Se connecter + + + vous connectez-vous avec un code de récupération + + + Vous n'avez pas accès à votre dispositif d'authentification ? Vous pouvez + + + Se souvenir de cette appareil + + + Authentification à deux facteurs + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx new file mode 100644 index 000000000..a6c6a3c26 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.da.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gendannelseskode + + + Du har anmodet om at logge ind med en gendannelseskode. Dette login vil ikke blive husket, før du angiver +    en Authenticator App kode ved log ind eller deaktiverer 2FA og logger ind igen. + + + Log ind + + + Bekræftelse af gendannelseskode + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx new file mode 100644 index 000000000..fcdaa6d76 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.es.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código de recuperación + + + Has podido iniciar sesión con un código de recuperación. Este inicio de sesión no sera recordado hasta que proveas + un código de aplicación autenticadora al iniciar sesión o deshabilita la autenticación en dos pasos e inicia sesión nuevamente. + + + Iniciar sesión + + + Verificación del código de recuperación + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx new file mode 100644 index 000000000..ccca2c11c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fi.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Palautuskoodi + + + Olet pyytänyt Kirjaudu sisään palautuskoodilla. Tätä sisäänkirjautumista ei muisteta, ennen kuin annat +    todennussovelluksen koodi kirjautumisen yhteydessä tai poista 2FA käytöstä ja kirjaudu sisään uudelleen. + + + Kirjaudu sisään + + + Palautuskoodin varmennus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fr.resx new file mode 100644 index 000000000..5f8d3690d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/LoginWithRecoveryCode.fr.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Code de récupération + + + Vous avez demandé à vous connecter avec un code de récupération. Cette connexion ne sera pas mémorisée tant que vous n'aurez pas fourni + un code d'authentification de l'application lors de la connexion ou désactivez 2FA puis reconnectez-vous. + + + Se connecter + + + Vérification du code de récupération + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.da.resx new file mode 100644 index 000000000..101dd3bb8 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ønsker du at logge ud af IdentityServer? + + + Log ud + + + Ja + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.es.resx new file mode 100644 index 000000000..203945250 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ¿Quisieras cerrar la sesión de IdentityServer? + + + Cerrar sesión + + + Si + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fi.resx new file mode 100644 index 000000000..d51a62d66 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Haluatko kirjautua ulos IdentityServeristä? + + + Kirjaudu ulos + + + Kyllä + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fr.resx new file mode 100644 index 000000000..b02f90325 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Logout.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Souhaitez-vous vous déconnecter d'IdentityServer ? + + + Déconnexion + + + Oui + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.da.resx new file mode 100644 index 000000000..34827e105 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registrer + + + Bekræft Password + + + Email + + + Password + + + Opret en ny konto. + + + Registrer + + + Brugernavn + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.es.resx new file mode 100644 index 000000000..8b1c44a6b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registrarse + + + Confirmar contraseña + + + E-mail + + + Contraseña + + + Crea una nueva cuenta. + + + Registrarse + + + Nombre de usuario + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fi.resx new file mode 100644 index 000000000..ee84b61b5 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Rekisteröidy + + + Vahvista salasana + + + Sähköposti + + + Salasana + + + Luo uusi tili. + + + Rekisteröidy + + + Käyttäjätunnus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fr.resx new file mode 100644 index 000000000..bfed0e681 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/Register.fr.resx @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + S'inscrire + + + Confirmer mot de passe + Confirmer (le) mot de passe + + + E-mail + + + Mot de passe + + + Créez un nouveau compte. + + + S'inscrire + + + Identifiant + Nom d'utilisateur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx new file mode 100644 index 000000000..e71ebb51f --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Registreringen er deaktiveret. + + + Registrerings Fejl + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx new file mode 100644 index 000000000..4265b6397 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + El registro de cuentas esta deshabilitado. + + + Problema de registro + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.fr.resx new file mode 100644 index 000000000..98ef5d9f0 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/RegisterFailure.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + L'inscription est désactivée. + + + Échec de l'inscription + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.da.resx new file mode 100644 index 000000000..f29c3fba7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Email + + + Password + + + Nulstil + + + Nulstil dit password. + + + Nulstil password + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.es.resx new file mode 100644 index 000000000..0d9048cb9 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + E-mail + + + Contraseña + + + Restablecer + + + Restablece tu contraseña. + + + Restablecer contraseña + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx new file mode 100644 index 000000000..7d85d9136 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + Sähköposti + + + Salasana + + + Nollaa + + + Nollaa salasana. + + + Nollaa salasana + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fr.resx new file mode 100644 index 000000000..f81fd8fa3 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPassword.fr.resx @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmer mot de passe + Confirmer (le) mot de passe + + + E-mail + + + Mot de passe + + + Réinitialiser + + + Réinitialisez votre mot de passe. + + + Réinitialiser le mot de passe + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx new file mode 100644 index 000000000..d3bdfe775 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Din adgangskode er nulstillet. Vær venlig + + + klik her for at logge ind + + + Bekræftelse af nulstilling af password + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx new file mode 100644 index 000000000..1386c9b33 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tu contraseña ha sido restablecida. Por favor, + + + has clic aquí para iniciar sesión + + + Confirmación de restablecimiento de contraseña + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx new file mode 100644 index 000000000..fdd93a4ec --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Salasanasi on nollattu. Ole kiltti + + + kirjaudu sisään napsauttamalla tätä + + + Nollaa salasanan vahvistus + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fr.resx new file mode 100644 index 000000000..b4527de44 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Account/ResetPasswordConfirmation.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Votre mot de passe a été réinitialisé. Veuillez + + + cliquez ici pour vous connecter + + + Réinitialiser la confirmation du mot de passe + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.da.resx new file mode 100644 index 000000000..df4f26d2e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.da.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Applikations Adgang + + + Nej, tillad ikke + + + Personlige Informationer + + + Husk min beslutning + + + anmoder om din tilladelse + + + Fjern markeringen af ​​de tilladelser, du ikke ønsker at give. + + + Ja, tillad + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.es.resx new file mode 100644 index 000000000..498d7eb22 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.es.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Acceso ha aplicación + + + No, no permitir + + + Información personal + + + Recordar mi decisión + + + está pidiendo su permiso + + + Deselecciona los permisos que no quieras otorgar. + + + Si, permitir + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fi.resx new file mode 100644 index 000000000..e3d94f966 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fi.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sovelluksen käyttö + + + Ei, älä salli + + + Henkilökohtaisia tietoja + + + Muista päätökseni + + + pyytää lupaa + + + Poista valinnat, joita et halua myöntää. + + + Kyllä, salli + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fr.resx new file mode 100644 index 000000000..78cbeba34 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Consent/Index.fr.resx @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Accès aux applications + + + Non, Refuser + Non, ne pas autoriser + + + Informations personnelles + + + Se souvenir de ma décision + + + demande votre permission + + + Décochez les permissions que vous ne souhaitez pas accorder. + + + Oui, Autoriser + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.da.resx new file mode 100644 index 000000000..9d2cdf8af --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Succes + + + Du har godkendt enheden + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.es.resx new file mode 100644 index 000000000..eef603d9e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Éxito + + + Has autorizado este dispositivo de forma exitosa + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fi.resx new file mode 100644 index 000000000..4613435f0 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Onnistui + + + Olet valtuuttanut laitteen onnistuneesti + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fr.resx new file mode 100644 index 000000000..508f75563 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/Success.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Succès + + + Vous avez autorisé avec succès l'appareil + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx new file mode 100644 index 000000000..688fca8a3 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Indtast den kode, der vises på din enhed + + + Bekræft + + + Bruger Kode + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx new file mode 100644 index 000000000..7f3a0e85a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Por favor, ingresa el código que se muestra en tu dispositivo + + + Enviar + + + Código de usuario + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx new file mode 100644 index 000000000..25dfcbaed --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Anna laitteellasi näkyvä koodi + + + Lähetä + + + Käyttäjäkoodi + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fr.resx new file mode 100644 index 000000000..2f74c7ee8 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeCapture.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Veuillez entrer le code affiché sur votre appareil + + + Valider + + + Code utilisateur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx new file mode 100644 index 000000000..937fc675d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Applikations Adgang + + + Bekræft, at autorisations anmodningen angiver koden: + + + Nej, tillad ikke + + + Personlige Informationer + + + Husk min beslutning + + + anmoder om din tilladelse + + + Fjern markeringen af ​​de tilladelser, du ikke ønsker at give. + + + Ja, tillad + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx new file mode 100644 index 000000000..effb2396e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Acceso a aplicación + + + Por favor, confirma que la petición de autorización tiene el código: + + + No, no permitir + + + Información personal + + + Recuerda mi decisión + + + esta preguntado por tu permiso + + + Desmarca los permisos que no quires otorgar. + + + Si, permitir + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx new file mode 100644 index 000000000..914e93915 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sovelluksen käyttö + + + Vahvista, että valtuutuspyynnössä on mainittu koodi: + + + Ei, älä salli + + + Henkilökohtaisia tietoja + + + Muista päätökseni + + + pyytää lupaa + + + Poista valinnat, joita et halua myöntää. + + + Kyllä, salli + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fr.resx new file mode 100644 index 000000000..b1192eb68 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Device/UserCodeConfirmation.fr.resx @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Accès Application + Accès aux applications, Accès à l'application + + + Veuillez confirmer que la demande d'autorisation mentionne le code : + + + Non, Refuser + Non, ne pas autoriser + + + Informations personnelles + + + Se souvenir de ma décision + + + demande votre permission + + + Décochez les permissions que vous ne souhaitez pas accorder. + + + Oui, Autoriser + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.da.resx new file mode 100644 index 000000000..fbf8cdcf5 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Claims + + + Clients + + + Egenskaber + + + Authentication cookie + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.es.resx new file mode 100644 index 000000000..9cdf0eaea --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Reclamaciones + + + Clientes + + + Propiedades + + + Cookie de autentificación + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx new file mode 100644 index 000000000..920e593a7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + väittää + + + Sovellukset + + + Ominaisuudet + + + Todennus eväste + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fr.resx new file mode 100644 index 000000000..b0c7d826a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Diagnostics/Index.fr.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Claims + + + Clients + + + Propriétés + + + Cookies d'authentification + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.da.resx new file mode 100644 index 000000000..f36248b0a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + API Grants + + + Oprettet: + + + Udløber: + + + Identity Grants + + + Du har ikke givet adgang til nogen applikationer + + + Fjern adgang + + + Nedenfor er listen over applikationer, du har givet adgang til, og navnene på de ressourcer, de har adgang til. + + + Client Applikations Adgang + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.es.resx new file mode 100644 index 000000000..b1499349c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Concesiones de API + + + Creado: + + + Expira: + + + Concesiones de identidad + + + No has dado acceso a ninguna aplicación + + + Revocar acceso + + + Debajo hay una lista de aplicaciones a las que has dado acceso y los nombres de los recursos a los que tienen acceso. + + + Acceso de aplicaciones cliente + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fi.resx new file mode 100644 index 000000000..a1fab30cc --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + API-tuet + + + Luotu: + + + Erääntyy: + + + Henkilöllisyystodistukset + + + Et ole antanut käyttöoikeutta mihinkään sovelluksiin + + + Peruuta käyttöoikeus + + + Alla on luettelo sovelluksista, joille olet saanut pääsyn, ja resurssien nimet, joihin heillä on pääsy. + + + Asiakassovelluksen käyttöoikeudet + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fr.resx new file mode 100644 index 000000000..f0901ecd6 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Grants/Index.fr.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Octrois API + + + Créé : + + + Expire : + + + Identity Grants + + + Vous n'avez donné accès à aucune application + + + Révoquer l'accès + + + Vous trouverez ci-dessous la liste des applications auxquelles vous avez donné accès et les noms des ressources auxquelles elles ont accès. + + + Accès aux applications client + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.da.resx new file mode 100644 index 000000000..6d74c2779 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.da.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Two-Factor Authentication + + + Skift password + + + Discovery Document + + + Gemte Grants + + + Log ind + + + Min personlige data + + + Min profil + + + Welcome to {0} + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.en.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.en.resx index af0758f32..4cde1b68c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.en.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.en.resx @@ -129,15 +129,6 @@ Persisted Grants - - ready to use samples - - - source code repository - - - Here are links to the - Login @@ -148,9 +139,6 @@ My profile - Welcome to Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Welcome to {0} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.es.resx new file mode 100644 index 000000000..f1939b122 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.es.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autentificación en dos pasos + + + Cambiar contraseña + + + Documento de descubrimiento + + + Concesiones persistidas + + + Inicio de sesión + + + Mi información personal + + + Mi perfil + + + Bienvenido a {0} + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fa.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fa.resx index b56d925ee..29693088c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fa.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fa.resx @@ -129,15 +129,6 @@ واگذاری های اصرارشده - - آماده استفاده از نمونه ها - - - مخزن کد منبع - - - در اینجا پیوندهایی آمده است به - ورود @@ -148,9 +139,6 @@ پروفایل من - خوش آمدید به Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + خوش آمدید به {0} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fi.resx new file mode 100644 index 000000000..b48e1990e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fi.resx @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kaksivaiheinen todennus + + + Vaihda salasana + + + Konfiguraation dokumentti + + + Pysyvät oikeudet + + + Kirjaudu sisään + + + Henkilökohtaiset tietoni + + + Profiilini + + + Tervetuloa {0}: een + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fr.resx new file mode 100644 index 000000000..67ee9eb73 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.fr.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authentification à deux facteurs + + + Modifier le mot de passe + + + Discovery Document + + + Consentements + Octrois persistants. Explicit mistake for clarity + + + Connexion + + + Mes données personnelles + + + Mon profil + + + Bienvenue sur {0} + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.ru.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.ru.resx index 5f474465c..d1d67555c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.ru.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.ru.resx @@ -129,15 +129,6 @@ Постоянные права - - готовые к использованию образцы - - - репозиторий исходного кода - - - Здесь ссылки на - Вход @@ -148,9 +139,6 @@ Мой профиль - Добро пожаловать в Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + Добро пожаловать в {0} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.sv.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.sv.resx index 701282614..724b4dc09 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.sv.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.sv.resx @@ -129,15 +129,6 @@ Medgivanden - - exempel - - - källkod - - - Här är länkarna till - Inloggning @@ -148,9 +139,6 @@ Min profil - Välkommen till Skoruba IdentitytServer4 - - - Skoruba IdentityServer4 + Välkommen till {0} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.zh.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.zh.resx index 5af5e3478..978978edb 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.zh.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Home/Index.zh.resx @@ -129,15 +129,6 @@ 持久授权 - - 准备好使用样品 - - - 源代码库 - - - 这是链接到 - 登录 @@ -148,9 +139,6 @@ 我的个人资料 - 欢迎来到 Skoruba IdentityServer4 - - - Skoruba IdentityServer4 + 欢迎来到 {0} \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx new file mode 100644 index 000000000..f102e61fb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Nyt Password + + + Gammelt Password + + + Skift password + + + Opdater Password + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx new file mode 100644 index 000000000..337bcae33 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + Nueva contraseña + + + Contraseña actual + + + Cambiar contraseña + + + Cambiar contraseña + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx new file mode 100644 index 000000000..01d3c0841 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + uusi salasana + + + vanha salasana + + + Vaihda salasana + + + Päivitä salasana + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fr.resx new file mode 100644 index 000000000..08433b56c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ChangePassword.fr.resx @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmer mot de passe + Confirmer mot de passe + + + Nouveau mot de passe + + + Ancien mot de passe + + + Modifier le mot de passe + + + Mettre à jour le mot de passe + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx new file mode 100644 index 000000000..cb8a61a01 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sletning af disse data fjerner din konto permanent, og kan ikke gendannes. + + + Slet data, og luk min konto + + + Password + + + Slet personlige data + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx new file mode 100644 index 000000000..a6c36b4f9 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Al eliminar estos datos estaras eliminado tu cuenta de manera permanente. No es posible deshacer esta acción. + + + Eliminar datos y cerrar mi cuenta + + + Contraseña + + + Eliminar datos personales + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx new file mode 100644 index 000000000..e4036781f --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tietojen poistaminen poistaa tilisi pysyvästi, eikä sitä voida palauttaa. + + + Poista tiedot ja sulje tilini + + + Salasana + + + Poista henkilökohtaiset tiedot + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fr.resx new file mode 100644 index 000000000..1c63fa386 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DeletePersonalData.fr.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + La suppression de ces données supprimera définitivement votre compte, cette action sera irrécupérable. + rétabli, restauré, réparé, corrigé, annulé, rectifié + + + Supprimer des données et fermer mon compte + + + Mot de passe + + + Supprimer les données personnelles + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx new file mode 100644 index 000000000..c90e247fd --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Deaktiver 2FA + + + Deaktivering af 2FA ændrer ikke nøglerne, der bruges i Authenticator App'en. Hvis du ønsker at ændre den nøgle, der bruges i en Authenticator App, skal du gøre det + + + nulstil dine Authenticator nøgler + + + Denne handling deaktiverer kun 2FA. + + + Deaktiver Two-Factor Authentication (2FA) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx new file mode 100644 index 000000000..7a99766a3 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Deshabilitar la autenticación en dos pasos + + + Deshabilitar la autenticación en dos pasos no cambia las llaves usadas en la app autenticadora. Si deseas cambiar la llave usada en la app autenticadora debes + + + restablecer las llaves de tu autenticador + + + Esta acción solo deshabilita la autenticación en dos pasos. + + + Deshabilita la autentificación en dos pasos + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx new file mode 100644 index 000000000..4fd4bea72 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista 2FA käytöstä + + + 2FA: n poistaminen käytöstä ei muuta todentajasovelluksissa käytettyjä näppäimiä. Jos haluat vaihtaa todennussovelluksessa käytetyn avaimen, sinun pitäisi tehdä + + + nollaa todennusavaimet + + + Tämä toiminta poistaa vain 2FA: n. + + + Poista kaksifaktorinen todennus (2FA) käytöstä + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx new file mode 100644 index 000000000..43af48711 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Disable2fa.fr.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Désactiver A2F + + + Désactiver A2F ne change pas les clés utilisées dans les applications d'authentification. Si vous souhaitez changer la clé utilisée dans une application d'authentification, vous devez + + + réinitialiser vos clés d'authentification + + + Cette action désactive uniquement A2F. + + + Désactiver l'authentification à deux facteurs (A2F) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx new file mode 100644 index 000000000..41791dea5 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Download dine data + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx new file mode 100644 index 000000000..7707a45f0 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Descarga tus datos + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx new file mode 100644 index 000000000..f09d1f51b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lataa tietosi + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fr.resx new file mode 100644 index 000000000..856e2291d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/DownloadPersonalData.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Téléchargez vos données + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx new file mode 100644 index 000000000..3aa85bc5c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.da.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Verifikationskode + + + Download en Two-Factor Authenticator App som f.eks. Microsoft Authenticator til + + + Google Authenticator for + + + Når du har scannet QR-koden eller indtastet nøglen ovenfor, vil din Two-Factor Authentication App give dig +                med en unik kode. Indtast koden i bekræftelsesfeltet nedenfor. + + + Scan QR-koden, eller indtast denne nøgle + + + i din Two-Factor Authentication App. Mellemrum og skriftstørrelse betyder ikke noget. + + + For at bruge en Authentication App skal du gennemføre følgende trin: + + + Konfigurer Authentication App + + + Bekræft + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx new file mode 100644 index 000000000..c72a4d26f --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.es.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Código de verificación + + + Descarga una app autenticadora de dos pasos como Microsoft Authenticator para + + + Google Authenticator para + + + Una vez hayas escaneado el codigo QR o hayas ingresado la llave arriva, tu app autenticadora de dos pasos podra proveerte + con un código unico. Ingresa el código en la caja de confirmación. + + + Escanea el código QR o ingresa esta llave + + + en tu app autenticadora de dos pasos. Los espacios y las mayusculas no importan. + + + Para usar una app autenticadora sigue los siguientes pasos: + + + Configurar app autenticadora + + + Verificar + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx new file mode 100644 index 000000000..4e2cdf3ed --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fi.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvistuskoodi + + + Lataa kaksifaktorinen todennussovellus, kuten Microsoft Authenticator + + + Google Authenticator verkkotunnukselle + + + Kun olet skannannut QR-koodin tai syöttänyt yllä olevan avaimen, kaksifaktorinen todennussovellus antaa sinulle +                ainutlaatuisella koodilla. Kirjoita koodi alla olevaan vahvistuskenttään. + + + Skannaa QR-koodi tai kirjoita tämä avain + + + kahden tekijän todennussovellukseesi. Väleillä ja kotelolla ei ole merkitystä. + + + Voit käyttää todennussovellusta seuraavien vaiheiden avulla: + + + Määritä todennussovellus + + + tarkistaa + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fr.resx new file mode 100644 index 000000000..4464ec67a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/EnableAuthenticator.fr.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Code de vérification + + + Téléchargez une application d'authentification à deux facteurs comme Microsoft Authenticator pour + + + Google Authenticator pour + + + Une fois que vous avez scanné le code QR ou entré la clé ci-dessus, votre application d'authentification à deux facteurs vous fournira + un code unique. Entrez le code dans le champ de confirmation ci-dessous. + + + Scannez le QR Code ou entrez cette clé + + + dans votre application d'authentification à deux facteurs. Les espaces et la casse n'ont pas d'importance. + + + Pour utiliser une application d'authentification, suivez les étapes suivantes : + + + Configurer l'application d'authentification + + + Vérifier + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx new file mode 100644 index 000000000..ea2eda9e8 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.da.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Fjern + + + Registrerede login + + + Administrer dine eksterne logins + + + Tilføj en anden service for at logge ind. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx new file mode 100644 index 000000000..c3fda7202 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.es.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Quitar + + + Inicios de sesión registrados + + + Administra tus inicios de sesión externos + + + Agrega otro servicio de inicio de sesión. + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx new file mode 100644 index 000000000..742e12a92 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fi.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista + + + Rekisteröidyt kirjautumiset + + + Hallitse ulkoisia kirjautumistietoja + + + Lisää toinen palvelu Kirjauduksesi sisään. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fr.resx new file mode 100644 index 000000000..7bda0fdd6 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ExternalLogins.fr.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Supprimer + Enlever + + + Connexions enregistrées + + + Gérer vos connexions externes + + + Ajouter un autre service pour vous connecter. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx new file mode 100644 index 000000000..1abb4ecb6 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Generer gendannelseskoder + + + Generering af nye gendannelseskoder ændrer ikke nøglerne, der bruges i Authentication Appen. Hvis du ønsker at ændre den nøgle, der bruges i Authentication Appen, skal du gøre det + + + Hvis du mister din enhed og ikke har gendannelseskoder, mister du adgang til din konto. + + + nulstil dine Authentication nøgler. + + + Gem disse koder et sikkert sted. + + + Generer Two-Factor Authentication (2FA) gendannelseskoder + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx new file mode 100644 index 000000000..ac0962bae --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Genera códigos de recuperación + + + Generar nuevos códigos de verificación no cambia las llaves usadas en la apps autenticadoras. Si deseas cambiar la llave usada en la app autenticadora deberias + + + Si pierdes tu dispositivo y no tienes el código de recuperación perderas el acceso a tu cuenta. + + + Restablece tus llaves autenticadoras. + + + Guarda estos códigos en un lugar seguro. + + + Genera códigos de recuperación para la autenticación en dos pasos + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx new file mode 100644 index 000000000..5494c4edc --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Luo palautuskoodit + + + Uusien palautuskoodien luominen ei muuta todentajasovelluksissa käytettyjä avaimia. Jos haluat vaihtaa todennussovelluksessa käytetyn avaimen, sinun pitäisi tehdä + + + Jos kadotat laitteen ja sinulla ei ole palautuskoodeja, menetät pääsyn tilillesi. + + + nollaa todennusavaimet. + + + Aseta nämä koodit turvalliseen paikkaan. + + + Luo kahden tekijän todennuksen (2FA) palautuskoodit + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fr.resx new file mode 100644 index 000000000..ba2a51258 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/GenerateRecoveryCodes.fr.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Générer des codes de récupération + + + La génération de nouveaux codes de récupération ne modifie pas les clés utilisées dans les applications d'authentification. Si vous souhaitez changer la clé utilisée dans une application d'authentification, vous devez + + + Si vous perdez votre appareil et que vous n'avez pas les codes de récupération, vous perdrez l'accès à votre compte. + + + réinitialiser vos clés d'authentification. + + + Mettez ces codes en lieu sûr. + + + Générer des codes de récupération d'authentification à deux facteurs (2FA) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.da.resx new file mode 100644 index 000000000..f038fa672 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.da.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Land + + + Email + + + By + + + Fuldt navn + + + Telefonnummer + + + Post adresse + + + Profil URL + + + Region + + + Gem + + + Send bekræftelses email + + + Adresse + + + Profil + + + Brugernavn + + + Website URL + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.es.resx new file mode 100644 index 000000000..e13838ef5 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.es.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + País + + + E-mail + + + Ciudad + + + Nombre completo + + + Número de telefono + + + Código postal + + + URL de perfil + + + Región + + + Guardar + + + Enviar e-mail de verificación + + + Dirección + + + Perfil + + + Nombre de usuario + + + Url de sitio web + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fi.resx new file mode 100644 index 000000000..4d87a59cc --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fi.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Maa + + + Sähköposti + + + Kaupunki + + + Koko nimi + + + Puhelinnumero + + + Postinumero + + + profiili-URL + + + alue + + + Tallenna + + + Lähetä vahvistusviesti + + + Katuosoite + + + Profiili + + + Käyttäjänimi + + + Nettisivun URL + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fr.resx new file mode 100644 index 000000000..93e4a1ad7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/Index.fr.resx @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Pays + + + E-mail + + + Ville + + + Nom et prénom + + + Numéro de téléphone + + + Code postal + + + URL du profil + + + Région + + + Sauvegarder + + + Envoyer un e-mail de vérification + + + Adresse postale + + + Profil + + + Identifiant + Nom d'utilisateur + + + URL du site + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx new file mode 100644 index 000000000..c2d2e520e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Mislykket login med service. + + + Login Fejlede + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx new file mode 100644 index 000000000..e0a477e41 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Inicio de sesión con servicio no exitoso. + + + Falló el inicio de sesión + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx new file mode 100644 index 000000000..742fb61e1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Epäonnistunut kirjautuminen palveluun. + + + Kirjautuminen epäonnistui + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fr.resx new file mode 100644 index 000000000..2ca02d51b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/LinkLoginFailure.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Connexion échouée avec le service. + + + Échec de connexion + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.da.resx new file mode 100644 index 000000000..a4eee1ebc --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.da.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Slet + + + Download + + + Din konto indeholder personlige data, som du har givet os. Denne side giver dig mulighed for at downloade eller slette disse data. + + + Personlig data + + + Sletning af disse data fjerner din konto permanent, og den kan ikke gendannes. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.es.resx new file mode 100644 index 000000000..660caa335 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.es.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Eliminar + + + Descargar + + + Tu cuenta contiene datos personales que nos has entregado. Esta página te permite descargar o eliminar estos datos. + + + Datos personales + + + Eliminar estos datos eliminara permanentemente tu cuenta. No es posible deshacer esta acción. + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx new file mode 100644 index 000000000..9ed12f6f7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fi.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Poista + + + ladata + + + Tilisi sisältää henkilökohtaisia tietoja, jotka olet antanut meille. Tällä sivulla voit ladata tai poistaa kyseisiä tietoja. + + + Henkilökohtaiset tiedot + + + Tietojen poistaminen poistaa tilisi pysyvästi, eikä sitä voida palauttaa. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fr.resx new file mode 100644 index 000000000..e2a7f4425 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/PersonalData.fr.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Supprimer + + + Télécharger + + + Votre compte contient des données personnelles que vous nous avez fournies. Cette page vous permet de télécharger ou de supprimer ces données. + + + Données personnelles + + + La suppression de ces données supprimera définitivement votre compte, ce qui est irrécupérable. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx new file mode 100644 index 000000000..3f43486be --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.da.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Denne proces deaktiverer 2FA, indtil du bekræfter din Authentication App. +        Hvis du ikke afslutter din Authentication App konfiguration, kan du miste adgang til din konto. + + + Nulstil Authentication nøgler + + + Hvis du nulstiller din Authentication nøgle, fungerer din Authentication App ikke før du konfigurerer den igen. + + + Nulstil Authentication nøgle + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx new file mode 100644 index 000000000..d1656dd21 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + + + + Este proceso deshabilitará la autenticación en dos pasos hasta que verifiques tu app autenticadora. + Si no completas la configuración de tu app autenticadora podrias perder el acceso a tu cuenta. + + + Restablecer llave autenticadora + + + Si restableces tu llave autenticadora tu app autenticadora podria no funcionar hasta que la configures. + + + Resetear llave autenticadora + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx new file mode 100644 index 000000000..7e3d0632c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fi.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tämä prosessi poistaa 2FA: n käytöstä, kunnes olet todennut todentajasovelluksesi. +        Jos et suorita todennussovelluksen määrityksiä, saatat menettää pääsyn tilillesi. + + + Nollaa todennusavain + + + Jos nollaat todennusavaimen, todennussovellus ei toimi, ennen kuin olet määrittänyt sen uudelleen. + + + Nollaa todennusavain + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fr.resx new file mode 100644 index 000000000..c04788c0d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ResetAuthenticator.fr.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ce processus désactive 2FA jusqu'à ce que vous vérifiez votre application d'authentification. + Si vous ne complétez pas la configuration de votre application d'authentification, vous risquez de perdre l'accès à votre compte. + + + Réinitialiser la clé d'authentification + + + Si vous réinitialisez votre clé d'authentification, votre application d'authentification ne fonctionnera pas tant que vous ne l'aurez pas reconfigurée. + + + Réinitialiser la clé d'authentification + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.da.resx new file mode 100644 index 000000000..4119cc1c6 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.da.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bekræft Password + + + Du har ikke et lokalt brugernavn / password til dette websted. Tilføj en lokal konto, så du kan logge på uden et eksternt login. + + + Nyt Password + + + Vælg Password + + + Vælg dit Password + + + Vælg Password + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.es.resx new file mode 100644 index 000000000..82b0799ac --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.es.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmar contraseña + + + No tienes un usuario/contraseña local para este sitio. Agrega una cuenta local para poder ingresar sin un inicio de sesión externo. + + + Nueva contraseña + + + Establecer contraseña + + + Establece tu contraseña + + + Establecer contraseña + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx new file mode 100644 index 000000000..147171346 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fi.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Vahvista salasana + + + Sinulla ei ole paikallista käyttäjänimeä / salasanaa tälle sivustolle. Lisää paikallinen tili, jotta voit Kirjaudu sisään ilman ulkoista kirjautumista. + + + uusi salasana + + + Aseta salasana + + + Aseta salasanasi + + + Aseta salasana + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx new file mode 100644 index 000000000..1cdb80a8e --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/SetPassword.fr.resx @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Confirmer mot de passe + Confirmer (le) mot de passe + + + Vous n'avez pas d'identifiant/mot de passe local pour ce site. Ajoutez un compte local pour pouvoir vous connecter sans connexion externe. + + + Nouveau mot de passe + + + Définir le mot de passe + Définir / Définissez + + + Définissez votre mot de passe + Définir / Définissez + + + Définir le mot de passe + Définir / Définissez + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx new file mode 100644 index 000000000..fd803f9e1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hvis du mister din enhed og ikke har gendannelseskoder, mister du adgang til din konto. + + + Gem disse koder et sikkert sted. + + + Gendannelseskoder + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx new file mode 100644 index 000000000..2b7b28752 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Si pierdes tu dispositivo y no tienes acceso a tus códigos de recuperación perderas el acceso a tu cuenta. + + + Guarda estos códigos en un lugar seguro. + + + Códigos de recuperación + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx new file mode 100644 index 000000000..87d662c9f --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Jos kadotat laitteen ja sinulla ei ole palautuskoodeja, menetät pääsyn tilillesi. + + + Aseta nämä koodit turvalliseen paikkaan. + + + Palautuskoodit + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fr.resx new file mode 100644 index 000000000..fd69b4451 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/ShowRecoveryCodes.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Si vous perdez votre appareil et n'avez pas les codes de récupération, vous perdrez l'accès à votre compte. + + + Mettez ces codes en lieu sûr. + + + Codes de récupération + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx new file mode 100644 index 000000000..24794b6c2 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.da.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tilføj Authentication App + + + Authentication App + + + før du kan logge ind med en gendannelseskode + + + Deaktiver 2FA + + + Glem din browser + + + generere et nyt sæt gendannelseskoder + + + Du har ingen gendannelseskoder tilbage + + + Du har 1 gendannelseskode tilbage + + + gendannelseskoder tilbage + + + Nulstil Authentication App + + + Nulstil gendannelseskoder + + + Konfigurer Authentication App + + + Two-Factor Authentication (2FA) + + + Du kan generere et nyt sæt gendannelseskoder + + + Du har + + + Du skal + + + Du burde + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx new file mode 100644 index 000000000..df05aef2c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.es.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Agrega una app autenticadora + + + App autenticadora + + + Antes de poder ingresar con un código de recuperación + + + Desabilitar la autenticación en dos pasos + + + Olvidar este navegador + + + genera un nuevo conjunto de códigos de recuperación + + + No te quedan códigos de recuperación + + + te queda un código de recuperación + + + códigos de recuperación + + + Restablecer app autenticadora + + + Restablecer códigos de recuperación + + + Configurar app autenticadora + + + Autentificación en dos pasos + + + Puedes generar un nuevo conjunto de códigos de recuperación + + + Tienes + + + Debes + + + Deberias + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx new file mode 100644 index 000000000..b2132fbb1 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fi.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Lisää todennussovellus + + + Authenticator-sovellus + + + ennen kuin voit Kirjaudu sisään palautuskoodilla + + + Poista 2FA käytöstä + + + Unohda tämä selain + + + luo uusi joukko palautuskoodeja + + + Sinulla ei ole palautuskoodeja jäljellä + + + Sinulla on 1 palautuskoodi jäljellä + + + palautuskoodit jäljellä + + + Nollaa todennussovellus + + + Palauta palautuskoodit + + + Aseta todennussovellus + + + Kaksivaiheinen todennus (2FA) + + + Voit luoda uuden palautuskoodijoukon + + + Sinulla on + + + Sinun täytyy + + + Sinun pitäisi + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fr.resx new file mode 100644 index 000000000..b31f71c81 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Manage/TwoFactorAuthentication.fr.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Ajouter une application d'authentification + + + Application d'authentification + + + avant de pouvoir vous connecter avec un code de récupération + + + Désactiver 2FA + + + Oublier ce navigateur + + + générer un nouvel ensemble de codes de récupération + + + Vous n'avez plus de codes de récupération + + + Il vous reste 1 code de récupération + + + codes de récupération restants + + + Réinitialiser l'application d'authentification + + + Réinitialiser les codes de récupération + + + Configurer l'application d'authentification + + + Authentification à deux facteurs (2FA) + + + Vous pouvez générer un nouvel ensemble de codes de récupération + + + Vous avez + + + Vous devez + + + Vous devriez + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx new file mode 100644 index 000000000..448e64e8c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sprog: + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx new file mode 100644 index 000000000..2628fbe14 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Idiomas: + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx new file mode 100644 index 000000000..4f91d16b5 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kieli: + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fr.resx new file mode 100644 index 000000000..d56c4bbf4 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Common/SelectLanguage.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Langue: + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx new file mode 100644 index 000000000..2d9c29b62 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer Admin + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx new file mode 100644 index 000000000..bb5c28976 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer Admin + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx new file mode 100644 index 000000000..5138ded0c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + IdentityServer-järjestelmänvalvoja + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fr.resx new file mode 100644 index 000000000..3d73f3f51 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Components/IdentityServerAdminLink/Default.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Admin IdentityServer + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.da.resx new file mode 100644 index 000000000..5c5d9a763 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.da.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Beklager, der opstod en fejl + + + Kalde Id: + + + Fejl + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.es.resx new file mode 100644 index 000000000..caca1746b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Perdón, hubo un error + + + ID de petición: + + + Error + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fi.resx new file mode 100644 index 000000000..ce3d8093b --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fi.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Valitettavasti tapahtui virhe + + + Pyydä tunnusta: + + + Virhe + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fr.resx new file mode 100644 index 000000000..e0f48233c --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Error.fr.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Désolé, une erreur s'est produite + + + ID requête : + + + Erreur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.da.resx new file mode 100644 index 000000000..dfe0a0154 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.da.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Når det er afsluttet, kan du lukke denne fane + + + Du vender nu tilbage til applikationen. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.es.resx new file mode 100644 index 000000000..06d1ce8f6 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.es.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Una vez completado, puedes cerrar esta pestaña + + + Estas siendo redireccionado a la aplicación. + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fi.resx new file mode 100644 index 000000000..e3526e954 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fi.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kun olet valmis, voit sulkea tämän välilehden + + + Palaatte nyt sovellukseen. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fr.resx new file mode 100644 index 000000000..37f74053d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/Redirect.fr.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Une fois terminé, vous pouvez fermer cet onglet + + + Vous allez maintenant être renvoyé à l'application. + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.da.resx new file mode 100644 index 000000000..ba808c466 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.da.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Two-Factor Authentication + + + Skift password + + + Mine eksterne logins + + + © + + + Grants + + + Mine personlige data + + + Min profil + + + Menu + + + Indstillinger + + + log ud + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.en.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.en.resx index 3b62d9d42..4b5029896 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.en.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.en.resx @@ -126,11 +126,8 @@ My external logins - - Skoruba IdentityServer4 - - © 2019 + © Grants @@ -144,16 +141,10 @@ Menu - - IdentityServer4 - Settings logout - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.es.resx new file mode 100644 index 000000000..508594ad7 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.es.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Autentificación en dos pasos + + + Cambiar contraseña + + + Mis inicios de sesión externos + + + © + + + Concesiones + + + Mis datos personales + + + Mi perfil + + + Menú + + + Configuración + + + Cerrar sesión + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fa.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fa.resx index 108aa9106..46730af34 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fa.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fa.resx @@ -126,34 +126,25 @@ ورودی های خارجی من - - Skoruba IdentityServer4 - - © 2019 + © واگذاری ها - + اطلاعات شخصی من - + پروفایل من فهرست - - IdentityServer4 - تنظیمات خروج - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fi.resx new file mode 100644 index 000000000..999969912 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fi.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Kaksivaiheinen todennus + + + Vaihda salasana + + + Omat ulkoiset kirjautumiset + + + © + + + Käyttöoikeudet + + + Henkilökohtaiset tietoni + + + Profiilini + + + valikko + + + asetukset + + + Kirjaudu ulos + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fr.resx new file mode 100644 index 000000000..40d841ddb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.fr.resx @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Authentification à deux facteurs + + + Modifier le mot de passe + + + Mes identifiants externes + + + © + + + Consentements + Octrois. Explicit mistake for clarity + + + Mes données personnelles + + + Mon profil + + + Menu + + + Réglages + + + Déconnexion + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.ru.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.ru.resx index b37a647d2..87cc9886d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.ru.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.ru.resx @@ -126,11 +126,8 @@ Моя внешняя учетная запись - - Skoruba IdentityServer4 - - © 2019 + © Права @@ -144,16 +141,10 @@ Меню - - IdentityServer4 - Настройки выход - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.sv.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.sv.resx index 00728d189..7525c993a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.sv.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.sv.resx @@ -126,11 +126,8 @@ Externa inlogg - - Skoruba IdentityServer4 - - © 2019 + © Medgivanden @@ -144,16 +141,10 @@ Many - - IdentityServer4 - Inställningar Logga ut - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.zh.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.zh.resx index 25a30e87a..f1b600922 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.zh.resx +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_Layout.zh.resx @@ -126,11 +126,8 @@ 我的外部登录 - - Skoruba IdentityServer4 - - © 2019 + © 授权 @@ -144,16 +141,10 @@ 菜单 - - IdentityServer4 - 设置 注销 - - Skoruba IdentityServer4 - \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx new file mode 100644 index 000000000..86aa64669 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (påkrævet) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx new file mode 100644 index 000000000..d35884f57 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (requerido) + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx new file mode 100644 index 000000000..fb2088702 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (vaaditaan) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fr.resx new file mode 100644 index 000000000..517e01341 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ScopeListItem.fr.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + (obligatoire) + (requis) + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx new file mode 100644 index 000000000..25888c27d --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.da.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Fejl + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx new file mode 100644 index 000000000..71f62ac84 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.es.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx new file mode 100644 index 000000000..a1ffe2eeb --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fi.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Virhe + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fr.resx b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fr.resx new file mode 100644 index 000000000..b708fee96 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Resources/Views/Shared/_ValidationSummary.fr.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Erreur + + \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/AuditEventSink.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/AuditEventSink.cs new file mode 100644 index 000000000..b80541180 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/AuditEventSink.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using IdentityServer4.Events; +using IdentityServer4.Services; +using Microsoft.Extensions.Logging; + +namespace SkorubaIdentityServer4Admin.STS.Identity.Services +{ + public class AuditEventSink : DefaultEventSink + { + public AuditEventSink(ILogger logger) : base(logger) + { + } + + public override Task PersistAsync(Event evt) + { + return base.PersistAsync(evt); + } + } +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/EmailSender.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/EmailSender.cs index ffbac94b6..846330d84 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/EmailSender.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/EmailSender.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.Extensions.Logging; @@ -21,3 +21,9 @@ public Task SendEmailAsync(string email, string subject, string htmlMessage) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SendgridEmailSender.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SendgridEmailSender.cs index e3926c617..4ec9b0fd9 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SendgridEmailSender.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SendgridEmailSender.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.Extensions.Logging; using SendGrid; using SkorubaIdentityServer4Admin.STS.Identity.Configuration; @@ -43,3 +43,9 @@ public async Task SendEmailAsync(string email, string subject, string htmlMessag } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SmtpEmailSender.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SmtpEmailSender.cs index 17db144fd..0c0a5cc96 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SmtpEmailSender.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Services/SmtpEmailSender.cs @@ -1,4 +1,5 @@ -using System.Net.Mail; +using System; +using System.Net.Mail; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.Extensions.Logging; @@ -21,9 +22,12 @@ public SmtpEmailSender(SmtpConfiguration configuration, ILogger log Host = _configuration.Host, Port = _configuration.Port, DeliveryMethod = SmtpDeliveryMethod.Network, - EnableSsl = _configuration.UseSSL, - Credentials = new System.Net.NetworkCredential(_configuration.Login, _configuration.Password) + EnableSsl = _configuration.UseSSL }; + if (!string.IsNullOrEmpty(_configuration.Password)) + _client.Credentials = new System.Net.NetworkCredential(_configuration.Login, _configuration.Password); + else + _client.UseDefaultCredentials = true; } public Task SendEmailAsync(string email, string subject, string htmlMessage) @@ -39,7 +43,7 @@ public Task SendEmailAsync(string email, string subject, string htmlMessage) _logger.LogInformation($"Email: {email}, subject: {subject}, message: {htmlMessage} successfully sent"); return Task.CompletedTask; } - catch (SmtpException ex) + catch (Exception ex) { _logger.LogError($"Exception {ex} during sending email: {email}, subject: {subject}"); throw; @@ -47,3 +51,9 @@ public Task SendEmailAsync(string email, string subject, string htmlMessage) } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj index 98268ab25..363dbf074 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/SkorubaIdentityServer4Admin.STS.Identity.csproj @@ -1,26 +1,62 @@ - - - - netcoreapp2.2 - 9c91d295-54c5-4d09-9bd6-fa56fb74011b - - - - - - - - - - - - - - - - - - - + + + + netcoreapp3.1 + 9c91d295-54c5-4d09-9bd6-fa56fb74011b + ..\..\docker-compose.dcproj + Linux + ..\.. + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Startup.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Startup.cs index ee38769a8..5dbb884ed 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Startup.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Startup.cs @@ -1,10 +1,15 @@ -using Microsoft.AspNetCore.Builder; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Hosting; using SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.DbContexts; using SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.Entities.Identity; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Constants; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces; using SkorubaIdentityServer4Admin.STS.Identity.Helpers; namespace SkorubaIdentityServer4Admin.STS.Identity @@ -12,53 +17,41 @@ namespace SkorubaIdentityServer4Admin.STS.Identity public class Startup { public IConfiguration Configuration { get; } - public IHostingEnvironment Environment { get; } - public ILogger Logger { get; set; } + public IWebHostEnvironment Environment { get; } - public Startup(IHostingEnvironment environment, ILoggerFactory loggerFactory) + public Startup(IWebHostEnvironment environment, IConfiguration configuration) { - var builder = new ConfigurationBuilder() - .SetBasePath(environment.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); - - if (environment.IsDevelopment()) - { - builder.AddUserSecrets(); - } - - Configuration = builder.Build(); + Configuration = configuration; Environment = environment; - Logger = loggerFactory.CreateLogger(); } public void ConfigureServices(IServiceCollection services) { - services.ConfigureRootConfiguration(Configuration); + var rootConfiguration = CreateRootConfiguration(); + services.AddSingleton(rootConfiguration); - // Add DbContext for Asp.Net Core Identity - services.AddIdentityDbContext(Configuration, Environment); + // Register DbContexts for IdentityServer and Identity + RegisterDbContexts(services); // Add email senders which is currently setup for SendGrid and SMTP services.AddEmailSenders(Configuration); - // Add services for authentication, including Identity model, IdentityServer4 and external providers - services.AddAuthenticationServices(Environment, Configuration, Logger); - + // Add services for authentication, including Identity model and external providers + RegisterAuthentication(services); + // Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers // Including settings for MVC and Localization // If you want to change primary keys or use another db model for Asp.Net Core Identity: - services.AddMvcWithLocalization(); + services.AddMvcWithLocalization(Configuration); // Add authorization policies for MVC - services.AddAuthorizationPolicies(); + RegisterAuthorization(services); + + services.AddIdSHealthChecks(Configuration); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - app.AddLogging(loggerFactory, Configuration); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); @@ -68,9 +61,55 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF app.UseSecurityHeaders(); app.UseStaticFiles(); - app.UseIdentityServer(); + UseAuthentication(app); app.UseMvcLocalizationServices(); - app.UseMvcWithDefaultRoute(); + + app.UseRouting(); + app.UseAuthorization(); + app.UseEndpoints(endpoint => + { + endpoint.MapDefaultControllerRoute(); + endpoint.MapHealthChecks("/health", new HealthCheckOptions + { + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + }); + } + + public virtual void RegisterDbContexts(IServiceCollection services) + { + services.RegisterDbContexts(Configuration); + } + + public virtual void RegisterAuthentication(IServiceCollection services) + { + services.AddAuthenticationServices(Configuration); + services.AddIdentityServer(Configuration); + } + + public virtual void RegisterAuthorization(IServiceCollection services) + { + var rootConfiguration = CreateRootConfiguration(); + services.AddAuthorizationPolicies(rootConfiguration); + } + + public virtual void UseAuthentication(IApplicationBuilder app) + { + app.UseIdentityServer(); + } + + protected IRootConfiguration CreateRootConfiguration() + { + var rootConfiguration = new RootConfiguration(); + Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration); + Configuration.GetSection(ConfigurationConsts.RegisterConfigurationKey).Bind(rootConfiguration.RegisterConfiguration); + return rootConfiguration; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs index 09a22f142..241d70df0 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewComponents/IdentityServerAdminLinkViewComponent.cs @@ -1,5 +1,5 @@ -using Microsoft.AspNetCore.Mvc; -using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces; +using Microsoft.AspNetCore.Mvc; +using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewComponents { @@ -19,4 +19,9 @@ public IViewComponentResult Invoke() return View(model: identityAdminUrl); } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalLoginConfirmationViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalLoginConfirmationViewModel.cs index 016a05b94..c2bad2e84 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalLoginConfirmationViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalLoginConfirmationViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -13,3 +13,9 @@ public class ExternalLoginConfirmationViewModel public string Email { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalProvider.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalProvider.cs index 756cf4b26..265749713 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalProvider.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ExternalProvider.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Samples -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -11,4 +11,9 @@ public class ExternalProvider public string DisplayName { get; set; } public string AuthenticationScheme { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ForgotPasswordViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ForgotPasswordViewModel.cs index 7103b9cec..e2e2aedc2 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ForgotPasswordViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ForgotPasswordViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -9,3 +9,9 @@ public class ForgotPasswordViewModel public string Email { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoggedOutViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoggedOutViewModel.cs index df53b5d53..7ecea4e72 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoggedOutViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoggedOutViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -18,4 +18,9 @@ public class LoggedOutViewModel public bool TriggerExternalSignout => ExternalAuthenticationScheme != null; public string ExternalAuthenticationScheme { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginInputModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginInputModel.cs index 79f61e378..51add87fc 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginInputModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginInputModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System.ComponentModel.DataAnnotations; @@ -17,4 +17,9 @@ public class LoginInputModel public bool RememberLogin { get; set; } public string ReturnUrl { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginViewModel.cs index 910ec82d6..fd8cef01c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System; using System.Collections.Generic; @@ -23,4 +23,9 @@ public class LoginViewModel : LoginInputModel public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1; public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null; } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWith2faViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWith2faViewModel.cs index 71c30572d..230b989ea 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWith2faViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWith2faViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -13,3 +13,9 @@ public class LoginWith2faViewModel public string ReturnUrl { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWithRecoveryCodeViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWithRecoveryCodeViewModel.cs index 45076cf26..582054897 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWithRecoveryCodeViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LoginWithRecoveryCodeViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -11,3 +11,9 @@ public class LoginWithRecoveryCodeViewModel public string ReturnUrl { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutInputModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutInputModel.cs index ab8b9d49c..974d8a0db 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutInputModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutInputModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -11,3 +11,9 @@ public class LogoutInputModel public string LogoutId { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutViewModel.cs index 31b93f3b9..badb5cc86 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/LogoutViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -11,3 +11,9 @@ public class LogoutViewModel : LogoutInputModel public bool ShowLogoutPrompt { get; set; } = true; } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RedirectViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RedirectViewModel.cs index 344f47b5f..165273666 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RedirectViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RedirectViewModel.cs @@ -10,4 +10,9 @@ public class RedirectViewModel { public string RedirectUrl { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterViewModel.cs index f79a8c0d8..aad4848dc 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -20,4 +20,9 @@ public class RegisterViewModel [Compare("Password")] public string ConfirmPassword { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs new file mode 100644 index 000000000..5f4906c46 --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/RegisterWithoutUsernameViewModel.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations; + +namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account +{ + public class RegisterWithoutUsernameViewModel + { + [Required] + [EmailAddress] + public string Email { get; set; } + + [Required] + [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] + [DataType(DataType.Password)] + public string Password { get; set; } + + [DataType(DataType.Password)] + [Compare("Password")] + public string ConfirmPassword { get; set; } + } +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ResetPasswordViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ResetPasswordViewModel.cs index 9900fa116..cb67cf9d8 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ResetPasswordViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Account/ResetPasswordViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account { @@ -20,3 +20,9 @@ public class ResetPasswordViewModel public string Code { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentInputModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentInputModel.cs index 5c107f383..0a7f5d796 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentInputModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentInputModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System.Collections.Generic; @@ -15,4 +15,9 @@ public class ConsentInputModel public bool RememberConsent { get; set; } public string ReturnUrl { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentViewModel.cs index 5a4883543..32095f7c7 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ConsentViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System.Collections.Generic; @@ -19,3 +19,9 @@ public class ConsentViewModel : ConsentInputModel public IEnumerable ResourceScopes { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ProcessConsentResult.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ProcessConsentResult.cs index 8c9f1e4a9..546794ec7 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ProcessConsentResult.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ProcessConsentResult.cs @@ -19,3 +19,9 @@ public class ProcessConsentResult public string ValidationError { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ScopeViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ScopeViewModel.cs index c67efd675..44a673b32 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ScopeViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Consent/ScopeViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Consent { @@ -16,3 +16,9 @@ public class ScopeViewModel public bool Checked { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationInputModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationInputModel.cs index 2a21d3962..11c897bd1 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationInputModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationInputModel.cs @@ -12,4 +12,9 @@ public class DeviceAuthorizationInputModel : ConsentInputModel { public string UserCode { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationViewModel.cs index eb42652e0..0de1e5540 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Device/DeviceAuthorizationViewModel.cs @@ -13,4 +13,9 @@ public class DeviceAuthorizationViewModel : ConsentViewModel public string UserCode { get; set; } public bool ConfirmUserCode { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Diagnostics/DiagnosticsViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Diagnostics/DiagnosticsViewModel.cs index a5c873e9d..e11727e30 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Diagnostics/DiagnosticsViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Diagnostics/DiagnosticsViewModel.cs @@ -31,4 +31,9 @@ public DiagnosticsViewModel(AuthenticateResult result) public AuthenticateResult AuthenticateResult { get; } public IEnumerable Clients { get; } = new List(); } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Grants/GrantsViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Grants/GrantsViewModel.cs index 678770ff5..cb647db5c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Grants/GrantsViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Grants/GrantsViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using System; using System.Collections.Generic; @@ -25,4 +25,9 @@ public class GrantViewModel public IEnumerable IdentityGrantNames { get; set; } public IEnumerable ApiGrantNames { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Home/ErrorViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Home/ErrorViewModel.cs index 4ad60602c..f776f9e9f 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Home/ErrorViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Home/ErrorViewModel.cs @@ -1,8 +1,8 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Original file: https://github.com/IdentityServer/IdentityServer4.Quickstart.UI -// Modified by Jan Škoruba +// Modified by Jan koruba using IdentityServer4.Models; @@ -12,4 +12,9 @@ public class ErrorViewModel { public ErrorMessage Error { get; set; } } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ChangePasswordViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ChangePasswordViewModel.cs index 809acb756..c8be99c46 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ChangePasswordViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ChangePasswordViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { @@ -20,3 +20,9 @@ public class ChangePasswordViewModel public string StatusMessage { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/DeletePersonalDataViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/DeletePersonalDataViewModel.cs index 56a0fe7ea..907f4bb08 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/DeletePersonalDataViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/DeletePersonalDataViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { @@ -11,3 +11,9 @@ public class DeletePersonalDataViewModel public string Password { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/EnableAuthenticatorViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/EnableAuthenticatorViewModel.cs index cbb3ee318..9086fc655 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/EnableAuthenticatorViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/EnableAuthenticatorViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage @@ -18,3 +18,9 @@ public class EnableAuthenticatorViewModel public string AuthenticatorUri { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ExternalLoginsViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ExternalLoginsViewModel.cs index 13d060734..383bbb0f3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ExternalLoginsViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ExternalLoginsViewModel.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; @@ -15,3 +15,9 @@ public class ExternalLoginsViewModel public string StatusMessage { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/IndexViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/IndexViewModel.cs index e753f655d..77b0150ab 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/IndexViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/IndexViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { @@ -50,3 +50,9 @@ public class IndexViewModel public string Country { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/RemoveLoginViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/RemoveLoginViewModel.cs index 421f9a125..9f74e9c37 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/RemoveLoginViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/RemoveLoginViewModel.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage +namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { public class RemoveLoginViewModel { @@ -6,3 +6,9 @@ public class RemoveLoginViewModel public string ProviderKey { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/SetPasswordViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/SetPasswordViewModel.cs index adca70bab..20d76f579 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/SetPasswordViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/SetPasswordViewModel.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { @@ -16,3 +16,9 @@ public class SetPasswordViewModel public string StatusMessage { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ShowRecoveryCodesViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ShowRecoveryCodesViewModel.cs index c755ea138..db40b1808 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ShowRecoveryCodesViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/ShowRecoveryCodesViewModel.cs @@ -1,7 +1,13 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage +namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { public class ShowRecoveryCodesViewModel { public string[] RecoveryCodes { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/TwoFactorAuthenticationViewModel.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/TwoFactorAuthenticationViewModel.cs index e7b053f25..0cb484756 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/TwoFactorAuthenticationViewModel.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/ViewModels/Manage/TwoFactorAuthenticationViewModel.cs @@ -1,4 +1,4 @@ -namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage +namespace SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage { public class TwoFactorAuthenticationViewModel { @@ -11,3 +11,9 @@ public class TwoFactorAuthenticationViewModel public bool IsMachineRemembered { get; set; } } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ConfirmEmail.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ConfirmEmail.cshtml index aa1daaa88..3e2fca1f1 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ConfirmEmail.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ConfirmEmail.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["Title"]; @@ -10,3 +10,9 @@ @Localizer["ConfirmMessage"]

    + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginConfirmation.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginConfirmation.cshtml index eee728233..993bd4e98 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginConfirmation.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginConfirmation.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.ExternalLoginConfirmationViewModel @{ @@ -34,4 +34,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginFailure.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginFailure.cshtml index b6a244c8c..ef500bad4 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginFailure.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ExternalLoginFailure.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -7,4 +7,9 @@

    @ViewData["Title"].

    @Localizer["Error"]

    -
    \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPassword.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPassword.cshtml index 4cc94c69a..3c1490c10 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPassword.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPassword.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.ForgotPasswordViewModel @{ @@ -22,4 +22,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPasswordConfirmation.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPasswordConfirmation.cshtml index cb29ca3ce..4ae909f56 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPasswordConfirmation.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ForgotPasswordConfirmation.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["Title"]; @@ -10,3 +10,9 @@ @Localizer["CheckEmailMessage"] + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Lockout.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Lockout.cshtml index 671175e9c..f348b41c2 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Lockout.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Lockout.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -7,4 +7,9 @@

    @ViewData["Title"]

    @Localizer["Info"]

    -
    \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoggedOut.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoggedOut.cshtml index 760d317df..53a0aec44 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoggedOut.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoggedOut.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.LoggedOutViewModel @@ -34,3 +34,9 @@ } } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Login.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Login.cshtml index 013e2c110..025271780 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Login.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Login.cshtml @@ -1,5 +1,5 @@ -@using Microsoft.AspNetCore.Mvc.Localization -@using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Intefaces +@using Microsoft.AspNetCore.Mvc.Localization +@using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces @using SkorubaIdentityServer4Admin.STS.Identity.Helpers.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.LoginViewModel @@ -115,4 +115,9 @@ } - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWith2fa.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWith2fa.cshtml index d962422eb..a3fc479b7 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWith2fa.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWith2fa.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.LoginWith2faViewModel @{ @@ -39,4 +39,9 @@

    @Localizer["NoAuthenticatorDevice"] @Localizer["LoginWithRecoveryCode"] -

    \ No newline at end of file +

    + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWithRecoveryCode.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWithRecoveryCode.cshtml index 774296f35..c2f2a340d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWithRecoveryCode.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/LoginWithRecoveryCode.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.LoginWithRecoveryCodeViewModel @{ @@ -24,4 +24,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Logout.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Logout.cshtml index 1d2ecc467..7f7dc9fd1 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Logout.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Logout.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.LogoutViewModel @@ -20,4 +20,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Register.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Register.cshtml index 6085638f6..40940b6b5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Register.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/Register.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.RegisterViewModel @{ @@ -45,4 +45,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterFailure.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterFailure.cshtml index ffc7a05fd..7d9a2864a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterFailure.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterFailure.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["Title"]; @@ -10,3 +10,9 @@ @Localizer["Error"]

    + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml new file mode 100644 index 000000000..ef54edc0a --- /dev/null +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/RegisterWithoutUsername.cshtml @@ -0,0 +1,46 @@ +@inject IViewLocalizer Localizer +@using Microsoft.AspNetCore.Mvc.Localization +@model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.RegisterWithoutUsernameViewModel +@{ + ViewData["Title"] = Localizer["Title"]; +} + +

    @ViewData["Title"].

    + +@await Html.PartialAsync("_ValidationSummary") + +
    +

    @Localizer["SubTitle"]

    +
    +
    + +
    + + +
    +
    +
    + +
    + + +
    +
    +
    + +
    + + +
    +
    +
    +
    + +
    +
    +
    + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPassword.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPassword.cshtml index ecab905c7..eb0effe30 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPassword.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPassword.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Account.ResetPasswordViewModel @{ @@ -40,3 +40,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPasswordConfirmation.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPasswordConfirmation.cshtml index 2165bdbaf..3d5879185 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPasswordConfirmation.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Account/ResetPasswordConfirmation.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = Localizer["Title"]; @@ -7,4 +7,9 @@

    @ViewData["Title"]

    @Localizer["ConfirmMessage"] @Localizer["Login"]. -

    \ No newline at end of file +

    + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Consent/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Consent/Index.cshtml index b02c54341..f6fd188eb 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Consent/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Consent/Index.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Consent.ConsentViewModel @@ -100,4 +100,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/Success.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/Success.cshtml index e60338880..671b08557 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/Success.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/Success.cshtml @@ -7,4 +7,9 @@ @Localizer["SuccessMessage"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeCapture.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeCapture.cshtml index 9352634db..313128b5f 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeCapture.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeCapture.cshtml @@ -39,4 +39,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeConfirmation.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeConfirmation.cshtml index b599b187a..ef1684bdf 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeConfirmation.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Device/UserCodeConfirmation.cshtml @@ -110,4 +110,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Diagnostics/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Diagnostics/Index.cshtml index 5ab811873..a1d79e246 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Diagnostics/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Diagnostics/Index.cshtml @@ -31,4 +31,9 @@
  • @client
  • } -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Grants/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Grants/Index.cshtml index 118324e07..d4bc5cc54 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Grants/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Grants/Index.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Grants.GrantsViewModel @@ -78,4 +78,9 @@ } } - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Home/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Home/Index.cshtml index 62e1efa9d..979f1d75d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Home/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Home/Index.cshtml @@ -1,9 +1,11 @@ -@using IdentityServer4.Extensions +@using IdentityServer4.Extensions @using Microsoft.AspNetCore.Mvc.Localization +@using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces @inject IViewLocalizer Localizer +@inject IRootConfiguration RootConfiguration
    -

    Logo
    @Localizer["Title"]

    -

    @Localizer["SubTitle"]

    +

    Logo
    @RootConfiguration.AdminConfiguration.PageTitle

    +

    @Localizer["SubTitle", RootConfiguration.AdminConfiguration.PageTitle]

    @@ -21,23 +23,23 @@
    } - + @if (User.IsAuthenticated()) { -
    -
    -

    @Localizer["Grants"]

    -
    -
    -

    - -

    - @Localizer["Grants"] +
    +
    +

    @Localizer["Grants"]

    +
    +
    -
    } - -
    + +

    @Localizer["Discovery"]

    @@ -107,12 +109,6 @@ } -
    -
    -

    - @Localizer["LinkTitle"] - @Localizer["LinkSource"], - @Localizer["LinkSamples"]. -

    -
    -
    + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ChangePassword.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ChangePassword.cshtml index 0826a4076..19d9be0c8 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ChangePassword.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ChangePassword.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.ChangePasswordViewModel @{ @@ -34,3 +34,9 @@
    + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DeletePersonalData.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DeletePersonalData.cshtml index 72f0584eb..77d1e21ba 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DeletePersonalData.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DeletePersonalData.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.DeletePersonalDataViewModel @{ @@ -25,4 +25,9 @@ } -
    \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Disable2fa.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Disable2fa.cshtml index 126393061..55de51ba4 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Disable2fa.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Disable2fa.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -21,3 +21,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DownloadPersonalData.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DownloadPersonalData.cshtml index 6655a7279..82b12ae05 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DownloadPersonalData.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/DownloadPersonalData.cshtml @@ -1,8 +1,13 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; } -

    @ViewData["Title"]

    \ No newline at end of file +

    @ViewData["Title"]

    + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/EnableAuthenticator.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/EnableAuthenticator.cshtml index 63373799c..c3363c62c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/EnableAuthenticator.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/EnableAuthenticator.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.EnableAuthenticatorViewModel @{ @@ -54,4 +54,9 @@ width: 300, height: 300 }); - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ExternalLogins.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ExternalLogins.cshtml index c823a13fe..5e5a2aac0 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ExternalLogins.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ExternalLogins.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.ExternalLoginsViewModel @{ @@ -52,3 +52,9 @@ } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/GenerateRecoveryCodes.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/GenerateRecoveryCodes.cshtml index c06e0fbf8..925c6762c 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/GenerateRecoveryCodes.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/GenerateRecoveryCodes.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -24,3 +24,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Index.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Index.cshtml index b7836d44d..3c76f2910 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Index.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/Index.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.IndexViewModel @@ -91,4 +91,9 @@ - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/LinkLoginFailure.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/LinkLoginFailure.cshtml index cf01e2e8e..8b4b470c3 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/LinkLoginFailure.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/LinkLoginFailure.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -9,4 +9,9 @@

    @ViewData["Title"]

    @Localizer["Error"]

    -
    \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/PersonalData.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/PersonalData.cshtml index c7b41a563..a1f358d5e 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/PersonalData.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/PersonalData.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ @@ -22,4 +22,9 @@ @Localizer["Delete"] - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ResetAuthenticator.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ResetAuthenticator.cshtml index 1b8fa75d9..a9bb3c3bb 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ResetAuthenticator.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ResetAuthenticator.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @{ ViewData["Title"] = Localizer["Title"]; @@ -18,4 +18,9 @@
    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/SetPassword.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/SetPassword.cshtml index 50ca7a5f9..065029db4 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/SetPassword.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/SetPassword.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.SetPasswordViewModel @{ @@ -29,3 +29,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ShowRecoveryCodes.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ShowRecoveryCodes.cshtml index fdae9c0f2..22ac24731 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ShowRecoveryCodes.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/ShowRecoveryCodes.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.ShowRecoveryCodesViewModel @{ @@ -22,4 +22,9 @@ @Model.RecoveryCodes[row] @Model.RecoveryCodes[row + 1]
    } - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/TwoFactorAuthentication.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/TwoFactorAuthentication.cshtml index f7b773742..4a51b443a 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/TwoFactorAuthentication.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/TwoFactorAuthentication.cshtml @@ -1,4 +1,4 @@ -@inject IViewLocalizer Localizer +@inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Mvc.Localization @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Manage.TwoFactorAuthenticationViewModel @{ @@ -76,3 +76,9 @@ } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/_StatusMessage.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/_StatusMessage.cshtml index 092bf1741..30d6e145d 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/_StatusMessage.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Manage/_StatusMessage.cshtml @@ -1,4 +1,4 @@ -@model string +@model string @if (!String.IsNullOrEmpty(Model)) { @@ -8,3 +8,9 @@ @Model } + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Common/SelectLanguage.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Common/SelectLanguage.cshtml index 5dd7172cd..50b34ff58 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Common/SelectLanguage.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Common/SelectLanguage.cshtml @@ -1,24 +1,31 @@ -@using Microsoft.AspNetCore.Builder +@using Microsoft.AspNetCore.Builder @using Microsoft.AspNetCore.Localization @using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.Extensions.Options @inject IViewLocalizer Localizer @inject IOptions LocOptions @{ - var requestCulture = Context.Features.Get(); - var cultureItems = LocOptions.Value.SupportedUICultures - .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) - .ToList(); - var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; + var requestCulture = Context.Features.Get(); + var cultureItems = LocOptions.Value.SupportedUICultures + .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName }) + .ToList(); + var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}"; } +@if (cultureItems.Count > 1) +{ +
    +
    +
    + + +
    +
    +
    +} + + + + -
    -
    -
    - - -
    -
    -
    \ No newline at end of file diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Components/IdentityServerAdminLink/Default.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Components/IdentityServerAdminLink/Default.cshtml index 163cf9830..55bb4ee30 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Components/IdentityServerAdminLink/Default.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Components/IdentityServerAdminLink/Default.cshtml @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @model string @inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Authorization @@ -8,4 +8,9 @@ @if ((await AuthorizationService.AuthorizeAsync(User, AuthorizationConsts.AdministrationPolicy)).Succeeded) { @Localizer["IdentityServerAdmin"] -} \ No newline at end of file +} + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Error.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Error.cshtml index 5fe7f0833..12f1d6543 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Error.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Error.cshtml @@ -1,12 +1,13 @@ -@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @using Microsoft.AspNetCore.Hosting +@using Microsoft.Extensions.Hosting @model SkorubaIdentityServer4Admin.STS.Identity.ViewModels.Home.ErrorViewModel -@inject IHostingEnvironment host +@inject IWebHostEnvironment Host @{ var error = Model?.Error?.Error; - var errorDescription = host.IsDevelopment() ? Model?.Error?.ErrorDescription : null; + var errorDescription = Host.IsDevelopment() ? Model?.Error?.ErrorDescription : null; var request_id = Model?.Error?.RequestId; } @@ -42,3 +43,9 @@ + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Redirect.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Redirect.cshtml index feb1e0609..f8f5d01ee 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Redirect.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/Redirect.cshtml @@ -4,4 +4,9 @@

    @Localizer["Title"]

    @Localizer["SubTitle"]

    - \ No newline at end of file + + + + + + diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/_Layout.cshtml b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/_Layout.cshtml index 11aedc91b..412f99fa5 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/_Layout.cshtml +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.STS.Identity/Views/Shared/_Layout.cshtml @@ -1,7 +1,9 @@ -@using IdentityServer4.Extensions +@using IdentityServer4.Extensions @using Microsoft.AspNetCore.Identity @using Microsoft.AspNetCore.Mvc.Localization @using SkorubaIdentityServer4Admin.Admin.EntityFramework.Shared.Entities.Identity +@using SkorubaIdentityServer4Admin.STS.Identity.Configuration.Interfaces +@inject IRootConfiguration RootConfiguration @inject IViewLocalizer Localizer @{ string name = null; @@ -21,9 +23,9 @@ - @Localizer["PageTitle"] - - + @RootConfiguration.AdminConfiguration.PageTitle + + @@ -40,10 +42,9 @@ ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:wt},jt="show",Pt="out",Rt={HIDE:"hide"+St,HIDDEN:"hidden"+St,SHOW:"show"+St,SHOWN:"shown"+St,INSERTED:"inserted"+St,CLICK:"click"+St,FOCUSIN:"focusin"+St,FOCUSOUT:"focusout"+St,MOUSEENTER:"mouseenter"+St,MOUSELEAVE:"mouseleave"+St},Ht="fade",Mt="show",qt=".tooltip-inner",Ft=".arrow",Bt="hover",Wt="focus",Ut="click",zt="manual",$t=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Mt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),o=m.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&p(r).addClass(Ht);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ft},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var u=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,c).emulateTransitionEnd(u)}else c()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Ut]=!1,this._activeTrigger[Wt]=!1,this._activeTrigger[Bt]=!1,p(this.tip).hasClass(Ht)){var o=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(o)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(At+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(qt)),this.getTitle()),p(e).removeClass(Ht+" "+Mt)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=Ct(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return It[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==zt){var t=e===Bt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Bt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Wt:Bt]=!0),p(t.getTipElement()).hasClass(Mt)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Wt:Bt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==Nt.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Et,e,this.constructor.DefaultType),e.sanitize&&(e.template=Ct(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Dt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(Tt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(Tt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Lt}},{key:"NAME",get:function(){return Et}},{key:"DATA_KEY",get:function(){return Tt}},{key:"Event",get:function(){return Rt}},{key:"EVENT_KEY",get:function(){return St}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Et]=$t._jQueryInterface,p.fn[Et].Constructor=$t,p.fn[Et].noConflict=function(){return p.fn[Et]=kt,$t._jQueryInterface};var Vt="popover",Kt="bs.popover",Qt="."+Kt,Xt=p.fn[Vt],Yt="bs-popover",Gt=new RegExp("(^|\\s)"+Yt+"\\S+","g"),Jt=l({},$t.Default,{placement:"right",trigger:"click",content:"",template:''}),Zt=l({},$t.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",on={HIDE:"hide"+Qt,HIDDEN:"hidden"+Qt,SHOW:"show"+Qt,SHOWN:"shown"+Qt,INSERTED:"inserted"+Qt,CLICK:"click"+Qt,FOCUSIN:"focusin"+Qt,FOCUSOUT:"focusout"+Qt,MOUSEENTER:"mouseenter"+Qt,MOUSELEAVE:"mouseleave"+Qt},sn=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Yt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Gt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>16),i=38+(t>>8&255),r=38+(255&t);return"#"+(16777216+65536*(n<255?n<1?0:n:255)+256*(i<255?i<1?0:i:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,t){return e&&e.parentNode?d.hasClass(e,t)?e:this.traverseDOMPath(e.parentNode,t):null}};u.status={deny:"deny",allow:"allow",dismiss:"dismiss"},u.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n+"ransition"])return t[n];return""}(),u.hasTransition=!!u.transitionEnd;var r,t,n,o=Object.keys(u.status).map(d.escapeRegExp);u.customStyles={},u.Popup=(r={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
    {{policy}}
    ',compliance:{info:'
    {{dismiss}}
    ',"opt-in":'
    {{deny}}{{allow}}
    ',"opt-out":'
    {{deny}}{{allow}}
    '},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null},e.prototype.initialise=function(e){this.options&&this.destroy(),d.deepExtend(this.options={},r),d.isPlainObject(e)&&d.deepExtend(this.options,e),function(){var e=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return e(u.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return e(u.status.allow),!0;var t=Object.keys(u.status),n=this.getStatus(),i=0<=t.indexOf(n);return i&&e(n),i}.call(this)&&(this.options.enabled=!1),c(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),c(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var t=this.options.window.replace("{{classes}}",function(){var e=this.options,t="top"==e.position||"bottom"==e.position?"banner":"floating";d.isMobile()&&(t="floating");var n=["cc-"+t,"cc-type-"+e.type,"cc-theme-"+e.theme];return e.static&&n.push("cc-static"),n.push.apply(n,a.call(this)),function(e){var t=d.hash(JSON.stringify(e)),n="cc-color-override-"+t,i=d.isPlainObject(e);return this.customStyleSelector=i?n:null,i&&function(e,t,n){if(u.customStyles[e])return++u.customStyles[e].references;var i={},r=t.popup,o=t.button,s=t.highlight;r&&(r.text=r.text?r.text:d.getContrast(r.background),r.link=r.link?r.link:r.text,i[n+".cc-window"]=["color: "+r.text,"background-color: "+r.background],i[n+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],i[n+" .cc-link,"+n+" .cc-link:active,"+n+" .cc-link:visited"]=["color: "+r.link],o&&(o.text=o.text?o.text:d.getContrast(o.background),o.border=o.border?o.border:"transparent",i[n+" .cc-btn"]=["color: "+o.text,"border-color: "+o.border,"background-color: "+o.background],o.padding&&i[n+" .cc-btn"].push("padding: "+o.padding),"transparent"!=o.background&&(i[n+" .cc-btn:hover, "+n+" .cc-btn:focus"]=["background-color: "+(o.hover||function(e){return"000000"!=(e=d.normaliseHex(e))?d.getLuminance(e):"#222"}(o.background))]),s?(s.text=s.text?s.text:d.getContrast(s.background),s.border=s.border?s.border:"transparent",i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+s.text,"border-color: "+s.border,"background-color: "+s.background]):i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var a=document.createElement("style");document.head.appendChild(a),u.customStyles[e]={references:1,element:a.sheet};var l=-1;for(var c in i)i.hasOwnProperty(c)&&a.sheet.insertRule(c+"{"+i[c].join(";")+"}",++l)}(t,e,"."+n),i}.call(this,this.options.palette),this.customStyleSelector&&n.push(this.customStyleSelector),n}.call(this).join(" ")).replace("{{children}}",function(){var t={},n=this.options;n.showLink||(n.elements.link="",n.elements.messagelink=n.elements.message),Object.keys(n.elements).forEach(function(e){t[e]=d.interpolateString(n.elements[e],function(e){var t=n.content[e];return e&&"string"==typeof t&&t.length?t:""})});var e=n.compliance[n.type];e=e||n.compliance.info,t.compliance=d.interpolateString(e,function(e){return t[e]});var i=n.layouts[n.layout];return i=i||n.layouts.basic,d.interpolateString(i,function(e){return t[e]})}.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(t=n),this.options.static){var i=l.call(this,'
    '+t+"
    ");i.style.display="",this.element=i.firstChild,this.element.style.display="none",d.addClass(this.element,"cc-invisible")}else this.element=l.call(this,t);(function(){var s=this.setStatus.bind(this),a=this.close.bind(this),e=this.options.dismissOnTimeout;"number"==typeof e&&0<=e&&(this.dismissTimeout=window.setTimeout(function(){s(u.status.dismiss),a(!0)},Math.floor(e)));var t=this.options.dismissOnScroll;if("number"==typeof t&&0<=t){var n=function(e){window.pageYOffset>Math.floor(t)&&(s(u.status.dismiss),a(!0),window.removeEventListener("scroll",n),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=n,window.addEventListener("scroll",n))}var i=this.options.dismissOnWindowClick,l=this.options.ignoreClicksFrom;if(i){var c=function(e){for(var t=!1,n=e.path.length,i=l.length,r=0;rn&&(t=!0),t?d.hasClass(i,"cc-active")||d.addClass(i,"cc-active"):d.hasClass(i,"cc-active")&&d.removeClass(i,"cc-active")},200);this.onMouseMove=n,window.addEventListener("mousemove",n)}}}.call(this),this.options.autoOpen&&this.autoOpen()},e.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(e){if(d.isPlainObject(e)){var t=d.hash(JSON.stringify(e)),n=u.customStyles[t];if(n&&!--n.references){var i=n.element.ownerNode;i&&i.parentNode&&i.parentNode.removeChild(i),u.customStyles[t]=null}}}(this.options.palette),this.options=null},e.prototype.open=function(e){if(this.element)return this.isOpen()||(u.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},e.prototype.close=function(e){if(this.element)return this.isOpen()&&(u.hasTransition?this.fadeOut():this.element.style.display="none",e&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},e.prototype.fadeIn=function(){var e=this.element;if(u.hasTransition&&e&&(this.afterTransition&&s.call(this,e),d.hasClass(e,"cc-invisible"))){if(e.style.display="",this.options.static){var t=this.element.clientHeight;this.element.parentNode.style.maxHeight=t+"px"}this.openingTimeout=setTimeout(i.bind(this,e),20)}},e.prototype.fadeOut=function(){var e=this.element;u.hasTransition&&e&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),i.bind(this,e)),d.hasClass(e,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,e),e.addEventListener(u.transitionEnd,this.afterTransition),d.addClass(e,"cc-invisible")))},e.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!u.hasTransition||!d.hasClass(this.element,"cc-invisible"))},e.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},e.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},e.prototype.hasAnswered=function(e){return 0<=Object.keys(u.status).indexOf(this.getStatus())},e.prototype.hasConsented=function(e){var t=this.getStatus();return t==u.status.allow||t==u.status.dismiss},e.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},e.prototype.setStatus=function(e){var t=this.options.cookie,n=d.getCookie(t.name),i=0<=Object.keys(u.status).indexOf(n);0<=Object.keys(u.status).indexOf(e)?(d.setCookie(t.name,e,t.expiryDays,t.domain,t.path,t.secure),this.options.onStatusChange.call(this,e,i)):this.clearStatus()},e.prototype.getStatus=function(){return d.getCookie(this.options.cookie.name)},e.prototype.clearStatus=function(){var e=this.options.cookie;d.setCookie(e.name,"",-1,e.domain,e.path)},e),u.Location=(t={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var n=JSON.parse(t);return n.error?m(n):{code:n.country}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var n=JSON.parse(t);return"ERROR"==n.statusCode?m({error:n.statusMessage}):{code:n.countryCode}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(t){window.geoip2?geoip2.country(function(e){try{t({code:e.country.iso_code})}catch(e){t(m(e))}},function(e){t(m(e))}):t(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}},h.prototype.getNextService=function(){for(var e;e=this.getServiceByIdx(++this.currentServiceIndex),this.currentServiceIndex>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,o,s,a,l=0,c=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,o=(3&t)<<4|(n=e.charCodeAt(l++))>>4,s=(15&n)<<2|(i=e.charCodeAt(l++))>>6,a=63&i,l===e.length+2?a=s=64:l===e.length+1&&(a=64),c.push(u.charAt(r),u.charAt(o),u.charAt(s),u.charAt(a));return c.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(a,e,O){(function(c){var e=O(2),h=O(3),T=O(6),g=O(7),v=O(8),y=O(9),S=O(10),t=O(11),u=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,w=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(k.settings.themes[e]=t),delete k.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[k.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&x(e))},run:function(e){e=e||{};var u={},d=m(k.settings,e);k.vars.preempted=!0,k.vars.dataAttr=d.dataAttr||k.setup.dataAttr,u.renderer=d.renderer?d.renderer:k.setup.renderer,-1===k.setup.renderers.join(",").indexOf(u.renderer)&&(u.renderer=k.setup.supportsSVG?"svg":k.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return u.stylesheets=[],u.svgXMLStylesheet=!0,u.noFontFallback=!!d.noFontFallback,u.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;u.stylesheets.push(i)}}),n.forEach(function(e){if(c.getComputedStyle){var t=c.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",o=n.indexOf(r);if(0===o)i=n;else if(1===o&&"?"===n[0])i=n.slice(1);else{var s=n.substr(o).match(/([^\"]*)"?\)/);if(null!==s)i=s[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var a=l(i,d);a&&p({mode:"background",el:e,flags:a,engineSettings:u})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(k.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,u,t.data,e):i&&f(d,u,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(k.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,o,s,a=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),c=null!=t.rendered&&"true"==t.rendered;a?0===t.src.indexOf(d.domain)?f(d,u,t.src,e):l&&(c?f(d,u,t.dataSrc,e):(n=t.src,i=d,r=u,o=t.dataSrc,s=e,g.imageExists(n,function(e){e||f(i,r,o,s)}))):l&&f(d,u,t.dataSrc,e)}),this}},k={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(k.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var o=r[0].split("/");n.holderURL=e;var s=o[1],a=s.match(/([\d]+p?)x([\d]+p?)/);if(!a)return!1;if(n.fluid=-1!==s.indexOf("p"),n.dimensions={width:a[1].replace("p","%"),height:a[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var c=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(u/c*100),c=100,n.dimensions.width=c+"%",n.dimensions.height=u+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){k.vars.cache.themeKeys=k.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=k.vars.cache.themeKeys[0|Math.random()*k.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,o=i.dimensions,s=i.theme,a=o.width+"x"+o.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(s.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=s.text.split("\\n"),c=0;c=r||!0==E)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,w+=f.properties.leading,_+=1,(g=new s.Group("line"+_)).y=w),!0!=E&&(m.moveTo(b,0),b+=p.spaceWidth+C.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new s.Text(e.text),(g=new s.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return o}(s);function l(){var e=null;switch(o.renderer){case"canvas":e=d(a,t);break;case"svg":e=u(a,t);break;default:throw"Holder: invalid renderer: "+o.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",o.noBackgroundSize||(i.style.backgroundSize=s.width+"px "+s.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),o.reRender&&c.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function x(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?k.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function s(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}s.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},s.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,o=r*(1-Math.abs(parseInt(i)%2-1)),s=n-r/2,a=0,l=0,c=0;return 0<=i&&i<1?(a=r,l=o):1<=i&&i<2?(a=o,l=r):2<=i&&i<3?(l=r,c=o):3<=i&&i<4?(l=o,c=r):4<=i&&i<5?(a=o,c=r):5<=i&&i<6&&(a=r,c=o),a+=s,l+=s,c+=s,[a=parseInt(255*a),l=parseInt(255*l),c=parseInt(255*c)]},s.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,o=-.09991*t-.33609*n+.436*i,s=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:o,v:s},this},s.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),o=s.rgb2hex(n,i,r);return new s(o)},s.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},s.prototype.lighterThan=function(e){return e instanceof s||(e=new s(e)),this.yuv.y>e.yuv.y},s.prototype.blendAlpha=function(e){e instanceof s||(e=new s(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new s(s.rgb2hex(n,i,r))},e.exports=s},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),w=n(7),_=i.svg_ns,x=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,s=r.children.holderTextGroup,o="#"+i+" text { "+function(e){return w.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(s.properties)+" } ";s.y+=.8*s.textPositionData.boundingBox.height;var a=[];Object.keys(s.children).forEach(function(e){var o=s.children[e];Object.keys(o.children).forEach(function(e){var t=o.children[e],n=s.x+o.x+t.x,i=s.y+o.y+t.y,r=x({tag:"text",content:t.properties.text,x:n,y:i});a.push(r)})});var l=x({tag:"g",content:a}),c=null;if(r.children.holderBg.properties.outline){var u=r.children.holderBg.properties.outline;c=x({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,u.width),"stroke-width":u.width,stroke:u.fill,fill:"none"})}var d=function(e,t){return x({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),u&&h.push(c),h.push(l);var f=x({tag:"g",id:i,content:h}),p=x({tag:"style",content:o,type:"text/css"}),m=x({tag:"defs",content:p}),g=x({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:_,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,o,s,a,l,c,u,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],c=l.match(/^[\w-]+/),u={tag:c?c[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(u.attr.id=d[1],i[d[1]]=u),h&&(i[h[1]]=u),f&&(u.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),u);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])s=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(o in t[g])t[g].hasOwnProperty(o)&&null!==t[g][o]&&!1!==t[g][o]&&("style"===o&&"object"==typeof t[g][o]?t[0].attr[o]=JSON.stringify(t[g][o],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[o]=t[g][o])}}if(!1!==t[0]){for(a in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(a)&&(r+=" "+a+'="'+((m=t[0].attr[a])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],s&&s(t[0]),i}},function(e,t){"use strict";var a=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=a.exec(n);if(!i)return n;var r="",o=0,s=0;for(o=i.index;o>10|55296,1023&i|56320)}function r(){x()}var e,f,w,o,s,p,h,m,_,l,c,x,C,a,E,g,u,v,y,T="sizzle"+1*new Date,b=n.document,S=0,i=0,k=le(),A=le(),D=le(),N=le(),O=function(e,t){return e===t&&(c=!0),0},I={}.hasOwnProperty,t=[],L=t.pop,j=t.push,P=t.push,R=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+q+")"+q+"*"),K=new RegExp(q+"|>"),Q=new RegExp(W),X=new RegExp("^"+F+"$"),Y={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),TAG:new RegExp("^("+F+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+q+"*(even|odd|(([+-]|)(\\d*)n|)"+q+"*(?:([+-]|)"+q+"*(\\d+)|))"+q+"*\\)|)","i"),bool:new RegExp("^(?:"+M+")$","i"),needsContext:new RegExp("^"+q+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+q+"*((?:-\\d)?\\d*)"+q+"*\\)|)(?=[^-]|$)","i")},G=/HTML$/i,J=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+q+"?|("+q+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,oe=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},se=we(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=R.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,R.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function ae(t,e,n,i){var r,o,s,a,l,c,u,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==C&&x(e),e=e||C,E)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(s=e.getElementById(r)))return n;if(s.id===r)return n.push(s),n}else if(d&&(s=d.getElementById(r))&&y(e,s)&&s.id===r)return n.push(s),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!N[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(u=t,d=e,1===h&&K.test(t)){for((a=e.getAttribute("id"))?a=a.replace(re,oe):e.setAttribute("id",a=T),o=(c=p(t)).length;o--;)c[o]="#"+a+" "+be(c[o]);u=c.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(u)),n}catch(e){N(t,!0)}finally{a===T&&e.removeAttribute("id")}}}return m(t.replace(z,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>w.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ce(e){return e[T]=!0,e}function ue(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)w.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&se(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(s){return ce(function(o){return o=+o,ce(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=ae.support={},s=ae.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!G.test(t||n&&n.nodeName||"HTML")},x=ae.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==C&&9===i.nodeType&&i.documentElement&&(a=(C=i).documentElement,E=!s(C),b!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ue(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(C.getElementsByClassName),f.getById=ue(function(e){return a.appendChild(e).id=T,!C.getElementsByName||!C.getElementsByName(T).length}),f.getById?(w.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(w.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,i,r,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(r=t.getElementsByName(e),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},w.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},u=[],g=[],(f.qsa=ee.test(C.querySelectorAll))&&(ue(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+q+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+q+"*(?:value|"+M+")"),e.querySelectorAll("[id~="+T+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+T+"+*").length||g.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+q+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ue(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),u.push("!=",W)}),g=g.length&&new RegExp(g.join("|")),u=u.length&&new RegExp(u.join("|")),t=ee.test(a.compareDocumentPosition),y=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===b&&y(b,e)?-1:t===C||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===C?-1:t===C?1:r?-1:o?1:l?H(l,e)-H(l,t):0;if(r===o)return he(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?he(s[i],a[i]):s[i]===b?-1:a[i]===b?1:0}),C},ae.matches=function(e,t){return ae(e,null,null,t)},ae.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&x(e),f.matchesSelector&&E&&!N[t+" "]&&(!u||!u.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ae.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ae.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=k[e+" "];return t||(t=new RegExp("(^|"+q+")"+e+"("+q+"|$)"))&&k(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=ae.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function N(e,n,i){return b(n)?T.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?T.grep(e,function(e){return e===n!==i}):"string"!=typeof n?T.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:I.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(i[1])&&T.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=E.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=T.fn,O=T(E);var L=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?T.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var xe=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function Te(){return!0}function Se(){return!1}function ke(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,i,r,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(i=i||n,n=void 0),t)Ae(e,a,n,i,t[a],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Se;else if(!r)return e;return 1===o&&(s=r,(r=function(e){return T().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=T.guid++)),e.each(function(){T.event.add(this,t,r,i,n)})}function De(e,r,o){o?(Y.set(e,r,!1),T.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Y.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(T.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=a.call(arguments),Y.set(this,r,i),t=o(this,r),this[r](),i!==(n=Y.get(this,r))||t?Y.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Y.set(this,r,{value:T.event.trigger(T.extend(i[0],T.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,r)&&T.event.add(e,r,Te)}T.event={global:{},add:function(t,e,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.get(t);if(g)for(n.handler&&(n=(o=n).handler,r=o.selector),r&&T.find.matchesSelector(re,r),n.guid||(n.guid=T.guid++),(l=g.events)||(l=g.events={}),(s=g.handle)||(s=g.handle=function(e){return void 0!==T&&T.event.triggered!==e.type?T.event.dispatch.apply(t,arguments):void 0}),c=(e=(e||"").match(R)||[""]).length;c--;)f=m=(a=Ee.exec(e[c])||[])[1],p=(a[2]||"").split(".").sort(),f&&(d=T.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=T.event.special[f]||{},u=T.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&T.expr.match.needsContext.test(r),namespace:p.join(".")},o),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,s)||t.addEventListener&&t.addEventListener(f,s)),d.add&&(d.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,u):h.push(u),T.event.global[f]=!0)},remove:function(e,t,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.hasData(e)&&Y.get(e);if(g&&(l=g.events)){for(c=(t=(t||"").match(R)||[""]).length;c--;)if(f=m=(a=Ee.exec(t[c])||[])[1],p=(a[2]||"").split(".").sort(),f){for(d=T.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=h.length;o--;)u=h[o],!r&&m!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(h.splice(o,1),u.selector&&h.delegateCount--,d.remove&&d.remove.call(e,u));s&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||T.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)T.event.remove(e,f+t[c],n,i,!0);T.isEmptyObject(l)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,o,s,a=T.event.fix(e),l=new Array(arguments.length),c=(Y.get(this,"events")||{})[a.type]||[],u=T.event.special[a.type]||{};for(l[0]=a,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,o,s,a,l,c;if(1===t.nodeType){if(Y.hasData(e)&&(o=Y.access(e),s=Y.set(t,o),c=o.events))for(r in delete s.handle,s.events={},c)for(n=0,i=c[r].length;n")},clone:function(e,t,n){var i,r,o,s,a,l,c,u=e.cloneNode(!0),d=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||T.isXMLDoc(e)))for(s=ge(u),i=0,r=(o=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],on=/(=)\?(?=&|$)|\?\?/;T.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||T.expando+"_"+jt++;return this[e]=!0,e}}),T.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,o,s=!1!==e.jsonp&&(on.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&on.test(e.data)&&"data");if(s||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,s?e[s]=e[s].replace(on,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return o||T.error(i+" was not called"),o[0]},e.dataTypes[0]="json",r=C[i],C[i]=function(){o=arguments},n.always(function(){void 0===r?T(C).removeProp(i):C[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),o&&b(r)&&r(o[0]),o=r=void 0}),"script"}),y.createHTMLDocument=((nn=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),T.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(i)):t=E),o=!n&&[],(r=D.exec(e))?[t.createElement(r[1])]:(r=_e([e],t,o),o&&o.length&&T(o).remove(),T.merge([],r.childNodes)));var i,r,o},T.fn.load=function(e,t,n){var i,r,o,s=this,a=e.indexOf(" ");return-1").append(T.parseHTML(e)).find(i):e)}).always(n&&function(e,t){s.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},T.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){T.fn[t]=function(e){return this.on(t,e)}}),T.expr.pseudos.animated=function(t){return T.grep(T.timers,function(e){return t===e.elem}).length},T.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,c=T.css(e,"position"),u=T(e),d={};"static"===c&&(e.style.position="relative"),a=u.offset(),o=T.css(e,"top"),l=T.css(e,"left"),r=("absolute"===c||"fixed"===c)&&-1<(o+l).indexOf("auto")?(s=(i=u.position()).top,i.left):(s=parseFloat(o)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,T.extend({},a))),null!=t.top&&(d.top=t.top-a.top+s),null!=t.left&&(d.left=t.left-a.left+r),"using"in t?t.using.call(e,d):u.css(d)}},T.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){T.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===T.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===T.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=T(e).offset()).top+=T.css(e,"borderTopWidth",!0),r.left+=T.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-T.css(i,"marginTop",!0),left:t.left-r.left-T.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===T.css(e,"position");)e=e.offsetParent;return e||re})}}),T.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var o="pageYOffset"===r;T.fn[t]=function(e){return U(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(o?i.pageXOffset:n,o?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),T.each(["top","left"],function(e,n){T.cssHooks[n]=Ze(y.pixelPosition,function(e,t){if(t)return t=Je(e,n),Ke.test(t)?T(e).position()[n]+"px":t})}),T.each({Height:"height",Width:"width"},function(s,a){T.each({padding:"inner"+s,content:a,"":"outer"+s},function(i,o){T.fn[o]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return U(this,function(e,t,n){var i;return m(e)?0===o.indexOf("outer")?e["inner"+s]:e.document.documentElement["client"+s]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+s],i["scroll"+s],e.body["offset"+s],i["offset"+s],i["client"+s])):void 0===n?T.css(e,t,r):T.style(e,t,n,r)},a,n?e:void 0,n)}})}),T.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){T.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(u(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return u(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=u(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,o,s,a,l=this[0],c=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&c&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=u.data(l.form,"validator").settings).rules,r=u.validator.staticRules(l),e){case"add":u.extend(r,u.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=u.extend(n.messages[l.name],t.messages));break;case"remove":return t?(a={},u.each(t.split(/\s/),function(e,t){a[t]=r[t],delete r[t]}),a):(delete i[l.name],r)}return(o=u.validator.normalizeRules(u.extend({},u.validator.classRules(l),u.validator.attributeRules(l),u.validator.dataRules(l),u.validator.staticRules(l)),l)).required&&(s=o.required,delete o.required,o=u.extend({required:s},o)),o.remote&&(s=o.remote,delete o.remote,o=u.extend(o,{remote:s})),o}}}),u.extend(u.expr.pseudos||u.expr[":"],{blank:function(e){return!u.trim(""+u(e).val())},filled:function(e){var t=u(e).val();return null!==t&&!!u.trim(""+t)},unchecked:function(e){return!u(e).prop("checked")}}),u.validator=function(e,t){this.settings=u.extend(!0,{},u.validator.defaults,e),this.currentForm=t,this.init()},u.validator.format=function(n,e){return 1===arguments.length?function(){var e=u.makeArray(arguments);return e.unshift(n),u.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=u.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 u(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,o,s=this.errorsFor(e),a=this.idOrName(e),l=u(e).attr("aria-describedby");s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(t)):(n=s=u("<"+this.settings.errorElement+">").attr("id",a+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,u(e)):n.insertAfter(e),s.is("label")?s.attr("for",a):0===s.parents("label[for='"+this.escapeCssMeta(a)+"']").length&&(r=s.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,u(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(o=this,u.each(o.groups,function(e,t){t===i&&u("[name='"+o.escapeCssMeta(e)+"']",o.currentForm).attr("aria-describedby",s.attr("id"))})))),!t&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=u(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),u(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return u(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return u("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!u(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!u.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,u(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],u(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(u(this.currentForm).submit(),this.submitButton&&u("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(u(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",u.data(e,"previousValue")||u.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),u(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:u.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=u(e).attr("class");return n&&u.each(n.split(" "),function(){this in u.validator.classRuleSettings&&u.extend(t,u.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,o,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,o,t,n);return i},staticRules:function(e){var t={},n=u.data(e.form,"validator");return n.settings.rules&&(t=u.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return u.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!u(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(u.data(r.form,"validator").resetElements(u(r)),delete i[e])}}else delete i[e]}),u.each(i,function(e,t){i[e]=u.isFunction(t)&&"normalizer"!==e?t(r):t}),u.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),u.each(["rangelength","range"],function(){var e;i[this]&&(u.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),u.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};u.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){u.validator.methods[e]=t,u.validator.messages[e]=void 0!==n?n:u.validator.messages[e],t.length<3&&u.validator.addClassRules(e,u.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,o))}var o,s=u(t).attr("type"),a="Step attribute on input type "+s+" is not supported.",l=new RegExp("\\b"+s+"\\b"),c=!0;if(s&&!l.test(["text","number","range"].join()))throw new Error(a);return o=i(n),(i(e)>o||r(e)%r(n)!=0)&&(c=!1),this.optional(t)||c},equalTo:function(e,t,n){var i=u(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){u(t).valid()}),e===i.val()},remote:function(o,s,e,a){if(this.optional(s))return"dependency-mismatch";a="string"==typeof a&&a||"remote";var l,t,n,c=this.previousValue(s,a);return this.settings.messages[s.name]||(this.settings.messages[s.name]={}),c.originalMessage=c.originalMessage||this.settings.messages[s.name][a],this.settings.messages[s.name][a]=c.message,e="string"==typeof e&&{url:e}||e,n=u.param(u.extend({data:o},e.data)),c.old===n?c.valid:(c.old=n,(l=this).startRequest(s),(t={})[s.name]=o,u.ajax(u.extend(!0,{mode:"abort",port:"validate"+s.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[s.name][a]=c.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(s),l.formSubmitted=i,l.successList.push(s),l.invalid[s.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(s,{method:a,parameters:o}),t[s.name]=c.message=n,l.invalid[s.name]=!0,l.showErrors(t)),c.valid=r,l.stopRequest(s,r)}},e)),"pending")}}});var i,r={};return u.ajaxPrefilter?u.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=u.ajax,u.ajax=function(e){var t=("mode"in e?e:u.ajaxSettings).mode,n=("port"in e?e:u.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),u}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,s=l.validator,a="unobtrusiveValidation";function c(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function u(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=o[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(a),r=l.proxy(f,i),o=s.unobtrusive.options||{};return n||(n={options:{errorClass:o.errorClass||"input-validation-error",errorElement:o.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+u(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+a,r).on("reset."+a,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(a,n)),n}return s.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,o,s=l(i),a=s.parents("form")[0];a&&((t=p(a)).options.rules[i.name]=r={},t.options.messages[i.name]=o={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=s.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=s.attr(e+this)}),this.adapt({element:i,form:a,message:t,params:n,rules:r,messages:o}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){s.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=s.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){c(e,n||t,!0)})},e.addMinMax=function(e,i,r,o,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?c(e,o,[t,n]):t?c(e,i,t):n&&c(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){c(e,i||t,e.params[n])})},s.addMethod("__dummy__",function(e,t,n){return!0}),s.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),s.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),s.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);c(e,"equalTo",l(e.form).find(":input").filter("[name='"+u(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||c(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},o=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,o);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+u(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),c(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&c(e,"minlength",e.params.min),e.params.nonalphamin&&c(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&c(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){c(e,"extension",e.params.extensions)}),l(function(){s.unobtrusive.parse(document)}),s.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(o[t],r[e]-("right"===e?o.width:o.height))),_({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";o=x({},o,s[t](e))}),e.offsets.popper=o,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=C(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,o=-1!==["top","bottom"].indexOf(i),s=o?"right":"bottom",a=o?"left":"top",l=o?"width":"height";return t[s]r(n[s])&&(e.offsets.popper[a]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=C(e.offsets.popper),o=e.offsets.reference,s=-1!==["left","right"].indexOf(i),a=s?"height":"width",l=s?"top":"left",c=s?"left":"top",u=s?"bottom":"right",d=D(n)[a];o[u]-dr[u]&&(e.offsets.popper[l]+=o[l]+d-r[u]);var h=o[l]+o[a]/2-d/2-C(e.offsets.popper)[l];return h=Math.max(Math.min(r[a]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[c]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(R(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=N(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case U:b=[g,v];break;case z:b=W(g);break;case $:b=W(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=N(g);var n=C(f.offsets.popper),i=f.offsets.reference,r=Math.floor,o="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),u="left"===g&&s||"right"===g&&a||"top"===g&&l||"bottom"===g&&c,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&s||d&&"end"===y&&a||!d&&"start"===y&&l||!d&&"end"===y&&c);(o||u||h)&&(f.flipped=!0,(o||u)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=C(e.offsets.popper),r=C(e.offsets.reference),o=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return i[o?"left":"top"]=r[t]-(s?i[o?"width":"height"]:0),e.placement=N(t),e.offsets.popper=C(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(z.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:wt},jt="show",Pt="out",Rt={HIDE:"hide"+St,HIDDEN:"hidden"+St,SHOW:"show"+St,SHOWN:"shown"+St,INSERTED:"inserted"+St,CLICK:"click"+St,FOCUSIN:"focusin"+St,FOCUSOUT:"focusout"+St,MOUSEENTER:"mouseenter"+St,MOUSELEAVE:"mouseleave"+St},Ht="fade",Mt="show",qt=".tooltip-inner",Ft=".arrow",Bt="hover",Wt="focus",Ut="click",zt="manual",$t=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Mt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),o=m.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&p(r).addClass(Ht);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ft},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var u=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,c).emulateTransitionEnd(u)}else c()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Ut]=!1,this._activeTrigger[Wt]=!1,this._activeTrigger[Bt]=!1,p(this.tip).hasClass(Ht)){var o=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(o)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(At+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(qt)),this.getTitle()),p(e).removeClass(Ht+" "+Mt)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=Ct(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return It[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==zt){var t=e===Bt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Bt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Wt:Bt]=!0),p(t.getTipElement()).hasClass(Mt)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Wt:Bt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==Nt.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Et,e,this.constructor.DefaultType),e.sanitize&&(e.template=Ct(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Dt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(Tt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(Tt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Lt}},{key:"NAME",get:function(){return Et}},{key:"DATA_KEY",get:function(){return Tt}},{key:"Event",get:function(){return Rt}},{key:"EVENT_KEY",get:function(){return St}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Et]=$t._jQueryInterface,p.fn[Et].Constructor=$t,p.fn[Et].noConflict=function(){return p.fn[Et]=kt,$t._jQueryInterface};var Vt="popover",Kt="bs.popover",Qt="."+Kt,Xt=p.fn[Vt],Yt="bs-popover",Gt=new RegExp("(^|\\s)"+Yt+"\\S+","g"),Jt=l({},$t.Default,{placement:"right",trigger:"click",content:"",template:''}),Zt=l({},$t.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",on={HIDE:"hide"+Qt,HIDDEN:"hidden"+Qt,SHOW:"show"+Qt,SHOWN:"shown"+Qt,INSERTED:"inserted"+Qt,CLICK:"click"+Qt,FOCUSIN:"focusin"+Qt,FOCUSOUT:"focusout"+Qt,MOUSEENTER:"mouseenter"+Qt,MOUSELEAVE:"mouseleave"+Qt},sn=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Yt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Gt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>16),i=38+(t>>8&255),r=38+(255&t);return"#"+(16777216+65536*(n<255?n<1?0:n:255)+256*(i<255?i<1?0:i:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,t){return e&&e.parentNode?d.hasClass(e,t)?e:this.traverseDOMPath(e.parentNode,t):null}};u.status={deny:"deny",allow:"allow",dismiss:"dismiss"},u.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n+"ransition"])return t[n];return""}(),u.hasTransition=!!u.transitionEnd;var r,t,n,o=Object.keys(u.status).map(d.escapeRegExp);u.customStyles={},u.Popup=(r={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
    {{policy}}
    ',compliance:{info:'
    {{dismiss}}
    ',"opt-in":'
    {{deny}}{{allow}}
    ',"opt-out":'
    {{deny}}{{allow}}
    '},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null},e.prototype.initialise=function(e){this.options&&this.destroy(),d.deepExtend(this.options={},r),d.isPlainObject(e)&&d.deepExtend(this.options,e),function(){var e=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return e(u.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return e(u.status.allow),!0;var t=Object.keys(u.status),n=this.getStatus(),i=0<=t.indexOf(n);return i&&e(n),i}.call(this)&&(this.options.enabled=!1),c(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),c(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var t=this.options.window.replace("{{classes}}",function(){var e=this.options,t="top"==e.position||"bottom"==e.position?"banner":"floating";d.isMobile()&&(t="floating");var n=["cc-"+t,"cc-type-"+e.type,"cc-theme-"+e.theme];return e.static&&n.push("cc-static"),n.push.apply(n,a.call(this)),function(e){var t=d.hash(JSON.stringify(e)),n="cc-color-override-"+t,i=d.isPlainObject(e);return this.customStyleSelector=i?n:null,i&&function(e,t,n){if(u.customStyles[e])return++u.customStyles[e].references;var i={},r=t.popup,o=t.button,s=t.highlight;r&&(r.text=r.text?r.text:d.getContrast(r.background),r.link=r.link?r.link:r.text,i[n+".cc-window"]=["color: "+r.text,"background-color: "+r.background],i[n+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],i[n+" .cc-link,"+n+" .cc-link:active,"+n+" .cc-link:visited"]=["color: "+r.link],o&&(o.text=o.text?o.text:d.getContrast(o.background),o.border=o.border?o.border:"transparent",i[n+" .cc-btn"]=["color: "+o.text,"border-color: "+o.border,"background-color: "+o.background],o.padding&&i[n+" .cc-btn"].push("padding: "+o.padding),"transparent"!=o.background&&(i[n+" .cc-btn:hover, "+n+" .cc-btn:focus"]=["background-color: "+(o.hover||function(e){return"000000"!=(e=d.normaliseHex(e))?d.getLuminance(e):"#222"}(o.background))]),s?(s.text=s.text?s.text:d.getContrast(s.background),s.border=s.border?s.border:"transparent",i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+s.text,"border-color: "+s.border,"background-color: "+s.background]):i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var a=document.createElement("style");document.head.appendChild(a),u.customStyles[e]={references:1,element:a.sheet};var l=-1;for(var c in i)i.hasOwnProperty(c)&&a.sheet.insertRule(c+"{"+i[c].join(";")+"}",++l)}(t,e,"."+n),i}.call(this,this.options.palette),this.customStyleSelector&&n.push(this.customStyleSelector),n}.call(this).join(" ")).replace("{{children}}",function(){var t={},n=this.options;n.showLink||(n.elements.link="",n.elements.messagelink=n.elements.message),Object.keys(n.elements).forEach(function(e){t[e]=d.interpolateString(n.elements[e],function(e){var t=n.content[e];return e&&"string"==typeof t&&t.length?t:""})});var e=n.compliance[n.type];e=e||n.compliance.info,t.compliance=d.interpolateString(e,function(e){return t[e]});var i=n.layouts[n.layout];return i=i||n.layouts.basic,d.interpolateString(i,function(e){return t[e]})}.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(t=n),this.options.static){var i=l.call(this,'
    '+t+"
    ");i.style.display="",this.element=i.firstChild,this.element.style.display="none",d.addClass(this.element,"cc-invisible")}else this.element=l.call(this,t);(function(){var s=this.setStatus.bind(this),a=this.close.bind(this),e=this.options.dismissOnTimeout;"number"==typeof e&&0<=e&&(this.dismissTimeout=window.setTimeout(function(){s(u.status.dismiss),a(!0)},Math.floor(e)));var t=this.options.dismissOnScroll;if("number"==typeof t&&0<=t){var n=function(e){window.pageYOffset>Math.floor(t)&&(s(u.status.dismiss),a(!0),window.removeEventListener("scroll",n),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=n,window.addEventListener("scroll",n))}var i=this.options.dismissOnWindowClick,l=this.options.ignoreClicksFrom;if(i){var c=function(e){for(var t=!1,n=e.path.length,i=l.length,r=0;rn&&(t=!0),t?d.hasClass(i,"cc-active")||d.addClass(i,"cc-active"):d.hasClass(i,"cc-active")&&d.removeClass(i,"cc-active")},200);this.onMouseMove=n,window.addEventListener("mousemove",n)}}}.call(this),this.options.autoOpen&&this.autoOpen()},e.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(e){if(d.isPlainObject(e)){var t=d.hash(JSON.stringify(e)),n=u.customStyles[t];if(n&&!--n.references){var i=n.element.ownerNode;i&&i.parentNode&&i.parentNode.removeChild(i),u.customStyles[t]=null}}}(this.options.palette),this.options=null},e.prototype.open=function(e){if(this.element)return this.isOpen()||(u.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},e.prototype.close=function(e){if(this.element)return this.isOpen()&&(u.hasTransition?this.fadeOut():this.element.style.display="none",e&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},e.prototype.fadeIn=function(){var e=this.element;if(u.hasTransition&&e&&(this.afterTransition&&s.call(this,e),d.hasClass(e,"cc-invisible"))){if(e.style.display="",this.options.static){var t=this.element.clientHeight;this.element.parentNode.style.maxHeight=t+"px"}this.openingTimeout=setTimeout(i.bind(this,e),20)}},e.prototype.fadeOut=function(){var e=this.element;u.hasTransition&&e&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),i.bind(this,e)),d.hasClass(e,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,e),e.addEventListener(u.transitionEnd,this.afterTransition),d.addClass(e,"cc-invisible")))},e.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!u.hasTransition||!d.hasClass(this.element,"cc-invisible"))},e.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},e.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},e.prototype.hasAnswered=function(e){return 0<=Object.keys(u.status).indexOf(this.getStatus())},e.prototype.hasConsented=function(e){var t=this.getStatus();return t==u.status.allow||t==u.status.dismiss},e.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},e.prototype.setStatus=function(e){var t=this.options.cookie,n=d.getCookie(t.name),i=0<=Object.keys(u.status).indexOf(n);0<=Object.keys(u.status).indexOf(e)?(d.setCookie(t.name,e,t.expiryDays,t.domain,t.path,t.secure),this.options.onStatusChange.call(this,e,i)):this.clearStatus()},e.prototype.getStatus=function(){return d.getCookie(this.options.cookie.name)},e.prototype.clearStatus=function(){var e=this.options.cookie;d.setCookie(e.name,"",-1,e.domain,e.path)},e),u.Location=(t={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var n=JSON.parse(t);return n.error?m(n):{code:n.country}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var n=JSON.parse(t);return"ERROR"==n.statusCode?m({error:n.statusMessage}):{code:n.countryCode}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(t){window.geoip2?geoip2.country(function(e){try{t({code:e.country.iso_code})}catch(e){t(m(e))}},function(e){t(m(e))}):t(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}},h.prototype.getNextService=function(){for(var e;e=this.getServiceByIdx(++this.currentServiceIndex),this.currentServiceIndex>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,o,s,a,l=0,c=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,o=(3&t)<<4|(n=e.charCodeAt(l++))>>4,s=(15&n)<<2|(i=e.charCodeAt(l++))>>6,a=63&i,l===e.length+2?a=s=64:l===e.length+1&&(a=64),c.push(u.charAt(r),u.charAt(o),u.charAt(s),u.charAt(a));return c.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(a,e,O){(function(c){var e=O(2),h=O(3),T=O(6),g=O(7),v=O(8),y=O(9),S=O(10),t=O(11),u=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,w=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(k.settings.themes[e]=t),delete k.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[k.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&x(e))},run:function(e){e=e||{};var u={},d=m(k.settings,e);k.vars.preempted=!0,k.vars.dataAttr=d.dataAttr||k.setup.dataAttr,u.renderer=d.renderer?d.renderer:k.setup.renderer,-1===k.setup.renderers.join(",").indexOf(u.renderer)&&(u.renderer=k.setup.supportsSVG?"svg":k.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return u.stylesheets=[],u.svgXMLStylesheet=!0,u.noFontFallback=!!d.noFontFallback,u.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;u.stylesheets.push(i)}}),n.forEach(function(e){if(c.getComputedStyle){var t=c.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",o=n.indexOf(r);if(0===o)i=n;else if(1===o&&"?"===n[0])i=n.slice(1);else{var s=n.substr(o).match(/([^\"]*)"?\)/);if(null!==s)i=s[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var a=l(i,d);a&&p({mode:"background",el:e,flags:a,engineSettings:u})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(k.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,u,t.data,e):i&&f(d,u,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(k.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,o,s,a=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),c=null!=t.rendered&&"true"==t.rendered;a?0===t.src.indexOf(d.domain)?f(d,u,t.src,e):l&&(c?f(d,u,t.dataSrc,e):(n=t.src,i=d,r=u,o=t.dataSrc,s=e,g.imageExists(n,function(e){e||f(i,r,o,s)}))):l&&f(d,u,t.dataSrc,e)}),this}},k={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(k.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var o=r[0].split("/");n.holderURL=e;var s=o[1],a=s.match(/([\d]+p?)x([\d]+p?)/);if(!a)return!1;if(n.fluid=-1!==s.indexOf("p"),n.dimensions={width:a[1].replace("p","%"),height:a[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var c=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(u/c*100),c=100,n.dimensions.width=c+"%",n.dimensions.height=u+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){k.vars.cache.themeKeys=k.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=k.vars.cache.themeKeys[0|Math.random()*k.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,o=i.dimensions,s=i.theme,a=o.width+"x"+o.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(s.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=s.text.split("\\n"),c=0;c=r||!0==E)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,w+=f.properties.leading,_+=1,(g=new s.Group("line"+_)).y=w),!0!=E&&(m.moveTo(b,0),b+=p.spaceWidth+C.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new s.Text(e.text),(g=new s.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return o}(s);function l(){var e=null;switch(o.renderer){case"canvas":e=d(a,t);break;case"svg":e=u(a,t);break;default:throw"Holder: invalid renderer: "+o.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",o.noBackgroundSize||(i.style.backgroundSize=s.width+"px "+s.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),o.reRender&&c.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function x(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?k.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function s(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}s.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},s.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,o=r*(1-Math.abs(parseInt(i)%2-1)),s=n-r/2,a=0,l=0,c=0;return 0<=i&&i<1?(a=r,l=o):1<=i&&i<2?(a=o,l=r):2<=i&&i<3?(l=r,c=o):3<=i&&i<4?(l=o,c=r):4<=i&&i<5?(a=o,c=r):5<=i&&i<6&&(a=r,c=o),a+=s,l+=s,c+=s,[a=parseInt(255*a),l=parseInt(255*l),c=parseInt(255*c)]},s.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,o=-.09991*t-.33609*n+.436*i,s=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:o,v:s},this},s.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),o=s.rgb2hex(n,i,r);return new s(o)},s.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},s.prototype.lighterThan=function(e){return e instanceof s||(e=new s(e)),this.yuv.y>e.yuv.y},s.prototype.blendAlpha=function(e){e instanceof s||(e=new s(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new s(s.rgb2hex(n,i,r))},e.exports=s},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),w=n(7),_=i.svg_ns,x=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,s=r.children.holderTextGroup,o="#"+i+" text { "+function(e){return w.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(s.properties)+" } ";s.y+=.8*s.textPositionData.boundingBox.height;var a=[];Object.keys(s.children).forEach(function(e){var o=s.children[e];Object.keys(o.children).forEach(function(e){var t=o.children[e],n=s.x+o.x+t.x,i=s.y+o.y+t.y,r=x({tag:"text",content:t.properties.text,x:n,y:i});a.push(r)})});var l=x({tag:"g",content:a}),c=null;if(r.children.holderBg.properties.outline){var u=r.children.holderBg.properties.outline;c=x({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,u.width),"stroke-width":u.width,stroke:u.fill,fill:"none"})}var d=function(e,t){return x({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),u&&h.push(c),h.push(l);var f=x({tag:"g",id:i,content:h}),p=x({tag:"style",content:o,type:"text/css"}),m=x({tag:"defs",content:p}),g=x({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:_,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,o,s,a,l,c,u,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],c=l.match(/^[\w-]+/),u={tag:c?c[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(u.attr.id=d[1],i[d[1]]=u),h&&(i[h[1]]=u),f&&(u.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),u);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])s=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(o in t[g])t[g].hasOwnProperty(o)&&null!==t[g][o]&&!1!==t[g][o]&&("style"===o&&"object"==typeof t[g][o]?t[0].attr[o]=JSON.stringify(t[g][o],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[o]=t[g][o])}}if(!1!==t[0]){for(a in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(a)&&(r+=" "+a+'="'+((m=t[0].attr[a])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],s&&s(t[0]),i}},function(e,t){"use strict";var a=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=a.exec(n);if(!i)return n;var r="",o=0,s=0;for(o=i.index;o Date: Thu, 23 Jan 2020 14:17:27 +0100 Subject: [PATCH 332/338] Fix health check for mysql --- src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs index 4b3729eff..a96056798 100644 --- a/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs +++ b/src/Skoruba.IdentityServer4.Admin/Helpers/StartupHelpers.cs @@ -485,8 +485,8 @@ public static void AddIdSHealthChecks Date: Thu, 23 Jan 2020 14:37:34 +0100 Subject: [PATCH 333/338] Fix template --- .../Helpers/StartupHelpers.cs | 4 ++-- .../Scripts/App/components/Language.js | 9 ++++++--- .../wwwroot/dist/js/bundle.min.js | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Helpers/StartupHelpers.cs b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Helpers/StartupHelpers.cs index ea59e6a5d..5692b3365 100644 --- a/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Helpers/StartupHelpers.cs +++ b/templates/template-publish/content/src/SkorubaIdentityServer4Admin.Admin/Helpers/StartupHelpers.cs @@ -485,8 +485,8 @@ public static void AddIdSHealthChecks>10|55296,1023&i|56320)}function r(){x()}var e,f,w,o,s,p,h,m,_,l,c,x,C,a,E,g,u,v,y,T="sizzle"+1*new Date,b=n.document,S=0,i=0,k=le(),A=le(),D=le(),N=le(),O=function(e,t){return e===t&&(c=!0),0},I={}.hasOwnProperty,t=[],L=t.pop,j=t.push,P=t.push,R=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+q+")"+q+"*"),K=new RegExp(q+"|>"),Q=new RegExp(W),X=new RegExp("^"+F+"$"),Y={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),TAG:new RegExp("^("+F+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+q+"*(even|odd|(([+-]|)(\\d*)n|)"+q+"*(?:([+-]|)"+q+"*(\\d+)|))"+q+"*\\)|)","i"),bool:new RegExp("^(?:"+M+")$","i"),needsContext:new RegExp("^"+q+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+q+"*((?:-\\d)?\\d*)"+q+"*\\)|)(?=[^-]|$)","i")},G=/HTML$/i,J=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+q+"?|("+q+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,oe=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},se=we(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=R.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,R.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function ae(t,e,n,i){var r,o,s,a,l,c,u,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==C&&x(e),e=e||C,E)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(s=e.getElementById(r)))return n;if(s.id===r)return n.push(s),n}else if(d&&(s=d.getElementById(r))&&y(e,s)&&s.id===r)return n.push(s),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!N[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(u=t,d=e,1===h&&K.test(t)){for((a=e.getAttribute("id"))?a=a.replace(re,oe):e.setAttribute("id",a=T),o=(c=p(t)).length;o--;)c[o]="#"+a+" "+be(c[o]);u=c.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(u)),n}catch(e){N(t,!0)}finally{a===T&&e.removeAttribute("id")}}}return m(t.replace(z,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>w.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ce(e){return e[T]=!0,e}function ue(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)w.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&se(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(s){return ce(function(o){return o=+o,ce(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=ae.support={},s=ae.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!G.test(t||n&&n.nodeName||"HTML")},x=ae.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==C&&9===i.nodeType&&i.documentElement&&(a=(C=i).documentElement,E=!s(C),b!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ue(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(C.getElementsByClassName),f.getById=ue(function(e){return a.appendChild(e).id=T,!C.getElementsByName||!C.getElementsByName(T).length}),f.getById?(w.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(w.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,i,r,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(r=t.getElementsByName(e),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},w.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},u=[],g=[],(f.qsa=ee.test(C.querySelectorAll))&&(ue(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+q+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+q+"*(?:value|"+M+")"),e.querySelectorAll("[id~="+T+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+T+"+*").length||g.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+q+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ue(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),u.push("!=",W)}),g=g.length&&new RegExp(g.join("|")),u=u.length&&new RegExp(u.join("|")),t=ee.test(a.compareDocumentPosition),y=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===b&&y(b,e)?-1:t===C||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===C?-1:t===C?1:r?-1:o?1:l?H(l,e)-H(l,t):0;if(r===o)return he(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?he(s[i],a[i]):s[i]===b?-1:a[i]===b?1:0}),C},ae.matches=function(e,t){return ae(e,null,null,t)},ae.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&x(e),f.matchesSelector&&E&&!N[t+" "]&&(!u||!u.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ae.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ae.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=k[e+" "];return t||(t=new RegExp("(^|"+q+")"+e+"("+q+"|$)"))&&k(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=ae.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function N(e,n,i){return b(n)?T.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?T.grep(e,function(e){return e===n!==i}):"string"!=typeof n?T.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:I.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(i[1])&&T.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=E.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=T.fn,O=T(E);var L=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?T.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var xe=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function Te(){return!0}function Se(){return!1}function ke(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,i,r,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(i=i||n,n=void 0),t)Ae(e,a,n,i,t[a],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Se;else if(!r)return e;return 1===o&&(s=r,(r=function(e){return T().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=T.guid++)),e.each(function(){T.event.add(this,t,r,i,n)})}function De(e,r,o){o?(Y.set(e,r,!1),T.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Y.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(T.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=a.call(arguments),Y.set(this,r,i),t=o(this,r),this[r](),i!==(n=Y.get(this,r))||t?Y.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Y.set(this,r,{value:T.event.trigger(T.extend(i[0],T.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,r)&&T.event.add(e,r,Te)}T.event={global:{},add:function(t,e,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.get(t);if(g)for(n.handler&&(n=(o=n).handler,r=o.selector),r&&T.find.matchesSelector(re,r),n.guid||(n.guid=T.guid++),(l=g.events)||(l=g.events={}),(s=g.handle)||(s=g.handle=function(e){return void 0!==T&&T.event.triggered!==e.type?T.event.dispatch.apply(t,arguments):void 0}),c=(e=(e||"").match(R)||[""]).length;c--;)f=m=(a=Ee.exec(e[c])||[])[1],p=(a[2]||"").split(".").sort(),f&&(d=T.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=T.event.special[f]||{},u=T.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&T.expr.match.needsContext.test(r),namespace:p.join(".")},o),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,s)||t.addEventListener&&t.addEventListener(f,s)),d.add&&(d.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,u):h.push(u),T.event.global[f]=!0)},remove:function(e,t,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.hasData(e)&&Y.get(e);if(g&&(l=g.events)){for(c=(t=(t||"").match(R)||[""]).length;c--;)if(f=m=(a=Ee.exec(t[c])||[])[1],p=(a[2]||"").split(".").sort(),f){for(d=T.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=h.length;o--;)u=h[o],!r&&m!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(h.splice(o,1),u.selector&&h.delegateCount--,d.remove&&d.remove.call(e,u));s&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||T.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)T.event.remove(e,f+t[c],n,i,!0);T.isEmptyObject(l)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,o,s,a=T.event.fix(e),l=new Array(arguments.length),c=(Y.get(this,"events")||{})[a.type]||[],u=T.event.special[a.type]||{};for(l[0]=a,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,o,s,a,l,c;if(1===t.nodeType){if(Y.hasData(e)&&(o=Y.access(e),s=Y.set(t,o),c=o.events))for(r in delete s.handle,s.events={},c)for(n=0,i=c[r].length;n")},clone:function(e,t,n){var i,r,o,s,a,l,c,u=e.cloneNode(!0),d=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||T.isXMLDoc(e)))for(s=ge(u),i=0,r=(o=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],on=/(=)\?(?=&|$)|\?\?/;T.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||T.expando+"_"+jt++;return this[e]=!0,e}}),T.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,o,s=!1!==e.jsonp&&(on.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&on.test(e.data)&&"data");if(s||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,s?e[s]=e[s].replace(on,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return o||T.error(i+" was not called"),o[0]},e.dataTypes[0]="json",r=C[i],C[i]=function(){o=arguments},n.always(function(){void 0===r?T(C).removeProp(i):C[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),o&&b(r)&&r(o[0]),o=r=void 0}),"script"}),y.createHTMLDocument=((nn=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),T.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(i)):t=E),o=!n&&[],(r=D.exec(e))?[t.createElement(r[1])]:(r=_e([e],t,o),o&&o.length&&T(o).remove(),T.merge([],r.childNodes)));var i,r,o},T.fn.load=function(e,t,n){var i,r,o,s=this,a=e.indexOf(" ");return-1").append(T.parseHTML(e)).find(i):e)}).always(n&&function(e,t){s.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},T.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){T.fn[t]=function(e){return this.on(t,e)}}),T.expr.pseudos.animated=function(t){return T.grep(T.timers,function(e){return t===e.elem}).length},T.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,c=T.css(e,"position"),u=T(e),d={};"static"===c&&(e.style.position="relative"),a=u.offset(),o=T.css(e,"top"),l=T.css(e,"left"),r=("absolute"===c||"fixed"===c)&&-1<(o+l).indexOf("auto")?(s=(i=u.position()).top,i.left):(s=parseFloat(o)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,T.extend({},a))),null!=t.top&&(d.top=t.top-a.top+s),null!=t.left&&(d.left=t.left-a.left+r),"using"in t?t.using.call(e,d):u.css(d)}},T.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){T.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===T.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===T.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=T(e).offset()).top+=T.css(e,"borderTopWidth",!0),r.left+=T.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-T.css(i,"marginTop",!0),left:t.left-r.left-T.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===T.css(e,"position");)e=e.offsetParent;return e||re})}}),T.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var o="pageYOffset"===r;T.fn[t]=function(e){return U(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(o?i.pageXOffset:n,o?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),T.each(["top","left"],function(e,n){T.cssHooks[n]=Ze(y.pixelPosition,function(e,t){if(t)return t=Je(e,n),Ke.test(t)?T(e).position()[n]+"px":t})}),T.each({Height:"height",Width:"width"},function(s,a){T.each({padding:"inner"+s,content:a,"":"outer"+s},function(i,o){T.fn[o]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return U(this,function(e,t,n){var i;return m(e)?0===o.indexOf("outer")?e["inner"+s]:e.document.documentElement["client"+s]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+s],i["scroll"+s],e.body["offset"+s],i["offset"+s],i["client"+s])):void 0===n?T.css(e,t,r):T.style(e,t,n,r)},a,n?e:void 0,n)}})}),T.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){T.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(u(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return u(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=u(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,o,s,a,l=this[0],c=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&c&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=u.data(l.form,"validator").settings).rules,r=u.validator.staticRules(l),e){case"add":u.extend(r,u.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=u.extend(n.messages[l.name],t.messages));break;case"remove":return t?(a={},u.each(t.split(/\s/),function(e,t){a[t]=r[t],delete r[t]}),a):(delete i[l.name],r)}return(o=u.validator.normalizeRules(u.extend({},u.validator.classRules(l),u.validator.attributeRules(l),u.validator.dataRules(l),u.validator.staticRules(l)),l)).required&&(s=o.required,delete o.required,o=u.extend({required:s},o)),o.remote&&(s=o.remote,delete o.remote,o=u.extend(o,{remote:s})),o}}}),u.extend(u.expr.pseudos||u.expr[":"],{blank:function(e){return!u.trim(""+u(e).val())},filled:function(e){var t=u(e).val();return null!==t&&!!u.trim(""+t)},unchecked:function(e){return!u(e).prop("checked")}}),u.validator=function(e,t){this.settings=u.extend(!0,{},u.validator.defaults,e),this.currentForm=t,this.init()},u.validator.format=function(n,e){return 1===arguments.length?function(){var e=u.makeArray(arguments);return e.unshift(n),u.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=u.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 u(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,o,s=this.errorsFor(e),a=this.idOrName(e),l=u(e).attr("aria-describedby");s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(t)):(n=s=u("<"+this.settings.errorElement+">").attr("id",a+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,u(e)):n.insertAfter(e),s.is("label")?s.attr("for",a):0===s.parents("label[for='"+this.escapeCssMeta(a)+"']").length&&(r=s.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,u(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(o=this,u.each(o.groups,function(e,t){t===i&&u("[name='"+o.escapeCssMeta(e)+"']",o.currentForm).attr("aria-describedby",s.attr("id"))})))),!t&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=u(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),u(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return u(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return u("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!u(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!u.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,u(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],u(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(u(this.currentForm).submit(),this.submitButton&&u("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(u(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",u.data(e,"previousValue")||u.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),u(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:u.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=u(e).attr("class");return n&&u.each(n.split(" "),function(){this in u.validator.classRuleSettings&&u.extend(t,u.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,o,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,o,t,n);return i},staticRules:function(e){var t={},n=u.data(e.form,"validator");return n.settings.rules&&(t=u.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return u.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!u(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(u.data(r.form,"validator").resetElements(u(r)),delete i[e])}}else delete i[e]}),u.each(i,function(e,t){i[e]=u.isFunction(t)&&"normalizer"!==e?t(r):t}),u.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),u.each(["rangelength","range"],function(){var e;i[this]&&(u.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),u.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};u.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){u.validator.methods[e]=t,u.validator.messages[e]=void 0!==n?n:u.validator.messages[e],t.length<3&&u.validator.addClassRules(e,u.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,o))}var o,s=u(t).attr("type"),a="Step attribute on input type "+s+" is not supported.",l=new RegExp("\\b"+s+"\\b"),c=!0;if(s&&!l.test(["text","number","range"].join()))throw new Error(a);return o=i(n),(i(e)>o||r(e)%r(n)!=0)&&(c=!1),this.optional(t)||c},equalTo:function(e,t,n){var i=u(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){u(t).valid()}),e===i.val()},remote:function(o,s,e,a){if(this.optional(s))return"dependency-mismatch";a="string"==typeof a&&a||"remote";var l,t,n,c=this.previousValue(s,a);return this.settings.messages[s.name]||(this.settings.messages[s.name]={}),c.originalMessage=c.originalMessage||this.settings.messages[s.name][a],this.settings.messages[s.name][a]=c.message,e="string"==typeof e&&{url:e}||e,n=u.param(u.extend({data:o},e.data)),c.old===n?c.valid:(c.old=n,(l=this).startRequest(s),(t={})[s.name]=o,u.ajax(u.extend(!0,{mode:"abort",port:"validate"+s.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[s.name][a]=c.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(s),l.formSubmitted=i,l.successList.push(s),l.invalid[s.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(s,{method:a,parameters:o}),t[s.name]=c.message=n,l.invalid[s.name]=!0,l.showErrors(t)),c.valid=r,l.stopRequest(s,r)}},e)),"pending")}}});var i,r={};return u.ajaxPrefilter?u.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=u.ajax,u.ajax=function(e){var t=("mode"in e?e:u.ajaxSettings).mode,n=("port"in e?e:u.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),u}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,s=l.validator,a="unobtrusiveValidation";function c(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function u(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=o[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(a),r=l.proxy(f,i),o=s.unobtrusive.options||{};return n||(n={options:{errorClass:o.errorClass||"input-validation-error",errorElement:o.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+u(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+a,r).on("reset."+a,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(a,n)),n}return s.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,o,s=l(i),a=s.parents("form")[0];a&&((t=p(a)).options.rules[i.name]=r={},t.options.messages[i.name]=o={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=s.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=s.attr(e+this)}),this.adapt({element:i,form:a,message:t,params:n,rules:r,messages:o}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){s.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=s.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){c(e,n||t,!0)})},e.addMinMax=function(e,i,r,o,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?c(e,o,[t,n]):t?c(e,i,t):n&&c(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){c(e,i||t,e.params[n])})},s.addMethod("__dummy__",function(e,t,n){return!0}),s.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),s.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),s.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);c(e,"equalTo",l(e.form).find(":input").filter("[name='"+u(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||c(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},o=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,o);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+u(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),c(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&c(e,"minlength",e.params.min),e.params.nonalphamin&&c(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&c(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){c(e,"extension",e.params.extensions)}),l(function(){s.unobtrusive.parse(document)}),s.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(o[t],r[e]-("right"===e?o.width:o.height))),_({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";o=x({},o,s[t](e))}),e.offsets.popper=o,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=C(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,o=-1!==["top","bottom"].indexOf(i),s=o?"right":"bottom",a=o?"left":"top",l=o?"width":"height";return t[s]r(n[s])&&(e.offsets.popper[a]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=C(e.offsets.popper),o=e.offsets.reference,s=-1!==["left","right"].indexOf(i),a=s?"height":"width",l=s?"top":"left",c=s?"left":"top",u=s?"bottom":"right",d=D(n)[a];o[u]-dr[u]&&(e.offsets.popper[l]+=o[l]+d-r[u]);var h=o[l]+o[a]/2-d/2-C(e.offsets.popper)[l];return h=Math.max(Math.min(r[a]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[c]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(R(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=N(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case U:b=[g,v];break;case z:b=W(g);break;case $:b=W(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=N(g);var n=C(f.offsets.popper),i=f.offsets.reference,r=Math.floor,o="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),u="left"===g&&s||"right"===g&&a||"top"===g&&l||"bottom"===g&&c,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&s||d&&"end"===y&&a||!d&&"start"===y&&l||!d&&"end"===y&&c);(o||u||h)&&(f.flipped=!0,(o||u)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=C(e.offsets.popper),r=C(e.offsets.reference),o=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return i[o?"left":"top"]=r[t]-(s?i[o?"width":"height"]:0),e.placement=N(t),e.offsets.popper=C(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(z.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:wt},jt="show",Pt="out",Rt={HIDE:"hide"+St,HIDDEN:"hidden"+St,SHOW:"show"+St,SHOWN:"shown"+St,INSERTED:"inserted"+St,CLICK:"click"+St,FOCUSIN:"focusin"+St,FOCUSOUT:"focusout"+St,MOUSEENTER:"mouseenter"+St,MOUSELEAVE:"mouseleave"+St},Ht="fade",Mt="show",qt=".tooltip-inner",Ft=".arrow",Bt="hover",Wt="focus",Ut="click",zt="manual",$t=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Mt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),o=m.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&p(r).addClass(Ht);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ft},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var u=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,c).emulateTransitionEnd(u)}else c()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Ut]=!1,this._activeTrigger[Wt]=!1,this._activeTrigger[Bt]=!1,p(this.tip).hasClass(Ht)){var o=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(o)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(At+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(qt)),this.getTitle()),p(e).removeClass(Ht+" "+Mt)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=Ct(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return It[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==zt){var t=e===Bt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Bt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Wt:Bt]=!0),p(t.getTipElement()).hasClass(Mt)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Wt:Bt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==Nt.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Et,e,this.constructor.DefaultType),e.sanitize&&(e.template=Ct(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Dt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(Tt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(Tt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Lt}},{key:"NAME",get:function(){return Et}},{key:"DATA_KEY",get:function(){return Tt}},{key:"Event",get:function(){return Rt}},{key:"EVENT_KEY",get:function(){return St}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Et]=$t._jQueryInterface,p.fn[Et].Constructor=$t,p.fn[Et].noConflict=function(){return p.fn[Et]=kt,$t._jQueryInterface};var Vt="popover",Kt="bs.popover",Qt="."+Kt,Xt=p.fn[Vt],Yt="bs-popover",Gt=new RegExp("(^|\\s)"+Yt+"\\S+","g"),Jt=l({},$t.Default,{placement:"right",trigger:"click",content:"",template:''}),Zt=l({},$t.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",on={HIDE:"hide"+Qt,HIDDEN:"hidden"+Qt,SHOW:"show"+Qt,SHOWN:"shown"+Qt,INSERTED:"inserted"+Qt,CLICK:"click"+Qt,FOCUSIN:"focusin"+Qt,FOCUSOUT:"focusout"+Qt,MOUSEENTER:"mouseenter"+Qt,MOUSELEAVE:"mouseleave"+Qt},sn=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Yt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Gt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>16),i=38+(t>>8&255),r=38+(255&t);return"#"+(16777216+65536*(n<255?n<1?0:n:255)+256*(i<255?i<1?0:i:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,t){return e&&e.parentNode?d.hasClass(e,t)?e:this.traverseDOMPath(e.parentNode,t):null}};u.status={deny:"deny",allow:"allow",dismiss:"dismiss"},u.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n+"ransition"])return t[n];return""}(),u.hasTransition=!!u.transitionEnd;var r,t,n,o=Object.keys(u.status).map(d.escapeRegExp);u.customStyles={},u.Popup=(r={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
    {{policy}}
    ',compliance:{info:'
    {{dismiss}}
    ',"opt-in":'
    {{deny}}{{allow}}
    ',"opt-out":'
    {{deny}}{{allow}}
    '},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null},e.prototype.initialise=function(e){this.options&&this.destroy(),d.deepExtend(this.options={},r),d.isPlainObject(e)&&d.deepExtend(this.options,e),function(){var e=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return e(u.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return e(u.status.allow),!0;var t=Object.keys(u.status),n=this.getStatus(),i=0<=t.indexOf(n);return i&&e(n),i}.call(this)&&(this.options.enabled=!1),c(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),c(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var t=this.options.window.replace("{{classes}}",function(){var e=this.options,t="top"==e.position||"bottom"==e.position?"banner":"floating";d.isMobile()&&(t="floating");var n=["cc-"+t,"cc-type-"+e.type,"cc-theme-"+e.theme];return e.static&&n.push("cc-static"),n.push.apply(n,a.call(this)),function(e){var t=d.hash(JSON.stringify(e)),n="cc-color-override-"+t,i=d.isPlainObject(e);return this.customStyleSelector=i?n:null,i&&function(e,t,n){if(u.customStyles[e])return++u.customStyles[e].references;var i={},r=t.popup,o=t.button,s=t.highlight;r&&(r.text=r.text?r.text:d.getContrast(r.background),r.link=r.link?r.link:r.text,i[n+".cc-window"]=["color: "+r.text,"background-color: "+r.background],i[n+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],i[n+" .cc-link,"+n+" .cc-link:active,"+n+" .cc-link:visited"]=["color: "+r.link],o&&(o.text=o.text?o.text:d.getContrast(o.background),o.border=o.border?o.border:"transparent",i[n+" .cc-btn"]=["color: "+o.text,"border-color: "+o.border,"background-color: "+o.background],o.padding&&i[n+" .cc-btn"].push("padding: "+o.padding),"transparent"!=o.background&&(i[n+" .cc-btn:hover, "+n+" .cc-btn:focus"]=["background-color: "+(o.hover||function(e){return"000000"!=(e=d.normaliseHex(e))?d.getLuminance(e):"#222"}(o.background))]),s?(s.text=s.text?s.text:d.getContrast(s.background),s.border=s.border?s.border:"transparent",i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+s.text,"border-color: "+s.border,"background-color: "+s.background]):i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var a=document.createElement("style");document.head.appendChild(a),u.customStyles[e]={references:1,element:a.sheet};var l=-1;for(var c in i)i.hasOwnProperty(c)&&a.sheet.insertRule(c+"{"+i[c].join(";")+"}",++l)}(t,e,"."+n),i}.call(this,this.options.palette),this.customStyleSelector&&n.push(this.customStyleSelector),n}.call(this).join(" ")).replace("{{children}}",function(){var t={},n=this.options;n.showLink||(n.elements.link="",n.elements.messagelink=n.elements.message),Object.keys(n.elements).forEach(function(e){t[e]=d.interpolateString(n.elements[e],function(e){var t=n.content[e];return e&&"string"==typeof t&&t.length?t:""})});var e=n.compliance[n.type];e=e||n.compliance.info,t.compliance=d.interpolateString(e,function(e){return t[e]});var i=n.layouts[n.layout];return i=i||n.layouts.basic,d.interpolateString(i,function(e){return t[e]})}.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(t=n),this.options.static){var i=l.call(this,'
    '+t+"
    ");i.style.display="",this.element=i.firstChild,this.element.style.display="none",d.addClass(this.element,"cc-invisible")}else this.element=l.call(this,t);(function(){var s=this.setStatus.bind(this),a=this.close.bind(this),e=this.options.dismissOnTimeout;"number"==typeof e&&0<=e&&(this.dismissTimeout=window.setTimeout(function(){s(u.status.dismiss),a(!0)},Math.floor(e)));var t=this.options.dismissOnScroll;if("number"==typeof t&&0<=t){var n=function(e){window.pageYOffset>Math.floor(t)&&(s(u.status.dismiss),a(!0),window.removeEventListener("scroll",n),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=n,window.addEventListener("scroll",n))}var i=this.options.dismissOnWindowClick,l=this.options.ignoreClicksFrom;if(i){var c=function(e){for(var t=!1,n=e.path.length,i=l.length,r=0;rn&&(t=!0),t?d.hasClass(i,"cc-active")||d.addClass(i,"cc-active"):d.hasClass(i,"cc-active")&&d.removeClass(i,"cc-active")},200);this.onMouseMove=n,window.addEventListener("mousemove",n)}}}.call(this),this.options.autoOpen&&this.autoOpen()},e.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(e){if(d.isPlainObject(e)){var t=d.hash(JSON.stringify(e)),n=u.customStyles[t];if(n&&!--n.references){var i=n.element.ownerNode;i&&i.parentNode&&i.parentNode.removeChild(i),u.customStyles[t]=null}}}(this.options.palette),this.options=null},e.prototype.open=function(e){if(this.element)return this.isOpen()||(u.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},e.prototype.close=function(e){if(this.element)return this.isOpen()&&(u.hasTransition?this.fadeOut():this.element.style.display="none",e&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},e.prototype.fadeIn=function(){var e=this.element;if(u.hasTransition&&e&&(this.afterTransition&&s.call(this,e),d.hasClass(e,"cc-invisible"))){if(e.style.display="",this.options.static){var t=this.element.clientHeight;this.element.parentNode.style.maxHeight=t+"px"}this.openingTimeout=setTimeout(i.bind(this,e),20)}},e.prototype.fadeOut=function(){var e=this.element;u.hasTransition&&e&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),i.bind(this,e)),d.hasClass(e,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,e),e.addEventListener(u.transitionEnd,this.afterTransition),d.addClass(e,"cc-invisible")))},e.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!u.hasTransition||!d.hasClass(this.element,"cc-invisible"))},e.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},e.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},e.prototype.hasAnswered=function(e){return 0<=Object.keys(u.status).indexOf(this.getStatus())},e.prototype.hasConsented=function(e){var t=this.getStatus();return t==u.status.allow||t==u.status.dismiss},e.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},e.prototype.setStatus=function(e){var t=this.options.cookie,n=d.getCookie(t.name),i=0<=Object.keys(u.status).indexOf(n);0<=Object.keys(u.status).indexOf(e)?(d.setCookie(t.name,e,t.expiryDays,t.domain,t.path,t.secure),this.options.onStatusChange.call(this,e,i)):this.clearStatus()},e.prototype.getStatus=function(){return d.getCookie(this.options.cookie.name)},e.prototype.clearStatus=function(){var e=this.options.cookie;d.setCookie(e.name,"",-1,e.domain,e.path)},e),u.Location=(t={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var n=JSON.parse(t);return n.error?m(n):{code:n.country}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var n=JSON.parse(t);return"ERROR"==n.statusCode?m({error:n.statusMessage}):{code:n.countryCode}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(t){window.geoip2?geoip2.country(function(e){try{t({code:e.country.iso_code})}catch(e){t(m(e))}},function(e){t(m(e))}):t(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}},h.prototype.getNextService=function(){for(var e;e=this.getServiceByIdx(++this.currentServiceIndex),this.currentServiceIndex>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,o,s,a,l=0,c=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,o=(3&t)<<4|(n=e.charCodeAt(l++))>>4,s=(15&n)<<2|(i=e.charCodeAt(l++))>>6,a=63&i,l===e.length+2?a=s=64:l===e.length+1&&(a=64),c.push(u.charAt(r),u.charAt(o),u.charAt(s),u.charAt(a));return c.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(a,e,O){(function(c){var e=O(2),h=O(3),T=O(6),g=O(7),v=O(8),y=O(9),S=O(10),t=O(11),u=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,w=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(k.settings.themes[e]=t),delete k.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[k.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&x(e))},run:function(e){e=e||{};var u={},d=m(k.settings,e);k.vars.preempted=!0,k.vars.dataAttr=d.dataAttr||k.setup.dataAttr,u.renderer=d.renderer?d.renderer:k.setup.renderer,-1===k.setup.renderers.join(",").indexOf(u.renderer)&&(u.renderer=k.setup.supportsSVG?"svg":k.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return u.stylesheets=[],u.svgXMLStylesheet=!0,u.noFontFallback=!!d.noFontFallback,u.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;u.stylesheets.push(i)}}),n.forEach(function(e){if(c.getComputedStyle){var t=c.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",o=n.indexOf(r);if(0===o)i=n;else if(1===o&&"?"===n[0])i=n.slice(1);else{var s=n.substr(o).match(/([^\"]*)"?\)/);if(null!==s)i=s[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var a=l(i,d);a&&p({mode:"background",el:e,flags:a,engineSettings:u})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(k.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,u,t.data,e):i&&f(d,u,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(k.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,o,s,a=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),c=null!=t.rendered&&"true"==t.rendered;a?0===t.src.indexOf(d.domain)?f(d,u,t.src,e):l&&(c?f(d,u,t.dataSrc,e):(n=t.src,i=d,r=u,o=t.dataSrc,s=e,g.imageExists(n,function(e){e||f(i,r,o,s)}))):l&&f(d,u,t.dataSrc,e)}),this}},k={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(k.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var o=r[0].split("/");n.holderURL=e;var s=o[1],a=s.match(/([\d]+p?)x([\d]+p?)/);if(!a)return!1;if(n.fluid=-1!==s.indexOf("p"),n.dimensions={width:a[1].replace("p","%"),height:a[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var c=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(u/c*100),c=100,n.dimensions.width=c+"%",n.dimensions.height=u+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){k.vars.cache.themeKeys=k.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=k.vars.cache.themeKeys[0|Math.random()*k.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,o=i.dimensions,s=i.theme,a=o.width+"x"+o.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(s.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=s.text.split("\\n"),c=0;c=r||!0==E)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,w+=f.properties.leading,_+=1,(g=new s.Group("line"+_)).y=w),!0!=E&&(m.moveTo(b,0),b+=p.spaceWidth+C.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new s.Text(e.text),(g=new s.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return o}(s);function l(){var e=null;switch(o.renderer){case"canvas":e=d(a,t);break;case"svg":e=u(a,t);break;default:throw"Holder: invalid renderer: "+o.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",o.noBackgroundSize||(i.style.backgroundSize=s.width+"px "+s.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),o.reRender&&c.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function x(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?k.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function s(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}s.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},s.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,o=r*(1-Math.abs(parseInt(i)%2-1)),s=n-r/2,a=0,l=0,c=0;return 0<=i&&i<1?(a=r,l=o):1<=i&&i<2?(a=o,l=r):2<=i&&i<3?(l=r,c=o):3<=i&&i<4?(l=o,c=r):4<=i&&i<5?(a=o,c=r):5<=i&&i<6&&(a=r,c=o),a+=s,l+=s,c+=s,[a=parseInt(255*a),l=parseInt(255*l),c=parseInt(255*c)]},s.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,o=-.09991*t-.33609*n+.436*i,s=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:o,v:s},this},s.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),o=s.rgb2hex(n,i,r);return new s(o)},s.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},s.prototype.lighterThan=function(e){return e instanceof s||(e=new s(e)),this.yuv.y>e.yuv.y},s.prototype.blendAlpha=function(e){e instanceof s||(e=new s(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new s(s.rgb2hex(n,i,r))},e.exports=s},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),w=n(7),_=i.svg_ns,x=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,s=r.children.holderTextGroup,o="#"+i+" text { "+function(e){return w.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(s.properties)+" } ";s.y+=.8*s.textPositionData.boundingBox.height;var a=[];Object.keys(s.children).forEach(function(e){var o=s.children[e];Object.keys(o.children).forEach(function(e){var t=o.children[e],n=s.x+o.x+t.x,i=s.y+o.y+t.y,r=x({tag:"text",content:t.properties.text,x:n,y:i});a.push(r)})});var l=x({tag:"g",content:a}),c=null;if(r.children.holderBg.properties.outline){var u=r.children.holderBg.properties.outline;c=x({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,u.width),"stroke-width":u.width,stroke:u.fill,fill:"none"})}var d=function(e,t){return x({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),u&&h.push(c),h.push(l);var f=x({tag:"g",id:i,content:h}),p=x({tag:"style",content:o,type:"text/css"}),m=x({tag:"defs",content:p}),g=x({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:_,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,o,s,a,l,c,u,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],c=l.match(/^[\w-]+/),u={tag:c?c[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(u.attr.id=d[1],i[d[1]]=u),h&&(i[h[1]]=u),f&&(u.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),u);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])s=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(o in t[g])t[g].hasOwnProperty(o)&&null!==t[g][o]&&!1!==t[g][o]&&("style"===o&&"object"==typeof t[g][o]?t[0].attr[o]=JSON.stringify(t[g][o],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[o]=t[g][o])}}if(!1!==t[0]){for(a in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(a)&&(r+=" "+a+'="'+((m=t[0].attr[a])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],s&&s(t[0]),i}},function(e,t){"use strict";var a=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=a.exec(n);if(!i)return n;var r="",o=0,s=0;for(o=i.index;o>10|55296,1023&i|56320)}function r(){x()}var e,f,w,o,s,p,h,m,_,l,c,x,C,a,E,g,u,v,y,T="sizzle"+1*new Date,b=n.document,S=0,i=0,k=le(),A=le(),D=le(),N=le(),O=function(e,t){return e===t&&(c=!0),0},I={}.hasOwnProperty,t=[],L=t.pop,j=t.push,P=t.push,R=t.slice,H=function(e,t){for(var n=0,i=e.length;n+~]|"+q+")"+q+"*"),K=new RegExp(q+"|>"),Q=new RegExp(W),X=new RegExp("^"+F+"$"),Y={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),TAG:new RegExp("^("+F+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+q+"*(even|odd|(([+-]|)(\\d*)n|)"+q+"*(?:([+-]|)"+q+"*(\\d+)|))"+q+"*\\)|)","i"),bool:new RegExp("^(?:"+M+")$","i"),needsContext:new RegExp("^"+q+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+q+"*((?:-\\d)?\\d*)"+q+"*\\)|)(?=[^-]|$)","i")},G=/HTML$/i,J=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,ee=/^[^{]+\{\s*\[native \w/,te=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ne=/[+~]/,ie=new RegExp("\\\\([\\da-f]{1,6}"+q+"?|("+q+")|.)","ig"),re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,oe=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},se=we(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{P.apply(t=R.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){j.apply(e,R.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function ae(t,e,n,i){var r,o,s,a,l,c,u,d=e&&e.ownerDocument,h=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==h&&9!==h&&11!==h)return n;if(!i&&((e?e.ownerDocument||e:b)!==C&&x(e),e=e||C,E)){if(11!==h&&(l=te.exec(t)))if(r=l[1]){if(9===h){if(!(s=e.getElementById(r)))return n;if(s.id===r)return n.push(s),n}else if(d&&(s=d.getElementById(r))&&y(e,s)&&s.id===r)return n.push(s),n}else{if(l[2])return P.apply(n,e.getElementsByTagName(t)),n;if((r=l[3])&&f.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(r)),n}if(f.qsa&&!N[t+" "]&&(!g||!g.test(t))&&(1!==h||"object"!==e.nodeName.toLowerCase())){if(u=t,d=e,1===h&&K.test(t)){for((a=e.getAttribute("id"))?a=a.replace(re,oe):e.setAttribute("id",a=T),o=(c=p(t)).length;o--;)c[o]="#"+a+" "+be(c[o]);u=c.join(","),d=ne.test(t)&&ve(e.parentNode)||e}try{return P.apply(n,d.querySelectorAll(u)),n}catch(e){N(t,!0)}finally{a===T&&e.removeAttribute("id")}}}return m(t.replace(z,"$1"),e,n,i)}function le(){var i=[];return function e(t,n){return i.push(t+" ")>w.cacheLength&&delete e[i.shift()],e[t+" "]=n}}function ce(e){return e[T]=!0,e}function ue(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),i=n.length;i--;)w.attrHandle[n[i]]=t}function he(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pe(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function me(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&se(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ge(s){return ce(function(o){return o=+o,ce(function(e,t){for(var n,i=s([],e.length,o),r=i.length;r--;)e[n=i[r]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in f=ae.support={},s=ae.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!G.test(t||n&&n.nodeName||"HTML")},x=ae.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:b;return i!==C&&9===i.nodeType&&i.documentElement&&(a=(C=i).documentElement,E=!s(C),b!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",r,!1):n.attachEvent&&n.attachEvent("onunload",r)),f.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),f.getElementsByTagName=ue(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),f.getElementsByClassName=ee.test(C.getElementsByClassName),f.getById=ue(function(e){return a.appendChild(e).id=T,!C.getElementsByName||!C.getElementsByName(T).length}),f.getById?(w.filter.ID=function(e){var t=e.replace(ie,d);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(w.filter.ID=function(e){var n=e.replace(ie,d);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,i,r,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(r=t.getElementsByName(e),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=f.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):f.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[r++];)1===n.nodeType&&i.push(n);return i},w.find.CLASS=f.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},u=[],g=[],(f.qsa=ee.test(C.querySelectorAll))&&(ue(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+q+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+q+"*(?:value|"+M+")"),e.querySelectorAll("[id~="+T+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+T+"+*").length||g.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+q+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(f.matchesSelector=ee.test(v=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ue(function(e){f.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),u.push("!=",W)}),g=g.length&&new RegExp(g.join("|")),u=u.length&&new RegExp(u.join("|")),t=ee.test(a.compareDocumentPosition),y=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!f.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===b&&y(b,e)?-1:t===C||t.ownerDocument===b&&y(b,t)?1:l?H(l,e)-H(l,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e===C?-1:t===C?1:r?-1:o?1:l?H(l,e)-H(l,t):0;if(r===o)return he(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?he(s[i],a[i]):s[i]===b?-1:a[i]===b?1:0}),C},ae.matches=function(e,t){return ae(e,null,null,t)},ae.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&x(e),f.matchesSelector&&E&&!N[t+" "]&&(!u||!u.test(t))&&(!g||!g.test(t)))try{var n=v.call(e,t);if(n||f.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ie,d),e[3]=(e[3]||e[4]||e[5]||"").replace(ie,d),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ae.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ae.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Q.test(n)&&(t=p(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ie,d).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=k[e+" "];return t||(t=new RegExp("(^|"+q+")"+e+"("+q+"|$)"))&&k(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,i,r){return function(e){var t=ae.attr(e,n);return null==t?"!="===i:!i||(t+="","="===i?t===r:"!="===i?t!==r:"^="===i?r&&0===t.indexOf(r):"*="===i?r&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function N(e,n,i){return b(n)?T.grep(e,function(e,t){return!!n.call(e,t,e)!==i}):n.nodeType?T.grep(e,function(e){return e===n!==i}):"string"!=typeof n?T.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||O,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this);if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:I.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(i[1])&&T.isPlainObject(t))for(i in t)b(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=E.getElementById(i[2]))&&(this[0]=r,this.length=1),this}).prototype=T.fn,O=T(E);var L=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,me={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ge(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?T.merge([e],n):n}function ve(e,t){for(var n=0,i=e.length;nx",y.noCloneChecked=!!ye.cloneNode(!0).lastChild.defaultValue;var xe=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function Te(){return!0}function Se(){return!1}function ke(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,i,r,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(i=i||n,n=void 0),t)Ae(e,a,n,i,t[a],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Se;else if(!r)return e;return 1===o&&(s=r,(r=function(e){return T().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=T.guid++)),e.each(function(){T.event.add(this,t,r,i,n)})}function De(e,r,o){o?(Y.set(e,r,!1),T.event.add(e,r,{namespace:!1,handler:function(e){var t,n,i=Y.get(this,r);if(1&e.isTrigger&&this[r]){if(i.length)(T.event.special[r]||{}).delegateType&&e.stopPropagation();else if(i=a.call(arguments),Y.set(this,r,i),t=o(this,r),this[r](),i!==(n=Y.get(this,r))||t?Y.set(this,r,!1):n={},i!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else i.length&&(Y.set(this,r,{value:T.event.trigger(T.extend(i[0],T.Event.prototype),i.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,r)&&T.event.add(e,r,Te)}T.event={global:{},add:function(t,e,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.get(t);if(g)for(n.handler&&(n=(o=n).handler,r=o.selector),r&&T.find.matchesSelector(re,r),n.guid||(n.guid=T.guid++),(l=g.events)||(l=g.events={}),(s=g.handle)||(s=g.handle=function(e){return void 0!==T&&T.event.triggered!==e.type?T.event.dispatch.apply(t,arguments):void 0}),c=(e=(e||"").match(R)||[""]).length;c--;)f=m=(a=Ee.exec(e[c])||[])[1],p=(a[2]||"").split(".").sort(),f&&(d=T.event.special[f]||{},f=(r?d.delegateType:d.bindType)||f,d=T.event.special[f]||{},u=T.extend({type:f,origType:m,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&T.expr.match.needsContext.test(r),namespace:p.join(".")},o),(h=l[f])||((h=l[f]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(t,i,p,s)||t.addEventListener&&t.addEventListener(f,s)),d.add&&(d.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),r?h.splice(h.delegateCount++,0,u):h.push(u),T.event.global[f]=!0)},remove:function(e,t,n,i,r){var o,s,a,l,c,u,d,h,f,p,m,g=Y.hasData(e)&&Y.get(e);if(g&&(l=g.events)){for(c=(t=(t||"").match(R)||[""]).length;c--;)if(f=m=(a=Ee.exec(t[c])||[])[1],p=(a[2]||"").split(".").sort(),f){for(d=T.event.special[f]||{},h=l[f=(i?d.delegateType:d.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=h.length;o--;)u=h[o],!r&&m!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(h.splice(o,1),u.selector&&h.delegateCount--,d.remove&&d.remove.call(e,u));s&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||T.removeEvent(e,f,g.handle),delete l[f])}else for(f in l)T.event.remove(e,f+t[c],n,i,!0);T.isEmptyObject(l)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,o,s,a=T.event.fix(e),l=new Array(arguments.length),c=(Y.get(this,"events")||{})[a.type]||[],u=T.event.special[a.type]||{};for(l[0]=a,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,Oe=/\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function He(e,t){var n,i,r,o,s,a,l,c;if(1===t.nodeType){if(Y.hasData(e)&&(o=Y.access(e),s=Y.set(t,o),c=o.events))for(r in delete s.handle,s.events={},c)for(n=0,i=c[r].length;n")},clone:function(e,t,n){var i,r,o,s,a,l,c,u=e.cloneNode(!0),d=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||T.isXMLDoc(e)))for(s=ge(u),i=0,r=(o=ge(e)).length;i").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",r=function(e){i.remove(),r=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(i[0])},abort:function(){r&&r()}}});var nn,rn=[],on=/(=)\?(?=&|$)|\?\?/;T.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=rn.pop()||T.expando+"_"+jt++;return this[e]=!0,e}}),T.ajaxPrefilter("json jsonp",function(e,t,n){var i,r,o,s=!1!==e.jsonp&&(on.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&on.test(e.data)&&"data");if(s||"jsonp"===e.dataTypes[0])return i=e.jsonpCallback=b(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,s?e[s]=e[s].replace(on,"$1"+i):!1!==e.jsonp&&(e.url+=(Pt.test(e.url)?"&":"?")+e.jsonp+"="+i),e.converters["script json"]=function(){return o||T.error(i+" was not called"),o[0]},e.dataTypes[0]="json",r=C[i],C[i]=function(){o=arguments},n.always(function(){void 0===r?T(C).removeProp(i):C[i]=r,e[i]&&(e.jsonpCallback=t.jsonpCallback,rn.push(i)),o&&b(r)&&r(o[0]),o=r=void 0}),"script"}),y.createHTMLDocument=((nn=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===nn.childNodes.length),T.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((i=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(i)):t=E),o=!n&&[],(r=D.exec(e))?[t.createElement(r[1])]:(r=_e([e],t,o),o&&o.length&&T(o).remove(),T.merge([],r.childNodes)));var i,r,o},T.fn.load=function(e,t,n){var i,r,o,s=this,a=e.indexOf(" ");return-1").append(T.parseHTML(e)).find(i):e)}).always(n&&function(e,t){s.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},T.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){T.fn[t]=function(e){return this.on(t,e)}}),T.expr.pseudos.animated=function(t){return T.grep(T.timers,function(e){return t===e.elem}).length},T.offset={setOffset:function(e,t,n){var i,r,o,s,a,l,c=T.css(e,"position"),u=T(e),d={};"static"===c&&(e.style.position="relative"),a=u.offset(),o=T.css(e,"top"),l=T.css(e,"left"),r=("absolute"===c||"fixed"===c)&&-1<(o+l).indexOf("auto")?(s=(i=u.position()).top,i.left):(s=parseFloat(o)||0,parseFloat(l)||0),b(t)&&(t=t.call(e,n,T.extend({},a))),null!=t.top&&(d.top=t.top-a.top+s),null!=t.left&&(d.left=t.left-a.left+r),"using"in t?t.using.call(e,d):u.css(d)}},T.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){T.offset.setOffset(this,t,e)});var e,n,i=this[0];return i?i.getClientRects().length?(e=i.getBoundingClientRect(),n=i.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,i=this[0],r={top:0,left:0};if("fixed"===T.css(i,"position"))t=i.getBoundingClientRect();else{for(t=this.offset(),n=i.ownerDocument,e=i.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===T.css(e,"position");)e=e.parentNode;e&&e!==i&&1===e.nodeType&&((r=T(e).offset()).top+=T.css(e,"borderTopWidth",!0),r.left+=T.css(e,"borderLeftWidth",!0))}return{top:t.top-r.top-T.css(i,"marginTop",!0),left:t.left-r.left-T.css(i,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===T.css(e,"position");)e=e.offsetParent;return e||re})}}),T.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,r){var o="pageYOffset"===r;T.fn[t]=function(e){return U(this,function(e,t,n){var i;if(m(e)?i=e:9===e.nodeType&&(i=e.defaultView),void 0===n)return i?i[r]:e[t];i?i.scrollTo(o?i.pageXOffset:n,o?n:i.pageYOffset):e[t]=n},t,e,arguments.length)}}),T.each(["top","left"],function(e,n){T.cssHooks[n]=Ze(y.pixelPosition,function(e,t){if(t)return t=Je(e,n),Ke.test(t)?T(e).position()[n]+"px":t})}),T.each({Height:"height",Width:"width"},function(s,a){T.each({padding:"inner"+s,content:a,"":"outer"+s},function(i,o){T.fn[o]=function(e,t){var n=arguments.length&&(i||"boolean"!=typeof e),r=i||(!0===e||!0===t?"margin":"border");return U(this,function(e,t,n){var i;return m(e)?0===o.indexOf("outer")?e["inner"+s]:e.document.documentElement["client"+s]:9===e.nodeType?(i=e.documentElement,Math.max(e.body["scroll"+s],i["scroll"+s],e.body["offset"+s],i["offset"+s],i["client"+s])):void 0===n?T.css(e,t,r):T.style(e,t,n,r)},a,n?e:void 0,n)}})}),T.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){T.fn[n]=function(e,t){return 0").attr("name",i.submitButton.name).val(u(i.submitButton).val()).appendTo(i.currentForm)),!(i.settings.submitHandler&&!i.settings.debug)||(t=i.settings.submitHandler.call(i,i.currentForm,n),e&&e.remove(),void 0!==t&&t)}return i.settings.debug&&n.preventDefault(),i.cancelSubmit?(i.cancelSubmit=!1,e()):i.form()?i.pendingRequest?!(i.formSubmitted=!0):e():(i.focusInvalid(),!1)})),i)}e&&e.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.")},valid:function(){var e,t,n;return u(this[0]).is("form")?e=this.validate().form():(n=[],e=!0,t=u(this[0].form).validate(),this.each(function(){(e=t.element(this)&&e)||(n=n.concat(t.errorList))}),t.errorList=n),e},rules:function(e,t){var n,i,r,o,s,a,l=this[0],c=void 0!==this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=l&&(!l.form&&c&&(l.form=this.closest("form")[0],l.name=this.attr("name")),null!=l.form)){if(e)switch(i=(n=u.data(l.form,"validator").settings).rules,r=u.validator.staticRules(l),e){case"add":u.extend(r,u.validator.normalizeRule(t)),delete r.messages,i[l.name]=r,t.messages&&(n.messages[l.name]=u.extend(n.messages[l.name],t.messages));break;case"remove":return t?(a={},u.each(t.split(/\s/),function(e,t){a[t]=r[t],delete r[t]}),a):(delete i[l.name],r)}return(o=u.validator.normalizeRules(u.extend({},u.validator.classRules(l),u.validator.attributeRules(l),u.validator.dataRules(l),u.validator.staticRules(l)),l)).required&&(s=o.required,delete o.required,o=u.extend({required:s},o)),o.remote&&(s=o.remote,delete o.remote,o=u.extend(o,{remote:s})),o}}}),u.extend(u.expr.pseudos||u.expr[":"],{blank:function(e){return!u.trim(""+u(e).val())},filled:function(e){var t=u(e).val();return null!==t&&!!u.trim(""+t)},unchecked:function(e){return!u(e).prop("checked")}}),u.validator=function(e,t){this.settings=u.extend(!0,{},u.validator.defaults,e),this.currentForm=t,this.init()},u.validator.format=function(n,e){return 1===arguments.length?function(){var e=u.makeArray(arguments);return e.unshift(n),u.validator.format.apply(this,e)}:(void 0===e||(2Warning: No message defined for "+e.name+""),i=/\$?\{(\d+)\}/g;return"function"==typeof n?n=n.call(this,t.parameters,e):i.test(n)&&(n=u.validator.format(n.replace(i,"{$1}"),t.parameters)),n},formatAndAdd:function(e,t){var n=this.defaultMessage(e,t);this.errorList.push({message:n,element:e,method:t.method}),this.errorMap[e.name]=n,this.submitted[e.name]=n},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t,n;for(e=0;this.errorList[e];e++)n=this.errorList[e],this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],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 u(this.errorList).map(function(){return this.element})},showLabel:function(e,t){var n,i,r,o,s=this.errorsFor(e),a=this.idOrName(e),l=u(e).attr("aria-describedby");s.length?(s.removeClass(this.settings.validClass).addClass(this.settings.errorClass),s.html(t)):(n=s=u("<"+this.settings.errorElement+">").attr("id",a+"-error").addClass(this.settings.errorClass).html(t||""),this.settings.wrapper&&(n=s.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(n):this.settings.errorPlacement?this.settings.errorPlacement.call(this,n,u(e)):n.insertAfter(e),s.is("label")?s.attr("for",a):0===s.parents("label[for='"+this.escapeCssMeta(a)+"']").length&&(r=s.attr("id"),l?l.match(new RegExp("\\b"+this.escapeCssMeta(r)+"\\b"))||(l+=" "+r):l=r,u(e).attr("aria-describedby",l),(i=this.groups[e.name])&&(o=this,u.each(o.groups,function(e,t){t===i&&u("[name='"+o.escapeCssMeta(e)+"']",o.currentForm).attr("aria-describedby",s.attr("id"))})))),!t&&this.settings.success&&(s.text(""),"string"==typeof this.settings.success?s.addClass(this.settings.success):this.settings.success(s,e)),this.toShow=this.toShow.add(s)},errorsFor:function(e){var t=this.escapeCssMeta(this.idOrName(e)),n=u(e).attr("aria-describedby"),i="label[for='"+t+"'], label[for='"+t+"'] *";return n&&(i=i+", #"+this.escapeCssMeta(n).replace(/\s+/g,", #")),this.errors().filter(i)},escapeCssMeta:function(e){return e.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name)),u(e).not(this.settings.ignore)[0]},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(e){return u(this.currentForm).find("[name='"+this.escapeCssMeta(e)+"']")},getLength:function(e,t){switch(t.nodeName.toLowerCase()){case"select":return u("option:selected",t).length;case"input":if(this.checkable(t))return this.findByName(t.name).filter(":checked").length}return e.length},depend:function(e,t){return!this.dependTypes[typeof e]||this.dependTypes[typeof e](e,t)},dependTypes:{boolean:function(e){return e},string:function(e,t){return!!u(e,t.form).length},function:function(e,t){return e(t)}},optional:function(e){var t=this.elementValue(e);return!u.validator.methods.required.call(this,t,e)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,u(e).addClass(this.settings.pendingClass),this.pending[e.name]=!0)},stopRequest:function(e,t){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[e.name],u(e).removeClass(this.settings.pendingClass),t&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(u(this.currentForm).submit(),this.submitButton&&u("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!t&&0===this.pendingRequest&&this.formSubmitted&&(u(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(e,t){return t="string"==typeof t&&t||"remote",u.data(e,"previousValue")||u.data(e,"previousValue",{old:null,valid:!0,message:this.defaultMessage(e,{method:t})})},destroy:function(){this.resetForm(),u(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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(e,t){e.constructor===String?this.classRuleSettings[e]=t:u.extend(this.classRuleSettings,e)},classRules:function(e){var t={},n=u(e).attr("class");return n&&u.each(n.split(" "),function(){this in u.validator.classRuleSettings&&u.extend(t,u.validator.classRuleSettings[this])}),t},normalizeAttributeRule:function(e,t,n,i){/min|max|step/.test(n)&&(null===t||/number|range|text/.test(t))&&(i=Number(i),isNaN(i)&&(i=void 0)),i||0===i?e[n]=i:t===n&&"range"!==t&&(e[n]=!0)},attributeRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)n="required"===t?(""===(n=e.getAttribute(t))&&(n=!0),!!n):r.attr(t),this.normalizeAttributeRule(i,o,t,n);return i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,i},dataRules:function(e){var t,n,i={},r=u(e),o=e.getAttribute("type");for(t in u.validator.methods)""===(n=r.data("rule"+t.charAt(0).toUpperCase()+t.substring(1).toLowerCase()))&&(n=!0),this.normalizeAttributeRule(i,o,t,n);return i},staticRules:function(e){var t={},n=u.data(e.form,"validator");return n.settings.rules&&(t=u.validator.normalizeRule(n.settings.rules[e.name])||{}),t},normalizeRules:function(i,r){return u.each(i,function(e,t){if(!1!==t){if(t.param||t.depends){var n=!0;switch(typeof t.depends){case"string":n=!!u(t.depends,r.form).length;break;case"function":n=t.depends.call(r,r)}n?i[e]=void 0===t.param||t.param:(u.data(r.form,"validator").resetElements(u(r)),delete i[e])}}else delete i[e]}),u.each(i,function(e,t){i[e]=u.isFunction(t)&&"normalizer"!==e?t(r):t}),u.each(["minlength","maxlength"],function(){i[this]&&(i[this]=Number(i[this]))}),u.each(["rangelength","range"],function(){var e;i[this]&&(u.isArray(i[this])?i[this]=[Number(i[this][0]),Number(i[this][1])]:"string"==typeof i[this]&&(e=i[this].replace(/[\[\]]/g,"").split(/[\s,]+/),i[this]=[Number(e[0]),Number(e[1])]))}),u.validator.autoCreateRanges&&(null!=i.min&&null!=i.max&&(i.range=[i.min,i.max],delete i.min,delete i.max),null!=i.minlength&&null!=i.maxlength&&(i.rangelength=[i.minlength,i.maxlength],delete i.minlength,delete i.maxlength)),i},normalizeRule:function(e){if("string"==typeof e){var t={};u.each(e.split(/\s/),function(){t[this]=!0}),e=t}return e},addMethod:function(e,t,n){u.validator.methods[e]=t,u.validator.messages[e]=void 0!==n?n:u.validator.messages[e],t.length<3&&u.validator.addClassRules(e,u.validator.normalizeRule(e))},methods:{required:function(e,t,n){if(!this.depend(n,t))return"dependency-mismatch";if("select"!==t.nodeName.toLowerCase())return this.checkable(t)?0=n[0]&&i<=n[1]},min:function(e,t,n){return this.optional(t)||n<=e},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},step:function(e,t,n){function i(e){var t=(""+e).match(/(?:\.(\d+))?$/);return t&&t[1]?t[1].length:0}function r(e){return Math.round(e*Math.pow(10,o))}var o,s=u(t).attr("type"),a="Step attribute on input type "+s+" is not supported.",l=new RegExp("\\b"+s+"\\b"),c=!0;if(s&&!l.test(["text","number","range"].join()))throw new Error(a);return o=i(n),(i(e)>o||r(e)%r(n)!=0)&&(c=!1),this.optional(t)||c},equalTo:function(e,t,n){var i=u(n);return this.settings.onfocusout&&i.not(".validate-equalTo-blur").length&&i.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){u(t).valid()}),e===i.val()},remote:function(o,s,e,a){if(this.optional(s))return"dependency-mismatch";a="string"==typeof a&&a||"remote";var l,t,n,c=this.previousValue(s,a);return this.settings.messages[s.name]||(this.settings.messages[s.name]={}),c.originalMessage=c.originalMessage||this.settings.messages[s.name][a],this.settings.messages[s.name][a]=c.message,e="string"==typeof e&&{url:e}||e,n=u.param(u.extend({data:o},e.data)),c.old===n?c.valid:(c.old=n,(l=this).startRequest(s),(t={})[s.name]=o,u.ajax(u.extend(!0,{mode:"abort",port:"validate"+s.name,dataType:"json",data:t,context:l.currentForm,success:function(e){var t,n,i,r=!0===e||"true"===e;l.settings.messages[s.name][a]=c.originalMessage,r?(i=l.formSubmitted,l.resetInternals(),l.toHide=l.errorsFor(s),l.formSubmitted=i,l.successList.push(s),l.invalid[s.name]=!1,l.showErrors()):(t={},n=e||l.defaultMessage(s,{method:a,parameters:o}),t[s.name]=c.message=n,l.invalid[s.name]=!0,l.showErrors(t)),c.valid=r,l.stopRequest(s,r)}},e)),"pending")}}});var i,r={};return u.ajaxPrefilter?u.ajaxPrefilter(function(e,t,n){var i=e.port;"abort"===e.mode&&(r[i]&&r[i].abort(),r[i]=n)}):(i=u.ajax,u.ajax=function(e){var t=("mode"in e?e:u.ajaxSettings).mode,n=("port"in e?e:u.ajaxSettings).port;return"abort"===t?(r[n]&&r[n].abort(),r[n]=i.apply(this,arguments),r[n]):i.apply(this,arguments)}),u}),function(e){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery-validation")):jQuery.validator.unobtrusive=e(jQuery)}(function(l){var e,s=l.validator,a="unobtrusiveValidation";function c(e,t,n){e.rules[t]=n,e.message&&(e.messages[t]=e.message)}function u(e){return e.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function d(e){return e.substr(0,e.lastIndexOf(".")+1)}function h(e,t){return 0===e.indexOf("*.")&&(e=e.replace("*.",t)),e}function f(e){var t=l(this),n="__jquery_unobtrusive_validation_form_reset";if(!t.data(n)){t.data(n,!0);try{t.data("validator").resetForm()}finally{t.removeData(n)}t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function p(i){function e(e,t){var n=o[e];n&&l.isFunction(n)&&n.apply(i,t)}var t=l(i),n=t.data(a),r=l.proxy(f,i),o=s.unobtrusive.options||{};return n||(n={options:{errorClass:o.errorClass||"input-validation-error",errorElement:o.errorElement||"span",errorPlacement:function(){(function(e,t){var n=l(this).find("[data-valmsg-for='"+u(t[0].name)+"']"),i=n.attr("data-valmsg-replace"),r=i?!1!==l.parseJSON(i):null;n.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",n),r?(n.empty(),e.removeClass("input-validation-error").appendTo(n)):e.hide()}).apply(i,arguments),e("errorPlacement",arguments)},invalidHandler:function(){(function(e,t){var n=l(this).find("[data-valmsg-summary=true]"),i=n.find("ul");i&&i.length&&t.errorList.length&&(i.empty(),n.addClass("validation-summary-errors").removeClass("validation-summary-valid"),l.each(t.errorList,function(){l("
  • ").html(this.message).appendTo(i)}))}).apply(i,arguments),e("invalidHandler",arguments)},messages:{},rules:{},success:function(){(function(e){var t=e.data("unobtrusiveContainer");if(t){var n=t.attr("data-valmsg-replace"),i=n?l.parseJSON(n):null;t.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),i&&t.empty()}}).apply(i,arguments),e("success",arguments)}},attachValidation:function(){t.off("reset."+a,r).on("reset."+a,r).validate(this.options)},validate:function(){return t.validate(),t.valid()}},t.data(a,n)),n}return s.unobtrusive={adapters:[],parseElement:function(i,e){var t,r,o,s=l(i),a=s.parents("form")[0];a&&((t=p(a)).options.rules[i.name]=r={},t.options.messages[i.name]=o={},l.each(this.adapters,function(){var e="data-val-"+this.name,t=s.attr(e),n={};void 0!==t&&(e+="-",l.each(this.params,function(){n[this]=s.attr(e+this)}),this.adapt({element:i,form:a,message:t,params:n,rules:r,messages:o}))}),l.extend(r,{__dummy__:!0}),e||t.attachValidation())},parse:function(e){var t=l(e),n=t.parents().addBack().filter("form").add(t.find("form")).has("[data-val=true]");t.find("[data-val=true]").each(function(){s.unobtrusive.parseElement(this,!0)}),n.each(function(){var e=p(this);e&&e.attachValidation()})}},(e=s.unobtrusive.adapters).add=function(e,t,n){return n||(n=t,t=[]),this.push({name:e,params:t,adapt:n}),this},e.addBool=function(t,n){return this.add(t,function(e){c(e,n||t,!0)})},e.addMinMax=function(e,i,r,o,t,n){return this.add(e,[t||"min",n||"max"],function(e){var t=e.params.min,n=e.params.max;t&&n?c(e,o,[t,n]):t?c(e,i,t):n&&c(e,r,n)})},e.addSingleVal=function(t,n,i){return this.add(t,[n||"val"],function(e){c(e,i||t,e.params[n])})},s.addMethod("__dummy__",function(e,t,n){return!0}),s.addMethod("regex",function(e,t,n){var i;return!!this.optional(t)||(i=new RegExp(n).exec(e))&&0===i.index&&i[0].length===e.length}),s.addMethod("nonalphamin",function(e,t,n){var i;return n&&(i=(i=e.match(/\W/g))&&i.length>=n),i}),s.methods.extension?(e.addSingleVal("accept","mimtype"),e.addSingleVal("extension","extension")):e.addSingleVal("extension","extension","accept"),e.addSingleVal("regex","pattern"),e.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),e.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),e.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),e.add("equalto",["other"],function(e){var t=d(e.element.name),n=h(e.params.other,t);c(e,"equalTo",l(e.form).find(":input").filter("[name='"+u(n)+"']")[0])}),e.add("required",function(e){"INPUT"===e.element.tagName.toUpperCase()&&"CHECKBOX"===e.element.type.toUpperCase()||c(e,"required",!0)}),e.add("remote",["url","type","additionalfields"],function(i){var r={url:i.params.url,type:i.params.type||"GET",data:{}},o=d(i.element.name);l.each(function(e){return e.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}(i.params.additionalfields||i.element.name),function(e,t){var n=h(t,o);r.data[n]=function(){var e=l(i.form).find(":input").filter("[name='"+u(n)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),c(i,"remote",r)}),e.add("password",["min","nonalphamin","regex"],function(e){e.params.min&&c(e,"minlength",e.params.min),e.params.nonalphamin&&c(e,"nonalphamin",e.params.nonalphamin),e.params.regex&&c(e,"regex",e.params.regex)}),e.add("fileextensions",["extensions"],function(e){c(e,"extension",e.params.extensions)}),l(function(){s.unobtrusive.parse(document)}),s.unobtrusive}),function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Popper=t()}(this,function(){"use strict";for(var e=["native code","[object MutationObserverConstructor]"],t="undefined"!=typeof window,n=["Edge","Trident","Firefox"],i=0,r=0;rr[e]&&!i.escapeWithReference&&(n=Math.min(o[t],r[e]-("right"===e?o.width:o.height))),_({},t,n)}};return n.forEach(function(e){var t=-1!==["left","top"].indexOf(e)?"primary":"secondary";o=x({},o,s[t](e))}),e.offsets.popper=o,e},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(e){var t=C(e.offsets.popper),n=e.offsets.reference,i=e.placement.split("-")[0],r=Math.floor,o=-1!==["top","bottom"].indexOf(i),s=o?"right":"bottom",a=o?"left":"top",l=o?"width":"height";return t[s]r(n[s])&&(e.offsets.popper[a]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,"arrow","keepTogether"))return e;var n=t.element;if("string"==typeof n){if(!(n=e.instance.popper.querySelector(n)))return e}else if(!e.instance.popper.contains(n))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),e;var i=e.placement.split("-")[0],r=C(e.offsets.popper),o=e.offsets.reference,s=-1!==["left","right"].indexOf(i),a=s?"height":"width",l=s?"top":"left",c=s?"left":"top",u=s?"bottom":"right",d=D(n)[a];o[u]-dr[u]&&(e.offsets.popper[l]+=o[l]+d-r[u]);var h=o[l]+o[a]/2-d/2-C(e.offsets.popper)[l];return h=Math.max(Math.min(r[a]-d,h),0),e.arrowElement=n,e.offsets.arrow={},e.offsets.arrow[l]=h,e.offsets.arrow[c]="",e},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(f,p){if(R(f.instance.modifiers,"inner"))return f;if(f.flipped&&f.placement===f.originalPlacement)return f;var m=H(f.instance.popper,f.instance.reference,p.padding,p.boundariesElement),g=f.placement.split("-")[0],v=N(g),y=f.placement.split("-")[1]||"",b=[];switch(p.behavior){case U:b=[g,v];break;case z:b=W(g);break;case $:b=W(g,!0);break;default:b=p.behavior}return b.forEach(function(e,t){if(g!==e||b.length===t+1)return f;g=f.placement.split("-")[0],v=N(g);var n=C(f.offsets.popper),i=f.offsets.reference,r=Math.floor,o="left"===g&&r(n.right)>r(i.left)||"right"===g&&r(n.left)r(i.top)||"bottom"===g&&r(n.top)r(m.right),l=r(n.top)r(m.bottom),u="left"===g&&s||"right"===g&&a||"top"===g&&l||"bottom"===g&&c,d=-1!==["top","bottom"].indexOf(g),h=!!p.flipVariations&&(d&&"start"===y&&s||d&&"end"===y&&a||!d&&"start"===y&&l||!d&&"end"===y&&c);(o||u||h)&&(f.flipped=!0,(o||u)&&(g=b[t+1]),h&&(y=function(e){return"end"===e?"start":"start"===e?"end":e}(y)),f.placement=g+(y?"-"+y:""),f.offsets.popper=O(f.instance.state.position,f.instance.popper,f.offsets.reference,f.placement),f=P(f.instance.modifiers,f,"flip"))}),f},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,n=t.split("-")[0],i=C(e.offsets.popper),r=C(e.offsets.reference),o=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return i[o?"left":"top"]=r[t]-(s?i[o?"width":"height"]:0),e.placement=N(t),e.offsets.popper=C(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,"hide","preventOverflow"))return e;var t=e.offsets.reference,n=j(e.instance.modifiers,function(e){return"preventOverflow"===e.name}).boundaries;if(t.bottomn.right||t.top>n.bottom||t.rightthis._items.length-1||e<0))if(this._isSliding)p(this._element).one(z.SLID,function(){return t.to(e)});else{if(n===e)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right
    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:wt},jt="show",Pt="out",Rt={HIDE:"hide"+St,HIDDEN:"hidden"+St,SHOW:"show"+St,SHOWN:"shown"+St,INSERTED:"inserted"+St,CLICK:"click"+St,FOCUSIN:"focusin"+St,FOCUSOUT:"focusout"+St,MOUSEENTER:"mouseenter"+St,MOUSELEAVE:"mouseleave"+St},Ht="fade",Mt="show",qt=".tooltip-inner",Ft=".arrow",Bt="hover",Wt="focus",Ut="click",zt="manual",$t=function(){function i(e,t){if(void 0===d)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=p(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(Mt))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var e=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(e);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var r=this.getTipElement(),o=m.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&p(r).addClass(Ht);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();p(r).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(r).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new d(this.element,r,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ft},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}}),p(r).addClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,p(t.element).trigger(t.constructor.Event.SHOWN),e===Pt&&t._leave(null,t)};if(p(this.tip).hasClass(Ht)){var u=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,c).emulateTransitionEnd(u)}else c()}},e.hide=function(e){function t(){n._hoverState!==jt&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),p(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()}var n=this,i=this.getTipElement(),r=p.Event(this.constructor.Event.HIDE);if(p(this.element).trigger(r),!r.isDefaultPrevented()){if(p(i).removeClass(Mt),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Ut]=!1,this._activeTrigger[Wt]=!1,this._activeTrigger[Bt]=!1,p(this.tip).hasClass(Ht)){var o=m.getTransitionDurationFromElement(i);p(i).one(m.TRANSITION_END,t).emulateTransitionEnd(o)}else t();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){p(this.getTipElement()).addClass(At+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(p(e.querySelectorAll(qt)),this.getTitle()),p(e).removeClass(Ht+" "+Mt)},e.setElementContent=function(e,t){"object"!=typeof t||!t.nodeType&&!t.jquery?this.config.html?(this.config.sanitize&&(t=Ct(t,this.config.whiteList,this.config.sanitizeFn)),e.html(t)):e.text(t):this.config.html?p(t).parent().is(e)||e.empty().append(t):e.text(p(t).text())},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e=e||("function"==typeof this.config.title?this.config.title.call(this.element):this.config.title)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},e._getAttachment=function(e){return It[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==zt){var t=e===Bt?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Bt?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");!this.element.getAttribute("title")&&"string"==e||(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Wt:Bt]=!0),p(t.getTipElement()).hasClass(Mt)||t._hoverState===jt?t._hoverState=jt:(clearTimeout(t._timeout),t._hoverState=jt,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===jt&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||p(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),p(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Wt:Bt]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Pt,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Pt&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){var t=p(this.element).data();return Object.keys(t).forEach(function(e){-1!==Nt.indexOf(e)&&delete t[e]}),"number"==typeof(e=l({},this.constructor.Default,t,"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),m.typeCheckConfig(Et,e,this.constructor.DefaultType),e.sanitize&&(e.template=Ct(e.template,e.whiteList,e.sanitizeFn)),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Dt);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(p(e).removeClass(Ht),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=p(this).data(Tt),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),p(this).data(Tt,e)),"string"==typeof n)){if(void 0===e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Lt}},{key:"NAME",get:function(){return Et}},{key:"DATA_KEY",get:function(){return Tt}},{key:"Event",get:function(){return Rt}},{key:"EVENT_KEY",get:function(){return St}},{key:"DefaultType",get:function(){return Ot}}]),i}();p.fn[Et]=$t._jQueryInterface,p.fn[Et].Constructor=$t,p.fn[Et].noConflict=function(){return p.fn[Et]=kt,$t._jQueryInterface};var Vt="popover",Kt="bs.popover",Qt="."+Kt,Xt=p.fn[Vt],Yt="bs-popover",Gt=new RegExp("(^|\\s)"+Yt+"\\S+","g"),Jt=l({},$t.Default,{placement:"right",trigger:"click",content:"",template:''}),Zt=l({},$t.DefaultType,{content:"(string|element|function)"}),en="fade",tn="show",nn=".popover-header",rn=".popover-body",on={HIDE:"hide"+Qt,HIDDEN:"hidden"+Qt,SHOW:"show"+Qt,SHOWN:"shown"+Qt,INSERTED:"inserted"+Qt,CLICK:"click"+Qt,FOCUSIN:"focusin"+Qt,FOCUSOUT:"focusout"+Qt,MOUSEENTER:"mouseenter"+Qt,MOUSELEAVE:"mouseleave"+Qt},sn=function(e){function i(){return e.apply(this,arguments)||this}!function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t}(i,e);var t=i.prototype;return t.isWithContent=function(){return this.getTitle()||this._getContent()},t.addAttachmentClass=function(e){p(this.getTipElement()).addClass(Yt+"-"+e)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var e=p(this.getTipElement());this.setElementContent(e.find(nn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find(rn),t),e.removeClass(en+" "+tn)},t._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},t._cleanTipClass=function(){var e=p(this.getTipElement()),t=e.attr("class").match(Gt);null!==t&&0=this._offsets[r]&&(void 0===this._offsets[r+1]||e>16),i=38+(t>>8&255),r=38+(255&t);return"#"+(16777216+65536*(n<255?n<1?0:n:255)+256*(i<255?i<1?0:i:255)+(r<255?r<1?0:r:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,t){return e&&e.parentNode?d.hasClass(e,t)?e:this.traverseDOMPath(e.parentNode,t):null}};u.status={deny:"deny",allow:"allow",dismiss:"dismiss"},u.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n+"ransition"])return t[n];return""}(),u.hasTransition=!!u.transitionEnd;var r,t,n,o=Object.keys(u.status).map(d.escapeRegExp);u.customStyles={},u.Popup=(r={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
    {{policy}}
    ',compliance:{info:'
    {{dismiss}}
    ',"opt-in":'
    {{deny}}{{allow}}
    ',"opt-out":'
    {{deny}}{{allow}}
    '},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null},e.prototype.initialise=function(e){this.options&&this.destroy(),d.deepExtend(this.options={},r),d.isPlainObject(e)&&d.deepExtend(this.options,e),function(){var e=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return e(u.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return e(u.status.allow),!0;var t=Object.keys(u.status),n=this.getStatus(),i=0<=t.indexOf(n);return i&&e(n),i}.call(this)&&(this.options.enabled=!1),c(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),c(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var t=this.options.window.replace("{{classes}}",function(){var e=this.options,t="top"==e.position||"bottom"==e.position?"banner":"floating";d.isMobile()&&(t="floating");var n=["cc-"+t,"cc-type-"+e.type,"cc-theme-"+e.theme];return e.static&&n.push("cc-static"),n.push.apply(n,a.call(this)),function(e){var t=d.hash(JSON.stringify(e)),n="cc-color-override-"+t,i=d.isPlainObject(e);return this.customStyleSelector=i?n:null,i&&function(e,t,n){if(u.customStyles[e])return++u.customStyles[e].references;var i={},r=t.popup,o=t.button,s=t.highlight;r&&(r.text=r.text?r.text:d.getContrast(r.background),r.link=r.link?r.link:r.text,i[n+".cc-window"]=["color: "+r.text,"background-color: "+r.background],i[n+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],i[n+" .cc-link,"+n+" .cc-link:active,"+n+" .cc-link:visited"]=["color: "+r.link],o&&(o.text=o.text?o.text:d.getContrast(o.background),o.border=o.border?o.border:"transparent",i[n+" .cc-btn"]=["color: "+o.text,"border-color: "+o.border,"background-color: "+o.background],o.padding&&i[n+" .cc-btn"].push("padding: "+o.padding),"transparent"!=o.background&&(i[n+" .cc-btn:hover, "+n+" .cc-btn:focus"]=["background-color: "+(o.hover||function(e){return"000000"!=(e=d.normaliseHex(e))?d.getLuminance(e):"#222"}(o.background))]),s?(s.text=s.text?s.text:d.getContrast(s.background),s.border=s.border?s.border:"transparent",i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+s.text,"border-color: "+s.border,"background-color: "+s.background]):i[n+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var a=document.createElement("style");document.head.appendChild(a),u.customStyles[e]={references:1,element:a.sheet};var l=-1;for(var c in i)i.hasOwnProperty(c)&&a.sheet.insertRule(c+"{"+i[c].join(";")+"}",++l)}(t,e,"."+n),i}.call(this,this.options.palette),this.customStyleSelector&&n.push(this.customStyleSelector),n}.call(this).join(" ")).replace("{{children}}",function(){var t={},n=this.options;n.showLink||(n.elements.link="",n.elements.messagelink=n.elements.message),Object.keys(n.elements).forEach(function(e){t[e]=d.interpolateString(n.elements[e],function(e){var t=n.content[e];return e&&"string"==typeof t&&t.length?t:""})});var e=n.compliance[n.type];e=e||n.compliance.info,t.compliance=d.interpolateString(e,function(e){return t[e]});var i=n.layouts[n.layout];return i=i||n.layouts.basic,d.interpolateString(i,function(e){return t[e]})}.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(t=n),this.options.static){var i=l.call(this,'
    '+t+"
    ");i.style.display="",this.element=i.firstChild,this.element.style.display="none",d.addClass(this.element,"cc-invisible")}else this.element=l.call(this,t);(function(){var s=this.setStatus.bind(this),a=this.close.bind(this),e=this.options.dismissOnTimeout;"number"==typeof e&&0<=e&&(this.dismissTimeout=window.setTimeout(function(){s(u.status.dismiss),a(!0)},Math.floor(e)));var t=this.options.dismissOnScroll;if("number"==typeof t&&0<=t){var n=function(e){window.pageYOffset>Math.floor(t)&&(s(u.status.dismiss),a(!0),window.removeEventListener("scroll",n),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=n,window.addEventListener("scroll",n))}var i=this.options.dismissOnWindowClick,l=this.options.ignoreClicksFrom;if(i){var c=function(e){for(var t=!1,n=e.path.length,i=l.length,r=0;rn&&(t=!0),t?d.hasClass(i,"cc-active")||d.addClass(i,"cc-active"):d.hasClass(i,"cc-active")&&d.removeClass(i,"cc-active")},200);this.onMouseMove=n,window.addEventListener("mousemove",n)}}}.call(this),this.options.autoOpen&&this.autoOpen()},e.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(e){if(d.isPlainObject(e)){var t=d.hash(JSON.stringify(e)),n=u.customStyles[t];if(n&&!--n.references){var i=n.element.ownerNode;i&&i.parentNode&&i.parentNode.removeChild(i),u.customStyles[t]=null}}}(this.options.palette),this.options=null},e.prototype.open=function(e){if(this.element)return this.isOpen()||(u.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},e.prototype.close=function(e){if(this.element)return this.isOpen()&&(u.hasTransition?this.fadeOut():this.element.style.display="none",e&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},e.prototype.fadeIn=function(){var e=this.element;if(u.hasTransition&&e&&(this.afterTransition&&s.call(this,e),d.hasClass(e,"cc-invisible"))){if(e.style.display="",this.options.static){var t=this.element.clientHeight;this.element.parentNode.style.maxHeight=t+"px"}this.openingTimeout=setTimeout(i.bind(this,e),20)}},e.prototype.fadeOut=function(){var e=this.element;u.hasTransition&&e&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),i.bind(this,e)),d.hasClass(e,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,e),e.addEventListener(u.transitionEnd,this.afterTransition),d.addClass(e,"cc-invisible")))},e.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!u.hasTransition||!d.hasClass(this.element,"cc-invisible"))},e.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},e.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},e.prototype.hasAnswered=function(e){return 0<=Object.keys(u.status).indexOf(this.getStatus())},e.prototype.hasConsented=function(e){var t=this.getStatus();return t==u.status.allow||t==u.status.dismiss},e.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},e.prototype.setStatus=function(e){var t=this.options.cookie,n=d.getCookie(t.name),i=0<=Object.keys(u.status).indexOf(n);0<=Object.keys(u.status).indexOf(e)?(d.setCookie(t.name,e,t.expiryDays,t.domain,t.path,t.secure),this.options.onStatusChange.call(this,e,i)):this.clearStatus()},e.prototype.getStatus=function(){return d.getCookie(this.options.cookie.name)},e.prototype.clearStatus=function(){var e=this.options.cookie;d.setCookie(e.name,"",-1,e.domain,e.path)},e),u.Location=(t={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var n=JSON.parse(t);return n.error?m(n):{code:n.country}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var n=JSON.parse(t);return"ERROR"==n.statusCode?m({error:n.statusMessage}):{code:n.countryCode}}catch(e){return m({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(t){window.geoip2?geoip2.country(function(e){try{t({code:e.country.iso_code})}catch(e){t(m(e))}},function(e){t(m(e))}):t(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}},h.prototype.getNextService=function(){for(var e;e=this.getServiceByIdx(++this.currentServiceIndex),this.currentServiceIndex>>0;if("function"!=typeof e)throw TypeError();var i,r=arguments[1];for(i=0;i>16&255)),n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i)),i=r=0),t+=1;return 12===r?(i>>=4,n.push(String.fromCharCode(255&i))):18===r&&(i>>=2,n.push(String.fromCharCode(i>>8&255)),n.push(String.fromCharCode(255&i))),n.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,i,r,o,s,a,l=0,c=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,o=(3&t)<<4|(n=e.charCodeAt(l++))>>4,s=(15&n)<<2|(i=e.charCodeAt(l++))>>6,a=63&i,l===e.length+2?a=s=64:l===e.length+1&&(a=64),c.push(u.charAt(r),u.charAt(o),u.charAt(s),u.charAt(a));return c.join("")},Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in r==!1&&(r.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in r.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),r.performance.now=function(){return Date.now()-e}}}(),r.requestAnimationFrame||(r.webkitRequestAnimationFrame&&r.webkitCancelAnimationFrame?((i=r).requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(i.performance.now())})},i.cancelAnimationFrame=i.webkitCancelAnimationFrame):r.mozRequestAnimationFrame&&r.mozCancelAnimationFrame?((n=r).requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(n.performance.now())})},n.cancelAnimationFrame=n.mozCancelAnimationFrame):((t=r).requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return r={},n.m=i=[function(e,t,n){e.exports=n(1)},function(a,e,O){(function(c){var e=O(2),h=O(3),T=O(6),g=O(7),v=O(8),y=O(9),S=O(10),t=O(11),u=O(12),d=O(15),m=g.extend,b=g.dimensionCheck,w=t.svg_ns,i={version:t.version,addTheme:function(e,t){return null!=e&&null!=t&&(k.settings.themes[e]=t),delete k.vars.cache.themeKeys,this},addImage:function(i,e){return y.getNodeArray(e).forEach(function(e){var t=y.newEl("img"),n={};n[k.setup.dataAttr]=i,y.setAttr(t,n),e.appendChild(t)}),this},setResizeUpdate:function(e,t){e.holderData&&(e.holderData.resizeUpdate=!!t,e.holderData.resizeUpdate&&x(e))},run:function(e){e=e||{};var u={},d=m(k.settings,e);k.vars.preempted=!0,k.vars.dataAttr=d.dataAttr||k.setup.dataAttr,u.renderer=d.renderer?d.renderer:k.setup.renderer,-1===k.setup.renderers.join(",").indexOf(u.renderer)&&(u.renderer=k.setup.supportsSVG?"svg":k.setup.supportsCanvas?"canvas":"html");var t=y.getNodeArray(d.images),n=y.getNodeArray(d.bgnodes),i=y.getNodeArray(d.stylenodes),r=y.getNodeArray(d.objects);return u.stylesheets=[],u.svgXMLStylesheet=!0,u.noFontFallback=!!d.noFontFallback,u.noBackgroundSize=!!d.noBackgroundSize,i.forEach(function(e){if(e.attributes.rel&&e.attributes.href&&"stylesheet"==e.attributes.rel.value){var t=e.attributes.href.value,n=y.newEl("a");n.href=t;var i=n.protocol+"//"+n.host+n.pathname+n.search;u.stylesheets.push(i)}}),n.forEach(function(e){if(c.getComputedStyle){var t=c.getComputedStyle(e,null).getPropertyValue("background-image"),n=e.getAttribute("data-background-src")||t,i=null,r=d.domain+"/",o=n.indexOf(r);if(0===o)i=n;else if(1===o&&"?"===n[0])i=n.slice(1);else{var s=n.substr(o).match(/([^\"]*)"?\)/);if(null!==s)i=s[1];else if(0===n.indexOf("url("))throw"Holder: unable to parse background URL: "+n}if(i){var a=l(i,d);a&&p({mode:"background",el:e,flags:a,engineSettings:u})}}}),r.forEach(function(e){var t={};try{t.data=e.getAttribute("data"),t.dataSrc=e.getAttribute(k.vars.dataAttr)}catch(e){}var n=null!=t.data&&0===t.data.indexOf(d.domain),i=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain);n?f(d,u,t.data,e):i&&f(d,u,t.dataSrc,e)}),t.forEach(function(e){var t={};try{t.src=e.getAttribute("src"),t.dataSrc=e.getAttribute(k.vars.dataAttr),t.rendered=e.getAttribute("data-holder-rendered")}catch(e){}var n,i,r,o,s,a=null!=t.src,l=null!=t.dataSrc&&0===t.dataSrc.indexOf(d.domain),c=null!=t.rendered&&"true"==t.rendered;a?0===t.src.indexOf(d.domain)?f(d,u,t.src,e):l&&(c?f(d,u,t.dataSrc,e):(n=t.src,i=d,r=u,o=t.dataSrc,s=e,g.imageExists(n,function(e){e||f(i,r,o,s)}))):l&&f(d,u,t.dataSrc,e)}),this}},k={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",themes:{gray:{bg:"#EEEEEE",fg:"#AAAAAA"},social:{bg:"#3a5a97",fg:"#FFFFFF"},industrial:{bg:"#434A52",fg:"#C2F200"},sky:{bg:"#0D8FDB",fg:"#FFFFFF"},vine:{bg:"#39DBAC",fg:"#1E292C"},lava:{bg:"#F8591A",fg:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16}};function f(e,t,n,i){var r=l(n.substr(n.lastIndexOf(e.domain)),e);r&&p({mode:null,el:i,flags:r,engineSettings:t})}function l(e,t){var n={theme:m(k.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},i=e.indexOf("?"),r=[e];-1!==i&&(r=[e.slice(0,i),e.slice(i+1)]);var o=r[0].split("/");n.holderURL=e;var s=o[1],a=s.match(/([\d]+p?)x([\d]+p?)/);if(!a)return!1;if(n.fluid=-1!==s.indexOf("p"),n.dimensions={width:a[1].replace("p","%"),height:a[2].replace("p","%")},2===r.length){var l=h.parse(r[1]);if(g.truthy(l.ratio)){n.fluid=!0;var c=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(u/c*100),c=100,n.dimensions.width=c+"%",n.dimensions.height=u+"%"}if(n.auto=g.truthy(l.auto),l.bg&&(n.theme.bg=g.parseColor(l.bg)),l.fg&&(n.theme.fg=g.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=m(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&parseFloat(l.size)&&(n.size=parseFloat(l.size)),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=g.truthy(l.nowrap),n.outline=g.truthy(l.outline),g.truthy(l.random)){k.vars.cache.themeKeys=k.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var d=k.vars.cache.themeKeys[0|Math.random()*k.vars.cache.themeKeys.length];n.theme=m(n.instanceOptions.themes[d],null)}}return n}function p(e){var t=e.mode,n=e.el,i=e.flags,r=e.engineSettings,o=i.dimensions,s=i.theme,a=o.width+"x"+o.height;t=null==t?i.fluid?"fluid":"image":t;if(null!=i.text&&(s.text=i.text,"object"===n.nodeName.toLowerCase())){for(var l=s.text.split("\\n"),c=0;c=r||!0==E)&&(v(f,g,b,f.properties.leading),f.add(g),b=0,w+=f.properties.leading,_+=1,(g=new s.Group("line"+_)).y=w),!0!=E&&(m.moveTo(b,0),b+=p.spaceWidth+C.width,g.add(m))}if(v(f,g,b,f.properties.leading),f.add(g),"left"===e.align)f.moveTo(e.width-i,null,null);else if("right"===e.align){for(y in f.children)(g=f.children[y]).moveTo(e.width-g.width,null,null);f.moveTo(0-(e.width-i),null,null)}else{for(y in f.children)(g=f.children[y]).moveTo((f.width-g.width)/2,null,null);f.moveTo((e.width-f.width)/2,null,null)}f.moveTo(null,(e.height-f.height)/2,null),(e.height-f.height)/2<0&&f.moveTo(null,0,null)}else m=new s.Text(e.text),(g=new s.Group("line0")).add(m),f.add(g),"left"===e.align?f.moveTo(e.width-i,null,null):"right"===e.align?f.moveTo(0-(e.width-i),null,null):f.moveTo((e.width-p.boundingBox.width)/2,null,null),f.moveTo(null,(e.height-p.boundingBox.height)/2,null);return o}(s);function l(){var e=null;switch(o.renderer){case"canvas":e=d(a,t);break;case"svg":e=u(a,t);break;default:throw"Holder: invalid renderer: "+o.renderer}return e}if(null==(e=l()))throw"Holder: couldn't render placeholder";"background"==n?(i.style.backgroundImage="url("+e+")",o.noBackgroundSize||(i.style.backgroundSize=s.width+"px "+s.height+"px")):("img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"}),o.reRender&&c.setTimeout(function(){var e=l();if(null==e)throw"Holder: couldn't render placeholder";"img"===i.nodeName.toLowerCase()?y.setAttr(i,{src:e}):"object"===i.nodeName.toLowerCase()&&y.setAttr(i,{data:e,type:"image/svg+xml"})},150)),y.setAttr(i,{"data-holder-rendered":!0})}function x(e){for(var t,n=0,i=(t=null==e||null==e.nodeType?k.vars.resizableImages:[e]).length;n","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){function s(e,t){"string"==typeof e&&("#"===(this.original=e).charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))}s.rgb2hex=function(e,t,n){return[e,t,n].map(function(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}).join("")},s.hsl2rgb=function(e,t,n){var i=e/60,r=(1-Math.abs(2*n-1))*t,o=r*(1-Math.abs(parseInt(i)%2-1)),s=n-r/2,a=0,l=0,c=0;return 0<=i&&i<1?(a=r,l=o):1<=i&&i<2?(a=o,l=r):2<=i&&i<3?(l=r,c=o):3<=i&&i<4?(l=o,c=r):4<=i&&i<5?(a=o,c=r):5<=i&&i<6&&(a=r,c=o),a+=s,l+=s,c+=s,[a=parseInt(255*a),l=parseInt(255*l),c=parseInt(255*c)]},s.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,i=255&this.raw,r=.2126*t+.7152*n+.0722*i,o=-.09991*t-.33609*n+.436*i,s=.615*t-.55861*n-.05639*i;return this.rgb={r:t,g:n,b:i},this.yuv={y:r,u:o,v:s},this},s.prototype.lighten=function(e){var t=255*(Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1))|0,n=Math.min(255,Math.max(0,this.rgb.r+t)),i=Math.min(255,Math.max(0,this.rgb.g+t)),r=Math.min(255,Math.max(0,this.rgb.b+t)),o=s.rgb2hex(n,i,r);return new s(o)},s.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},s.prototype.lighterThan=function(e){return e instanceof s||(e=new s(e)),this.yuv.y>e.yuv.y},s.prototype.blendAlpha=function(e){e instanceof s||(e=new s(e));var t=e,n=t.alpha*t.rgb.r+(1-t.alpha)*this.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*this.rgb.g,r=t.alpha*t.rgb.b+(1-t.alpha)*this.rgb.b;return new s(s.rgb2hex(n,i,r))},e.exports=s},function(e,t){e.exports={version:"2.9.6",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){var y=n(13),b=n(8),i=n(11),w=n(7),_=i.svg_ns,x=function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]};e.exports=function(e,t){var n=t.engineSettings.stylesheets.map(function(e){return''}).join("\n"),i="holder_"+Number(new Date).toString(16),r=e.root,s=r.children.holderTextGroup,o="#"+i+" text { "+function(e){return w.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}(s.properties)+" } ";s.y+=.8*s.textPositionData.boundingBox.height;var a=[];Object.keys(s.children).forEach(function(e){var o=s.children[e];Object.keys(o.children).forEach(function(e){var t=o.children[e],n=s.x+o.x+t.x,i=s.y+o.y+t.y,r=x({tag:"text",content:t.properties.text,x:n,y:i});a.push(r)})});var l=x({tag:"g",content:a}),c=null;if(r.children.holderBg.properties.outline){var u=r.children.holderBg.properties.outline;c=x({tag:"path",d:function(e,t,n){var i=n/2;return["M",i,i,"H",e-i,"V",t-i,"H",i,"V",0,"M",0,i,"L",e,t-i,"M",0,t-i,"L",e,i].join(" ")}(r.children.holderBg.width,r.children.holderBg.height,u.width),"stroke-width":u.width,stroke:u.fill,fill:"none"})}var d=function(e,t){return x({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}(r.children.holderBg,"rect"),h=[];h.push(d),u&&h.push(c),h.push(l);var f=x({tag:"g",id:i,content:h}),p=x({tag:"style",content:o,type:"text/css"}),m=x({tag:"defs",content:p}),g=x({tag:"svg",content:[m,f],width:r.properties.width,height:r.properties.height,xmlns:_,viewBox:[0,0,r.properties.width,r.properties.height].join(" "),preserveAspectRatio:"none"}),v=y(g);return/\&(x)?#[0-9A-Fa-f]/.test(v[0])&&(v[0]=v[0].replace(/&#/gm,"&#")),v=n+v[0],b.svgStringToDataURI(v,"background"===t.mode)}},function(e,t,n){n(14);e.exports=function e(t,n,i){"use strict";var r,o,s,a,l,c,u,d,h,f,p,m,g=1,v=!0;function y(e,t){if(null!==t&&!1!==t&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}if(i=i||{},"string"==typeof t[0])t[0]=(l=t[0],c=l.match(/^[\w-]+/),u={tag:c?c[0]:"div",attr:{},children:[]},d=l.match(/#([\w-]+)/),h=l.match(/\$([\w-]+)/),f=l.match(/\.[\w-]+/g),d&&(u.attr.id=d[1],i[d[1]]=u),h&&(i[h[1]]=u),f&&(u.attr.class=f.join(" ").replace(/\./g,"")),l.match(/&$/g)&&(v=!1),u);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));g=0}for(;g/g,">"))),t[0].children.push(t[g]);else if("number"==typeof t[g])t[0].children.push(t[g]);else if(Array.isArray(t[g])){if(Array.isArray(t[g][0])){if(t[g].reverse().forEach(function(e){t.splice(g+1,0,e)}),0!==g)continue;g++}e(t[g],n,i),t[g][0]&&t[0].children.push(t[g][0])}else if("function"==typeof t[g])s=t[g];else{if("object"!=typeof t[g])throw new TypeError('"'+t[g]+'" is not allowed as a value.');for(o in t[g])t[g].hasOwnProperty(o)&&null!==t[g][o]&&!1!==t[g][o]&&("style"===o&&"object"==typeof t[g][o]?t[0].attr[o]=JSON.stringify(t[g][o],y).slice(2,-2).replace(/","/g,";").replace(/":"/g,":").replace(/\\"/g,"'"):t[0].attr[o]=t[g][o])}}if(!1!==t[0]){for(a in r="<"+t[0].tag,t[0].attr)t[0].attr.hasOwnProperty(a)&&(r+=" "+a+'="'+((m=t[0].attr[a])||0===m?String(m).replace(/&/g,"&").replace(/"/g,"""):"")+'"');r+=">",t[0].children.forEach(function(e){r+=e}),r+="",t[0]=r}return i[0]=t[0],s&&s(t[0]),i}},function(e,t){"use strict";var a=/["'&<>]/;e.exports=function(e){var t,n=""+e,i=a.exec(n);if(!i)return n;var r="",o=0,s=0;for(o=i.index;o Date: Thu, 23 Jan 2020 14:41:25 +0100 Subject: [PATCH 334/338] Update to 1.0.0-rc1-update2 --- templates/2-publish-template.ps1 | 2 +- .../Skoruba.IdentityServer4.Admin.Templates.nuspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/2-publish-template.ps1 b/templates/2-publish-template.ps1 index ef47c3e27..c79f7bdde 100644 --- a/templates/2-publish-template.ps1 +++ b/templates/2-publish-template.ps1 @@ -3,7 +3,7 @@ nuget pack $templateNuspecPath dotnet new --debug:reinit -$templateLocalName = "Skoruba.IdentityServer4.Admin.Templates.1.0.0-rc1-update1.nupkg" +$templateLocalName = "Skoruba.IdentityServer4.Admin.Templates.1.0.0-rc1-update2.nupkg" dotnet.exe new -i $templateLocalName dotnet.exe new skoruba.is4admin --name MyProject --title MyProject --adminemail 'admin@skoruba.com' --adminpassword 'Pa$$word123' --adminrole MyRole --adminclientid MyClientId --adminclientsecret MyClientSecret --dockersupport true \ No newline at end of file diff --git a/templates/template-publish/Skoruba.IdentityServer4.Admin.Templates.nuspec b/templates/template-publish/Skoruba.IdentityServer4.Admin.Templates.nuspec index c89606397..4c9486ceb 100644 --- a/templates/template-publish/Skoruba.IdentityServer4.Admin.Templates.nuspec +++ b/templates/template-publish/Skoruba.IdentityServer4.Admin.Templates.nuspec @@ -2,7 +2,7 @@ Skoruba.IdentityServer4.Admin.Templates - 1.0.0-rc1-update1 + 1.0.0-rc1-update2 Jan Škoruba false https://github.com/skoruba/IdentityServer4.Admin/blob/master/LICENSE.md From e8bc9baaa503af2f205131ad2ee43ccc8c976414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Thu, 23 Jan 2020 14:47:35 +0100 Subject: [PATCH 335/338] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a10f667a3..97174d59a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The application is written in the **Asp.Net Core MVC - using .NET Core 3.1** - Install the dotnet new template: ```sh -dotnet new -i Skoruba.IdentityServer4.Admin.Templates::1.0.0-rc1-update1 +dotnet new -i Skoruba.IdentityServer4.Admin.Templates::1.0.0-rc1-update2 ``` - Create new project: From 853d505c987d382eaf5f70a33a5a76d0d8c54849 Mon Sep 17 00:00:00 2001 From: janskoruba Date: Thu, 23 Jan 2020 17:00:29 +0100 Subject: [PATCH 336/338] Add publish script for docker hub --- build/publish-docker-images.ps1 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 build/publish-docker-images.ps1 diff --git a/build/publish-docker-images.ps1 b/build/publish-docker-images.ps1 new file mode 100644 index 000000000..006a7a4bf --- /dev/null +++ b/build/publish-docker-images.ps1 @@ -0,0 +1,12 @@ +# build docker images according to docker-compose +docker-compose build + +# rename images with following tag +docker tag skoruba-identityserver4-admin skoruba/identityserver4-admin:rc1 +docker tag skoruba-identityserver4-sts-identity skoruba/identityserver4-sts-identity:rc1 +docker tag skoruba-identityserver4-admin-api skoruba/identityserver4-admin-api:rc1 + +# push to docker hub +docker push skoruba/identityserver4-admin:rc1 +docker push skoruba/identityserver4-admin-api:rc1 +docker push skoruba/identityserver4-sts-identity:rc1 \ No newline at end of file From 50da1e4ffb4b133f5499791bfa8492dbeb367808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Thu, 23 Jan 2020 17:03:42 +0100 Subject: [PATCH 337/338] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 97174d59a..50568b275 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,9 @@ docker-compose up -d - `skoruba/identityserver4-admin-api:rc1` - STS: - `skoruba/identityserver4-sts-identity:rc1` + +### Publish Docker images to Docker hub +- Check the script in `build/publish-docker-images.ps1` - change the profile name according to your requirements. ## Installation of the Client Libraries From a3162c32fffc517e662f94ca48ee4054fd272e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0koruba?= Date: Fri, 24 Jan 2020 09:35:39 +0100 Subject: [PATCH 338/338] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50568b275..94474acdd 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ dotnet new -i Skoruba.IdentityServer4.Admin.Templates::1.0.0-rc1-update2 - Create new project: ```sh -dotnet new skoruba.is4admin --name MyProject --title MyProject --adminemail "admin@skoruba.com" --adminpassword "Pa$$word123" --adminrole MyRole --adminclientid MyClientId --adminclientsecret MyClientSecret --dockersupport true +dotnet new skoruba.is4admin --name MyProject --title MyProject --adminemail "admin@example.com" --adminpassword "Pa$$word123" --adminrole MyRole --adminclientid MyClientId --adminclientsecret MyClientSecret --dockersupport true ``` Project template options: